1 /*   viewer3d.c
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *            National Center for Biotechnology Information (NCBI)
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government do not place any restriction on its use or reproduction.
13 *  We would, however, appreciate having the NCBI and the author cited in
14 *  any work or product based on this material
15 *
16 *  Although all reasonable efforts have been taken to ensure the accuracy
17 *  and reliability of the software and data, the NLM and the U.S.
18 *  Government do not and cannot warrant the performance or results that
19 *  may be obtained by using this software or data. The NLM and the U.S.
20 *  Government disclaim all warranties, express or implied, including
21 *  warranties of performance, merchantability or fitness for any particular
22 *  purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name:  viewer3d.c
27 *
28 * Author:  Alex Smirnov, Denis Vakatov
29 *
30 * Version Creation Date:   04/03/95
31 *
32 * $Revision: 6.6 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * $Log: viewer3d.c,v $
39 * Revision 6.6  2007/05/01 22:01:30  kans
40 * changes in preparation for supporing Quartz on Macintosh
41 *
42 * Revision 6.5  2000/01/11 01:16:45  lewisg
43 * fix color selection in Cn3D, other misc. bugs
44 *
45 * Revision 6.4  1998/08/12 23:04:06  vakatov
46 * [64-bit platforms]  Made "idBuffer" be VoidPtr[] rather than Int4[];
47 * Fixed bugs mostly caused by casting between Int4 vars and 8-byte pointers
48 *
49 * Revision 6.3  1998/08/07 22:27:00  vakatov
50 * +FitZ() -- makes sure that picture does not outrun the "Z=0" plane
51 * +GetSphere3D() -- to keep in-sync the viewer and static Nlm_stCon
52 *
53 * Revision 6.2  1998/04/20 18:30:36  lewisg
54 * moved typedef for _Nlm_Viewer3D to include file
55 *
56 * Revision 6.1  1997/11/26 21:30:56  vakatov
57 * Fixed errors and warnings issued by C and C++ (GNU and Sun) compilers
58 *
59 * Revision 5.17  1997/06/12 20:56:57  vakatov
60 * Nlm_SetPosition3D() -- don't fail if the drawing area gets too small
61 * ScreenToWorld() -- fixed memory leak
62 *
63 * Revision 5.16  1997/06/11 17:07:36  vakatov
64 * DrawViewer3D():  redraw if p_version has changed
65 *
66 * Revision 5.15  1997/05/29 17:54:13  vakatov
67 * Provided unconditional redraw of highlighted primitives
68 *
69 * Revision 5.14  1997/05/20 15:15:08  vakatov
70 * Rotate():  on Z-rotation, now rotate around the center of currently
71 * visible area(instead of the picture center);  added ScreenToWorld()
72 * function to map screen coordinates to the world ones
73 *
74 * Revision 5.13  1997/03/31 16:52:37  vakatov
75 * Z-rotation implemented and added to alternative standard mouse
76 * groups(-ZX and -YZ). Added Z-rotation scrollbar.
77 * Moved all picture-rotation code from rotateXY(), QRotate() and
78 * RotateViewer() to the new universal Rotate().
79 *
80  * Revision 1.25  1997/03/31  16:18:12  vakatov
81  * Fixed scrollbar updating (using ResetClip) in ViewerRotate. Other
82  * minor fixes.
83  *
84  * Revision 1.24  1997/03/25  22:59:41  vakatov
85  * All coord-rotation code from rotateXY(), QRotate() and RotateVierer()
86  * moved to the new universal Rotate()
87  * Z-rotation added to alternative standard mouse groups(-ZX and -YZ)
88  *
89  * Revision 1.23  1997/03/25  19:40:38  vakatov
90  * Z-rotation works;  wanna revise the former rotateXY() function to let
91  * it rotate around an arbitrary point
92  *
93  * Revision 5.12  1997/03/21  16:17:05  vakatov
94  * For SunOS compiler, casted most of the MemCpy() #1,#2 arguments to VoidPtr
95  *
96  * Revision 5.11  1997/03/20  19:03:16  vakatov
97  * Heavily redesigned the 3D-Viewer code and internal data structures to work
98  * with the new panel-mouse management.
99  * Incapsulated code&data of the 3D-Viewer controls.
100  * Added code for the "soft viewer resize".  General code cleaning.
101  *
102  * Revision 5.10  1996/11/22  19:47:29  vakatov
103  * Nlm_CreateViewer3D():  set image-dependent background color;
104  * + extensive type casting
105  *
106  * Revision 5.9  1996/09/20  13:54:47  vakatov
107  * Nlm_AttachPicture3D(): assign new picture *at first*; then do anyth. else
108  *
109  * Revision 5.8  1996/09/19  18:54:18  vakatov
110  * Replace Reset() by CorrectBarValue() to avoid undesirable call to
111  * the scrollbar callbacks
112  *
113  * Revision 5.7  1996/07/25  14:52:34  epstein
114  * BigScalar change for OSF1 portability
115  *
116  * Revision 5.6  1996/07/24  16:59:59  vakatov
117  * Trapped crashes caused by attempts to rotate and zoom blank 3D-pictures
118  *
119  * Revision 5.5  1996/07/23  21:51:29  vakatov
120  * [WIN_MOTIF]  Reserve 32th(instead of 0th) color for the background
121  * color; it lets CN3D do not confuse other parts of the program and allows
122  * to save the background color to GIF metafile
123  *
124  * Revision 5.3  1996/06/14  20:16:38  vakatov
125  * [WIN_MSWIN]  Slight modification in the bg-color setting
126  *
127  * Revision 5.2  1996/06/14  14:33:04  vakatov
128  * Added a set of functions to control the 3D-Viewer background color
129  * [WIN_MOTIF] Special precautions made to avoid Motif/3D-Viewer color conflict
130  *
131  * Revision 5.1  1996/06/07  15:19:39  hogue
132  * Removed the PlayLayer button and sundry stuff from MAC.
133  *
134  * Revision 5.0  1996/05/28  13:45:08  ostell
135  * Set to revision 5.0
136  *
137  * Revision 1.23  1996/05/23  14:36:35  hogue
138  * Fixed PrintViewer/PasteViewer discrepancy in .h file, added
139  * IsPlaying3D, StopPlaying3D, StartPlaying3D for more
140  * external control of the animation
141  *
142  * Revision 1.22  1996/05/21  22:00:40  vakatov
143  * The viewer scrollbar width/height are now treated more carefully.
144  * Do not store viewer width and height in the camera position storage as
145  * it caused a coredump when resizing the viewer.
146  * Viewer rotation flag is ON(was OFF) in the very begining.
147  *
148  * Revision 1.21  1996/05/14  15:29:08  hogue
149  * Made the Horizontal viewer controls more compact.
150  *
151  * Revision 1.20  1996/05/13  15:04:21  hogue
152  * Save button in Viewer Controls now optional
153  *
154  * Revision 1.19  1996/05/09  18:45:35  vakatov
155  * There was a bug resulting the program crash while switching between
156  * pictures with different number of layers(and then restoring the
157  * camera position) -- fixed.
158  *
159  * Revision 1.18  1996/05/07  18:30:03  vakatov
160  * Nlm_CreateViewer3D() -- slightly changed;
161  * Nlm_AllLayerSetStates3D() function -- added;
162  * Nlm_AllLayerSet3D() -- modified, "state" parameter added
163  * Nlm_RewindLayer3D() -- prototype and content modified;
164  * + a lot of variable casting and code simplifying
165  *
166  * Revision 1.17  1996/04/23  16:30:47  vakatov
167  * Nlm_PlayLayer3D() -- fixed an extra(some cycles) delay responding to
168  * the V3D_bPLAY("Go") toggle button release event
169  *
170  * Revision 1.16  1996/04/17  21:31:58  vakatov
171  * Implemented "Nlm_SaveViewer3D()" function which allows one to save
172  * presently visible part of the 3D-viewer picture into a GIF metafile.
173  * Added "Copy" button to the 3D-viewer controls.
174  * Fixed a bug caused by "the asynchroneous commenting" of "Print" and "Copy"
175  * controls.
176  * Added "Nlm_GetViewerImage3D()" function returning image of the 3D-viewer.
177  *
178  * Revision 1.15  1996/04/09  15:24:49  vakatov
179  * Most of the basic, commonly used colors (0 - 15, eventually including
180  * white and black) are not to be overwritten by the 3D-viewer image
181  * drawing routine now.
182  * The initial brightness level has been increased from 3 to 4 (43% to 57%).
183  *
184  * Revision 1.14  1996/04/07  20:04:56  kans
185  * getlayertop3d needed (void) as prototype
186  *
187  * Revision 1.13  1996/04/04  18:58:39  vakatov
188  * Slight corrections to the camera storing/restoring algorithm and
189  * the relevant data to avoid the object/camera position mismatching --
190  * while setting the camera attributes stored during the work with another
191  * picture.
192  *
193  * Revision 1.12  1996/04/03  16:03:33  vakatov
194  * Now ZoomAll() can keep the camera angle (ZOOM_KEEP_ANGLE method)
195  *
196  * Revision 1.11  1996/04/02  22:30:02  vakatov
197  * AttachZoomPic3D() removed; now previously stored camera position
198  * is to be restored within AttachPicture3D automatically, as soon as
199  * valid (non-NULL and initialized) "camera" argument is provided
200  *
201  * Revision 1.10  1996/04/01  23:07:03  vakatov
202  * Now one can use prevously stored camera position
203  * in the "AttachZoomPic3D(...,TRUE)"
204  *
205  * Revision 1.8  1996/03/30  23:48:02  hogue
206  * removed unused variables, fixed a return value.
207  *
208  * Revision 1.7  1996/03/30  23:24:47  hogue
209  * Cast MemCpy and Memset, changed camera to Int4, fixed nonportable uses of MemCpy, Added an AttachZoomPic .  Cameras are still not always saved and restored correctly...
210  *
211 * ==========================================================================
212 */
213 
214 #include <math.h>
215 
216 #ifndef _VIBRANT_
217 #include <vibrant.h>
218 #endif
219 
220 #ifndef _VIEWER3D_
221 #include <viewer3d.h>
222 #endif
223 
224 #ifndef _PPICT3D_
225 #include <ppict3d.h>
226 #endif
227 
228 #include <matrix.h>
229 
230 
231 /*****************************************************************************
232 *
233 *   DEFINES
234 *
235 *****************************************************************************/
236 
237 #define CAMERA_KEY      8071967
238 #define FIND_BLOCK_SIZE 8
239 
240 
241 /*****************************************************************************
242 *
243 *   TYPEDEFS and DECLARATIONS
244 *
245 *****************************************************************************/
246 
247 typedef struct _Nlm_Viewer3D structViewer3D;
248 
249 typedef struct
250 {
251   Uint1  perspectN;
252   Uint1  brighN;
253   Uint1  colorPicN;
254   Uint1  colorHLR, colorHLG, colorHLB;
255   Uint1  colorFon;
256   Uint1  adjust;
257   Int4   scale;
258   Uint1  colorFonR, colorFonG, colorFonB, dummy_align;
259 }  PCamera3DUnion;
260 
261 
262 struct _Nlm_Controls3D
263 {
264   GrouP   group;
265 
266   ButtoN  zoomAll;
267   ButtoN  Move3D;
268   ButtoN  Zoom3D;
269   GrouP   adjustButtons;
270   ButtoN  plusButton;
271   ButtoN  minusButton;
272 
273 /* layer - animation controls */
274   ButtoN  allButton;
275   ButtoN  rewindButton;
276   ButtoN  prevButton;
277   ButtoN  nextButton;
278   ButtoN  playButton;
279 }  structControls3D;
280 
281 
282 
283 typedef enum
284 {
285   ZOOM_ALL,
286   ZOOM_KEEP_ANGLE,
287   ZOOM_KEEP_ALL
288 }
289 enumZoom3D;
290 
291 
292 typedef enum
293 {
294   ROTATE_X,
295   ROTATE_Y,
296   ROTATE_Z
297 }
298 enumRotate3D;
299 
300 
301 /*****************************************************************************
302 *
303 *   GLOBAL VARIABLES
304 *
305 *****************************************************************************/
306 
307 Uint1  Nlm_Isqrt[129*129];
308 extern Nlm_Context3D Nlm_stCon;
309 
310 
311 
312 /*****************************************************************************
313 *
314 *   STATIC VARIABLES
315 *
316 *****************************************************************************/
317 
318 static CharPtr      viewerClass = "Viewer3D";
319 static Boolean      isqrtInit = FALSE;
320 static Uint1        perspectAll[6] = { 8,6,4,3,2,1 };
321 static Int2         brighAll[7]    = { -150,-100,-50,0,50,100,150 };
322 static Uint1        colorPicAll[6] = { 2,3,4,6,8,255 };
323 static Uint1        currlayer = 0;
324 static ButtoN       V3D_bPLAY = NULL;
325 static Uint1        toplayer  = 0;
326 
327 
328 /*****************************************************************************
329 *
330 *   STATIC FUNCTIONS
331 *
332 *****************************************************************************/
333 
SetUpContext(Viewer3D vvv)334 static void SetUpContext(Viewer3D vvv)
335 {
336   Nlm_stCon.xmin = (Int4)0;
337   Nlm_stCon.xmax = (Int4)vvv->width - 1;
338   Nlm_stCon.ymin = (Int4)0;
339   Nlm_stCon.ymax = (Int4)vvv->height - 1;
340   Nlm_stCon.zmax = vvv->zmax;
341   Nlm_stCon.pic  = vvv->pic;
342   Nlm_stCon.width  = (Int4)vvv->width;
343   Nlm_stCon.height = (Int4)vvv->height;
344   MemCpy(Nlm_stCon.layerTable, vvv->layerTable, sizeof(Nlm_stCon.layerTable));
345   MemCpy((VoidPtr)Nlm_stCon.a, (VoidPtr)vvv->a, sizeof(Nlm_stCon.a         ));
346   MemCpy((VoidPtr)Nlm_stCon.c, (VoidPtr)vvv->c, sizeof(Nlm_stCon.c         ));
347   Nlm_stCon.scale = vvv->scale;
348   Nlm_stCon.colorOffset = vvv->colorOffset;
349   Nlm_stCon.colorStep   = vvv->colorStep;
350   Nlm_stCon.colorScale  = vvv->colorScale;
351   Nlm_stCon.perspect   = vvv->perspect;
352   Nlm_stCon.zmaxPersp  = Nlm_stCon.perspect  * Nlm_stCon.zmax;
353   Nlm_stCon.zmaxPersp1 = Nlm_stCon.zmaxPersp + Nlm_stCon.zmax;
354   if ( vvv->pic )
355     Nlm_stCon.colorHL = (Uint1)((Nlm_PPict3DPtr)vvv->pic)->totalColors;
356 }
357 
GetSphere3D(Viewer3D vvv,Spher3D * sph)358 static Boolean GetSphere3D(Viewer3D vvv, Spher3D *sph)
359 {
360   SetUpContext(vvv);
361   return Nlm_GetSegSphere3D(vvv->pic, NULL, sph);
362 }
363 
364 
MakeIntMat(Viewer3D vvv)365 static void MakeIntMat(Viewer3D vvv)
366 {
367   Int2   i;
368   double PNTR dPtr = &vvv->dAOrt[0][0];
369   Int4   PNTR iPtr = &vvv->a[0][0];
370 
371   for (i = 0;  i < 9;  i++)
372     {
373       double tmpDoub = *dPtr;
374       if (tmpDoub < 1.0e-100  &&  tmpDoub > -1.0e-100)
375         *iPtr = INT4_MAX;
376       else
377         {
378           tmpDoub = vvv->dscale / tmpDoub;
379           if      (tmpDoub > (double)INT4_MAX)
380             *iPtr = INT4_MAX;
381           else if (tmpDoub < (double)INT4_MIN)
382             *iPtr = INT4_MIN;
383           else
384             *iPtr = (Int4)tmpDoub;
385         }
386       dPtr++;
387       iPtr++;
388     }
389 
390   dPtr = vvv->dC;
391   iPtr = vvv->c;
392   for (i = 0;  i < 3;  i++)
393     *iPtr++ = (Int4)(*dPtr++);
394 
395   vvv->scale = (Int4)vvv->dscale;
396 }
397 
398 
399 /* Adjust viewer along the Z axis
400  */
FitZ(Viewer3D vvv)401 static Boolean FitZ(Viewer3D vvv)
402 {
403   Spher3D sph;
404   Int4    z_max;
405   double  z_offset;
406 
407   if ( !GetSphere3D(vvv, &sph) )
408     return FALSE; /* empty viewer picture */
409 
410   z_max = (Int4)((double)sph.radius * 2.0 / vvv->dscale) + 1;
411   z_offset = (double)((z_max>>1) + 1) -
412     ((double)sph.x * vvv->dAOrt[2][0] +
413      (double)sph.y * vvv->dAOrt[2][1] +
414      (double)sph.z * vvv->dAOrt[2][2]) / vvv->dscale;
415 
416   if ((Int4)z_offset <= (Int4)vvv->dC[2])
417     return TRUE; /* picture fits the viewer(does not run out of Z=0 plane) */
418 
419   /* adjust */
420   vvv->zmax  = z_max;
421   vvv->dC[2] = z_offset;
422   vvv->colorScale = (vvv->zmax<<8) / vvv->colorStep;
423   MakeIntMat(vvv);
424   SetUpContext(vvv);
425   return TRUE;
426 }
427 
428 
DrawViewer3D(Viewer3D vvv)429 static void DrawViewer3D(Viewer3D vvv)
430 {
431   register Viewer3D       VVV = vvv;
432   register Nlm_PPict3DPtr PPP = (Nlm_PPict3DPtr)(VVV ? VVV->pic : NULL);
433 
434   if (PPP == NULL)
435     return;
436 
437   Nlm_stCon.image = LockPixMapImage ( VVV->image );
438   if ( Nlm_stCon.image == NULL ) {
439     Nlm_DiagPutRecord(DA_ERROR, viewerClass, "DrawViewer3D",
440                       "Cannot lock memory block");
441     return;
442   }
443 
444   if (PPP->version != VVV->p_version  ||  VVV->c_version != VVV->c_versionPrev)
445     {
446       Uint1 i, k, colorStep;
447       Uint2 j;
448       Int4  red, green, blue;
449       Int4  colorPic;
450       Int4  brigh, kbrigh;
451 
452       VVV->colorOffset = 33;
453       colorStep = (Uint1)((256 - VVV->colorOffset) / (PPP->totalColors + 1));
454       if (colorStep > 32)
455         colorStep = 32;
456       VVV->colorStep = colorStep;
457       i = (Uint1)VVV->colorOffset;
458       colorPic = (Int4)colorPicAll[VVV->colorPicN];
459       brigh = (Int4)brighAll[VVV->brighN];
460       for (j = 0; j <= PPP->totalColors;  j++)
461         {
462           if (j != PPP->totalColors) {
463             red   = PPP->colorR[j];
464             green = PPP->colorG[j];
465             blue  = PPP->colorB[j];
466           }
467           else {
468             red   = VVV->colorHLR;
469             green = VVV->colorHLG;
470             blue  = VVV->colorHLB;
471           }
472 
473           red   = red   + 2 * (255 - red  ) / colorPic;
474           green = green + 2 * (255 - green) / colorPic;
475           blue  = blue  + 2 * (255 - blue ) / colorPic;
476           for (k = 1;  k <= colorStep;  k++)
477             {
478               if (brigh >= 0)
479                 kbrigh = (256 - brigh) * k + brigh * colorStep;
480               else
481                 kbrigh = (256 + brigh) * k;
482 
483               kbrigh /= (Int4)colorStep;
484               SetColorImage(VVV->image, i++, (Uint1)((red   * kbrigh)>>8),
485                                              (Uint1)((green * kbrigh)>>8),
486                                              (Uint1)((blue  * kbrigh)>>8));
487             }
488         }
489       SetColorImage(VVV->image, VVV->colorFon,
490                     VVV->colorFonR, VVV->colorFonG, VVV->colorFonB);
491 
492       ImageSetPalette(VVV->image, VVV->parentWindow);
493       VVV->c_versionPrev = VVV->c_version;
494 
495       if (VVV->p_version != PPP->version)
496         {
497           VVV->p_version = PPP->version;
498           VVV->g_version++;
499         }
500     }
501 
502   if (VVV->g_version != VVV->g_versionPrev)
503     {
504       Uint2 iwidth, iheight;
505 
506       Nlm_stCon.zBuffer = (Uint2Ptr) HandLock( VVV->zBuffer );
507       if ( Nlm_stCon.zBuffer == NULL ) {
508         Nlm_DiagPutRecord(DA_ERROR, viewerClass, "DrawViewer3D",
509                           "Can not lock memory block");
510         return;
511       }
512       VVV->colorScale = (VVV->zmax<<8) / VVV->colorStep;
513       GetImageSize(VVV->image, &iwidth, &iheight);
514       MemSet((void*)Nlm_stCon.image,   VVV->colorFon,  iwidth*iheight );
515       MemSet((void*)Nlm_stCon.zBuffer, 0, sizeof(Int2)*iwidth*iheight );
516       if ( FitZ(VVV) ) {
517         PPP->seg.base.fTable->draw( &PPP->seg );
518       }
519       ImageModified( VVV->image );
520       VVV->g_versionPrev = VVV->g_version;
521       HandUnlock( VVV->zBuffer );
522     }
523 
524   {{
525     RecT  r;
526     PoinT p;
527     ObjectRect(vvv->panel, &r);
528 #ifdef WIN_MOTIF
529     p.x = 2;
530     p.y = 2;
531 #else
532     p.x = (Int2)(r.left + 2);
533     p.y = (Int2)(r.top  + 2);
534 #endif
535     ImageShow(VVV->image, p);
536   }}
537 
538   UnlockPixMapImage( VVV->image );
539 }
540 
541 
DrawViewer3D_CB(PaneL panel)542 static void DrawViewer3D_CB(PaneL panel)
543 {
544   DrawViewer3D( PanelToViewer3D( panel ) );
545 }
546 
547 
548 
WorldToScreen(Viewer3D vvv,double x,double y,double z,double * xS,double * yS,double * zS)549 static void WorldToScreen(Viewer3D vvv,
550                           double  x,  double  y,  double  z,
551                           double *xS, double *yS, double *zS)
552 {
553   register Viewer3D VVV = vvv;
554 
555   *xS = VVV->dC[0] + (x * VVV->dAOrt[0][0] +
556                       y * VVV->dAOrt[0][1] +
557                       z * VVV->dAOrt[0][2]) / VVV->dscale;
558   *yS = VVV->dC[1] + (x * VVV->dAOrt[1][0] +
559                       y * VVV->dAOrt[1][1] +
560                       z * VVV->dAOrt[1][2]) / VVV->dscale;
561   *zS = VVV->dC[2] + (x * VVV->dAOrt[2][0] +
562                       y * VVV->dAOrt[2][1] +
563                       z * VVV->dAOrt[2][2]) / VVV->dscale;
564 }
565 
566 
ScreenToWorld(Viewer3D vvv,double xS,double yS,double zS,double * x,double * y,double * z)567 static void ScreenToWorld(Viewer3D vvv,
568                           double  xS, double  yS, double  zS,
569                           double *x,  double *y,  double *z)
570 {
571   Uint4 i,j;
572   Nlm_Matrix A  = Nlm_MatrixNew(3, 3);
573   Nlm_Matrix sV = Nlm_MatrixNew(3, 1);
574   Nlm_Matrix wV;
575 
576   Nlm_MatrixSetNode(sV, 0, 0, (xS - vvv->dC[0]) * vvv->dscale);
577   Nlm_MatrixSetNode(sV, 1, 0, (yS - vvv->dC[1]) * vvv->dscale);
578   Nlm_MatrixSetNode(sV, 2, 0, (zS - vvv->dC[2]) * vvv->dscale);
579 
580   for (i = 0;  i < 3;  i++)
581   for (j = 0;  j < 3;  j++)
582     Nlm_MatrixSetNode(A, i, j, vvv->dAOrt[i][j]);
583 
584   wV = Nlm_MatrixSolve(A, sV);
585 
586   *x = Nlm_MatrixNode(wV, 0, 0);
587   *y = Nlm_MatrixNode(wV, 1, 0);
588   *z = Nlm_MatrixNode(wV, 2, 0);
589 
590   Nlm_MatrixDelete( wV );
591   Nlm_MatrixDelete( sV );
592   Nlm_MatrixDelete( A );
593 }
594 
595 
MakeOffsets(Viewer3D vvv,double xWorld,double yWorld,double zWorld,double xScreen,double yScreen,double zScreen)596 static void MakeOffsets(Viewer3D vvv,
597                         double xWorld,  double yWorld,  double zWorld,
598                         double xScreen, double yScreen, double zScreen)
599 {
600   vvv->dC[0] = xScreen -
601                (xWorld * vvv->dAOrt[0][0] +
602                 yWorld * vvv->dAOrt[0][1] +
603                 zWorld * vvv->dAOrt[0][2]) / vvv->dscale;
604   vvv->dC[1] = yScreen -
605                (xWorld * vvv->dAOrt[1][0] +
606                 yWorld * vvv->dAOrt[1][1] +
607                 zWorld * vvv->dAOrt[1][2]) / vvv->dscale;
608   vvv->dC[2] = zScreen -
609                (xWorld * vvv->dAOrt[2][0] +
610                 yWorld * vvv->dAOrt[2][1] +
611                 zWorld * vvv->dAOrt[2][2]) / vvv->dscale;
612 
613   vvv->g_version++;
614 }
615 
616 
MakeFloatMat(Viewer3D vvv)617 static void MakeFloatMat(Viewer3D vvv)
618 {
619   Int2   i;
620   double PNTR dPtr = &vvv->dAOrt[0][0];
621   Int4   PNTR iPtr = &vvv->a[0][0];
622 
623   vvv->dscale = (double)vvv->scale;
624 
625   for (i = 0;  i < 9;  i++, dPtr++, iPtr++)
626     *dPtr = (iPtr != 0) ? (vvv->dscale / (double)*iPtr) : (vvv->dscale * 4);
627 
628   dPtr = vvv->dC;
629   iPtr = vvv->c;
630   for (i = 0;  i < 3;  i++)
631     *dPtr++ = (double)(*iPtr++);
632 }
633 
634 
ZoomAll(Viewer3D vvv,enumZoom3D method)635 static void ZoomAll(Viewer3D vvv, enumZoom3D method)
636 {
637   Spher3D  sph;
638   Int4     diametr;
639 
640   if ( !GetSphere3D(vvv, &sph) )
641     return;
642 
643   diametr = sph.radius << 1;
644 
645   if (method == ZOOM_ALL)
646     {
647       vvv->dAOrt[0][0] = vvv->dAOrt[1][1] = vvv->dAOrt[2][2] = (double)1;
648       vvv->dAOrt[0][1] = vvv->dAOrt[0][2] =
649       vvv->dAOrt[1][0] = vvv->dAOrt[1][2] =
650       vvv->dAOrt[2][0] = vvv->dAOrt[2][1] = (double)0;
651     }
652 
653   if (method == ZOOM_KEEP_ALL  &&  !vvv->is_zoomed)
654     method = ZOOM_KEEP_ANGLE;
655 
656   if (method != ZOOM_KEEP_ALL)
657     {
658       double scale = (double)diametr / (double)MIN(vvv->width, vvv->height);
659       if (scale < 10000.0)
660         scale = 10000.0;
661       vvv->dscale = (double)scale *
662         (double)vvv->perspect /  ((double)vvv->perspect + 0.5);
663       vvv->is_zoomed = FALSE;
664     }
665 
666   vvv->zmax = (Int4)((double)diametr / vvv->dscale) + 1;
667 
668   if (method != ZOOM_KEEP_ALL)
669     {
670       MakeOffsets(vvv, (double)sph.x, (double)sph.y, (double)sph.z,
671                   (double)(vvv->width>>1),
672                   (double)(vvv->height>>1),
673                   (double)((vvv->zmax>>1) + 1));
674     }
675   else
676     {
677       vvv->dC[2] = (double)((vvv->zmax>>1) + 1) -
678         ((double)sph.x * vvv->dAOrt[2][0] +
679          (double)sph.y * vvv->dAOrt[2][1] +
680          (double)sph.z * vvv->dAOrt[2][2]) / vvv->dscale;
681       vvv->g_version++;
682     }
683 
684   MakeIntMat( vvv );
685 }
686 
687 
Move3D(Viewer3D vvv,Int2 dx,Int2 dy)688 static void Move3D(Viewer3D vvv, Int2 dx, Int2 dy)
689 {
690   vvv->dC[0] += (double)dx;
691   vvv->dC[1] -= (double)dy;
692 
693   MakeIntMat( vvv );
694   vvv->g_version++;
695 }
696 
697 
Zoom3D(Viewer3D vvv,Int2 x1,Int2 y1,Int2 x2,Int2 y2)698 static void Zoom3D(Viewer3D vvv, Int2 x1, Int2 y1, Int2 x2, Int2 y2)
699 {
700   Spher3D  sph;
701   double   scale;
702   int      width, height;
703 
704   if ( !GetSphere3D(vvv, &sph) )
705     return;
706 
707   {{
708     RecT r;
709     ObjectRect(vvv->panel, &r);
710     x1 -= r.left; x2 -= r.left;
711     y1 -= r.top;  y2 -= r.top;
712     width = x2 - x1;
713     if (width < 0)
714       {
715         width = -width;
716         x1 = x2;
717       }
718     y1 = (Int2)(vvv->height - y1);
719     y2 = (Int2)(vvv->height - y2);
720     height = y2 - y1;
721     if (height < 0)
722       {
723         height = -height;
724         y1 = y2;
725       }
726   }}
727 
728   {{
729     double minscale = (double)sph.radius / 32000.0 / vvv->dscale;
730     double d = (double)height / (double)vvv->height;
731     scale    = (double)width  / (double)vvv->width;
732     if (d > scale)
733       scale = d;
734     if (scale < minscale)
735       scale = minscale;
736   }}
737 
738   vvv->dC[0] = (vvv->dC[0] - (double)(x1+width /2)) / scale + vvv->width / 2;
739   vvv->dC[1] = (vvv->dC[1] - (double)(y1+height/2)) / scale + vvv->height/ 2;
740   vvv->dscale *= scale;
741   vvv->zmax = (Int4)((double)sph.radius * 2.0 / vvv->dscale) + 1;
742   vvv->dC[2] = (double)((vvv->zmax>>1) + 1) -
743     ((double)sph.x * vvv->dAOrt[2][0] +
744      (double)sph.y * vvv->dAOrt[2][1] +
745      (double)sph.z * vvv->dAOrt[2][2]) / vvv->dscale;
746 
747   MakeIntMat( vvv );
748   vvv->g_version++;
749   vvv->is_zoomed = TRUE;
750 }
751 
752 
753 /***********************************************************************
754  *  Generic ROTATION functions
755  */
756 
Rotate(Viewer3D vvv,Int4 dAngle,enumRotate3D pivot)757 static void Rotate(Viewer3D vvv, Int4 dAngle, enumRotate3D pivot)
758 {
759   double   dx, dy, dz;
760   double   xx, yy, zz;
761   double   d;
762   double   ssin;
763   double   ccos;
764   double   a[3][3];
765   Spher3D  sph;
766   Int2     i,j;
767 
768   if ( !dAngle )
769     return;
770 
771   /* store viewport position */
772   if ( !GetSphere3D(vvv, &sph) )
773     return;
774 
775   WorldToScreen(vvv, (double)sph.x, (double)sph.y, (double)sph.z,
776                      &dx, &dy, &dz);
777 
778   if (pivot == ROTATE_Z)
779     { /* rotate around the center of the visible area */
780       dx = vvv->width  / 2;
781       dy = vvv->height / 2;
782     }
783 
784   ScreenToWorld(vvv, dx, dy, dz, &xx, &yy, &zz);
785 
786 
787   /* compose rotation matrix */
788   d = (double)dAngle * NCBIMATH_PI / 180.0;
789   ssin = sin( d );
790   ccos = cos( d );
791 
792   for (i = 0;  i < 3; i++)
793   for (j = 0;  j < 3; j++)
794     a[i][j] = 0.0;
795 
796   switch ( pivot )
797     {
798     case ROTATE_X:
799       a[0][0] = 1.0;
800       a[1][1] =  ccos;  a[1][2] = ssin;
801       a[2][1] = -ssin;  a[2][2] = ccos;
802       break;
803     case ROTATE_Y:
804       a[0][0] =  ccos;  a[0][2] = ssin;
805       a[1][1] = 1.0;
806       a[2][0] = -ssin;  a[2][2] = ccos;
807       break;
808     case ROTATE_Z:
809       a[0][0] =  ccos;  a[0][1] = ssin;
810       a[1][0] = -ssin;  a[1][1] = ccos;
811       a[2][2] = 1.0;
812       break;
813     }
814 
815   {{ /* rotate */
816     double b[3][3];
817     for (j = 0;  j < 3;  j++)
818     for (i = 0;  i < 3;  i++)
819       {
820         b[i][j] =
821           a[i][0] * vvv->dAOrt[0][j] +
822           a[i][1] * vvv->dAOrt[1][j] +
823           a[i][2] * vvv->dAOrt[2][j];
824       }
825     MemCpy((VoidPtr)vvv->dAOrt, (VoidPtr)b, sizeof(vvv->dAOrt));
826   }}
827 
828   /* restore viewport position */
829   MakeOffsets(vvv, xx, yy, zz, dx, dy, dz);
830 
831   MakeIntMat( vvv );
832   vvv->g_version++;
833 }
834 
835 
ViewerRotate(SlatE panel,Int4 delta,enumRotate3D pivot,Boolean adjust_scrollbar,Boolean redraw)836 static void ViewerRotate(SlatE panel, Int4 delta,
837                          enumRotate3D pivot,
838                          Boolean adjust_scrollbar, Boolean redraw)
839 {
840   Viewer3D vvv;
841   if (panel == NULL  ||
842       !Visible(panel)  ||  !AllParentsVisible(panel))
843     return;
844 
845   vvv = PanelToViewer3D( (PaneL)panel );
846 
847   if ( adjust_scrollbar )
848     { /* adjust the relevant rotation scrollbar, if any */
849       BaR sbar = NULL;
850       switch ( pivot )
851         {
852         case ROTATE_X:
853           sbar = GetSlateVScrollBar( panel );
854           break;
855         case ROTATE_Y:
856           sbar = GetSlateHScrollBar( panel );
857           break;
858         case ROTATE_Z:
859           sbar = vvv->z_rotate;
860           break;
861         }
862 
863       if ( sbar )
864         {
865           ResetClip();
866           CorrectBarValue(sbar, (GetValue(sbar) + delta + 360) % 360);
867         }
868     }
869 
870   /* the coordination transformation (rotation) */
871   if (pivot == ROTATE_X)
872     delta = -delta;
873   Rotate(vvv, delta, pivot);
874 
875   if ( redraw )
876     { /* Draw the viewer */
877       WindoW   tempPort = CurrentWindow();
878       UseWindow( ParentWindow(panel) );
879       Select( panel );
880       DrawViewer3D( vvv );
881       UseWindow( tempPort );
882     }
883 
884   Nlm_DiagReset();
885 }
886 
887 
ResetViewerProc_CB(PaneL panel)888 static void ResetViewerProc_CB(PaneL panel)
889 {
890   Viewer3D vvv = PanelToViewer3D( panel );
891   if ( !vvv  )
892     return;
893 
894   vvv->panel = NULL;
895   DeleteViewer3D( PanelToViewer3D( panel ) );
896 }
897 
898 
ResetImage3D(Viewer3D vvv)899 static void ResetImage3D(Viewer3D vvv)
900 {
901   vvv->width = vvv->height = 0;
902 
903   if ( vvv->image ) {
904       DeleteImage( vvv->image );
905       vvv->image = NULL;
906     }
907 
908   if ( vvv->zBuffer ) {
909     HandFree( vvv->zBuffer );
910     vvv->zBuffer = NULL;
911   }
912 }
913 
914 
915 
916 /***********************************************************************
917  *  SCROLLBARS
918  */
919 
920 
ViewerVScrollProc(BaR sb,SlatE viewer,Int2 newval,Int2 oldval)921 static void ViewerVScrollProc(BaR sb, SlatE viewer, Int2 newval, Int2 oldval)
922 {
923   ViewerRotate(viewer, newval - oldval, ROTATE_X, FALSE, TRUE);
924 }
925 
ViewerHScrollProc(BaR sb,SlatE viewer,Int2 newval,Int2 oldval)926 static void ViewerHScrollProc(BaR sb, SlatE viewer, Int2 newval, Int2 oldval)
927 {
928   ViewerRotate(viewer, newval - oldval, ROTATE_Y, FALSE, TRUE);
929 }
930 
ViewerZScrollProc(BaR sb,GraphiC group,Int2 newval,Int2 oldval)931 static void ViewerZScrollProc(BaR sb, GraphiC group, Int2 newval, Int2 oldval)
932 {
933   SlatE viewer = (SlatE)GetObjectExtra( sb );
934   ViewerRotate(viewer, newval - oldval, ROTATE_Z, FALSE, TRUE);
935 }
936 
937 
938 /***********************************************************************
939  * PRIMITIVEs
940  */
941 
Nlm_AddFoundPrim(Viewer3D vvv,Prim3D primId)942 static Boolean Nlm_AddFoundPrim(Viewer3D vvv, Prim3D primId)
943 {
944   Uint2 i;
945 
946   if (primId == 0)
947     return TRUE;
948 
949   for (i = 0;  i < vvv->nPrimFound;  i++)
950     if (vvv->foundPrim[i] == primId)
951       return TRUE;
952 
953   if (vvv->nPrimFound >= MAX_FOUND_PRIM)
954     return FALSE;
955 
956   vvv->foundPrim[vvv->nPrimFound++] = primId;
957   return TRUE;
958 }
959 
960 
Nlm_RedrawPrim3D(Viewer3D vvv,Nlm_Base3DPtr pBase)961 static void Nlm_RedrawPrim3D(Viewer3D vvv, Nlm_Base3DPtr pBase)
962 {
963   if (vvv->pic == NULL)
964     return;
965 
966   Nlm_stCon.image = LockPixMapImage( vvv->image );
967   if (Nlm_stCon.image == NULL) {
968     Nlm_DiagPutRecord(DA_ERROR, viewerClass, "RedrawPrim3D",
969                       "Cannot lock image memory block");
970     return;
971   }
972   Nlm_stCon.zBuffer = (Uint2Ptr) HandLock( vvv->zBuffer );
973   if (Nlm_stCon.zBuffer == NULL) {
974     UnlockPixMapImage( vvv->image );
975     Nlm_DiagPutRecord(DA_ERROR, viewerClass, "RedrawPrim3D",
976                       "Cannot lock Z-buffer memory block" );
977     return;
978   }
979 
980   vvv->colorScale = (vvv->zmax<<8) / vvv->colorStep;
981   SetUpContext( vvv );
982   if (pBase->status & HL_MASK)
983     {
984       Uint1 color = pBase->color;
985       pBase->color = Nlm_stCon.colorHL;
986       pBase->fTable->draw( (Nlm_VoidPtr)pBase );
987       pBase->color = color;
988     }
989   else
990     {
991       pBase->fTable->draw( (Nlm_VoidPtr)pBase );
992     }
993 
994   ImageModified( vvv->image );
995   HandUnlock( vvv->zBuffer );
996   UnlockPixMapImage( vvv->image );
997 }
998 
999 
Nlm_ResetHLSeg3D(Segment3D segment)1000 static void Nlm_ResetHLSeg3D(Segment3D segment)
1001 {
1002   register Nlm_Base3DPtr prim = (Nlm_Base3DPtr)segment;
1003 
1004   prim->status &= ~HL_MASK;
1005   for (prim = ((Nlm_PSeg3DPtr)prim)->first;  prim;  prim = prim->next) {
1006     if (prim->fTable->code == 0)
1007       Nlm_ResetHLSeg3D((Segment3D)prim);
1008     else
1009       prim->status &= ~HL_MASK;
1010   }
1011 }
1012 
1013 
1014 /***********************************************************************
1015  *  LAYERing
1016  */
1017 
Nlm_AllLayerSetStates3D(Viewer3D vvv,Nlm_Boolean state)1018 static void Nlm_AllLayerSetStates3D(Viewer3D vvv, Nlm_Boolean state)
1019 {
1020   register Uint1 level = 0;
1021   do
1022     {
1023       SetLayer3D(vvv->pic, level, state);
1024       vvv->layerTable[level] = state;
1025     }
1026   while (level++ != 255);
1027 }
1028 
1029 
Nlm_AllLayerSet3D(Viewer3D vvv,Nlm_Boolean state)1030 NLM_EXTERN void Nlm_AllLayerSet3D(Viewer3D vvv, Nlm_Boolean state)
1031 {
1032   Spher3D  sph;
1033   double   dx, dy, dz;
1034 
1035   if (vvv == NULL  ||  vvv->pic == NULL)
1036     return;
1037 
1038   Nlm_AllLayerSetStates3D(vvv, state);
1039 
1040   if ( GetSphere3D(vvv, &sph) )
1041     {
1042       WorldToScreen (vvv,
1043                      (double)sph.x, (double)sph.y, (double)sph.z,
1044                      &dx, &dy, &dz );
1045       MakeOffsets   (vvv,
1046                      (double)sph.x, (double)sph.y, (double)sph.z,
1047                      dx,  dy,  dz );
1048       MakeIntMat( vvv );
1049     }
1050 
1051   RedrawViewer3D( vvv );
1052 }
1053 
1054 
Nlm_RewindLayer3D(Viewer3D vvv)1055 static void Nlm_RewindLayer3D(Viewer3D vvv)
1056 {
1057   if (vvv == NULL  ||  vvv->pic == NULL)
1058     return;
1059 
1060   Nlm_AllLayerSetStates3D(vvv, FALSE);
1061 
1062   SetLayer3D(vvv->pic, 1, TRUE);
1063   vvv->layerTable[0] = TRUE;
1064   currlayer = 0;
1065   RedrawViewer3D( vvv );
1066 }
1067 
1068 
Nlm_PrevLayer3D(Viewer3D vvv)1069 extern void Nlm_PrevLayer3D (Viewer3D vvv)
1070 {
1071   if (vvv == NULL  ||  vvv->pic == NULL)
1072     return;
1073 
1074   Nlm_AllLayerSetStates3D(vvv, FALSE);
1075 
1076   currlayer = (Uint1)((currlayer != 0) ? (currlayer - 1) : toplayer);
1077   SetLayer3D(vvv->pic, currlayer, TRUE);
1078   vvv->layerTable[currlayer] = TRUE;
1079 
1080   RedrawViewer3D( vvv );
1081 }
1082 
1083 
Nlm_NextLayer3D(Viewer3D vvv)1084 extern void Nlm_NextLayer3D(Viewer3D vvv)
1085 {
1086   if (vvv == NULL  ||  vvv->pic == NULL)
1087     return;
1088 
1089   Nlm_AllLayerSetStates3D(vvv, FALSE);
1090 
1091   currlayer = (Uint1)((currlayer != toplayer) ? (currlayer + 1) : 0);
1092   SetLayer3D(vvv->pic, currlayer, TRUE);
1093   vvv->layerTable[currlayer] = TRUE;
1094 
1095   RedrawViewer3D( vvv );
1096 }
1097 
1098 
Nlm_IsPlaying3D(void)1099 extern Boolean Nlm_IsPlaying3D(void)
1100 {
1101 #ifdef WIN_MAC
1102    return FALSE;
1103 #else
1104    return (Boolean)(V3D_bPLAY  &&  GetStatus( V3D_bPLAY ));
1105 #endif
1106 }
1107 
1108 
Nlm_StopPlaying3D(void)1109 extern void  Nlm_StopPlaying3D(void)
1110 {
1111   if ( V3D_bPLAY )
1112     SetStatus(V3D_bPLAY, FALSE);
1113 }
1114 
1115 
Nlm_StartPlaying3D(Viewer3D vvv)1116 extern void Nlm_StartPlaying3D(Viewer3D vvv)
1117 {
1118 #ifndef WIN_MAC
1119   if ( V3D_bPLAY )
1120     {
1121       SetStatus(V3D_bPLAY, TRUE);
1122       Nlm_PlayLayer3D( vvv );
1123     }
1124 #endif
1125 }
1126 
1127 
Nlm_PlayLayer3D(Viewer3D vvv)1128 extern void Nlm_PlayLayer3D(Viewer3D vvv)
1129 {
1130 #ifndef WIN_MAC
1131   if (vvv == NULL  ||  vvv->pic == NULL)
1132     return;
1133 
1134   Nlm_AllLayerSetStates3D(vvv, FALSE);
1135 
1136   SetLayer3D(vvv->pic, currlayer, TRUE);
1137   vvv->layerTable[currlayer] = TRUE;
1138   while (!QuittingProgram()  &&  IsPlaying3D())
1139     {
1140       SetLayer3D(vvv->pic, currlayer, FALSE);
1141       vvv->layerTable[currlayer] = FALSE;
1142 
1143       currlayer = (Uint1)((currlayer != toplayer) ? (currlayer + 1) : 0);
1144       SetLayer3D(vvv->pic, currlayer, TRUE);
1145       vvv->layerTable[currlayer] = TRUE;
1146 
1147       RedrawViewer3D( vvv );
1148       while ( Nlm_EventAvail() )
1149         Nlm_ProcessAnEvent();
1150     }
1151 #endif
1152 }
1153 
1154 
Nlm_SetLayerTop3D(Uint1 top)1155 extern void Nlm_SetLayerTop3D(Uint1 top)
1156 {
1157   toplayer = top;
1158 }
1159 
1160 
Nlm_GetLayerTop3D(void)1161 extern Uint1 Nlm_GetLayerTop3D(void)
1162 {
1163   return toplayer;
1164 }
1165 
1166 
1167 
1168 
1169 /***********************************************************************
1170  *  VIEWER CONTROLS
1171  ***********************************************************************/
1172 
1173 /* Callbacks
1174  */
1175 
1176 /* Animation callbacks */
1177 
AllLayerOnProc(ButtoN b)1178 static void AllLayerOnProc( ButtoN b )
1179 {
1180   Nlm_AllLayerSet3D((Viewer3D)GetObjectExtra(b), TRUE);
1181 }
1182 
RewindLayerProc(ButtoN b)1183 static void RewindLayerProc(ButtoN b)
1184 {
1185   Nlm_RewindLayer3D( (Viewer3D)GetObjectExtra( b ) );
1186 }
1187 
PrevLayerProc(ButtoN b)1188 static void PrevLayerProc(ButtoN b)
1189 {
1190   Nlm_PrevLayer3D( (Viewer3D)GetObjectExtra( b ) );
1191 }
1192 
NextLayerProc(ButtoN b)1193 static void NextLayerProc(ButtoN b)
1194 {
1195   Nlm_PrevLayer3D( (Viewer3D)GetObjectExtra( b ) );
1196 }
1197 
1198 #ifndef WIN_MAC
PlayLayerProc(ButtoN b)1199 static void PlayLayerProc(ButtoN b)
1200 {
1201   Nlm_PlayLayer3D( (Viewer3D)GetObjectExtra( b ) );
1202 }
1203 #endif
1204 
1205 /* Navigation callbacks */
1206 
UnzoomProc(ButtoN b)1207 static void UnzoomProc(ButtoN b)
1208 {
1209   Nlm_ZoomAll3D( (Viewer3D)GetObjectExtra( b ) );
1210 }
1211 
MoveProc(ButtoN b)1212 static void MoveProc(ButtoN b)
1213 {
1214   SetStdMouse3D((Viewer3D)GetObjectExtra( b ), Mouse3D_Move);
1215   MsgAlert(KEY_OK, SEV_INFO, "Cn3D Online Manual",
1216            "Use the [Shift] modifier key to move with mouse");
1217 }
1218 
ZoomProc(ButtoN b)1219 static void ZoomProc(ButtoN b)
1220 {
1221   SetStdMouse3D((Viewer3D)GetObjectExtra( b ), Mouse3D_Zoom);
1222   MsgAlert(KEY_OK, SEV_INFO, "Cn3D Online Manual",
1223            "Use the [Control] modifier key to zoom with mouse");
1224 }
1225 
1226 
1227 /* Adjustment callbacks */
1228 
AdjustProc(GrouP g)1229 static void AdjustProc(GrouP g)
1230 {
1231   Nlm_SetAdjust3D((Viewer3D)GetObjectExtra(g), (Uint1)GetValue(g));
1232 }
1233 
PlusProc(ButtoN b)1234 static void PlusProc(ButtoN b)
1235 {
1236   Nlm_Adjust3D((Viewer3D)GetObjectExtra( b ), TRUE);
1237 }
1238 
MinusProc(ButtoN b)1239 static void MinusProc(ButtoN b)
1240 {
1241   Nlm_Adjust3D((Viewer3D)GetObjectExtra( b ), FALSE);
1242 }
1243 
1244 
1245 /* Create and place the viewer controls
1246  */
1247 
BasicControls3D(GrouP prnt,Boolean vertical,Controls3D controls)1248 static GrouP BasicControls3D(GrouP      prnt,
1249                              Boolean    vertical,
1250                              Controls3D controls)
1251 {
1252   GrouP mGroup;
1253   GrouP tmpGroup;
1254   GrouP tmptmpGroup;
1255 
1256   Nlm_DiagReset();
1257 
1258   if ( vertical )
1259     {
1260       mGroup = HiddenGroup(prnt, 1, 0, NULL);
1261 #ifdef WIN_MOTIF
1262       SetGroupMargins(mGroup, 0, 0);
1263 #else
1264       SetGroupMargins(mGroup, 1, 1);
1265 #endif
1266       SetGroupSpacing(mGroup, 0, 0);
1267 
1268       StaticPrompt(mGroup, "Zoom:", 0, 0, Nlm_systemFont, 'c');
1269       controls->zoomAll = PushButton(mGroup, "All",  UnzoomProc);
1270       controls->Move3D  = PushButton(mGroup, "Move", MoveProc  );
1271       controls->Zoom3D  = PushButton(mGroup, "Zoom", ZoomProc  );
1272       StaticPrompt(mGroup, "------", 0, 0, Nlm_systemFont, 'c');
1273 
1274       controls->adjustButtons = tmpGroup =
1275         HiddenGroup(mGroup, 1, 3, AdjustProc);
1276       RadioButton(tmpGroup, "Persp");
1277       RadioButton(tmpGroup, "Brigh");
1278       RadioButton(tmpGroup, "Color");
1279       SetValue(tmpGroup, 1);
1280 
1281       tmpGroup = HiddenGroup(mGroup, 2, 1, NULL);
1282       controls->minusButton = PushButton(tmpGroup, "-",  MinusProc);
1283       controls->plusButton  = PushButton(tmpGroup, "+",  PlusProc );
1284       StaticPrompt(mGroup, "------", 0, 0, Nlm_systemFont, 'c');
1285     }
1286   else
1287     {  /* horizontal*/
1288       /* rearranged to use a single horizontal group */
1289       mGroup = HiddenGroup(prnt, 0, 1, NULL);
1290       SetGroupSpacing(mGroup, 6, 1);
1291 
1292       tmpGroup = HiddenGroup(mGroup, 3, 0, NULL);
1293       SetGroupSpacing(tmpGroup, 1, 0);
1294       controls->minusButton = PushButton(tmpGroup, "-", MinusProc);
1295       controls->adjustButtons = tmptmpGroup =
1296         HiddenGroup(tmpGroup, 3, 0, AdjustProc);
1297       RadioButton(tmptmpGroup, "p");
1298       RadioButton(tmptmpGroup, "b");
1299       RadioButton(tmptmpGroup, "c");
1300       SetValue(tmptmpGroup, 1);
1301       controls->plusButton = PushButton(tmpGroup, "+", PlusProc);
1302 
1303       tmpGroup = HiddenGroup(mGroup, 4, 0, NULL);
1304       controls->zoomAll = PushButton(tmpGroup, "All",  UnzoomProc);
1305       controls->Move3D  = PushButton(tmpGroup, "Move", MoveProc  );
1306       controls->Zoom3D  = PushButton(tmpGroup, "Zoom", ZoomProc  );
1307     }
1308 
1309   return mGroup;
1310 }
1311 
1312 
FreeControls(GraphiC group,VoidPtr controls)1313 static void FreeControls(GraphiC group, VoidPtr controls)
1314 {
1315   MemFree( controls );
1316 }
1317 
1318 
Nlm_CreateControls3D(GrouP prnt,Boolean vertical,Boolean anim_ctrl,GrouP * ctrl_group)1319 extern Controls3D Nlm_CreateControls3D(GrouP prnt,
1320                                        Boolean vertical,
1321                                        Boolean anim_ctrl,
1322                                        GrouP  *ctrl_group)
1323 {
1324   Controls3D controls = (Controls3D)MemNew( sizeof(structControls3D) );
1325   GrouP      mGroup   = BasicControls3D(prnt, vertical, controls);
1326 
1327   controls->group = mGroup;
1328   SetObjectExtra(controls->group, controls, FreeControls);
1329 
1330   if ( anim_ctrl )
1331     {
1332       GrouP tmpGroup = mGroup;
1333       if ( vertical )
1334         {
1335           StaticPrompt(mGroup, "Animate:", 0, 0, Nlm_systemFont, 'r');
1336           tmpGroup = HiddenGroup(mGroup, 4, 1, NULL);
1337         }
1338 
1339       controls->allButton    = PushButton(tmpGroup, "*",  AllLayerOnProc);
1340       controls->rewindButton = PushButton(tmpGroup, "|<", RewindLayerProc);
1341       controls->prevButton   = PushButton(tmpGroup, "<",  PrevLayerProc);
1342       controls->nextButton   = PushButton(tmpGroup, ">",  NextLayerProc);
1343 #ifndef WIN_MAC
1344       V3D_bPLAY = controls->playButton = CheckBox(mGroup, "Go", PlayLayerProc);
1345 #endif
1346     }
1347 
1348   if ( ctrl_group )
1349     *ctrl_group = mGroup;
1350   return controls;
1351 }
1352 
1353 
Nlm_DeleteControls3D(Controls3D controls)1354 extern void Nlm_DeleteControls3D(Controls3D controls)
1355 {
1356   Remove( controls->group );
1357 }
1358 
1359 
1360 /* Link the viewer controls to a viewer
1361  */
1362 
Nlm_LinkBasicControls3D(Controls3D controls,Viewer3D vvv)1363 static void Nlm_LinkBasicControls3D(Controls3D controls, Viewer3D vvv)
1364 {
1365   SetObjectExtra(controls->zoomAll,       vvv, NULL);
1366   SetObjectExtra(controls->Move3D,        vvv, NULL);
1367   SetObjectExtra(controls->Zoom3D,        vvv, NULL);
1368   SetObjectExtra(controls->adjustButtons, vvv, NULL);
1369   SetObjectExtra(controls->plusButton,    vvv, NULL);
1370   SetObjectExtra(controls->minusButton,   vvv, NULL);
1371 }
1372 
1373 #ifndef WIN_MAC
Cleanup_V3D_bPLAY(GraphiC playButton,VoidPtr vvv)1374 static void Cleanup_V3D_bPLAY(GraphiC playButton, VoidPtr vvv)
1375 {
1376   if ((ButtoN)playButton == V3D_bPLAY)
1377     V3D_bPLAY = NULL;
1378 }
1379 #endif
1380 
Nlm_LinkControls3D(Controls3D controls,Viewer3D vvv)1381 extern void Nlm_LinkControls3D(Controls3D controls, Viewer3D vvv)
1382 {
1383    if (controls == NULL)
1384      return;
1385 
1386    Nlm_LinkBasicControls3D(controls, vvv);
1387    if ( !controls->allButton )
1388      return;
1389 
1390    SetObjectExtra(controls->allButton,    vvv, NULL);
1391    SetObjectExtra(controls->rewindButton, vvv, NULL);
1392    SetObjectExtra(controls->prevButton,   vvv, NULL);
1393    SetObjectExtra(controls->nextButton,   vvv, NULL);
1394 #ifndef WIN_MAC
1395    SetObjectExtra(controls->playButton,   vvv, Cleanup_V3D_bPLAY);
1396 #endif
1397 }
1398 
1399 
1400 /* ADJUSTMENT (color, brightness, perspective)
1401  */
1402 
Nlm_Adjust3D(Viewer3D vvv,Boolean plus)1403 extern void Nlm_Adjust3D(Viewer3D vvv, Boolean plus)
1404 {
1405   Boolean needRedraw = FALSE;
1406 
1407   switch ( vvv->adjust )
1408     {
1409     case ADJUST3D_PERSPECT:
1410       if ( plus ) {
1411         if (vvv->perspectN < 5) {
1412           vvv->perspectN++;
1413           needRedraw = TRUE;
1414         }
1415       } else {
1416         if (vvv->perspectN > 0) {
1417           vvv->perspectN--;
1418           needRedraw = TRUE;
1419         }
1420       }
1421       if ( needRedraw )
1422         {
1423           Spher3D sph;
1424           double dx,dy,dz;
1425 
1426           vvv->g_version++;
1427           if ( !GetSphere3D(vvv, &sph) )
1428             break;
1429 
1430           WorldToScreen(vvv, (double)sph.x, (double)sph.y, (double)sph.z,
1431                         &dx, &dy, &dz);
1432           vvv->dscale = (vvv->dscale * (2.0 * (double)vvv->perspect + 1.0)) /
1433             (2.0 * (double)vvv->perspect);
1434           vvv->perspect = perspectAll[vvv->perspectN];
1435           vvv->dscale = (vvv->dscale * 2.0 * (double)vvv->perspect) /
1436             (2.0 * (double)vvv->perspect + 1.0);
1437           vvv->zmax = (Int4)((double)(sph.radius<<1) / vvv->dscale) + 1;
1438           MakeOffsets(vvv, (double)sph.x, (double)sph.y, (double)sph.z,
1439                       dx, dy, (double)((vvv->zmax>>1) + 1));
1440           MakeIntMat( vvv );
1441         }
1442       break;
1443 
1444     case ADJUST3D_BRIGH:
1445       if ( plus ) {
1446         if ( vvv->brighN < 6 ) {
1447           vvv->brighN++; vvv->c_version++;
1448           needRedraw = TRUE;
1449         }
1450       } else {
1451         if ( vvv->brighN > 0 ) {
1452           vvv->brighN--; vvv->c_version++;
1453           needRedraw = TRUE;
1454         }
1455       }
1456       break;
1457 
1458     case ADJUST3D_COLOR:
1459       if ( plus ) {
1460         if ( vvv->colorPicN < 5 ) {
1461           vvv->colorPicN++; vvv->c_version++;
1462           needRedraw = TRUE;
1463         }
1464       } else {
1465         if ( vvv->colorPicN > 0 ) {
1466           vvv->colorPicN--; vvv->c_version++;
1467           needRedraw = TRUE;
1468         }
1469       }
1470   }
1471 
1472   if ( needRedraw )
1473     {
1474       WindoW tmpPort = SavePort( vvv->panel );
1475       Select( vvv->panel );
1476       DrawViewer3D ( vvv );
1477       RestorePort( tmpPort );
1478       Nlm_DiagReset();
1479     }
1480 }
1481 
1482 
1483 /***********************************************************************
1484  *  MOUSE EVENT HANDLERS
1485  ***********************************************************************/
1486 
1487 /* MOVE
1488  */
1489 
Move_DrawTrace(MA_TracePtr trace)1490 static void Move_DrawTrace(MA_TracePtr trace)
1491 {
1492   if ( EqualPt(trace->start, trace->end) )
1493     return;
1494 
1495 #ifdef WIN_MOTIF
1496   SetColor( 0xf1 );
1497 #endif
1498   InvertMode();
1499   DrawLine(trace->start, trace->end);
1500   CopyMode();
1501 }
1502 
Move_PressMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1503 static void Move_PressMA(MAPtr ma,
1504                          MA_TracePtr trace, PoinT point, VoidPtr extra)
1505 {
1506   trace->start = trace->end = point;
1507 }
1508 
Move_DragMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1509 static void Move_DragMA(MAPtr ma,
1510                         MA_TracePtr trace, PoinT point, VoidPtr extra)
1511 {
1512   Move_DrawTrace( trace );
1513   trace->end = point;
1514   Move_DrawTrace( trace );
1515 }
1516 
Move_ReleaseMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1517 static void Move_ReleaseMA(MAPtr ma,
1518                            MA_TracePtr trace, PoinT point, VoidPtr extra)
1519 {
1520   Move_DrawTrace( trace );
1521   trace->end = point;
1522 
1523   if ( EqualPt(trace->start, trace->end) )
1524     return;
1525 
1526   {{
1527     Viewer3D vvv = MAToViewer3D( ma );
1528     Move3D(vvv, (Int2)(trace->end.x - trace->start.x),
1529                 (Int2)(trace->end.y - trace->start.y));
1530     DrawViewer3D( vvv );
1531   }}
1532 
1533   trace->start = trace->end;
1534 }
1535 
Move_CancelMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1536 static void Move_CancelMA(MAPtr ma,
1537                           MA_TracePtr trace, PoinT point, VoidPtr extra)
1538 {
1539   Move_DrawTrace( trace );
1540 }
1541 
1542 
1543 /* ZOOM
1544  */
1545 
Zoom_DrawTrace(MA_TracePtr trace)1546 static void Zoom_DrawTrace(MA_TracePtr trace)
1547 {
1548   RecT rubber_box;
1549   if ( EqualPt(trace->start, trace->end) )
1550     return;
1551 
1552 #ifdef WIN_MOTIF
1553   SetColor( 0xf1 );
1554 #endif
1555   InvertMode();
1556   LoadRect(&rubber_box, trace->start.x, trace->start.y,
1557                         trace->end.x,   trace->end.y);
1558   FrameRect( &rubber_box );
1559   CopyMode();
1560 }
1561 
Zoom_PressMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1562 static void Zoom_PressMA(MAPtr ma,
1563                          MA_TracePtr trace, PoinT point, VoidPtr extra)
1564 {
1565   trace->start = trace->end = point;
1566 }
1567 
Zoom_DragMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1568 static void Zoom_DragMA(MAPtr ma,
1569                         MA_TracePtr trace, PoinT point, VoidPtr extra)
1570 {
1571   Zoom_DrawTrace( trace );
1572   trace->end = point;
1573   Zoom_DrawTrace( trace );
1574 }
1575 
Zoom_ReleaseMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1576 static void Zoom_ReleaseMA(MAPtr ma,
1577                            MA_TracePtr trace, PoinT point, VoidPtr extra)
1578 {
1579   Zoom_DrawTrace( trace );
1580   trace->end = point;
1581 
1582   if ( EqualPt(trace->start, trace->end) )
1583     return;
1584 
1585   {{
1586     Viewer3D vvv = MAToViewer3D( ma );
1587     Zoom3D(vvv, trace->start.x, trace->start.y,
1588                 trace->end.x,   trace->end.y);
1589     DrawViewer3D( vvv );
1590   }}
1591 }
1592 
Zoom_CancelMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1593 static void Zoom_CancelMA(MAPtr ma,
1594                           MA_TracePtr trace, PoinT point, VoidPtr extra)
1595 {
1596   Zoom_DrawTrace( trace );
1597 }
1598 
1599 
1600 /* ROTATE
1601  */
1602 
1603 typedef struct
1604 {
1605   enumRotate3D H; /* horizontal dragging */
1606   enumRotate3D V; /* vertical   dragging */
1607 }
1608 RotatePivots3D, PNTR RotatePivots3DPtr;
1609 
Rotate_PressMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1610 static void Rotate_PressMA(MAPtr ma,
1611                            MA_TracePtr trace, PoinT point, VoidPtr extra)
1612 {
1613   trace->start = point;
1614 }
1615 
Rotate_DragMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1616 static void Rotate_DragMA(MAPtr ma,
1617                           MA_TracePtr trace, PoinT point, VoidPtr extra)
1618 {
1619   Viewer3D vvv = MAToViewer3D( ma );
1620   RotatePivots3DPtr pivot = (RotatePivots3DPtr)extra;
1621 
1622   if ( EqualPt(trace->start, point) )
1623     return;
1624 
1625   ViewerRotate((SlatE)vvv->panel,
1626                (Int4)((180.0 * (point.x - trace->start.x)) / vvv->width),
1627                pivot->H, TRUE, FALSE);
1628 
1629   ViewerRotate((SlatE)vvv->panel,
1630                (Int4)((180.0 * (point.y - trace->start.y)) / vvv->height),
1631                pivot->V, TRUE, TRUE);
1632 
1633   trace->start = point;
1634 }
1635 
1636 
1637 
1638 /* MISC
1639  */
1640 
Bg_HL_DClickMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1641 static void Bg_HL_DClickMA(MAPtr ma,
1642                            MA_TracePtr trace, PoinT point, VoidPtr extra)
1643 {
1644   Viewer3D vvv = MAToViewer3D( ma );
1645   Uint2    n_prim = FindPrim3D(vvv, point);
1646 
1647   if ( n_prim )
1648     { /* Highlight primitive */
1649       Prim3D prim = GetFoundPrim3D(vvv, 0);
1650       SetHLColor3D(vvv, 0, 255, 0);
1651       HighlightPrim3D(vvv, prim, (Boolean)(!IsPrim3DHlighted(vvv, prim)));
1652       RedrawViewer3D( vvv );
1653     }
1654   else
1655     { /* Choose and change viewer background color */
1656       if ( ChooseColorDialog(&vvv->colorFonR,
1657                              &vvv->colorFonG,
1658                              &vvv->colorFonB,
1659                              0) )
1660         Nlm_SetBackground3D(vvv,
1661                             vvv->colorFonR,
1662                             vvv->colorFonG,
1663                             vvv->colorFonB);
1664     }
1665 }
1666 
1667 
1668 /* RESET
1669  */
1670 
ResetMA(MAPtr ma,MA_TracePtr trace,PoinT point,VoidPtr extra)1671 static void ResetMA(MAPtr ma,
1672                     MA_TracePtr trace, PoinT point, VoidPtr extra)
1673 {
1674   VERIFY ( MA_UnsetAll( ma ) );
1675 }
1676 
1677 
1678 
1679 /* Initialize MA for the viewer
1680  */
1681 
InitializeMA(Viewer3D vvv)1682 static Boolean InitializeMA(Viewer3D vvv)
1683 {
1684   MAPtr ma = vvv->ma;
1685 
1686   /* rotate */
1687   MActionPtr rotate_press   =
1688     MA_AddAction(ma, MK_Normal, MA_Press,   Rotate_PressMA, NULL, NULL);
1689 
1690   static RotatePivots3D RotateDrag_YX = { ROTATE_Y, ROTATE_X };
1691   MActionPtr rotate_drag_YX =
1692     MA_AddAction(ma, MK_Normal, MA_Drag, Rotate_DragMA, &RotateDrag_YX, NULL);
1693   MA_GroupPtr rotate_group_YX = MA_AddGroup(ma, "Rotate_YX",
1694                                             rotate_press,   MA_ONLY,
1695                                             rotate_drag_YX, MA_ONLY,
1696                                             NULL);
1697 
1698   static RotatePivots3D RotateDrag_ZX = { ROTATE_Z, ROTATE_X };
1699   MActionPtr rotate_drag_ZX =
1700     MA_AddAction(ma, MK_Normal, MA_Drag, Rotate_DragMA, &RotateDrag_ZX, NULL);
1701   MA_GroupPtr rotate_group_ZX = MA_AddGroup(ma, "Rotate_ZX",
1702                                             rotate_press,   MA_ONLY,
1703                                             rotate_drag_ZX, MA_ONLY,
1704                                             NULL);
1705 
1706   static RotatePivots3D RotateDrag_YZ = { ROTATE_Y, ROTATE_Z };
1707   MActionPtr rotate_drag_YZ =
1708     MA_AddAction(ma, MK_Normal, MA_Drag, Rotate_DragMA, &RotateDrag_YZ, NULL);
1709   MA_GroupPtr rotate_group_YZ = MA_AddGroup(ma, "Rotate_YZ",
1710                                             rotate_press,   MA_ONLY,
1711                                             rotate_drag_YZ, MA_ONLY,
1712                                             NULL);
1713 
1714   /* move */
1715   MActionPtr move_press   =
1716     MA_AddAction(ma, MK_Shift, MA_Press,   Move_PressMA,   NULL, NULL);
1717   MActionPtr move_drag    =
1718     MA_AddAction(ma, MK_Shift, MA_Drag,    Move_DragMA,    NULL, NULL);
1719   MActionPtr move_release =
1720     MA_AddAction(ma, MK_Shift, MA_Release, Move_ReleaseMA, NULL, NULL);
1721   MActionPtr move_cancel  =
1722     MA_AddAction(ma, MK_Shift, MA_Cancel,  Move_CancelMA,  NULL, NULL);
1723 
1724   MA_GroupPtr move_group = MA_AddGroup(ma, "Move",
1725                                        move_press,   MA_ONLY,
1726                                        move_drag,    MA_ONLY,
1727                                        move_release, MA_ONLY,
1728                                        move_cancel,  MA_ONLY,
1729                                        NULL);
1730 
1731   /* zoom */
1732   MActionPtr zoom_press   =
1733     MA_AddAction(ma, MK_Ctrl, MA_Press,   Zoom_PressMA,   NULL, NULL);
1734   MActionPtr zoom_drag    =
1735     MA_AddAction(ma, MK_Ctrl, MA_Drag,    Zoom_DragMA,    NULL, NULL);
1736   MActionPtr zoom_release =
1737     MA_AddAction(ma, MK_Ctrl, MA_Release, Zoom_ReleaseMA, NULL, NULL);
1738   MActionPtr zoom_cancel  =
1739     MA_AddAction(ma, MK_Ctrl, MA_Cancel,  Zoom_CancelMA,  NULL, NULL);
1740 
1741   MA_GroupPtr zoom_group = MA_AddGroup(ma, "Zoom",
1742                                        zoom_press,   MA_ONLY,
1743                                        zoom_drag,    MA_ONLY,
1744                                        zoom_release, MA_ONLY,
1745                                        zoom_cancel,  MA_ONLY,
1746                                        NULL);
1747 
1748   /* miscellaneous actions */
1749   MActionPtr bg_hl_dclick =
1750     MA_AddAction(ma, MK_Normal, MA_DClick,  Bg_HL_DClickMA, NULL,
1751                  "Highlight-Prim or Background");
1752 
1753   /* this group disables all mouse actions when set */
1754   MActionPtr reset_init =
1755     MA_AddAction(ma, MK_Normal, MA_Init,  ResetMA, NULL, NULL);
1756 
1757   MA_GroupPtr reset_group = MA_AddGroup(ma, "No Action",
1758                                         reset_init, MA_SHARED,
1759                                         NULL);
1760 
1761 
1762   {{ /* "No-Action"s */
1763     int i, j;
1764     for (i = 0;  i < MK_Default;  i++)
1765     for (j = 0;  j < MA_Init;     j++)
1766       {
1767         VERIFY ( MA_AddAction(ma, (enumMKey)i, (enumMAction)j,
1768                               DoNothingMA,   NULL, "No Action") );
1769       }
1770   }}
1771 
1772 
1773   /* register the set of standard 3D-viewer groups */
1774   vvv->ma_std_group[Mouse3D_DoNothing] = reset_group;
1775   vvv->ma_std_group[Mouse3D_RotateYX ] = rotate_group_YX;
1776   vvv->ma_std_group[Mouse3D_RotateZX ] = rotate_group_ZX;
1777   vvv->ma_std_group[Mouse3D_RotateYZ ] = rotate_group_YZ;
1778   vvv->ma_std_group[Mouse3D_Move     ] = move_group;
1779   vvv->ma_std_group[Mouse3D_Zoom     ] = zoom_group;
1780 
1781 
1782   /* Test, Setup defaults and Link viewer panel to MA */
1783   if (!rotate_press  ||
1784       !rotate_drag_YX  ||  !rotate_group_YX  ||
1785       !rotate_drag_ZX  ||  !rotate_group_ZX  ||
1786       !rotate_drag_YZ  ||  !rotate_group_YZ  ||
1787       !move_press      ||  !move_drag        ||  !move_release  ||
1788       !move_cancel     ||  !move_group       ||
1789       !zoom_press      ||  !zoom_drag        ||  !zoom_release  ||
1790       !zoom_cancel     ||  !zoom_group       ||
1791       !bg_hl_dclick    ||
1792       !reset_group     ||
1793 
1794       !SetStdMouse3D(vvv, Mouse3D_RotateYX)  ||
1795       !SetStdMouse3D(vvv, Mouse3D_Move    )  ||
1796       !SetStdMouse3D(vvv, Mouse3D_Zoom    )  ||
1797       !MA_SetAction(bg_hl_dclick, FALSE)  ||
1798       !MA_LinkPanel(ma, vvv->panel))
1799     {
1800       MA_Reset( ma );
1801       return FALSE;
1802     }
1803 
1804   return TRUE;
1805 }
1806 
1807 
1808 
1809 /*****************************************************************************
1810 *
1811 *   EXTERNAL FUNCTIONS
1812 *
1813 *****************************************************************************/
1814 
1815 /*
1816  * Viewer data access
1817  */
1818 
MAToViewer3D(MAPtr ma)1819 extern Viewer3D MAToViewer3D(MAPtr ma)
1820 {
1821   return (Viewer3D)MA_GetExtra( ma );
1822 }
1823 
1824 
PanelToViewer3D(PaneL panel)1825 extern Viewer3D PanelToViewer3D(PaneL panel)
1826 {
1827   MAPtr ma;
1828   GetPanelExtra(panel, &ma);
1829 
1830   return MAToViewer3D( ma );
1831 }
1832 
1833 
Nlm_SetAdjust3D(Viewer3D vvv,Uint1 ajust)1834 extern void Nlm_SetAdjust3D(Viewer3D vvv, Uint1 ajust)
1835 {
1836   if ( vvv )
1837     vvv->adjust = ajust;
1838 }
1839 
1840 
Nlm_SetHLColor3D(Viewer3D vvv,Uint1 red,Uint1 green,Uint1 blue)1841 extern void Nlm_SetHLColor3D(Viewer3D vvv, Uint1 red, Uint1 green, Uint1 blue )
1842 {
1843   Nlm_DiagReset();
1844   if (vvv == NULL)
1845     return;
1846 
1847   vvv->colorHLR = red;
1848   vvv->colorHLG = green;
1849   vvv->colorHLB = blue;
1850   vvv->c_version++;
1851 }
1852 
1853 
Nlm_GetViewerImage3D(Viewer3D vvv)1854 extern Nlm_Image Nlm_GetViewerImage3D(Viewer3D vvv)
1855 {
1856   return vvv->image;
1857 }
1858 
1859 
Nlm_GetViewerInfo3D(Viewer3D vvv,Picture3D PNTR pic,Nlm_Camera3DPtr camera,RectPtr rectangle)1860 extern void Nlm_GetViewerInfo3D(Viewer3D vvv, Picture3D PNTR pic,
1861                                 Nlm_Camera3DPtr camera, RectPtr rectangle)
1862 {
1863   PCamera3DUnion camUnn;
1864 
1865   Nlm_DiagReset();
1866   if (pic != NULL)
1867     *pic = NULL;
1868 
1869   if (vvv == NULL)
1870     return;
1871 
1872   if (pic != NULL)
1873     *pic = vvv->pic;
1874 
1875   if (camera != NULL  &&  vvv->pic != NULL)
1876     {
1877       camera->dummy[0] = CAMERA_KEY;
1878 
1879       MemCpy((VoidPtr)&camera->dummy[1],  (VoidPtr)vvv->a, sizeof(vvv->a));
1880       MemCpy((VoidPtr)&camera->dummy[10], (VoidPtr)vvv->c, sizeof(vvv->c));
1881 
1882       camUnn.colorHLR   = vvv->colorHLR;
1883       camUnn.colorHLG   = vvv->colorHLG;
1884       camUnn.colorHLB   = vvv->colorHLB;
1885       camUnn.perspectN  = vvv->perspectN;
1886       camUnn.brighN     = vvv->brighN;
1887       camUnn.colorPicN  = vvv->colorPicN;
1888       camUnn.colorFon   = vvv->colorFon;
1889       camUnn.colorFonR  = vvv->colorFonR;
1890       camUnn.colorFonG  = vvv->colorFonG;
1891       camUnn.colorFonB  = vvv->colorFonB;
1892       camUnn.adjust     = vvv->adjust;
1893       camUnn.scale      = vvv->scale;
1894 
1895       MemCpy((VoidPtr)&camera->dummy[13], (VoidPtr)&camUnn, sizeof(camUnn));
1896     }
1897 
1898   if (rectangle != NULL)
1899     ObjectRect(vvv->panel, rectangle);
1900 }
1901 
1902 
Nlm_GetFoundPrim3D(Viewer3D vvv,Uint2 primIndex)1903 extern Prim3D Nlm_GetFoundPrim3D(Viewer3D vvv, Uint2 primIndex)
1904 {
1905   Nlm_DiagReset();
1906   if (vvv == NULL  ||  primIndex >= vvv->nPrimFound)
1907     return NULL;
1908 
1909   return vvv->foundPrim[primIndex];
1910 }
1911 
1912 
Nlm_IsSeg3DHlighted(Viewer3D vvv,Segment3D segment)1913 extern Boolean Nlm_IsSeg3DHlighted(Viewer3D vvv, Segment3D segment)
1914 {
1915   Nlm_DiagReset();
1916 
1917   return (Boolean)(segment != NULL  &&
1918                    (((Nlm_Base3DPtr)segment)->status & HL_SEGMENT));
1919 }
1920 
1921 
Nlm_IsPrim3DHlighted(Viewer3D vvv,Prim3D prim)1922 extern Boolean Nlm_IsPrim3DHlighted(Viewer3D vvv, Prim3D prim)
1923 {
1924   Nlm_DiagReset();
1925   return (Boolean)
1926     (prim != NULL  &&  (((Nlm_Base3DPtr)prim)->status & HL_PRIMITIVE));
1927 }
1928 
1929 
Nlm_SetBackground3D(Nlm_Viewer3D vvv,Nlm_Uint1 red,Nlm_Uint1 green,Nlm_Uint1 blue)1930 extern void Nlm_SetBackground3D(Nlm_Viewer3D vvv,
1931                                 Nlm_Uint1 red, Nlm_Uint1 green, Nlm_Uint1 blue)
1932 {
1933   if (vvv == NULL)
1934       return;
1935 
1936   SetColorCell((Nlm_GraphiC)vvv->panel, vvv->colorFon,
1937                (vvv->colorFonR = red),
1938                (vvv->colorFonG = green),
1939                (vvv->colorFonB = blue));
1940 
1941   vvv->c_version++;
1942 }
1943 
1944 
1945 /*
1946  * Viewer auxiliary routines
1947  */
1948 
BgColorDlg3D(Viewer3D vvv)1949 extern void BgColorDlg3D(Viewer3D vvv)
1950 { /* Choose and change the viewer background color */
1951   if ( ChooseColorDialog(&vvv->colorFonR,
1952                          &vvv->colorFonG,
1953                          &vvv->colorFonB,
1954                          0) )
1955     Nlm_SetBackground3D(vvv,
1956                         vvv->colorFonR,
1957                         vvv->colorFonG,
1958                         vvv->colorFonB);
1959 }
1960 
1961 
Nlm_ZoomAll3D(Viewer3D vvv)1962 extern void Nlm_ZoomAll3D(Viewer3D vvv)
1963 {
1964   WindoW tmpPort;
1965   if (!Visible(vvv->panel) ||  !AllParentsVisible(vvv->panel))
1966     return;
1967 
1968   ZoomAll(vvv, ZOOM_KEEP_ANGLE);
1969   tmpPort = SavePort( vvv->panel );
1970   Select( vvv->panel );
1971   DrawViewer3D( vvv );
1972   RestorePort( tmpPort );
1973   Nlm_DiagReset();
1974 }
1975 
1976 
1977 #ifndef WIN_MOTIF
Nlm_CopyViewer3D(Viewer3D vvv)1978 extern void Nlm_CopyViewer3D(Viewer3D vvv)
1979 {
1980   SaveImageClip( vvv->image );
1981 }
1982 
Nlm_PrintViewer3D(Viewer3D vvv)1983 extern void Nlm_PrintViewer3D(Viewer3D vvv)
1984 {
1985   PrintImage( vvv->image );
1986 }
1987 #endif
1988 
1989 
Nlm_SaveViewer3D(Viewer3D vvv)1990 extern void Nlm_SaveViewer3D(Viewer3D vvv)
1991 {
1992   Char fname[PATH_MAX];
1993   if ( !GetOutputFileName(fname, sizeof(fname), "*.gif") )
1994     return;
1995 
1996   SaveImageGIF(vvv->image, fname);
1997 }
1998 
1999 
Nlm_FindPrim3D(Viewer3D vvv,PoinT pt)2000 extern Uint2 Nlm_FindPrim3D(Viewer3D vvv, PoinT pt)
2001 {
2002   Nlm_PPict3DPtr PPP;
2003 
2004   RecT r;
2005   int  i,j,k;
2006   int  x, y;
2007 
2008   Nlm_DiagReset();
2009   if (vvv == NULL)
2010     return 0;
2011 
2012   ObjectRect(vvv->panel, &r);
2013 
2014   Nlm_stCon.zBuffer  =
2015     (Uint2Ptr)MemNew((2*FIND_BLOCK_SIZE+1) *
2016                      (2*FIND_BLOCK_SIZE+1) * sizeof(Uint2));
2017   Nlm_stCon.idBuffer =
2018     (VoidPtr*)MemNew((2*FIND_BLOCK_SIZE+1) *
2019                      (2*FIND_BLOCK_SIZE+1) * sizeof(VoidPtr));
2020   if (!Nlm_stCon.zBuffer  ||  !Nlm_stCon.idBuffer) {
2021     Nlm_DiagPutRecord(DA_ERROR, viewerClass, "FindPrim3D",
2022                       "Cannot lock memory block");
2023     Nlm_stCon.zBuffer  = (Uint2Ptr)MemFree(Nlm_stCon.zBuffer);
2024     Nlm_stCon.idBuffer = (VoidPtr*)MemFree(Nlm_stCon.idBuffer);
2025     return 0;
2026   }
2027 
2028   PPP = (Nlm_PPict3DPtr)vvv->pic;
2029 
2030   pt.x -= r.left + 2;
2031   pt.y -= r.top  + 4;
2032 #ifdef NEGYSCREEN
2033   pt.y = (Int2)(vvv->height - pt.y);
2034 #endif
2035   SetUpContext( vvv );
2036   Nlm_stCon.widthCur = Nlm_stCon.heightCur = FIND_BLOCK_SIZE * 2 + 1;
2037   Nlm_UpdateGver( PPP );
2038   Nlm_stCon.xmin = pt.x - FIND_BLOCK_SIZE;
2039   Nlm_stCon.xmax = pt.x + FIND_BLOCK_SIZE;
2040   Nlm_stCon.ymin = pt.y - FIND_BLOCK_SIZE;
2041   Nlm_stCon.ymax = pt.y + FIND_BLOCK_SIZE;
2042   PPP->seg.base.fTable->hittest( (Nlm_VoidPtr)&PPP->seg );
2043   vvv->nPrimFound = 0;
2044   for (i =  0;  i <= (FIND_BLOCK_SIZE - 1);  i++)
2045   for (j = -i;  j <= i;  j++)
2046   for (k =  0;  k <  4;  k++) {
2047     switch ( k ) {
2048     case 0:
2049       x = -j;  y = -i;  break;
2050     case 1:
2051       x =  j;  y =  i;  break;
2052     case 2:
2053       x = -i;  y =  j;  break;
2054     default:
2055       x =  i;  y = -j;
2056     }
2057     x += FIND_BLOCK_SIZE;
2058     y += FIND_BLOCK_SIZE;
2059     Nlm_AddFoundPrim(vvv,
2060                      (Prim3D)Nlm_stCon.idBuffer[y * (FIND_BLOCK_SIZE+1) + x]);
2061   }
2062 
2063   Nlm_stCon.zBuffer  = (Uint2Ptr) MemFree( Nlm_stCon.zBuffer  );
2064   Nlm_stCon.idBuffer = (VoidPtr*) MemFree( Nlm_stCon.idBuffer );
2065   return vvv->nPrimFound;
2066 }
2067 
2068 
Nlm_HighlightSeg3D(Viewer3D vvv,Segment3D segment,Boolean highlight)2069 extern void Nlm_HighlightSeg3D(Viewer3D vvv,
2070                                Segment3D segment, Boolean highlight)
2071 {
2072   register Nlm_Base3DPtr prim = (Nlm_Base3DPtr)segment;
2073 
2074   Nlm_DiagReset();
2075   if (vvv == NULL  ||  prim == 0)
2076     return;
2077 
2078   if ( highlight )
2079     prim->status |= HL_SEGMENT;
2080   else
2081     prim->status &= ~HL_MASK;
2082 
2083   for (prim = ((Nlm_PSeg3DPtr)prim)->first;  prim;  prim = prim->next) {
2084     if (prim->fTable->code == 0)
2085       Nlm_HighlightSeg3D(vvv, (Segment3D)prim, highlight);
2086     else if ( highlight )
2087       prim->status |= HL_SEGMENT;
2088     else
2089       prim->status &= ~HL_SEGMENT;
2090   }
2091 
2092   {{
2093     register Nlm_PPict3DPtr PPP = (Nlm_PPict3DPtr)vvv->pic;
2094     if (PPP->version == vvv->p_version)
2095       {
2096         Nlm_RedrawPrim3D(vvv, (Nlm_Base3DPtr)segment);
2097         vvv->p_version++;
2098       }
2099     PPP->version++;
2100   }}
2101 }
2102 
2103 
Nlm_HighlightPrim3D(Viewer3D vvv,Prim3D prim,Boolean highlight)2104 extern void Nlm_HighlightPrim3D(Viewer3D vvv, Prim3D prim, Boolean highlight)
2105 {
2106   Nlm_DiagReset();
2107   if (vvv == NULL  ||  prim == NULL)
2108     return;
2109 
2110   if ( highlight )
2111     ((Nlm_Base3DPtr)prim)->status |= HL_PRIMITIVE;
2112   else
2113     ((Nlm_Base3DPtr)prim)->status &= ~HL_PRIMITIVE;
2114 
2115   {{
2116     register Nlm_PPict3DPtr PPP = (Nlm_PPict3DPtr)vvv->pic;
2117     if (PPP->version == vvv->p_version)
2118       {
2119         Nlm_RedrawPrim3D(vvv, (Nlm_Base3DPtr)prim);
2120         vvv->p_version++;
2121       }
2122     PPP->version++;
2123   }}
2124 }
2125 
2126 
Nlm_ResetHighlight3D(Viewer3D vvv)2127 extern Boolean Nlm_ResetHighlight3D(Viewer3D vvv)
2128 {
2129   Nlm_DiagReset();
2130 
2131   if (vvv != NULL  &&  vvv->pic != NULL)
2132     {
2133       register Nlm_PPict3DPtr PPP = (Nlm_PPict3DPtr)vvv->pic;
2134       Nlm_ResetHLSeg3D( (Segment3D)&PPP->seg );
2135       PPP->version++;
2136     }
2137 
2138   return TRUE;
2139 }
2140 
2141 
Nlm_MapWorldToViewer3D(Viewer3D vvv,Int4 x,Int4 y,Int4 z,PoinT PNTR vPoint)2142 extern Boolean Nlm_MapWorldToViewer3D(Viewer3D vvv, Int4 x, Int4 y, Int4 z,
2143                                       PoinT PNTR vPoint)
2144 {
2145   register Viewer3D VVV = vvv;
2146   Int4 xs, ys, zs;
2147   Int4 t4, zmaxPersp, zmaxPersp1;
2148 
2149   Nlm_DiagReset();
2150   if (VVV == NULL)
2151     return FALSE;
2152 
2153   zmaxPersp  = VVV->perspect * VVV->zmax;
2154   zmaxPersp1 = zmaxPersp + VVV->zmax;
2155   xs = x/VVV->a[0][0] + y/VVV->a[0][1] + z/VVV->a[0][2] + VVV->c[0];
2156   ys = x/VVV->a[1][0] + y/VVV->a[1][1] + z/VVV->a[1][2] + VVV->c[1];
2157   zs = x/VVV->a[2][0] + y/VVV->a[2][1] + z/VVV->a[2][2] + VVV->c[2];
2158   t4 = xs - (VVV->width >>1);
2159   xs = (VVV->width >>1) + (t4 * zmaxPersp) / (zmaxPersp1 - zs);
2160   t4 = ys - (VVV->height>>1);
2161   ys = (VVV->height>>1) - (t4 * zmaxPersp) / (zmaxPersp1 - zs);
2162 
2163   vPoint->x = (Int2)xs;
2164   vPoint->y = (Int2)ys;
2165   return TRUE;
2166 }
2167 
2168 
Nlm_SetStdMouse3D(Viewer3D vvv,enumStdMA3D action)2169 extern Boolean Nlm_SetStdMouse3D(Viewer3D vvv, enumStdMA3D action)
2170 {
2171   return MA_SetGroup( vvv->ma_std_group[action] );
2172 }
2173 
2174 
2175 /*
2176  * Viewer general management
2177  */
2178 
Nlm_CreateViewer3D(GrouP prnt,Uint2Ptr width,Uint2 height,Int4 flags,MenU ma_group_menu,MenU ma_action_menu,Nlm_MAInit3DFunc ma_init_func,VoidPtr ma_init_data)2179 extern Viewer3D Nlm_CreateViewer3D(GrouP prnt,
2180                                    Uint2Ptr width, Uint2 height,
2181                                    Int4 flags,
2182                                    MenU ma_group_menu, MenU ma_action_menu,
2183                                    Nlm_MAInit3DFunc ma_init_func,
2184                                    VoidPtr          ma_init_data)
2185 {
2186   Viewer3D vvv     = NULL;
2187   CharPtr  err_msg = NULL;
2188 
2189   while ( TRUE ) {{{ /* TRY! */
2190 
2191   Int4  i;
2192   Uint2 x_width;
2193 
2194   Nlm_DiagReset();
2195 
2196   if ( !isqrtInit )
2197     {
2198       Int4 j, k = 0;
2199       for (i =  0; i < 128; i++)
2200       for (j = -i; j <= i;  j++)
2201         Nlm_Isqrt[k++] = (Uint1)(sqrt( (double)(i*i - j*j) ));
2202 
2203       isqrtInit = TRUE;
2204     }
2205 
2206   vvv = (Viewer3D)MemNew( sizeof(structViewer3D) );
2207   if (vvv == NULL) {
2208     err_msg = "Cannot allocate memory block for the viewer";
2209     break;
2210   }
2211 
2212   vvv->parentWindow = ParentWindow( (Handle)prnt );
2213   vvv->panel = AutonomousPanel(prnt,
2214                               (Int2)*width, (Int2)height,
2215                                DrawViewer3D_CB,
2216                                ((flags & Y_ROTATE_SBAR) ?
2217                                 ViewerVScrollProc : NULL),
2218                                ((flags & X_ROTATE_SBAR) ?
2219                                 ViewerHScrollProc : NULL),
2220                                sizeof(MAPtr), ResetViewerProc_CB, NULL);
2221   if ( !vvv->panel ) {
2222     err_msg = "Cannot create panel";
2223     break;
2224   }
2225 
2226   if (flags & Z_ROTATE_SBAR)
2227     {
2228       vvv->z_rotate = ScrollBar(prnt, 1, 0, ViewerZScrollProc);
2229       if ( !vvv->z_rotate ) {
2230         err_msg = "Cannot create Z-rotation scrollbar";
2231         break;
2232       }
2233       SetObjectExtra(vvv->z_rotate, vvv->panel, NULL);
2234     }
2235 
2236   {{
2237     RecT rect;
2238     GetPosition(vvv->panel, &rect);
2239     rect.right  = (Int2)(rect.left + *width);
2240     rect.bottom = (Int2)(rect.top  + height);
2241     if ( !SetPosition3D(vvv, &rect) ) {
2242       err_msg = "Cannot allocate memory for the viewer image & zBuffer";
2243       break;
2244     }
2245     x_width = (Uint2)(rect.right - rect.left);
2246   }}
2247 
2248   vvv->colorHLR  = vvv->colorHLG  = vvv->colorHLB = (Uint1)255;
2249   vvv->colorFon  = ImageGetBlack( vvv->image );
2250   vvv->colorFonR = vvv->colorFonG = vvv->colorFonB = (Uint1)0;
2251   for ( i=0; i<256; i++ )
2252     vvv->layerTable[i] = TRUE;
2253 
2254   if (flags & X_ROTATE_SBAR) {
2255     BaR sb = GetSlateHScrollBar( (SlatE)vvv->panel );
2256     CorrectBarValue(sb, 0);
2257     SetRange(sb, 10, 10, 360);
2258   }
2259   if (flags & Y_ROTATE_SBAR) {
2260     BaR sb = GetSlateVScrollBar( (SlatE)vvv->panel );
2261     CorrectBarValue(sb, 0);
2262     SetRange(sb, 10, 10, 360);
2263   }
2264   if (flags & Z_ROTATE_SBAR) {
2265     SetRange(vvv->z_rotate, 10, 10, 360);
2266     CorrectBarValue(vvv->z_rotate, 180);
2267   }
2268 
2269   vvv->adjust = ADJUST3D_PERSPECT;
2270 
2271   vvv->ma = MA_Create(ma_group_menu, ma_action_menu);
2272   MA_SetExtra(vvv->ma, vvv);
2273 
2274   if ( !InitializeMA( vvv ) ) {
2275     err_msg = "Cannot create/initialize standard mouse controls";
2276     break;
2277   }
2278 
2279   if (ma_init_func  &&  !(*ma_init_func)(vvv->ma, ma_init_data)) {
2280     err_msg = "Cannot create/initialize user-specified mouse controls";
2281     break;
2282   }
2283 
2284   *width = x_width;
2285   return vvv;
2286   }}} /* End of TRY;  below is the CATCH block(post-error cleaning code): */
2287 
2288 
2289   ASSERT ( err_msg );
2290   Nlm_DiagPutRecord(DA_ERROR, viewerClass, "CreateViewer3D", err_msg);
2291   if ( vvv )
2292     {
2293       if ( vvv->panel )
2294         Remove( vvv->panel );
2295       if ( vvv->z_rotate )
2296         Remove( vvv->z_rotate );
2297       ResetImage3D( vvv );
2298       MemFree( vvv );
2299     }
2300 
2301   return NULL;
2302 }
2303 
2304 
Nlm_SetPosition3D(Viewer3D vvv,RectPtr rect)2305 extern Boolean Nlm_SetPosition3D(Viewer3D vvv, RectPtr rect)
2306 {
2307   Int4 width  = rect->right - rect->left;
2308   Int4 height = rect->bottom - rect->top;
2309 
2310   Nlm_DiagReset();
2311 
2312   ResetImage3D( vvv );
2313 
2314   if ( vvv->z_rotate )
2315     {
2316       rect->top += Nlm_hScrollBarHeight;
2317       height    -= Nlm_hScrollBarHeight;
2318     }
2319 
2320   if ( GetSlateVScrollBar((SlatE)vvv->panel) )
2321     width  -= Nlm_vScrollBarWidth  + 3;
2322   if ( GetSlateHScrollBar((SlatE)vvv->panel) )
2323     height -= Nlm_hScrollBarHeight + 3;
2324 
2325   if (width < 16  ||  height < 16
2326 #ifdef WIN16
2327       ||  width * height > (Int4)0x7FFF
2328 #endif
2329       )
2330     return FALSE;
2331 
2332   vvv->image = CreateImage();
2333   if (vvv->image == NULL)
2334     return FALSE;
2335 
2336   {{
2337     Uint2 x_width = (Uint2)width;
2338     if ( !AllocateImage(vvv->image, &x_width, (Uint2)height, 32, 256) ) {
2339       ResetImage3D( vvv );
2340       return FALSE;
2341     }
2342     width = x_width;
2343   }}
2344 
2345   vvv->width  = (Int2)width;
2346   vvv->height = (Int2)height;
2347   vvv->zBuffer = HandNew(sizeof(Int2) * vvv->width * vvv->height);
2348   if (vvv->zBuffer == NULL) {
2349     ResetImage3D( vvv );
2350     return FALSE;
2351   }
2352 
2353   vvv->g_version++;
2354   vvv->c_version++;
2355 
2356   ZoomAll(vvv, ZOOM_KEEP_ALL);
2357 
2358   rect->right  = (Int2)(rect->left + vvv->width  + 3);
2359   rect->bottom = (Int2)(rect->top  + vvv->height + 3);
2360   if ( GetSlateVScrollBar((SlatE)vvv->panel) )
2361     rect->right  += Nlm_vScrollBarWidth;
2362   if ( GetSlateHScrollBar((SlatE)vvv->panel) )
2363     rect->bottom += Nlm_hScrollBarHeight;
2364 
2365   SetPosition(vvv->panel, rect);
2366   ProcessUpdatesFirst( FALSE );
2367   AdjustPrnt(vvv->panel, rect, FALSE);
2368 
2369   if ( vvv->z_rotate )
2370     {
2371       rect->bottom = rect->top;
2372       rect->top   -= Nlm_hScrollBarHeight;
2373       SetPosition(vvv->z_rotate, rect);
2374     }
2375 
2376   return TRUE;
2377 }
2378 
2379 
Nlm_AttachPicture3D(Viewer3D vvv,Picture3D picture,Nlm_Camera3DPtr camera)2380 extern Boolean Nlm_AttachPicture3D(Viewer3D vvv, Picture3D picture,
2381                                    Nlm_Camera3DPtr camera)
2382 {
2383   Nlm_PPict3DPtr PPP = (Nlm_PPict3DPtr)picture;
2384 
2385   Nlm_DiagReset();
2386   if (vvv == NULL)
2387     return FALSE;
2388 
2389   vvv->pic = NULL;
2390   {{
2391     BaR sb;
2392     sb = GetSlateHScrollBar( (SlatE)vvv->panel );
2393     if ( sb ) {
2394       CorrectBarValue(sb, 0);
2395       SetRange(sb, 10, 10, 360);
2396     }
2397     sb = GetSlateVScrollBar( (SlatE)vvv->panel );
2398     if ( sb ) {
2399       CorrectBarValue(sb, 0);
2400       SetRange(sb, 10, 10, 360);
2401     }
2402     if ( vvv->z_rotate ) {
2403       CorrectBarValue(vvv->z_rotate, 180);
2404       SetRange(vvv->z_rotate, 10, 10, 360);
2405     }
2406   }}
2407   vvv->pic = picture;
2408 
2409   ASSERT ( sizeof(vvv->layerTable)  ==  sizeof(PPP->layerTable) );
2410   MemCpy(vvv->layerTable, PPP->layerTable, sizeof(vvv->layerTable));
2411   SetLayer3D(picture, 1, TRUE);
2412   vvv->layerTable[0] = TRUE;
2413   currlayer = 0;
2414 
2415 
2416   ASSERT ( CAMERA_SIZE_I4 * sizeof(Int4)  ==  sizeof(camera->dummy) );
2417   if (camera != NULL  &&  camera->dummy[0] == CAMERA_KEY)
2418     {
2419       PCamera3DUnion camUnn;
2420 
2421       ASSERT ( sizeof(vvv->a) <=
2422 	       sizeof(camera->dummy) - 1*sizeof(camera->dummy[0]) );
2423       MemCpy((VoidPtr)vvv->a,  (VoidPtr)&camera->dummy[1],  sizeof(vvv->a));
2424 
2425       ASSERT ( sizeof(vvv->c) <=
2426 	       sizeof(camera->dummy) - 10*sizeof(camera->dummy[0]) );
2427       MemCpy((VoidPtr)vvv->c,  (VoidPtr)&camera->dummy[10], sizeof(vvv->c));
2428 
2429       ASSERT ( sizeof(camUnn) <=
2430 	       sizeof(camera->dummy) - 13*sizeof(camera->dummy[0]) );
2431       MemCpy((VoidPtr)&camUnn, (VoidPtr)&camera->dummy[13], sizeof(camUnn));
2432 
2433       vvv->perspectN  = camUnn.perspectN;
2434       vvv->perspect   = perspectAll[vvv->perspectN];
2435       vvv->brighN     = camUnn.brighN;
2436       vvv->colorPicN  = camUnn.colorPicN;
2437       vvv->colorHLR   = camUnn.colorHLR;
2438       vvv->colorHLG   = camUnn.colorHLG;
2439       vvv->colorHLB   = camUnn.colorHLB;
2440       vvv->colorFon   = camUnn.colorFon;
2441       vvv->colorFonR  = camUnn.colorFonR;
2442       vvv->colorFonG  = camUnn.colorFonG;
2443       vvv->colorFonB  = camUnn.colorFonB;
2444       vvv->adjust     = camUnn.adjust;
2445       vvv->scale      = camUnn.scale;
2446       MakeFloatMat( vvv );
2447       ZoomAll(vvv, ZOOM_KEEP_ALL);
2448     }
2449   else
2450     {
2451       vvv->perspectN = 2;
2452       vvv->perspect  = perspectAll[vvv->perspectN];
2453       vvv->brighN    = 5;
2454       vvv->colorPicN = 5;
2455       ZoomAll(vvv, ZOOM_ALL);
2456     }
2457   vvv->c_version++;
2458   vvv->g_version++;
2459   SetUpContext( vvv );
2460 
2461   if (Visible(vvv->panel)  &&  AllParentsVisible(vvv->panel))
2462     {
2463       RecT   r;
2464       WindoW tempPort = SavePort( vvv->panel );
2465       Select( vvv->panel );
2466       ObjectRect(vvv->panel, &r);
2467       InvalRect( &r );
2468       RestorePort( tempPort );
2469     }
2470 
2471   return DiagHasErrorRec();
2472 }
2473 
2474 
Nlm_RedrawViewer3D(Viewer3D vvv)2475 extern Boolean Nlm_RedrawViewer3D(Viewer3D vvv)
2476 {
2477   Nlm_DiagReset();
2478 
2479   if (!Visible( vvv->panel )  ||  !AllParentsVisible( vvv->panel ))
2480     return FALSE;
2481 
2482   {{
2483     WindoW tempPort = SavePort( vvv->panel );
2484     Select( vvv->panel );
2485     DrawViewer3D( vvv );
2486     RestorePort( tempPort );
2487   }}
2488 
2489   return DiagHasErrorRec();
2490 }
2491 
2492 
Nlm_DeleteViewer3D(Nlm_Viewer3D vvv)2493 extern void Nlm_DeleteViewer3D(Nlm_Viewer3D vvv)
2494 {
2495   if (vvv == NULL)
2496     return;
2497 
2498   Nlm_DiagReset();
2499 
2500   MA_Destroy( vvv->ma );
2501 
2502   ResetImage3D( vvv );
2503 
2504   if ( vvv->panel )
2505     Remove( vvv->panel );
2506 
2507   MemFree( vvv );
2508 }
2509 
2510