1 #include "SUMA_suma.h"
2
3 extern SUMA_CommonFields *SUMAg_CF;
4 extern int SUMAg_N_DOv;
5 extern SUMA_DO *SUMAg_DOv;
6 extern SUMA_SurfaceViewer *SUMAg_SVv;
7 extern int SUMAg_N_SVv;
8
9 /*!
10 SUMA's viewing paramters are tuned to show human brains in mm units.
11 When a human surface is entered in cm units, some scaling needs to be
12 done so that the surface appears nice.
13 For example, in the cm vs mm case, I got nasty shading errors because
14 the viewing distance was too far.
15 A similar problem might arise if the surface is very small, like a rat's
16 for example. So there should be some scaling needed for other species.
17 */
SUMA_DimSclFac(char * units,char * specie)18 float SUMA_DimSclFac(char *units, char *specie)
19 {
20 static char FuncName[]={"SUMA_DimSclFac"};
21 float scm=1.0;
22
23 SUMA_ENTRY;
24
25 scm = 1.0;
26
27 if (!units) units = SUMA_EnvVal("SUMA_NodeCoordsUnits");
28 /* scaling for units */
29 if (units) {
30 if (!strcasecmp(units,"mm")) {
31 scm = 1.0;
32 } else if (!strcasecmp(units,"cm")) {
33 scm = 10.0;
34 } else {
35 SUMA_S_Warnv(
36 "Bad value of '%s' for units variable or\n"
37 " ENV 'SUMA_NodeCoordsUnits'. Using 'mm'\n",
38 units);
39 }
40 }
41
42 /* scaling for species - not sure what to do yet. Wait until it is needed */
43 /* You'll need to set the factor be
44 scm = scm * AVERAGE_HUMAN_BRAIN_SIZE/AVERAGE_SPECIE_SIZE */
45
46 /* might also want an automatic fix that guess at what to do */
47
48 SUMA_RETURN(scm);
49 }
50
51 /*!
52 \brief a function that returns the first viewer that is in momentum mode
53 isv = SUMA_WhichViewerInMomentum( SVv, N_SV, sv);
54
55 \param SVv (SUMA_SurfaceViewer *) vector of surface viewers
56 \param N_SV (int ) number of surface viewer structures in SVv
57 \param sv (SUMA_SurfaceViewer *) if !NULL then the function returns the
58 index of a surface viewer OTHER THAN sv that is in momentum mode.
59 Otherwise the first surface viewer in momentum mode is returned
60 \return isv (int) the index (into SVv) of the first viewer that is in
61 momentum mode. If sv is not NULL then it is the index of the
62 first viewer OTHER THAN sv that is in momentum mode
63 If none are found, ans = -1
64
65 - To turn the index into the viewer's label use:
66 if (isv >= 0) sprintf(slabel,"[%c] SUMA", 65+isv);
67 else sprintf(slabel,"[DOH] SUMA");
68 */
69
SUMA_WhichViewerInMomentum(SUMA_SurfaceViewer * SVv,int N_SV,SUMA_SurfaceViewer * sv)70 int SUMA_WhichViewerInMomentum(SUMA_SurfaceViewer *SVv, int N_SV,
71 SUMA_SurfaceViewer *sv)
72 {
73 static char FuncName[]={"SUMA_WhichViewerInMomentum"};
74 int ii = -1;
75
76 SUMA_ENTRY;
77
78 if (!SVv) SUMA_RETURN(-1);
79
80 for (ii=0; ii < SUMAg_N_SVv; ++ii) {
81 if (SVv[ii].GVS[SVv[ii].StdView].ApplyMomentum) {
82 if (!sv) { /* don't care which one */
83 SUMA_RETURN(ii);
84 } else if (&(SUMAg_SVv[ii]) != sv) { /* other than sv */
85 SUMA_RETURN(ii);
86 }
87 }
88 }
89
90 SUMA_RETURN(-1);
91
92 }
93
94 /*!
95 return an appropriate fov setting
96 */
SUMA_sv_auto_fov(SUMA_SurfaceViewer * sv)97 float SUMA_sv_auto_fov(SUMA_SurfaceViewer *sv)
98 {
99 static char FuncName[]={"SUMA_sv_auto_fov"};
100 float mxdim = -1.0, fov = FOV_INITIAL,
101 maxv[3]={-1.0, -1.0, -1.0}, *xyzr,
102 minv[3]={1000000.0, 10000000.0, 1000000.0}, avgdim=30.0;
103 int i, N_sel=0, *Vis_IDs=NULL, k=0;
104 double CurrentDistance;
105 SUMA_DSET *dset=NULL;
106 SUMA_SurfaceObject *SO=NULL;
107 SUMA_Boolean LocalHead = NOPE;
108
109 SUMA_ENTRY;
110
111 if (sv->iState < 0) {
112 SUMA_S_Errv("Can't do this with no state set, returning %f!",
113 FOV_INITIAL);
114 SUMA_RETURN(FOV_INITIAL);
115 }
116 if (sv->auto_FOV_val[sv->iState] > 0.0)
117 SUMA_RETURN(sv->auto_FOV_val[sv->iState]);
118
119 /* automatic determination */
120 Vis_IDs = (int *)SUMA_malloc(sizeof(int)*SUMAg_N_DOv);
121 minv[0] = minv[1] = minv[2] = 1;
122 maxv[0] = maxv[1] = maxv[2] = 0;
123 N_sel = SUMA_Selectable_ADOs (sv, SUMAg_DOv, Vis_IDs);
124 if (!N_sel) {
125 SUMA_LH("Nothing selectable!");
126 SUMA_free(Vis_IDs); Vis_IDs= NULL;
127 SUMA_RETURN(FOV_INITIAL);
128 } else {
129 for (i=0; i<N_sel;++i) {
130 SUMA_LHv("Working object %s\n",iDO_label(Vis_IDs[i]));
131 switch (SUMAg_DOv[Vis_IDs[i]].ObjectType) {
132 case SO_type:
133 SO = (SUMA_SurfaceObject *)SUMAg_DOv[Vis_IDs[i]].OP;
134 if (minv[0] > maxv[0]) { /* init */
135 for (k=0; k<3; ++k) {
136 minv[k] = SO->MinDims[k];
137 maxv[k] = SO->MaxDims[k];
138 }
139 } else {
140 for (k=0; k<3; ++k) {
141 if (SO->MinDims[k] < minv[k])
142 minv[k] = SO->MinDims[k];
143 if (SO->MaxDims[k] > maxv[k])
144 maxv[k] = SO->MaxDims[k];
145 }
146 }
147
148 /* Note that prior to Aug. 2013 k only went up to 1 (k<2),
149 both below and above. Despite that, avgdim was dividing by 3,
150 rather than the expected '2'. Not sure why that was, but
151 for now, we're sticking with saner situation */
152 avgdim = 0.0;
153 for (k=0;k<3;++k) {
154 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
155 avgdim += maxv[k] - minv[k];
156 }
157 avgdim /= 3.0;
158 break;
159 case GRAPH_LINK_type:
160 if(!(dset=SUMA_find_GLDO_Dset(
161 (SUMA_GraphLinkDO *)(SUMAg_DOv[Vis_IDs[i]].OP)))){
162 SUMA_S_Err("Gilda");
163 break;
164 }
165
166 if (!SUMA_IS_REAL_VARIANT(iDO_variant(Vis_IDs[i]))) break;
167 xyzr = SUMA_GDSET_XYZ_Range(dset, iDO_variant(Vis_IDs[i]), NULL);
168 if (minv[0] > maxv[0]) { /* init */
169 for (k=0; k<3; ++k) {
170 minv[k] = xyzr[2*k];
171 maxv[k] = xyzr[2*k+1];
172 }
173 } else {
174 for (k=0; k<3; ++k) {
175 if (xyzr[2*k] < minv[k]) minv[k] = xyzr[2*k];
176 if (xyzr[2*k+1] > maxv[k]) maxv[k] = xyzr[2*k+1];
177 }
178 }
179 if (!strcmp(iDO_variant(Vis_IDs[i]), "GMATRIX")) {
180 avgdim = 0.0; /* X Y dims only */
181 for (k=0;k<2;++k) {
182 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
183 avgdim += maxv[k] - minv[k];
184 }
185 avgdim /= 2.0;
186 /* increase dims a little to allow for text placement */
187 avgdim *= 1.15; mxdim *= 1.15;
188 } else {
189 avgdim = 0.0;
190 for (k=0;k<3;++k) {
191 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
192 avgdim += maxv[k] - minv[k];
193 }
194 avgdim /= 3.0;
195 }
196 break;
197 case TRACT_type: {
198 SUMA_TractDO *tdo=(SUMA_TractDO *)SUMAg_DOv[Vis_IDs[i]].OP;
199 xyzr = SUMA_TDO_XYZ_Range(tdo, NULL);
200 if (minv[0] > maxv[0]) { /* init */
201 for (k=0; k<3; ++k) {
202 minv[k] = xyzr[2*k];
203 maxv[k] = xyzr[2*k+1];
204 }
205 } else {
206 for (k=0; k<3; ++k) {
207 if (xyzr[2*k] < minv[k]) minv[k] = xyzr[2*k];
208 if (xyzr[2*k+1] > maxv[k]) maxv[k] = xyzr[2*k+1];
209 }
210 }
211 avgdim = 0.0;
212 for (k=0;k<3;++k) {
213 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
214 avgdim += maxv[k] - minv[k];
215 }
216 avgdim /= 3.0;
217 break; }
218 case VO_type: {
219 SUMA_VolumeObject *vo=
220 (SUMA_VolumeObject *)SUMAg_DOv[Vis_IDs[i]].OP;
221 xyzr = SUMA_VO_XYZ_Range(vo, NULL);
222 if (minv[0] > maxv[0]) { /* init */
223 for (k=0; k<3; ++k) {
224 minv[k] = xyzr[2*k];
225 maxv[k] = xyzr[2*k+1];
226 }
227 } else {
228 for (k=0; k<3; ++k) {
229 if (xyzr[2*k] < minv[k]) minv[k] = xyzr[2*k];
230 if (xyzr[2*k+1] > maxv[k]) maxv[k] = xyzr[2*k+1];
231 }
232 }
233 avgdim = 0.0;
234 for (k=0;k<3;++k) {
235 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
236 avgdim += maxv[k] - minv[k];
237 }
238 avgdim /= 3.0;
239 break; }
240 case CDOM_type: {
241 xyzr = SUMA_CIFTI_DO_XYZ_Range(
242 (SUMA_CIFTI_DO*)SUMAg_DOv[Vis_IDs[i]].OP, NULL);
243 if (minv[0] > maxv[0]) { /* init */
244 for (k=0; k<3; ++k) {
245 minv[k] = xyzr[2*k];
246 maxv[k] = xyzr[2*k+1];
247 }
248 } else {
249 for (k=0; k<3; ++k) {
250 if (xyzr[2*k] < minv[k]) minv[k] = xyzr[2*k];
251 if (xyzr[2*k+1] > maxv[k]) maxv[k] = xyzr[2*k+1];
252 }
253 }
254 avgdim = 0.0;
255 for (k=0;k<3;++k) {
256 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
257 avgdim += maxv[k] - minv[k];
258 }
259 avgdim /= 3.0;
260 break; }
261 case MASK_type: {
262 SUMA_MaskDO *mo=
263 (SUMA_MaskDO *)SUMAg_DOv[Vis_IDs[i]].OP;
264 xyzr = SUMA_MDO_XYZ_Range(mo, NULL);
265 if (minv[0] > maxv[0]) { /* init */
266 for (k=0; k<3; ++k) {
267 minv[k] = xyzr[2*k];
268 maxv[k] = xyzr[2*k+1];
269 }
270 } else {
271 for (k=0; k<3; ++k) {
272 if (xyzr[2*k] < minv[k]) minv[k] = xyzr[2*k];
273 if (xyzr[2*k+1] > maxv[k]) maxv[k] = xyzr[2*k+1];
274 }
275 }
276 avgdim = 0.0;
277 for (k=0;k<3;++k) {
278 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
279 avgdim += maxv[k] - minv[k];
280 }
281 avgdim /= 3.0;
282 break; }
283 default:
284 SUMA_LHv("Ignoring dims of %s\n", iDO_label(Vis_IDs[i]));
285 avgdim = 0.0;
286 for (k=0;k<3;++k) {
287 if (maxv[k] - minv[k] > mxdim) mxdim = maxv[k] - minv[k];
288 avgdim += maxv[k] - minv[k];
289 }
290 avgdim /= 3.0;
291 break;
292 }
293 }
294 }
295 SUMA_free(Vis_IDs); Vis_IDs= NULL;
296 SUMA_LHv("Have mxdim = %f, avgdim = %f (rat %.2f)\n",
297 mxdim, avgdim, mxdim / avgdim);
298 /* Current avg. distance from camera */
299 CurrentDistance = sqrt((sv->GVS[sv->StdView].ViewFrom[0] -
300 sv->GVS[sv->StdView].ViewCenter[0]) *
301 (sv->GVS[sv->StdView].ViewFrom[0] -
302 sv->GVS[sv->StdView].ViewCenter[0]) +
303 (sv->GVS[sv->StdView].ViewFrom[1] -
304 sv->GVS[sv->StdView].ViewCenter[1]) *
305 (sv->GVS[sv->StdView].ViewFrom[1] -
306 sv->GVS[sv->StdView].ViewCenter[1]) +
307 (sv->GVS[sv->StdView].ViewFrom[2] -
308 sv->GVS[sv->StdView].ViewCenter[2]) *
309 (sv->GVS[sv->StdView].ViewFrom[2] -
310 sv->GVS[sv->StdView].ViewCenter[2]));
311
312 if (mxdim > 0 && mxdim < 1000) {
313 SUMA_LHv("sv %p mxdim=%f, avgdim=%f, rat=%f, DimSclFac = %f, "
314 "CurrentDist = %f\n",
315 sv, mxdim, avgdim, mxdim / avgdim,
316 sv->GVS[sv->StdView].DimSclFac, CurrentDistance);
317 if (mxdim / avgdim > 2.2) { /* crazy aspect, adopt average size */
318 mxdim = avgdim;
319 }
320 /* fov is the double of the angle at the camera of the square triangle
321 with depth = CurrentDistance and width = half the biggest distance
322 Not sure about the DimSclFac usage here, need to retest it at some
323 point.*/
324 /* make mxdim a little larger for some framing */
325 fov = 2.0*atan((double)(mxdim *1.1* sv->GVS[sv->StdView].DimSclFac)
326 / 2.0 / CurrentDistance)*180.0/SUMA_PI;
327 SUMA_LHv("Computed fov to be %f degrees\n", fov);
328 } else {
329 static int nwarn=0;
330 fov = FOV_INITIAL;
331 if (!(nwarn % SUMA_MAX_SURF_VIEWERS)) {
332 SUMA_S_Errv("max dim too strange (%f)\nUsing default (%f).\n"
333 "Similar messages will be decimated.\n",
334 mxdim, fov);
335 }
336 ++nwarn;
337 }
338
339 /* institutional memory */
340 sv->auto_FOV_val[sv->iState] = fov;
341
342 SUMA_RETURN(fov);
343 }
344
345
346 /* This is used to hold the functions that manipulate SV, Surface Viewer Structures */
347 /*!
348 \brief returns a string corresponding to the link type
349
350 SUMA_Boolean SUMA_LockEnum_LockType (SUMA_LINK_TYPES i, char *Name);
351 \param i (SUMA_LINK_TYPES) see enum type in SUMA_define.h
352 \param Name (char *) a preallocated character string (no more than 50 chars)
353 \return YUP/NOPE OK, error
354 */
SUMA_LockEnum_LockType(SUMA_LINK_TYPES i,char * Name)355 SUMA_Boolean SUMA_LockEnum_LockType (SUMA_LINK_TYPES i, char *Name)
356 {
357 static char FuncName[]={"SUMA_LockEnum_LockType"};
358 SUMA_ENTRY;
359
360 switch (i) {
361 case SUMA_No_Lock:
362 sprintf (Name, "No Lock");
363 break;
364 case SUMA_I_Lock:
365 sprintf (Name, "Index Lock");
366 break;
367 case SUMA_XYZ_Lock:
368 sprintf (Name, "XYZ Lock");
369 break;
370 default:
371 sprintf (Name, "?");
372 SUMA_RETURN (NOPE);
373
374 }
375
376 SUMA_RETURN (YUP);
377 }
378
379 /* Use this function to capture GVS as last displayed */
SUMA_CopyGeomViewStruct(SUMA_GEOMVIEW_STRUCT * gvs1,SUMA_GEOMVIEW_STRUCT * gvs2)380 SUMA_Boolean SUMA_CopyGeomViewStruct(SUMA_GEOMVIEW_STRUCT *gvs1,
381 SUMA_GEOMVIEW_STRUCT *gvs2)
382 {
383 static char FuncName[]={"SUMA_CopyGeomViewStruct"};
384
385 SUMA_ENTRY;
386
387 if (!gvs1 || !gvs2) SUMA_RETURN(NOPE);
388
389 /* This assumes that SUMA_GEOMVIEW_STRUCT has no dynamic allocations */
390 memcpy(gvs2, gvs1, sizeof(SUMA_GEOMVIEW_STRUCT));
391 SUMA_RETURN(YUP);
392 }
393
394
395 /* overzealous but prudent */
SUMA_DiffGeomViewStruct(SUMA_GEOMVIEW_STRUCT gvs1,SUMA_GEOMVIEW_STRUCT gvs2,int level)396 SUMA_Boolean SUMA_DiffGeomViewStruct(SUMA_GEOMVIEW_STRUCT gvs1,
397 SUMA_GEOMVIEW_STRUCT gvs2,
398 int level)
399 {
400 static char FuncName[]={"SUMA_DiffGeomViewStruct"};
401
402 SUMA_ENTRY;
403
404 if (level <= 1) { /* big deal, should change position of object in space */
405 if (SUMA_VEC_DIFF3(gvs1.ViewFrom, gvs2.ViewFrom)) SUMA_RETURN(2);
406 if (SUMA_VEC_DIFF3(gvs1.ViewCenter, gvs2.ViewCenter)) SUMA_RETURN(4);
407 if (SUMA_VEC_DIFF3(gvs1.ViewCamUp, gvs2.ViewCamUp)) SUMA_RETURN(6);
408 if (gvs1.ViewDistance != gvs2.ViewDistance) SUMA_RETURN(7);
409 if (SUMA_VEC_DIFF3(gvs1.translateVec, gvs2.translateVec))
410 SUMA_RETURN(15);
411 if (SUMA_VEC_DIFF3(gvs1.RotaCenter, gvs2.RotaCenter)) SUMA_RETURN(16);
412 if (SUMA_VEC_DIFF4(gvs1.deltaQuat, gvs2.deltaQuat)) SUMA_RETURN(24);
413 if (SUMA_VEC_DIFF4(gvs1.currentQuat, gvs2.currentQuat)) SUMA_RETURN(25);
414 if (gvs1.ApplyMomentum != gvs2.ApplyMomentum) SUMA_RETURN(26);
415
416 }
417 if (level > 1) { /* any change */
418 if (gvs1.DimSclFac != gvs2.DimSclFac) SUMA_RETURN(1);
419 if (SUMA_VEC_DIFF3(gvs1.ViewFromOrig, gvs2.ViewFromOrig)) SUMA_RETURN(3);
420 if (SUMA_VEC_DIFF3(gvs1.ViewCenterOrig, gvs2.ViewCenterOrig))
421 SUMA_RETURN(5);
422 if (gvs1.translateBeginX != gvs2.translateBeginX) SUMA_RETURN(8);
423 if (gvs1.translateBeginY != gvs2.translateBeginY) SUMA_RETURN(9);
424 if (gvs1.translateDeltaX != gvs2.translateDeltaX) SUMA_RETURN(10);
425 if (gvs1.translateDeltaY != gvs2.translateDeltaY) SUMA_RETURN(11);
426 if (gvs1.TranslateGain != gvs2.TranslateGain) SUMA_RETURN(12);
427 if (gvs1.ArrowtranslateDeltaX != gvs2.ArrowtranslateDeltaX)
428 SUMA_RETURN(13);
429 if (gvs1.ArrowtranslateDeltaY != gvs2.ArrowtranslateDeltaY)
430 SUMA_RETURN(14);
431 if (gvs1.zoomDelta != gvs2.zoomDelta) SUMA_RETURN(17);
432 if (gvs1.zoomBegin != gvs2.zoomBegin) SUMA_RETURN(18);
433 if (gvs1.spinDeltaX != gvs2.spinDeltaX) SUMA_RETURN(19);
434 if (gvs1.spinDeltaY != gvs2.spinDeltaY) SUMA_RETURN(20);
435 if (gvs1.spinBeginX != gvs2.spinBeginX) SUMA_RETURN(21);
436 if (gvs1.spinBeginY != gvs2.spinBeginY) SUMA_RETURN(22);
437 if (gvs1.MinIdleDelta != gvs2.MinIdleDelta) SUMA_RETURN(23);
438 if (gvs1.vLHpry[0] != gvs2.vLHpry[0]) SUMA_RETURN(27);
439 if (gvs1.vLHpry0[0] != gvs2.vLHpry0[0]) SUMA_RETURN(28);
440 if (gvs1.vLHpry[1] != gvs2.vLHpry[1]) SUMA_RETURN(29);
441 if (gvs1.vLHpry0[1] != gvs2.vLHpry0[1]) SUMA_RETURN(30);
442 if (gvs1.vLHpry[2] != gvs2.vLHpry[2]) SUMA_RETURN(31);
443 if (gvs1.vLHpry0[2] != gvs2.vLHpry0[2]) SUMA_RETURN(32);
444 if (gvs1.LHlol != gvs2.LHlol) SUMA_RETURN(33);
445 }
446
447 /* if (gvs1. != gvs2.) SUMA_RETURN(); */
448
449 SUMA_RETURN(0); /* no difference */
450 }
451
SUMA_VerifyRenderOrder(char * ord,void * unused)452 int SUMA_VerifyRenderOrder(char *ord, void *unused)
453 {
454 static char FuncName[]={"SUMA_VerifyRenderOrder"};
455
456 if (SUMA_SetObjectDisplayOrder(ord, NULL) < 0) return(0);
457
458 return(1);
459 }
460
SUMA_SetObjectDisplayOrder(char * ord,int * otseq)461 int SUMA_SetObjectDisplayOrder(char *ord, int *otseq)
462 {
463 static char FuncName[]={"SUMA_SetObjectDisplayOrder"};
464 NI_str_array *sar = NULL;
465 int iii, cnt = 0, bad = 0, dummy[N_DO_TYPES], used[N_DO_TYPES];
466 SUMA_Boolean LocalHead = NOPE;
467
468 SUMA_ENTRY;
469
470 cnt = -1;
471
472 if (!otseq) otseq = dummy;
473
474 if (!ord || !strcmp(ord,"DEFAULT")) {
475 otseq[0] = VO_type;
476 otseq[1] = SO_type;
477 otseq[2] = GRAPH_LINK_type;
478 cnt = 3;
479 RETURN(cnt);
480 }
481
482 memset(used, 0, N_DO_TYPES*sizeof(int));
483 deblank_name(ord);
484 if ((sar = SUMA_NI_decode_string_list( ord , ",;"))) {
485 cnt = 0;
486 for (iii=0; iii<sar->num; ++iii) {
487 if (sar->str[iii]) deblank_name(sar->str[iii]);
488 if (sar->str[iii]) {
489 bad = 0;
490 if (!strncasecmp(sar->str[iii],"sur", 3)) {
491 if (!used[SO_type]) {
492 otseq[cnt++] = SO_type;
493 used[SO_type] = 1;
494 } else {
495 SUMA_S_Err("Duplicate reference to surfaces in %s",
496 sar->str[iii]);
497 bad = 1;
498 }
499 } else if (!strncasecmp(sar->str[iii],"vol", 3)) {
500 if (!used[VO_type]) {
501 otseq[cnt++] = VO_type;
502 used[VO_type] = 1;
503 } else {
504 SUMA_S_Err("Duplicate reference to volumes in %s",
505 sar->str[iii]);
506 bad = 1;
507 }
508 } else if (!strncasecmp(sar->str[iii],"gra", 3)) {
509 if (!used[GRAPH_LINK_type]) {
510 otseq[cnt++] = GRAPH_LINK_type;
511 used[GRAPH_LINK_type] = 1;
512 } else {
513 SUMA_S_Err("Duplicate reference to graphs in %s",
514 sar->str[iii]);
515 bad = 1;
516 }
517 } else if (!strcmp(sar->str[iii],"S")) {
518 if (!used[SO_type]) {
519 otseq[cnt++] = SO_type;
520 used[SO_type] = 1;
521 } else {
522 SUMA_S_Err("Duplicate reference to surfaces in %s",
523 sar->str[iii]);
524 bad = 1;
525 }
526 } else if (!strcmp(sar->str[iii],"V")) {
527 if (!used[VO_type]) {
528 otseq[cnt++] = VO_type;;
529 used[VO_type] = 1;
530 } else {
531 SUMA_S_Err("Duplicate reference to volumes in %s",
532 sar->str[iii]);
533 bad = 1;
534 }
535 } else if (!strcmp(sar->str[iii],"G")) {
536 if (!used[GRAPH_LINK_type]) {
537 otseq[cnt++] = GRAPH_LINK_type;
538 used[GRAPH_LINK_type] = 1;
539 } else {
540 SUMA_S_Err("Duplicate reference to graphs in %s",
541 sar->str[iii]);
542 bad = 1;
543 }
544 } else if (sar->num == 1) {
545 int OK=0, jjj;
546 char *ss=sar->str[0];
547 for (jjj=0; jjj<strlen(ss); ++jjj) {
548 if (ss[jjj] == 'S' || ss[jjj] == 'V' || ss[jjj] == 'G') ++OK;
549 }
550 if (OK != strlen(ss)) {
551 bad = 2;
552 }
553 for (jjj=0; jjj<strlen(ss); ++jjj) {
554 switch (ss[jjj]) {
555 case 'S':
556 if (!used[SO_type]) {
557 otseq[cnt++] = SO_type;
558 used[SO_type] = 1;
559 } else {
560 SUMA_S_Err("Duplicate reference to surfaces in %s",
561 sar->str[0]);
562 bad = 1;
563 }
564 break;
565 case 'V':
566 if (!used[VO_type]) {
567 otseq[cnt++] = VO_type;
568 used[VO_type] = 1;
569 } else {
570 SUMA_S_Err("Duplicate reference to volumes in %s",
571 sar->str[0]);
572 bad = 1;
573 }
574 break;
575 case 'G':
576 if (!used[GRAPH_LINK_type]) {
577 otseq[cnt++] = GRAPH_LINK_type;
578 used[GRAPH_LINK_type] = 1;
579 } else {
580 SUMA_S_Err("Duplicate reference to graphs in %s",
581 sar->str[0]);
582 bad = 1;
583 }
584 break;
585 }
586 }
587 } else {
588 bad = 2;
589 }
590 if (bad) {
591 if (bad == 2 && otseq != dummy) {
592 SUMA_S_Warn("Object type %s in env SUMA_ObjectDisplayOrder '%s'\n"
593 "was not recognized. For now only 'surface'\n"
594 "'volume', and 'graph' are allowed.\n",
595 sar->str[iii], ord);
596 }
597 if (otseq == dummy) SUMA_RETURN(-1);
598 }
599 }
600 }
601 sar = SUMA_free_NI_str_array(sar);
602 }
603 if (LocalHead && otseq != dummy) {
604 SUMA_LH("Sequence now:");
605 for (iii=0; iii<cnt; ++iii) {
606 fprintf(SUMA_STDERR,"%d ", otseq[iii]);
607 }
608 fprintf(SUMA_STDERR,"\n");
609 }
610
611 if (ord && ord[0] != '\0' && cnt < 1 && otseq == dummy)
612 SUMA_RETURN(-1); /* an error flag used by SUMA_VerifyRenderOrder()*/
613
614 SUMA_RETURN(cnt);
615 }
616
617 /*!
618 Create a SurfaceViewer data structure
619 */
SUMA_Alloc_SurfaceViewer_Struct(int N)620 SUMA_SurfaceViewer *SUMA_Alloc_SurfaceViewer_Struct (int N)
621 {
622 static char FuncName[]={"SUMA_Alloc_SurfaceViewer_Struct"};
623 SUMA_SurfaceViewer *SV=NULL, *SVv=NULL;
624 int i=-1, j=-1, n=-1, iii=-1;
625 float a[3], lightpos[3];
626 char *lightstr;
627 SUMA_Boolean LocalHead = NOPE;
628
629 SUMA_ENTRY;
630
631 SVv = (SUMA_SurfaceViewer *)SUMA_calloc(N, sizeof(SUMA_SurfaceViewer));
632 if (SVv == NULL) {
633 fprintf(SUMA_STDERR,"Error %s: Failed to SUMA_malloc SV\n", FuncName);
634 SUMA_RETURN (NULL);
635 }
636 for (i=0; i < N; ++i) {
637 SV = &(SVv[i]);
638 memset(SV, 0, sizeof(SUMA_SurfaceViewer));
639
640 SV->C_mode = SUMA_CONV_NONE;
641 SV->C_filter = SUMA_C_newfilter(1, 1);
642 SV->LoadedTextures[0] = -1; /* plug */
643 SV->N_GVS = SUMA_N_STANDARD_VIEWS;
644 SV->GVS = (SUMA_GEOMVIEW_STRUCT *)
645 SUMA_calloc(SV->N_GVS, sizeof(SUMA_GEOMVIEW_STRUCT));
646 SV->GVS_last_PickMode = (SUMA_GEOMVIEW_STRUCT *)
647 SUMA_calloc(SV->N_GVS, sizeof(SUMA_GEOMVIEW_STRUCT));
648 if (!SV->GVS) {
649 fprintf(SUMA_STDERR,
650 "Error %s: Could not allocate for N_GVS.\n",
651 FuncName);
652 SUMA_RETURN (NULL);
653 }
654 SV->StdView = SUMA_3D; /* default */
655
656 /* set the standards for all viewing modes here */
657 SV->verbose = 1;
658 {
659 char *eee = getenv("SUMA_AdjustMouseMotionWithZoom");
660 if (eee) {
661 if (strcasecmp (eee, "YES") == 0) SV->ZoomCompensate = 1.0;
662 else SV->ZoomCompensate = 0.0;
663 } else {
664 SV->ZoomCompensate = 1.0;
665 }
666 }
667 {
668 char *eee = getenv("SUMA_FreezeFOVAcrossStates");
669 if (eee) {
670 if (strcasecmp (eee, "YES") == 0) SV->FreezeZoomXstates = 1;
671 else SV->FreezeZoomXstates = 0;
672 } else {
673 SV->FreezeZoomXstates = 1;
674 }
675 }
676 {
677 char *eee = getenv("SUMA_ViewOrthographicProjection");
678 if (eee) {
679 if (strcasecmp (eee, "YES") == 0) SV->ortho = 1;
680 else SV->ortho = 0;
681 } else {
682 SV->ortho = 0;
683 }
684 }
685
686 SV->ShowLabelAtXhair = 1;
687 if (!SUMA_isEnv("SUMA_ShowLabelsAtCrossHair","YES")) {
688 SV->ShowLabelAtXhair = 0;
689 }
690 SV->ShowSelectedDatum = 1;
691 SV->ShowSelectedFaceSet = 1;
692 SV->ShowSelectedEdge = 1;
693
694 SV->SelAdo = (DList *)SUMA_calloc(1,sizeof(DList));
695 dlist_init (SV->SelAdo, SUMA_Free_SelectedDO_Datum);
696 SV->LastSel_ado_idcode_str = NULL;
697
698 SV->Aspect = 1.0;
699 SV->FOV = NULL;
700 SV->auto_FOV_val = NULL;
701 SV->FOV_last_PickMode = NULL;
702
703 for (j=0; j < SV->N_GVS; ++j) {
704 memset(&(SV->GVS[j]), 0, sizeof(SUMA_GEOMVIEW_STRUCT));
705 SV->GVS[j].DimSclFac = SUMA_DimSclFac(NULL, NULL);
706 switch (j) {
707 case SUMA_2D_Z0:
708 case SUMA_2D_Z0L:
709 /* Default top view, rotate by nothing */
710 SUMA_HOME_QUAT(j, SV->GVS[j].currentQuat);
711 SV->GVS[j].ApplyMomentum = False;
712
713 SV->GVS[j].vLHpry[0] = 0.0;
714 SV->GVS[j].vLHpry0[0] = 0.0;
715 SV->GVS[j].vLHpry[1] = 0.0;
716 SV->GVS[j].vLHpry0[1] = 0.0;
717 SV->GVS[j].vLHpry[2] = 0.0;
718 SV->GVS[j].vLHpry0[2] = 0.0;
719 SV->GVS[j].LHlol = 0;
720 SV->GVS[j].MinIdleDelta = 1;
721 SV->GVS[j].TranslateGain = TRANSLATE_GAIN;
722 SV->GVS[j].ArrowtranslateDeltaX = ARROW_TRANSLATE_DELTAX;
723 SV->GVS[j].ArrowtranslateDeltaY = ARROW_TRANSLATE_DELTAY;
724
725 SV->GVS[j].ViewCamUp[0] = 0.0;
726 SV->GVS[j].ViewCamUp[1] = 1.0;
727 SV->GVS[j].ViewCamUp[2] = 0.0;
728
729 SV->GVS[j].ViewFrom[0] = 0.0;
730 SV->GVS[j].ViewFrom[1] = 0.0;
731 SV->GVS[j].ViewFrom[2] = SUMA_DEFAULT_VIEW_FROM;
732
733 SV->GVS[j].ViewCenter[0] = 0.0;
734 SV->GVS[j].ViewCenter[1] = 0.0;
735 SV->GVS[j].ViewCenter[2] = 0.0;
736
737 SV->GVS[j].RotaCenter[0] = 0.0;
738 SV->GVS[j].RotaCenter[1] = 0.0;
739 SV->GVS[j].RotaCenter[2] = 0.0;
740 break;
741 case SUMA_3D_Z0:
742 case SUMA_3D:
743 SUMA_HOME_QUAT(j, SV->GVS[j].currentQuat);
744
745 SV->GVS[j].ApplyMomentum = False;
746
747 SV->GVS[j].vLHpry[0] = 0.0;
748 SV->GVS[j].vLHpry0[0] = 0.0;
749 SV->GVS[j].vLHpry[1] = 0.0;
750 SV->GVS[j].vLHpry0[1] = 0.0;
751 SV->GVS[j].vLHpry[2] = 0.0;
752 SV->GVS[j].vLHpry0[2] = 0.0;
753 SV->GVS[j].LHlol = 0;
754 SV->GVS[j].MinIdleDelta = 1;
755 SV->GVS[j].TranslateGain = TRANSLATE_GAIN;
756 SV->GVS[j].ArrowtranslateDeltaX = ARROW_TRANSLATE_DELTAX;
757 SV->GVS[j].ArrowtranslateDeltaY = ARROW_TRANSLATE_DELTAY;
758
759 SV->GVS[j].ViewCamUp[0] = 0.0;
760 SV->GVS[j].ViewCamUp[1] = 1.0;
761 SV->GVS[j].ViewCamUp[2] = 0.0;
762
763 SV->GVS[j].ViewFrom[0] = 0.0;
764 SV->GVS[j].ViewFrom[1] = 0.0;
765 SV->GVS[j].ViewFrom[2] = 0.0;
766
767 SV->GVS[j].ViewCenter[0] = 0.0;
768 SV->GVS[j].ViewCenter[1] = 0.0;
769 SV->GVS[j].ViewCenter[2] = 0.0;
770
771 SV->GVS[j].RotaCenter[0] = 0.0;
772 SV->GVS[j].RotaCenter[1] = 0.0;
773 SV->GVS[j].RotaCenter[2] = 0.0;
774
775 SV->GVS[j].translateVec[0] = 0.0;
776 SV->GVS[j].translateVec[1] = 0.0;
777 break;
778 default:
779 fprintf(SUMA_STDERR,
780 "Error %s: Undefined viewing mode.\n", FuncName);
781 SUMA_RETURN (NULL);
782
783 }
784 }
785
786
787 SV->light0_position[0] = 0.0;
788 SV->light0_position[1] = 0.0;
789
790 SV->light0_position[2] = 1.0 * SUMA_INTITIAL_LIGHT0_SWITCH;
791 SV->lit_for = SUMA_INTITIAL_LIGHT0_SWITCH;
792
793 SV->light0_position[3] = 0.0;
794
795 lightstr = getenv("SUMA_Light0Position");
796 if (lightstr) {
797 if (SUMA_StringToNum (lightstr, (void *)lightpos, 3, 1) == 3) {
798 SV->light0_position[0] = lightpos[0];
799 SV->light0_position[1] = lightpos[1];
800 SV->light0_position[2] = lightpos[2];
801 }
802 }
803
804 SV->light1_position[0] = 1.0;
805 SV->light1_position[1] = 1.0;
806 SV->light1_position[2] = 1.0;
807 SV->light1_position[3] = 0.0;
808
809 lightstr = getenv("SUMA_Light1Position");
810 if (lightstr) {
811 if (SUMA_StringToNum (lightstr, (void *)lightpos, 3, 1) == 3) {
812 SV->light1_position[0] = lightpos[0];
813 SV->light1_position[1] = lightpos[1];
814 SV->light1_position[2] = lightpos[2];
815 }
816 }
817
818
819 SV->dim_spe = 1.0;
820 SV->dim_dif = 1.0;
821 SV->dim_emi = 1.0;
822 SV->dim_amb = 1.0;
823
824 {
825 static SUMA_Boolean err = NOPE;
826 float fv3[3];
827 char *eee = getenv("SUMA_Light0Color");
828 if (eee && !err) {
829 if (SUMA_StringToNum (eee, (void *)fv3, 3, 1) != 3) {
830 err = YUP;
831 SUMA_SL_Err("Syntax error in environment\n"
832 "variable SUMA_Light0Color");
833 SV->light0_color[0] = SUMA_LIGHT0_COLOR_R;
834 SV->light0_color[1] = SUMA_LIGHT0_COLOR_G;
835 SV->light0_color[2] = SUMA_LIGHT0_COLOR_B;
836 SV->light0_color[3] = SUMA_LIGHT0_COLOR_A;
837 }else {
838 SV->light0_color[0] = fv3[0];
839 SV->light0_color[1] = fv3[1];
840 SV->light0_color[2] = fv3[2];
841 SV->light0_color[3] = SUMA_LIGHT0_COLOR_A;
842 }
843 }else {
844 SV->light0_color[0] = SUMA_LIGHT0_COLOR_R;
845 SV->light0_color[1] = SUMA_LIGHT0_COLOR_G;
846 SV->light0_color[2] = SUMA_LIGHT0_COLOR_B;
847 SV->light0_color[3] = SUMA_LIGHT0_COLOR_A;
848 }
849 }
850
851 {
852 static SUMA_Boolean err = NOPE;
853 float fv3[3];
854 char *eee = getenv("SUMA_AmbientLight");
855 if (eee && !err) {
856 if (SUMA_StringToNum (eee, (void *)fv3, 3, 1) != 3) {
857 err = YUP;
858 SUMA_SL_Err("Syntax error in environment\n"
859 "variable SUMA_AmbientLight");
860 SV->lmodel_ambient[0] = SUMA_LMODEL_AMBIENT_COLOR_R;
861 SV->lmodel_ambient[1] = SUMA_LMODEL_AMBIENT_COLOR_G;
862 SV->lmodel_ambient[2] = SUMA_LMODEL_AMBIENT_COLOR_B;
863 SV->lmodel_ambient[3] = SUMA_LMODEL_AMBIENT_COLOR_A;
864 }else {
865 SV->lmodel_ambient[0] = fv3[0];
866 SV->lmodel_ambient[1] = fv3[1];
867 SV->lmodel_ambient[2] = fv3[2];
868 SV->lmodel_ambient[3] = SUMA_LMODEL_AMBIENT_COLOR_A;
869 }
870 }else {
871 SV->lmodel_ambient[0] = SUMA_LMODEL_AMBIENT_COLOR_R;
872 SV->lmodel_ambient[1] = SUMA_LMODEL_AMBIENT_COLOR_G;
873 SV->lmodel_ambient[2] = SUMA_LMODEL_AMBIENT_COLOR_B;
874 SV->lmodel_ambient[3] = SUMA_LMODEL_AMBIENT_COLOR_A;
875 }
876 }
877 {
878 static SUMA_Boolean err = NOPE;
879 float fv3[3];
880 char *eee = getenv("SUMA_BackgroundColor");
881 if (eee && !err) {
882 if (SUMA_StringToNum (eee, (void *)fv3, 3,1) != 3) {
883 err = YUP;
884 SUMA_SL_Err("Syntax error in environment\n"
885 "variable SUMA_BackgroundColor");
886 SV->clear_color[0] = SUMA_CLEAR_COLOR_R;
887 SV->clear_color[1] = SUMA_CLEAR_COLOR_G;
888 SV->clear_color[2] = SUMA_CLEAR_COLOR_B;
889 SV->clear_color[3] = SUMA_CLEAR_COLOR_A;
890 }else {
891 SV->clear_color[0] = fv3[0];
892 SV->clear_color[1] = fv3[1];
893 SV->clear_color[2] = fv3[2];
894 SV->clear_color[3] = SUMA_CLEAR_COLOR_A;
895 }
896 }else {
897 SV->clear_color[0] = SUMA_CLEAR_COLOR_R;
898 SV->clear_color[1] = SUMA_CLEAR_COLOR_G;
899 SV->clear_color[2] = SUMA_CLEAR_COLOR_B;
900 SV->clear_color[3] = SUMA_CLEAR_COLOR_A;
901 }
902 }
903
904 SV->wWindWidth = 350;
905 SV->wWindHeight = 350;
906 SV->DrawAreaHeightOffset = -1; /* Not known yet */
907 SV->DrawAreaWidthOffset = -1; /* Not known yet */
908 {
909 char *eee = getenv("SUMA_ArrowRotAngle");
910 if (eee) {
911 float rotval = strtod(eee, NULL);
912 if (rotval > 0.0 && rotval < 360.0)
913 SV->ArrowRotationAngle = SUMA_PI * rotval / 180.0;
914 else
915 SV->ArrowRotationAngle = SUMA_PI *
916 ARROW_ROTATION_ANGLE_DEG / 180.0;
917 } else
918 SV->ArrowRotationAngle = SUMA_PI * ARROW_ROTATION_ANGLE_DEG / 180.0;
919 }
920 {
921 char *eee = getenv("SUMA_KeyZoomGain");
922 if (eee) {
923 float rotval = strtod(eee, NULL);
924 if (rotval > 0.0 && rotval < 50.0) SV->KeyZoomGain = rotval/100.0;
925 else SV->KeyZoomGain = 0.05;
926 } else SV->KeyZoomGain = 0.05;
927 }
928 {
929 char *eee = getenv("SUMA_KeyNodeJump");
930 if (eee) {
931 int KeyNodeJump = (int)strtod(eee, NULL);
932 if (KeyNodeJump > 0 && KeyNodeJump <= 10)
933 SV->KeyNodeJump = KeyNodeJump;
934 else SV->KeyNodeJump = 1;
935 } else SV->KeyNodeJump = 1;
936 }
937 {
938 char *eee = getenv("SUMA_ContourThickness");
939 if (eee) {
940 float th = strtod(eee, NULL);
941 if (th > 0 && th <= 100)
942 SV->ContThick = th;
943 else SV->ContThick = 1;
944 } else SV->ContThick = 1;
945 }
946
947 {
948 char *eee = getenv("SUMA_FOV_Original");
949 if (eee) {
950 float fovinit = strtod(eee, NULL);
951 if (fovinit > 1.0 && fovinit < 100.0) SV->FOV_original = fovinit;
952 else if (fovinit < 0) SV->FOV_original = -1;
953 else SV->FOV_original = FOV_INITIAL;
954 } else SV->FOV_original = FOV_INITIAL;
955 }
956
957 SV->Open = NOPE;
958
959 SV->RegistDO = (SUMA_DO_LOCATOR *)
960 SUMA_calloc( SUMA_MAX_DISPLAYABLE_OBJECTS, sizeof(SUMA_DO_LOCATOR));
961 if (SV->RegistDO == NULL) {
962 SUMA_S_Err("Failed to SUMA_malloc SV->RegistDO");
963 SUMA_RETURN (NULL);
964 }
965 SV->N_DO = 0; /* Nothing is registered with the viewer yet */
966
967 SV->ColList = (SUMA_COLORLIST_STRUCT **)
968 SUMA_calloc(SUMA_MAX_DISPLAYABLE_OBJECTS,sizeof(SUMA_COLORLIST_STRUCT*));
969 SV->N_ColList = 0; /* this number reflects the number of surfaces that
970 have colorlist structures in SV */
971
972 SV->ShowEyeAxis = 0;
973 SV->ShowMeshAxis = 0; /* Turned off Oct 15 04 in favor of WorldAxis */
974 SV->ShowWorldAxis = SUMA_NO_WAX;
975
976
977 SV->WAx = SUMA_Alloc_Axis ("Viewer World Axis", AO_type);
978
979 if (SV->WAx == NULL) {
980 fprintf(SUMA_STDERR,"Error %s: Error Allocating axis\n", FuncName);
981 SUMA_RETURN(NULL);
982 }
983 SV->WAx->atype = SUMA_SCALE_BOX;
984
985 SV->Ch = SUMA_Alloc_CrossHair ();
986 if (SV->Ch == NULL) {
987 SUMA_S_Err("Failed in SUMA_Alloc_CrossHair");
988 SUMA_RETURN (NULL);
989 } else SV->ShowCrossHair = 1;
990
991 SV->X = (SUMA_X *)SUMA_calloc(1,sizeof(SUMA_X));
992 if (SV->X == NULL) {
993 SUMA_S_Err("Failed to SUMA_malloc SV->X");
994 SUMA_RETURN (NULL);
995 }
996
997 SV->X->Title = NULL;
998 SV->X->LookAt_prmpt = NULL;
999 SV->X->SetRot_prmpt = NULL;
1000 SV->X->JumpIndex_prmpt = NULL;
1001 SV->X->JumpXYZ_prmpt = NULL;
1002 SV->X->JumpFocusNode_prmpt = NULL;
1003 SV->X->JumpFocusFace_prmpt = NULL;
1004 SV->X->HighlightBox_prmpt = NULL;
1005 SV->X->SetRenderOrder_prmpt = NULL;
1006 SV->X->TOPLEVEL = NULL;
1007 SV->X->MOMENTUMID = 0;
1008 SV->X->REDISPLAYPENDING = 0;
1009 SV->X->DOUBLEBUFFER = True;
1010 SV->X->aWIDTH = SV->X->aHEIGHT = 300; /* if you change this, make sure you
1011 do so for fallbackResources in SUMA_display */
1012 SV->X->ViewCont = SUMA_CreateViewContStruct();
1013 SV->X->DPY = NULL;
1014 SV->X->FORM = SV->X->FRAME = SV->X->GLXAREA = NULL;
1015 SV->X->VISINFO = NULL;
1016 SV->X->REDISPLAYID = SV->X->MOMENTUMID = 0;
1017 SV->X->CMAP = 0;
1018 SV->X->GLXCONTEXT=NULL;
1019 SV->X->CrappyDrawable = 0;
1020 SV->X->gc=NULL;
1021 SV->X->ToggleCrossHair_View_tglbtn=NULL;
1022 SV->X->ToolsMenu = SUMA_Alloc_Menu_Widget(SW_N_Tools);
1023 SV->X->FileMenu = SUMA_Alloc_Menu_Widget(SW_N_File);
1024 SV->X->ViewMenu = SUMA_Alloc_Menu_Widget(SW_N_View);
1025 SV->X->HelpMenu = SUMA_Alloc_Menu_Widget(SW_N_Help);
1026
1027 SV->Focus_DO_ID = -1;
1028
1029 SV->State = NULL;
1030 SV->iState = -1;
1031 SV->VSv = NULL;
1032 SV->N_VSv = 0;
1033 SV->LastNonMapStateID = -1;
1034
1035 SV->iCurGroup = -1;
1036 SV->CurGroupName = NULL;
1037 SUMA_AdoptGroup(SV, NULL); /* Set to the default so we have something */
1038
1039 SV->PolyMode = SRM_Fill;
1040 SV->TransMode = STM_0;
1041 SV->MouseMode = SUMA_DEF_MMODE;
1042 SV->MouseMode_ado_idcode_str = NULL;
1043 SV->DO_DrawMask = SDODM_All;
1044
1045 #if SUMA_BACKFACE_CULL
1046 SV->BF_Cull = YUP;
1047 #else
1048 SV->BF_Cull = NOPE;
1049 #endif
1050
1051 SV->ShowForeground = YUP;
1052 SV->ShowBackground = YUP;
1053
1054 {
1055 char *eee = getenv("SUMA_CenterOnPatch");
1056 if (eee) {
1057 if (strcasecmp (eee, "YES") == 0) SV->UsePatchDims = YUP;
1058 else SV->UsePatchDims = NOPE;
1059 } else {
1060 SV->UsePatchDims = NOPE;
1061 }
1062 }
1063 SV->Back_Modfact = SUMA_BACKGROUND_MODULATION_FACTOR;
1064
1065 SV->isShaded = NOPE;
1066
1067 SV->LinkAfniCrossHair = YUP;
1068
1069 SV->ResetGLStateVariables = YUP;
1070 SV->NewGeom = NOPE;
1071 SV->BS = NULL;
1072
1073 SV->ShowRight = YUP;
1074 SV->ShowLeft = YUP;
1075 SV->Record = NOPE;
1076 SV->rdc = SUMA_RDC_NOT_SET;
1077
1078 SV->Blend_Mode = SUMA_NO_BLEND;
1079
1080 SV->Do_3Drender = 0;
1081 memset(&(SV->SER), 0, sizeof(SUMA_EnablingRecord));
1082
1083 SV->DO_PickMode = 0;
1084 SV->pick_colid_list = NULL;
1085 SV->PickPix[0] = SV->PickPix[1] = -1;
1086 SV->pickrenpix4 = NULL;
1087
1088 /* Squence of types to be displayed. Anything not in the list
1089 gets displayed first */
1090 SV->N_otseq = SUMA_SetObjectDisplayOrder("DEFAULT", SV->otseq);
1091 {
1092 char *eee = getenv("SUMA_ObjectDisplayOrder");
1093 if (eee) {
1094 if ((SV->N_otseq = SUMA_SetObjectDisplayOrder(eee, SV->otseq))<0){
1095 SUMA_S_Warn("Failed to parse %s, reverting to default order",
1096 eee);
1097 SV->N_otseq = SUMA_SetObjectDisplayOrder("DEFAULT", SV->otseq);
1098 }
1099 }
1100 }
1101
1102 SV->PryAx = 3;
1103 }
1104 SUMA_RETURN (SVv);
1105 }
1106
SUMA_Get_From_PickResult_List(SUMA_SurfaceViewer * sv,SUMA_ALL_DO * ado,char * variant)1107 SUMA_PICK_RESULT *SUMA_Get_From_PickResult_List(SUMA_SurfaceViewer *sv,
1108 SUMA_ALL_DO *ado, char *variant)
1109 {
1110 static char FuncName[]={"SUMA_Get_From_PickResult_List"};
1111 DListElmt *el = NULL;
1112 SUMA_SEL_ADO_DATUM *ss = NULL;
1113 SUMA_PICK_RESULT *PR = NULL;
1114 SUMA_Boolean LocalHead = NOPE;
1115
1116 SUMA_ENTRY;
1117
1118 if (!sv || !sv->SelAdo || !ado) SUMA_RETURN(NULL);
1119 if (!variant) variant = "none";
1120 if (!dlist_size(sv->SelAdo)) SUMA_RETURN(NULL);
1121 SUMA_LH("Get %s", ADO_LABEL(ado));
1122 el = NULL;
1123 do {
1124 if (!el) el = dlist_head(sv->SelAdo);
1125 else el = dlist_next(el);
1126
1127 ss = (SUMA_SEL_ADO_DATUM *)el->data;
1128 if (!strcmp(ss->ado_idcode_str, ADO_ID(ado)) &&
1129 !strcmp(ss->variant, variant)) {
1130 dlist_remove(sv->SelAdo, el, (void **)&ss);
1131 PR = ss->PR; ss->PR = NULL;
1132 SUMA_Free_SelectedDO_Datum(ss); ss = NULL;
1133 SUMA_RETURN(PR);
1134 }
1135 } while (el != dlist_tail(sv->SelAdo));
1136
1137 SUMA_RETURN(NULL);
1138 }
1139
SUMA_Add_To_PickResult_List(SUMA_SurfaceViewer * sv,SUMA_ALL_DO * ado,char * variant,SUMA_PICK_RESULT ** PR)1140 SUMA_Boolean SUMA_Add_To_PickResult_List(SUMA_SurfaceViewer *sv,
1141 SUMA_ALL_DO *ado,
1142 char *variant, SUMA_PICK_RESULT **PR)
1143 {
1144 static char FuncName[]={"SUMA_Add_To_PickResult_List"};
1145 DListElmt *el = NULL;
1146 SUMA_SEL_ADO_DATUM *ss = NULL;
1147 SUMA_Boolean LocalHead = NOPE;
1148
1149 SUMA_ENTRY;
1150
1151 if (!sv || !sv->SelAdo) SUMA_RETURN(NOPE);
1152 if (!variant) variant = "none";
1153 if (ado) { /* Add */
1154 SUMA_LH("Add %s", ADO_LABEL(ado));
1155 ss = (SUMA_SEL_ADO_DATUM *)
1156 SUMA_calloc(1,sizeof(SUMA_SEL_ADO_DATUM));
1157 ss->ado_idcode_str = SUMA_copy_string(ADO_ID(ado));
1158 ss->variant = SUMA_copy_string(variant);
1159 if (PR) { ss->PR = *PR; *PR = NULL; }
1160 dlist_ins_next(sv->SelAdo, dlist_tail(sv->SelAdo),
1161 (void *)ss);
1162 } else if (!strcmp(variant,"TERSUM")) { /* empty entire list */
1163 SUMA_LH("Cleanup your act %d entries", dlist_size(sv->SelAdo));
1164 if (dlist_size(sv->SelAdo)) {
1165 while (el = dlist_head(sv->SelAdo)) {
1166 dlist_remove(sv->SelAdo, el, (void **)&ss);
1167 SUMA_Free_SelectedDO_Datum(ss);
1168 }
1169 }
1170 } else {
1171 SUMA_LH("Nothing done (%p, %s)", ado, variant);
1172 SUMA_DUMP_TRACE("Whodunnit?");
1173 }
1174 SUMA_RETURN(YUP);
1175 }
1176
SUMA_Show_PickList(DList * SelAdo,int detail,char * headstring,FILE * out)1177 void SUMA_Show_PickList(DList *SelAdo, int detail, char *headstring, FILE *out)
1178 {
1179 static char FuncName[]={"SUMA_Show_PickList"};
1180 char *s;
1181
1182 SUMA_ENTRY;
1183
1184 if (!out) out = SUMA_STDERR;
1185
1186 if (headstring) fprintf(out, "%s", headstring);
1187
1188 s = SUMA_PickList_Info(SelAdo, detail);
1189 if (s) fprintf(out, "%s", s);
1190
1191 SUMA_ifree(s);
1192
1193 SUMA_RETURNe;
1194 }
1195
SUMA_PickList_Info(DList * SelAdo,int detail)1196 char *SUMA_PickList_Info(DList *SelAdo, int detail)
1197 {
1198 static char FuncName[]={"SUMA_Show_PickList_Info"};
1199 SUMA_STRING *SS = NULL;
1200 DListElmt *el = NULL;
1201 SUMA_SEL_ADO_DATUM *ss = NULL;
1202 char *s=NULL;
1203 SUMA_ALL_DO *ado=NULL;
1204 int ii;
1205 SUMA_Boolean LocalHead = NOPE;
1206
1207 SUMA_ENTRY;
1208
1209 SS = SUMA_StringAppend (NULL, NULL);
1210
1211 if (!SelAdo) {
1212 SS = SUMA_StringAppend(SS, "NULL SelAdo");
1213 goto OUT;
1214 }
1215 SS = SUMA_StringAppend_va(SS,
1216 "SelAdo list of %d entries\n", dlist_size(SelAdo));
1217 el = NULL; ii = 0;
1218 do {
1219 if (!el) el = dlist_head(SelAdo);
1220 else el = dlist_next(el);
1221 if (!(ss = (SUMA_SEL_ADO_DATUM *)el->data)) {
1222 SS = SUMA_StringAppend_va(SS,"%d: NULL data!!!\n", ii);
1223 } else {
1224 if ((ado = SUMA_whichADOg(ss->ado_idcode_str))) {
1225 SS = SUMA_StringAppend_va(SS,"%d: ADO %s, variant %s\n",
1226 ii, ADO_LABEL(ado), ss->variant);
1227 }else {
1228 SS = SUMA_StringAppend_va(SS,"%d: ADO NULL!!!\n",ii);
1229 }
1230 }
1231 ++ii;
1232 } while (el != dlist_tail(SelAdo));
1233
1234 OUT:
1235 SS = SUMA_StringAppend (SS, NULL);
1236 s = SS->s;
1237 SUMA_free(SS);
1238
1239 SUMA_RETURN(s);
1240 }
1241
1242
SUMA_Process_Selected_ADO(SUMA_SurfaceViewer * sv,int deepfirst)1243 SUMA_Boolean SUMA_Process_Selected_ADO(SUMA_SurfaceViewer *sv, int deepfirst)
1244 {
1245 static char FuncName[]={"SUMA_Process_Selected_ADO"};
1246 DListElmt *el = NULL;
1247 SUMA_SEL_ADO_DATUM *ss = NULL;
1248 SUMA_ALL_DO *ado=NULL;
1249 int ii, nn, *isrt;
1250 SUMA_SEL_ADO_DATUM **ssv=NULL;
1251 float *Pxyz, *Sxyz;
1252 SUMA_Boolean LocalHead = NOPE;
1253
1254 SUMA_ENTRY;
1255
1256 if (!sv || !sv->SelAdo) SUMA_RETURN(NOPE);
1257 if (!(nn=dlist_size(sv->SelAdo))) {
1258 SUMA_LH("Empty list");
1259 SUMA_RETURN(YUP);
1260 }
1261
1262 if (LocalHead) {
1263 SUMA_Show_PickList(sv->SelAdo, 1, "Before sorting:\n", NULL);
1264 }
1265
1266 if (nn > 1) {
1267 Pxyz = (float *)SUMA_calloc(3*nn, sizeof(float));
1268 Sxyz = (float *)SUMA_calloc(3*nn, sizeof(float));
1269 ssv = (SUMA_SEL_ADO_DATUM **)SUMA_calloc(nn, sizeof(SUMA_SEL_ADO_DATUM *));
1270
1271
1272 el = NULL; ii = 0;
1273 do {
1274 if (!el) el = dlist_head(sv->SelAdo);
1275 else el = dlist_next(el);
1276 if (!(ss = (SUMA_SEL_ADO_DATUM *)el->data)) {
1277 SUMA_S_Err("NULL data!!!"); SUMA_RETURN(NOPE);
1278 }
1279 if ((ado = SUMA_whichADOg(ss->ado_idcode_str))) {
1280 /* Collect the PickXYZs */
1281 Pxyz[3*ii] = ss->PR->PickXYZ[0];
1282 Pxyz[3*ii+1] = ss->PR->PickXYZ[1];
1283 Pxyz[3*ii+2] = ss->PR->PickXYZ[2];
1284 ssv[ii] = ss; /* Keep a copy */
1285 ++ii;
1286 } else {
1287 SUMA_LH("NULL ado?");
1288 }
1289 } while (el != dlist_tail(sv->SelAdo));
1290
1291 nn = ii; /* in case we had null nonesense */
1292 if (!nn) {
1293 SUMA_LH("Nothing good in here");
1294 SUMA_ifree(ssv); SUMA_ifree(Pxyz); SUMA_ifree(Sxyz);
1295 SUMA_RETURN(YUP);
1296 }
1297
1298 /* Now change all dems coords to eyeball land */
1299 SUMA_World2ScreenCoordsF(sv, nn, Pxyz, Sxyz, NULL, YUP, NOPE);
1300
1301 /* Sort by depth */
1302 for (ii=0; ii<nn; ++ii) {
1303 Sxyz[ii] = Sxyz[3*ii+2];
1304 }
1305 isrt = SUMA_z_qsort (Sxyz, nn);
1306
1307 /* Delete the list and recreate sorted */
1308 el = NULL;
1309 do {
1310 dlist_remove(sv->SelAdo, dlist_head(sv->SelAdo), (void **)&ss);
1311 /* Do not delete ss, we have a copy in ssv */
1312 } while (dlist_size(sv->SelAdo));
1313
1314 /* Now recreate in ordered fashion */
1315 if (!deepfirst) {
1316 for (ii=0; ii<nn; ++ii) {
1317 dlist_ins_next(sv->SelAdo, dlist_head(sv->SelAdo), ssv[isrt[ii]]);
1318 ssv[isrt[ii]]=NULL;
1319 }
1320 } else {
1321 for (ii=0; ii<nn; ++ii) {
1322 dlist_ins_prev(sv->SelAdo, dlist_head(sv->SelAdo), ssv[isrt[ii]]);
1323 ssv[isrt[ii]]=NULL;
1324 }
1325 }
1326
1327 SUMA_ifree(isrt); SUMA_ifree(ssv); SUMA_ifree(Pxyz); SUMA_ifree(Sxyz);
1328 }
1329
1330 if (LocalHead) { /* Show me the list after sorting */
1331 if (deepfirst) {
1332 SUMA_Show_PickList(sv->SelAdo, 1,
1333 "After sorting deepest first:\n", NULL);
1334 } else {
1335 SUMA_Show_PickList(sv->SelAdo, 1,
1336 "After sorting deepest last:\n", NULL);
1337 }
1338 }
1339
1340 /* Now apply the top pick */
1341 SUMA_LH("On to apply the PR");
1342 el = dlist_head(sv->SelAdo);
1343 ss = (SUMA_SEL_ADO_DATUM *)el->data;
1344 SUMA_Apply_PR(sv, &(ss->PR));
1345 SUMA_LH("Returning");
1346
1347 SUMA_RETURN(YUP);
1348 }
1349
SUMA_Free_SelectedDO_Datum(void * data)1350 void SUMA_Free_SelectedDO_Datum(void *data)
1351 {
1352 SUMA_SEL_ADO_DATUM *ss = (SUMA_SEL_ADO_DATUM *)data;
1353 if (ss) {
1354 SUMA_ifree(ss->ado_idcode_str);
1355 SUMA_ifree(ss->variant);
1356 if (ss->PR) ss->PR = SUMA_free_PickResult(ss->PR);
1357 SUMA_free(ss);
1358 }
1359 }
1360
SUMA_SV_GetShowSelectedDatum(SUMA_SurfaceViewer * sv)1361 int SUMA_SV_GetShowSelectedDatum(SUMA_SurfaceViewer *sv)
1362 {
1363 static char FuncName[]={"SUMA_SV_GetShowSelectedDatum"};
1364
1365 if (!sv) return(0);
1366 return(sv->ShowSelectedDatum);
1367 }
1368
SUMA_SV_SetShowSelectedDatum(SUMA_SurfaceViewer * sv,int act,int callback)1369 SUMA_Boolean SUMA_SV_SetShowSelectedDatum(SUMA_SurfaceViewer *sv,
1370 int act, int callback)
1371 {
1372 static char FuncName[]={"SUMA_SV_SetShowSelectedDatum"};
1373
1374 if (!sv) return(NOPE);
1375
1376 sv->ShowSelectedDatum = act;
1377 XmToggleButtonSetState(sv->X->ViewMenu->mw[SW_ViewNodeInFocus],
1378 act, callback);
1379 return(YUP);
1380 }
1381
SUMA_SV_GetShowSelectedFaceSet(SUMA_SurfaceViewer * sv)1382 int SUMA_SV_GetShowSelectedFaceSet(SUMA_SurfaceViewer *sv)
1383 {
1384 static char FuncName[]={"SUMA_SV_GetShowSelectedFaceSet"};
1385
1386 if (!sv) return(0);
1387 return(sv->ShowSelectedFaceSet);
1388 }
1389
SUMA_SV_SetShowSelectedFaceSet(SUMA_SurfaceViewer * sv,int act,int callback)1390 SUMA_Boolean SUMA_SV_SetShowSelectedFaceSet(SUMA_SurfaceViewer *sv,
1391 int act, int callback)
1392 {
1393 static char FuncName[]={"SUMA_SV_SetShowSelectedFaceSet"};
1394
1395 if (!sv || !sv->X) return(NOPE);
1396 sv->ShowSelectedFaceSet = act;
1397 XmToggleButtonSetState(sv->X->ViewMenu->mw[SW_ViewSelectedFaceset],
1398 act, callback);
1399 return(YUP);
1400 }
1401
1402
SUMA_Free_SurfaceViewer_Struct(SUMA_SurfaceViewer * SV)1403 SUMA_Boolean SUMA_Free_SurfaceViewer_Struct (SUMA_SurfaceViewer *SV)
1404 {
1405 static char FuncName[]={"SUMA_Free_SurfaceViewer_Struct"};
1406 int i;
1407
1408 SUMA_ENTRY;
1409
1410 if (SV->WAx) SUMA_Free_Axis(SV->WAx);
1411 if (SV->C_filter) SUMA_C_free(SV->C_filter); SV->C_filter=NULL;
1412 if (SV->Ch) SUMA_Free_CrossHair (SV->Ch);
1413 if (SV->SelAdo) dlist_destroy(SV->SelAdo); SUMA_ifree(SV->SelAdo);
1414 SUMA_ifree(SV->LastSel_ado_idcode_str);
1415
1416 if (SV->X->Title) SUMA_free(SV->X->Title);
1417 if (SV->X->LookAt_prmpt) SUMA_FreePromptDialogStruct (SV->X->LookAt_prmpt);
1418 if (SV->X->SetRot_prmpt) SUMA_FreePromptDialogStruct (SV->X->SetRot_prmpt);
1419 if (SV->X->JumpIndex_prmpt)
1420 SUMA_FreePromptDialogStruct (SV->X->JumpIndex_prmpt);
1421 if (SV->X->JumpXYZ_prmpt)
1422 SUMA_FreePromptDialogStruct (SV->X->JumpXYZ_prmpt);
1423 if (SV->X->JumpFocusNode_prmpt)
1424 SUMA_FreePromptDialogStruct (SV->X->JumpFocusNode_prmpt);
1425 if (SV->X->JumpFocusFace_prmpt)
1426 SUMA_FreePromptDialogStruct (SV->X->JumpFocusFace_prmpt);
1427 if (SV->X->HighlightBox_prmpt)
1428 SUMA_FreePromptDialogStruct (SV->X->HighlightBox_prmpt);
1429 if (SV->X->SetRenderOrder_prmpt)
1430 SUMA_FreePromptDialogStruct (SV->X->SetRenderOrder_prmpt);
1431 if (SV->X->ViewCont) SUMA_FreeViewContStruct(SV->X->ViewCont);
1432 if (SV->X) SUMA_free(SV->X);
1433 if (SV->RegistDO) SUMA_free(SV->RegistDO);
1434 if (SV->VSv) {
1435 for (i=0; i < SV->N_VSv; ++i) {
1436 if (!SUMA_Free_ViewState (&(SV->VSv[i]))) {
1437 fprintf (SUMA_STDERR,
1438 "Error %s: failed in SUMA_Free_ViewState.\n", FuncName);
1439 }
1440 }
1441 }
1442 SUMA_ifree(SV->pickrenpix4);
1443 SUMA_ifree(SV->MouseMode_ado_idcode_str);
1444
1445 if (SV->CurGroupName) SUMA_free(SV->CurGroupName); SV->CurGroupName= NULL;
1446
1447 if (SV->GVS) SUMA_free(SV->GVS);
1448 if (SV->State) SV->State = NULL; /* never free that one */
1449 if (SV->ColList) {
1450 for (i=0; i < SV->N_ColList; ++i) {
1451 if (!SUMA_EmptyColorList (SV, NULL))
1452 SUMA_S_Err("Failed in SUMA_EmptyColorList.");
1453 }
1454 /* done dumping structure contents, now free pointer */
1455 SUMA_ifree(SV->ColList);
1456 SV->N_ColList = 0;
1457 }
1458
1459 if (SV->BS) {
1460 SUMA_EmptyDestroyList(SV->BS);
1461 }
1462
1463 SUMA_ifree(SV->FOV);
1464 SUMA_ifree(SV->FOV_last_PickMode);
1465 SUMA_ifree(SV->auto_FOV_val);
1466
1467 SUMA_RETURN(YUP);
1468 }
1469
SUMA_Free_SurfaceViewer_Struct_Vect(SUMA_SurfaceViewer * SVv,int N)1470 SUMA_Boolean SUMA_Free_SurfaceViewer_Struct_Vect (SUMA_SurfaceViewer *SVv, int N)
1471 {
1472 static char FuncName[]={"SUMA_Free_SurfaceViewer_Struct_Vect"};
1473 int i;
1474 SUMA_Boolean Ret= YUP;
1475
1476 SUMA_ENTRY;
1477
1478 for (i=0; i < N; ++i) {
1479 if (&SVv[i] != NULL) {
1480 Ret = Ret * SUMA_Free_SurfaceViewer_Struct (&SVv[i]);
1481 }
1482 }
1483
1484 if (SVv) SUMA_free(SVv);
1485 SUMA_RETURN(Ret);
1486 }
1487
1488 /*!
1489 \brief SUMA_ADO_FillColorList_Params(SUMA_ALL_DO *ADO,
1490 int *N_points, char *idcode);
1491 */
SUMA_ADO_FillColorList_Params(SUMA_ALL_DO * ADO,int * N_points,char ** idcode)1492 SUMA_Boolean SUMA_ADO_FillColorList_Params(SUMA_ALL_DO *ADO,
1493 int *N_points, char **idcode)
1494 {
1495 static char FuncName[]={"SUMA_ADO_FillColorList_Params"};
1496 SUMA_Boolean LocalHead = NOPE;
1497
1498 SUMA_ENTRY;
1499
1500 if (!ADO || !N_points || !idcode) {
1501 SUMA_RETURN(NOPE);
1502 }
1503 *N_points = -1; *idcode = NULL;
1504
1505 switch (ADO->do_type) {
1506 case SO_type: {
1507 SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ADO;
1508 *N_points = SO->N_Node;
1509 *idcode = SO->idcode_str;
1510 SUMA_LHv("Filling a color list for surface %s (%s).\n",
1511 SO->Label, SO->idcode_str);
1512 } break;
1513 case GDSET_type: {
1514 SUMA_DSET *dset=(SUMA_DSET *)ADO;
1515 if (!SUMA_isGraphDset(dset)) {
1516 SUMA_S_Err("Dataset should be graph type");
1517 SUMA_RETURN(NOPE);
1518 }
1519 *N_points = 1+SUMA_GDSET_Max_Edge_Index(dset);
1520 *idcode = SDSET_ID(dset);
1521 SUMA_LHv("Filling a color list for dset %s (%s).\n",
1522 SDSET_LABEL(dset), SDSET_ID(dset));
1523 } break;
1524 case GRAPH_LINK_type: {
1525 SUMA_DSET *dset=SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)ADO);
1526 if (dset)
1527 SUMA_RETURN(SUMA_ADO_FillColorList_Params(
1528 (SUMA_ALL_DO *)dset, N_points, idcode));
1529 } break;
1530 case CDOM_type:
1531 case MASK_type:
1532 case TRACT_type:
1533 case VO_type: {
1534 *N_points = SUMA_ADO_N_Datum(ADO);
1535 *idcode = ADO_ID(ADO);
1536 SUMA_LHv("Filling a color list for tract %s (%s) %d points.\n",
1537 ADO_LABEL(ADO), ADO_ID(ADO), *N_points);
1538 break; }
1539 default:
1540 SUMA_S_Errv("Not ready for type %d (%s)\n",
1541 ADO->do_type,
1542 SUMA_ObjectTypeCode2ObjectTypeName(ADO->do_type));
1543 SUMA_RETURN(NOPE);
1544 }
1545
1546 SUMA_RETURN(YUP);
1547 }
1548
SUMA_BlankColorListStruct(SUMA_COLORLIST_STRUCT * cl)1549 SUMA_Boolean SUMA_BlankColorListStruct(SUMA_COLORLIST_STRUCT *cl)
1550 {
1551 static char FuncName[]={"SUMA_BlankColorListStruct"};
1552 int i = 0;
1553
1554 SUMA_ENTRY;
1555
1556 if (!cl || !cl->glar_ColorList_private) {
1557 SUMA_S_Err("NULL input");
1558 SUMA_RETURN(NOPE);
1559 }
1560 /* fill up with blanks, may be unecessary ... */
1561 i=0;
1562 while (i < cl->N_glar_ColorList) {
1563 cl->glar_ColorList_private[i] =
1564 SUMA_GRAY_NODE_COLOR; ++i;
1565 cl->glar_ColorList_private[i] =
1566 SUMA_GRAY_NODE_COLOR; ++i;
1567 cl->glar_ColorList_private[i] =
1568 SUMA_GRAY_NODE_COLOR; ++i;
1569 cl->glar_ColorList_private[i] = SUMA_NODE_ALPHA; ++i;
1570 }
1571
1572 SUMA_RETURN(YUP);
1573 }
1574
1575 /*
1576 Accessor function to pointer cl->glar_ColorList_private
1577 */
SUMA_GetColorListPtr(SUMA_COLORLIST_STRUCT * cl)1578 GLfloat * SUMA_GetColorListPtr (SUMA_COLORLIST_STRUCT *cl)
1579 {
1580 static char FuncName[]={"SUMA_GetColorListPtr"};
1581
1582 if (!cl) return(NULL);
1583 if (cl->glar_ColorList_private) {
1584 return(cl->glar_ColorList_private);
1585 } else if (cl->idcode_str) {
1586 SUMA_ALL_DO *ado = SUMA_whichADOg(cl->idcode_str);
1587 int N_points;
1588 char *idcode=NULL;
1589 SUMA_Boolean LocalHead = NOPE;
1590 SUMA_LH("Found but must allocate for colorlist");
1591 if (!SUMA_ADO_FillColorList_Params(ado, &N_points, &idcode)) {
1592 SUMA_S_Err("Failed to initialize params");
1593 return(NULL);
1594 }
1595 /* That previous call to get N_points may be a waste.
1596 The number of values is already in cl->N_glar_ColorList
1597 so just check for redundancy now */
1598 if (4*N_points != cl->N_glar_ColorList) {
1599 SUMA_S_Err("This should not happen: %d clashes with %d",
1600 N_points, cl->N_glar_ColorList);
1601 return(NULL);
1602 }
1603 if (!(cl->glar_ColorList_private =
1604 (GLfloat *) SUMA_calloc (N_points*4, sizeof(GLfloat)))) {
1605 SUMA_S_Crit("Failed to allocate %d floats for glar_ColorList_private",
1606 N_points*4);
1607 return(NULL);
1608 }
1609 if (!SUMA_BlankColorListStruct(cl)) {
1610 SUMA_S_Err("Failed to fill with gray?!?");
1611 return(NULL);
1612 }
1613 /* Will need mixing in all likelihood, go ahead, why not */
1614 cl->Remix = YUP;
1615 ++cl->RemixID;
1616 return(cl->glar_ColorList_private);
1617 }
1618 return(NULL);
1619 }
1620
1621
1622
1623 /*!
1624 \brief ans = SUMA_FillColorList (sv, so);
1625 Creates a colorlist structure for a certain displayable.
1626
1627 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer
1628 \param so (SUMA_SurfaceObject *) pointer to surface object
1629
1630 Remix flag is set to YUP since this function is called when DOs are
1631 being registered with a viewer and a remix is highly likely.
1632
1633 \return ans YUP/NOPE
1634
1635 */
SUMA_FillColorList(SUMA_SurfaceViewer * sv,SUMA_ALL_DO * ADO)1636 SUMA_Boolean SUMA_FillColorList (SUMA_SurfaceViewer *sv, SUMA_ALL_DO *ADO)
1637 {
1638 static char FuncName[]={"SUMA_FillColorList"};
1639 int i, N_points;
1640 char *idcode=NULL;
1641 SUMA_COLORLIST_STRUCT *clinh=NULL;
1642 SUMA_Boolean LocalHead = NOPE;
1643
1644 SUMA_ENTRY;
1645
1646 if (!sv) {
1647 SUMA_RETURN(NOPE);
1648 }
1649
1650 switch(ADO->do_type) {
1651 case GRAPH_LINK_type: {
1652 SUMA_DSET *dset=SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)ADO);
1653 if (dset) SUMA_RETURN(SUMA_FillColorList(sv,(SUMA_ALL_DO *)dset));
1654 SUMA_S_Err("GLDO without dset!");
1655 SUMA_RETURN(NOPE);
1656 } break;
1657 }
1658
1659
1660 if (!SUMA_ADO_FillColorList_Params(ADO, &N_points, &idcode) ) {
1661 SUMA_S_Err("Failed to initialize variables");
1662 SUMA_RETURN(NOPE);
1663 }
1664
1665 if (!idcode) {
1666 fprintf (SUMA_STDERR,"Error %s: idcode is NULL.\n", FuncName);
1667 SUMA_RETURN (NOPE);
1668 }
1669
1670 /* make sure idcode is not in the list already */
1671 for (i=0; i<sv->N_ColList; ++i) {
1672 if (strcmp (idcode, sv->ColList[i]->idcode_str) == 0) {
1673 if (ADO->do_type != GDSET_type &&
1674 ADO->do_type != CDOM_type &&
1675 ADO->do_type != TRACT_type &&
1676 ADO->do_type != VO_type &&
1677 ADO->do_type != MASK_type
1678 ) {
1679 SUMA_S_Err("idcode is already in sv->ColList, \n"
1680 "This is an error for a SurfaceObject, though I doubt\n"
1681 "it is of serious consequence. Type is question is %s\n"
1682 "for DO type %s\n", ADO_LABEL(ADO), ADO_TNAME(ADO));
1683 SUMA_RETURN (NOPE);
1684 } else {
1685 SUMA_LH("List for %s found",
1686 SUMA_DO_dbg_info(idcode));
1687 /* No harm done, no need to get upset. */
1688 SUMA_RETURN(YUP);
1689 }
1690 }
1691 }
1692
1693 SUMA_LH("Need to create or link to existing list."
1694 "will insert into position: %d", sv->N_ColList);
1695 if (sv->N_ColList >= SUMA_MAX_DISPLAYABLE_OBJECTS) {
1696 SUMA_SL_Crit("sv->N_ColList >= SUMA_MAX_DISPLAYABLE_OBJECTS");
1697 SUMA_RETURN (NOPE);
1698 }
1699
1700 /* create the ColList struct */
1701 if (sv->ColList[sv->N_ColList]) {
1702 SUMA_S_Err("sv->ColorList[%d] is not NULL. Cannot reallocate.\n"
1703 "not expecting this scenario at this stage", sv->N_ColList);
1704 SUMA_RETURN (NOPE);
1705 }
1706
1707 /* Should we inherit? */
1708 clinh = NULL;
1709 switch (ADO->do_type) {
1710 case SO_type:
1711 /* Don't inherit, surfaces can have different colorings in
1712 different viewers */
1713 break;
1714 case VO_type: /* Those beasts cost a lot of memory, share with sv[0] */
1715 if (sv != SUMAg_SVv+0) {
1716 clinh = SUMA_GetColorListStruct (SUMAg_SVv, idcode);
1717 }
1718 break;
1719 default: /* For all others, make new copy, decide later whether
1720 should inherit */
1721 break;
1722 }
1723 if (clinh) {
1724 SUMA_LH("Inheriting");
1725 sv->ColList[sv->N_ColList] =
1726 (SUMA_COLORLIST_STRUCT*)SUMA_LinkToPointer((void *)clinh);
1727 } else {
1728 SUMA_LH("Recreating, N_points = %d", N_points);
1729 sv->ColList[sv->N_ColList] =
1730 (SUMA_COLORLIST_STRUCT *)SUMA_calloc(1, sizeof(SUMA_COLORLIST_STRUCT));
1731 sv->ColList[sv->N_ColList]->N_links = 0;
1732 memset(sv->ColList[sv->N_ColList]->per_sv_extra, PSV_NOTHING,
1733 SUMA_MAX_SURF_VIEWERS*sizeof(int));
1734 sv->ColList[sv->N_ColList]->owner_id[0] = '\0';
1735 sv->ColList[sv->N_ColList]->LinkedPtrType = SUMA_LINKED_COLORLIST_TYPE;
1736 sv->ColList[sv->N_ColList]->do_type = not_DO_type;
1737
1738 sv->ColList[sv->N_ColList]->N_glar_ColorList = N_points*4;
1739
1740 sv->ColList[sv->N_ColList]->idcode_str =
1741 (char *)SUMA_malloc((strlen(idcode)+1) * sizeof(char));
1742 if (!sv->ColList[sv->N_ColList]->idcode_str) {
1743 SUMA_S_Err("Failed to allocate for idcode_str.");
1744 SUMA_RETURN (NOPE);
1745 }
1746 sv->ColList[sv->N_ColList]->idcode_str =
1747 strcpy (sv->ColList[sv->N_ColList]->idcode_str, idcode);
1748
1749 if (sv->Open) { /* ZSS: Feb 2014 */
1750 /* Only allocate if Viewer is open, otherwise
1751 don't allocate for float vector, let SUMA_GetColorList()
1752 take care of that */
1753 if (!SUMA_GetColorListPtr(sv->ColList[sv->N_ColList])) {
1754 SUMA_S_Err("Failed to allocate for glar_ColorList.");
1755 SUMA_RETURN (NOPE);
1756 }
1757 } else {
1758 sv->ColList[sv->N_ColList]->glar_ColorList_private = NULL;
1759 }
1760
1761 }
1762
1763 ++sv->N_ColList;
1764 SUMA_LH("N_ColList now %d, latest glar %p",
1765 sv->N_ColList, sv->ColList[sv->N_ColList-1]->glar_ColorList_private);
1766 SUMA_RETURN (YUP);
1767 }
1768
1769 /*!
1770 glar_ColorList = SUMA_GetColorList (sv, DO_idstr);
1771 returns the pointer to the colorlist of the DO (or SO) with ID string DO_idstr
1772
1773 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer in question
1774 \param DO_idstr (char *) ID string of DO (usually a Surface Object)
1775 \return glar_ColorList (GLfloat *) a pointer to the array containing
1776 node colors
1777 \sa SUMA_GetColorListStruct, SUMA_GetColorListPtr
1778 */
SUMA_GetColorList(SUMA_SurfaceViewer * sv,char * DO_idstr)1779 GLfloat * SUMA_GetColorList (SUMA_SurfaceViewer *sv, char *DO_idstr)
1780 {
1781 static char FuncName[]={"SUMA_GetColorList"};
1782 int i;
1783 SUMA_Boolean Found = NOPE;
1784 SUMA_Boolean LocalHead = NOPE;
1785
1786 SUMA_ENTRY_LH;
1787
1788 if (!DO_idstr) {
1789 SUMA_S_Err("DO_idstr is NULL, this should not be.");
1790 SUMA_RETURN (NULL);
1791 }
1792
1793 SUMA_LH("Looking for colorlist of %s",
1794 SUMA_DO_dbg_info(DO_idstr));
1795 /* find the culprit */
1796 Found = NOPE;
1797 i = 0;
1798 while (!Found && i < sv->N_ColList) {
1799 if (strcmp (DO_idstr, sv->ColList[i]->idcode_str) == 0) {
1800 Found = YUP;
1801 SUMA_RETURN (SUMA_GetColorListPtr(sv->ColList[i]));
1802 }
1803 ++i;
1804 }
1805
1806 #if 0
1807 /* This should be deleted, but is left for Rick's joy at the moment.
1808 In the first pass, a CIFTI DO got its own colorplane and the colorization
1809 was done for the entire multi domain data set then to colorize a sub-domain
1810 the color list pointer was offset by the total number of data in sub-domains
1811 preceding it. That scheme however proved problematic when going back and forth
1812 between sub-domains and the whole dataset because datum indices in a
1813 multi-domain dataset are not unique.
1814 So this approach was scrapped in favor of dealing only with elementary
1815 datasets and domains */
1816 if (!Found) { /* Perhaps this DO is part of a CIFTI conglomorate */
1817 SUMA_CIFTI_DO *CO=NULL;
1818 int ksub;
1819 if ((CO = SUMA_find_CIFTI_subdom_container(DO_idstr, &ksub, NULL, 0))) {
1820 /* search again to find the pointer to the colorlist of the entire
1821 CIFTI domain */
1822 Found = NOPE;
1823 i = 0;
1824 while (!Found && i < sv->N_ColList) {
1825 if (strcmp (ADO_ID((SUMA_ALL_DO *)CO),
1826 sv->ColList[i]->idcode_str) == 0) {
1827 Found = YUP;
1828 } else ++i;
1829 }
1830 if (Found) {
1831 GLfloat *glc=NULL;
1832 SUMA_LH(
1833 "Found CIFTI container's colorlist for id %s, offset of 4*%d",
1834 DO_idstr, SUMA_CIFTI_SubDomFullOffset(CO, ksub));
1835
1836 /* Now return the pointer offset to the sub-domain */
1837 glc = SUMA_GetColorListPtr(sv->ColList[i])+
1838 4*SUMA_CIFTI_SubDomFullOffset(CO, ksub);
1839 SUMA_RETURN(glc);
1840 } else {
1841 SUMA_LH("Found cobwebs");
1842 }
1843 }
1844 }
1845 #endif
1846
1847 if (!Found) {
1848 SUMA_S_Err("DO_idstr %s was not found.\n", DO_idstr);
1849 SUMA_RETURN (NULL);
1850 }
1851
1852 /* should not get to this point */
1853 SUMA_S_Err("Logic error. Should not get here.");
1854 SUMA_RETURN (NULL);
1855
1856 }
1857
1858 /* Return the color list structure for a particular object */
SUMA_GetColorListStruct(SUMA_SurfaceViewer * sv,char * DO_idstr)1859 SUMA_COLORLIST_STRUCT * SUMA_GetColorListStruct (SUMA_SurfaceViewer *sv,
1860 char *DO_idstr)
1861 {
1862 static char FuncName[]={"SUMA_GetColorListStruct"};
1863 int i;
1864 SUMA_COLORLIST_STRUCT *cls = NULL;
1865 SUMA_Boolean Found = NOPE;
1866 SUMA_Boolean LocalHead = NOPE;
1867
1868 SUMA_ENTRY_LH;
1869
1870 if (!DO_idstr) {
1871 SUMA_S_Err("DO_idstr is NULL, this should not be.");
1872 SUMA_RETURN (NULL);
1873 }
1874
1875 SUMA_LH("Looking for colorlist struct of %s",
1876 SUMA_DO_dbg_info(DO_idstr));
1877
1878 /* find the culprit */
1879 Found = NOPE;
1880 i = 0;
1881 while (!Found && i < sv->N_ColList) {
1882 if (strcmp (DO_idstr, sv->ColList[i]->idcode_str) == 0) {
1883 Found = YUP;
1884 if (!SUMA_GetColorListPtr(sv->ColList[i])) {
1885 SUMA_RETURN(NULL);
1886 }
1887 SUMA_RETURN (sv->ColList[i]);
1888 }
1889 ++i;
1890 }
1891
1892 if (!Found) {
1893 SUMA_S_Err("DO_idstr %s was not found.\n", DO_idstr);
1894 SUMA_RETURN (NULL);
1895 }
1896
1897 /* should not get to this point */
1898 SUMA_S_Err("Logic error. Should not get here.");
1899 SUMA_RETURN (NULL);
1900 }
1901
1902 /*!
1903 frees the Node Neighbor structure formed in SUMA_Build_FirstNeighb
1904 */
SUMA_Free_ColorList(SUMA_COLORLIST_STRUCT * cl)1905 SUMA_Boolean SUMA_Free_ColorList (SUMA_COLORLIST_STRUCT *cl)
1906 {
1907 static char FuncName[]={"SUMA_Free_ColorList"};
1908 SUMA_Boolean LocalHead = NOPE;
1909
1910 SUMA_ENTRY;
1911
1912 if (!cl) SUMA_RETURN(YUP);
1913
1914 SUMA_LH("Entered to free colorlist of %s, (glar = %p)",
1915 SUMA_DO_dbg_info(cl->idcode_str), cl->glar_ColorList_private);
1916 if (LocalHead) SUMA_DUMP_TRACE("At Free ColorList");
1917
1918 if (cl->N_links) {
1919 SUMA_LH("Just a link release");
1920 cl = (SUMA_COLORLIST_STRUCT *)SUMA_UnlinkFromPointer((void *)cl);
1921 SUMA_RETURN (YUP);
1922 }
1923
1924 /* no more links, go for it */
1925 SUMA_LH("No more links freeing time");
1926 SUMA_ifree(cl->idcode_str);
1927 SUMA_ifree(cl->glar_ColorList_private);
1928 SUMA_ifree(cl);
1929 SUMA_RETURN (YUP);
1930 }
1931
1932 /*!
1933
1934 \brief Empty a colorlist structure
1935
1936 ans = SUMA_EmptyColorList (sv, DO_idstr)
1937
1938 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer in question
1939 \param DO_idstr (char *) ID string of DO (usually a Surface Object) If you want to delete all
1940 color lists, set this pointer to NULL
1941 \return ans (SUMA_Boolean) YUP/NOPE
1942
1943 */
SUMA_EmptyColorList(SUMA_SurfaceViewer * sv,char * DO_idstr)1944 SUMA_Boolean SUMA_EmptyColorList (SUMA_SurfaceViewer *sv, char *DO_idstr)
1945 {
1946 static char FuncName[]={"SUMA_EmptyColorList"};
1947 int i;
1948 SUMA_Boolean Found = NOPE;
1949 SUMA_Boolean LocalHead = NOPE;
1950
1951 SUMA_ENTRY;
1952
1953 if (!sv->ColList) {
1954 SUMA_S_Err("sv->ColList is NULL, this should not be.");
1955 SUMA_RETURN (NOPE);
1956 }
1957
1958 SUMA_LH("Emptying collist for sv %p, id %s", sv, DO_idstr);
1959 if (!DO_idstr) {
1960 /* empty them all */
1961 for (i=0; i < sv->N_ColList; ++i) {
1962 if (!SUMA_Free_ColorList(sv->ColList[i])) {
1963 SUMA_S_Err("Failed to free colorlist");
1964 SUMA_RETURN(NOPE);
1965 }
1966 sv->ColList[i]=NULL;
1967 sv->N_ColList = 0;
1968 }
1969
1970 } else { /* just empty one */
1971 SUMA_LH("Emptying col list for %s", DO_idstr);
1972 Found = NOPE;
1973 i = 0;
1974 while (!Found && i < sv->N_ColList) {
1975 if (strcmp (DO_idstr, sv->ColList[i]->idcode_str) == 0) {
1976 Found = YUP;
1977 if (!SUMA_Free_ColorList(sv->ColList[i])) {
1978 SUMA_S_Err("Failed to free colorlist");
1979 SUMA_RETURN(NOPE);
1980 }
1981 /* copy the last in the list here */
1982 if (i < sv->N_ColList) {
1983 sv->ColList[i] = sv->ColList[sv->N_ColList-1];
1984
1985 /* mark the last element as empty */
1986 sv->ColList[sv->N_ColList-1] = NULL;
1987 /* decrement the number of full elements in ColList */
1988 --sv->N_ColList;
1989 }
1990 }
1991 ++i;
1992 }
1993
1994 if (!Found) {
1995 SUMA_S_Errv("item %s (%s) was not found, this should not be.\n",
1996 DO_idstr, SUMA_DO_dbg_info(DO_idstr));
1997 SUMA_DUMP_TRACE("Whence the unfound");
1998 SUMA_RETURN (NOPE);
1999 }
2000 }
2001
2002 SUMA_RETURN (YUP);
2003 }
2004
2005 /*!
2006 ans = SUMA_SetShownLocalRemixFlag (SUMA_SurfaceViewer *sv)
2007 Set Remix flags for all surfaces in sv->RegistDO regardless of
2008 their relationship.
2009 This is useful when you change the settings for background color modulation
2010 and the like.
2011 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer
2012 \return ans (SUMA_Boolean) YUP/NOPE
2013 \sa SUMA_SetRemixFlag
2014 \sa SUMA_SetLocalRemixFlag
2015
2016 */
SUMA_SetShownLocalRemixFlag(SUMA_SurfaceViewer * sv)2017 SUMA_Boolean SUMA_SetShownLocalRemixFlag (SUMA_SurfaceViewer *sv)
2018 {
2019 static char FuncName[]={"SUMA_SetShownLocalRemixFlag"};
2020 int k;
2021
2022 SUMA_ENTRY;
2023
2024 for (k=0; k < sv->N_ColList; ++k) {
2025 sv->ColList[k]->Remix = YUP;
2026 }
2027
2028 SUMA_RETURN (YUP);
2029 }
2030
2031 /*!
2032 ans = SUMA_SetLocalRemixFlag (char *idcode_str, SUMA_SurfaceViewer *sv);
2033 Search RegistDO for sv and if a Surface in RegistDO is related
2034 to DO_idcode_str then its remix flag is set to yes.
2035
2036 \param idcode_str (char *) IDcode of the surface that had its colorplanes
2037 modified
2038 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer
2039 \return ans (SUMA_Boolean) YUP/NOPE
2040 \sa SUMA_SetRemixFlag
2041 \sa SUMA_SetShownLocalRemixFlag
2042
2043 Will I ever use that one, not common to have related surfaces in one view ...?
2044 */
SUMA_SetLocalRemixFlag(char * DO_idcode_str,SUMA_SurfaceViewer * sv)2045 SUMA_Boolean SUMA_SetLocalRemixFlag (char *DO_idcode_str, SUMA_SurfaceViewer *sv)
2046 {
2047 static char FuncName[]={"SUMA_SetLocalRemixFlag"};
2048 SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
2049 int k, kk;
2050 void *pp = NULL;
2051 SUMA_DSET *dset=NULL;
2052 char *p2=NULL;
2053 SUMA_ALL_DO *ado2=NULL;
2054 SUMA_DO_Types tp;
2055 SUMA_Boolean Found = NOPE;
2056
2057 SUMA_ENTRY;
2058
2059 if (!DO_idcode_str || !sv) {
2060 SUMA_S_Err("NULL sv or DO_idcode_str. BAD");
2061 SUMA_RETURN (NOPE);
2062 }
2063
2064 if (!(pp = SUMA_find_any_object(DO_idcode_str, &tp))) {
2065 SUMA_S_Errv("Bad id %s\n", DO_idcode_str);
2066 SUMA_RETURN (NOPE);
2067 }
2068
2069 switch (tp) {
2070 case SO_type:
2071 SO1 = (SUMA_SurfaceObject *)pp;
2072 /* search for relatives in RegistDO */
2073 for (k=0; k < sv->N_DO; ++k) {
2074 ado2 = (SUMA_ALL_DO *)SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2075 if (SUMA_isRelated((SUMA_ALL_DO *)SO1, ado2, 1)){
2076 /* kinship of da first order */
2077 SO2 = (SUMA_SurfaceObject *)SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2078 /* related, set flag for remixing SO2 */
2079 kk = 0;
2080 Found = NOPE;
2081 while (!Found && kk < sv->N_ColList) {
2082 if (strcmp(SO2->idcode_str,sv->ColList[kk]->idcode_str) == 0) {
2083 Found = YUP;
2084 sv->ColList[kk]->Remix = YUP;
2085 }
2086 ++kk;
2087 }
2088 if (!Found) {
2089 SUMA_S_Err("Failed to find surface in ColList structs. BAD.");
2090 SUMA_RETURN (NOPE);
2091 }
2092 }
2093 }
2094 break;
2095 case CDOM_type:
2096 SUMA_S_Err("Is this needed (perhaps once we have isotopic COs ? "
2097 "If so then do it");
2098 SUMA_RETURN (NOPE);
2099 break;
2100 case GDSET_type:
2101 dset = (SUMA_DSET *)pp;
2102 for (k=0; k < sv->N_DO; ++k) {
2103 ado2 = (SUMA_ALL_DO *)SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2104 if (SUMA_isRelated((SUMA_ALL_DO *)dset, ado2, 1)){
2105 kk = 0;
2106 Found = NOPE;
2107 while (!Found && kk < sv->N_ColList) {
2108 if ((p2 = SUMA_ADO_idcode(ado2)) &&
2109 !strcmp(p2, sv->ColList[kk]->idcode_str)) {
2110 Found = YUP;
2111 sv->ColList[kk]->Remix = YUP;
2112 }
2113 ++kk;
2114 }
2115 if (!Found) {
2116 SUMA_S_Err("Failed to find DSET in ColList structs. BAD.");
2117 SUMA_RETURN (NOPE);
2118 }
2119 }
2120 }
2121 break;
2122 default:
2123 SUMA_S_Errv("Type %d is not welcome here\n", tp);
2124 SUMA_RETURN(NOPE);
2125 }
2126
2127 SUMA_RETURN (YUP);
2128 }
2129
2130
2131
2132 /*!
2133 ans = SUMA_SetRemixFlag (char *idcode_str, SUMA_SurfaceViewer *SVv,
2134 int N_SVv);
2135 Search RegistDO for each Surface Viewer and if a Surface in
2136 RegistDO is related to DO_idcode_str then its remix flag is set to yes.
2137
2138 \param idcode_str (char *) IDcode of the surface that had its
2139 colorplanes modified
2140 \param SVv (SUMA_SurfaceViewer *) vector of existing surface viewers
2141 (typically, that is SUMAg_SVv)
2142 \param N_SVv (int) number of surface viewers (typically that is N_SUMAg_SVv)
2143 \return ans (SUMA_Boolean) YUP/NOPE
2144 \sa SUMA_SetLocalRemixFlag
2145 \sa SUMA_SetShownLocalRemix
2146
2147 DO NOT SET THE REMIXFLAG unless you have modified the colorplanes of a
2148 certain surface. This function will set a remix flags to all related surfaces
2149 that are being displayed in all viewers. You want to do this
2150 when one (or all) of the colorplanes is changed. Alternately, if you make
2151 changes that only affect the surface as is it shown in the viewer (change
2152 background modulation for example), you want to do the remixing
2153 for the concerned surface or surfaces only in that viewer and not in all
2154 viewers open. Perhaps I should write a function to set the remix flags
2155 for surfaces within the viewer only. Something like SUMA_SetLocalRemixFlag or
2156 SUMA_SetShownLocalRemix.
2157
2158 */
SUMA_SetRemixFlag(char * DO_idcode_str,SUMA_SurfaceViewer * SVv,int N_SVv)2159 SUMA_Boolean SUMA_SetRemixFlag (char *DO_idcode_str, SUMA_SurfaceViewer *SVv,
2160 int N_SVv)
2161 {
2162 static char FuncName[]={"SUMA_SetRemixFlag"};
2163 SUMA_SurfaceViewer *sv;
2164 int i, k, kk;
2165 void *pp=NULL;
2166 SUMA_DO_Types tp;
2167 SUMA_ALL_DO*ado2;
2168 char *p2=NULL;
2169 SUMA_Boolean Found = NOPE;
2170 SUMA_Boolean LocalHead = NOPE;
2171
2172 SUMA_ENTRY;
2173
2174 if (!DO_idcode_str || !SVv) {
2175 fprintf (SUMA_STDERR,
2176 "Error %s: NULL SVv or DO_idcode_str. BAD\n", FuncName);
2177 SUMA_RETURN (NOPE);
2178 }
2179
2180 SUMA_LH("Look for any object");
2181 SUMA_LHv(" id %s\n", DO_idcode_str);
2182 if (!(pp = SUMA_find_any_object(DO_idcode_str, &tp))) {
2183 SUMA_S_Errv("Bad id %s\n", DO_idcode_str);
2184 SUMA_RETURN (NOPE);
2185 }
2186 SUMA_LH("Switching...");
2187 switch (tp) {
2188 case SO_type: {
2189 SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
2190 SO1 = (SUMA_SurfaceObject *)pp;
2191 /* search all viewers */
2192 for (i=0; i < N_SVv; ++i) {
2193 if (LocalHead)
2194 fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
2195 sv = &(SVv[i]);
2196 /* search for relatives in RegistDO */
2197 for (k=0; k < sv->N_DO; ++k) {
2198 if (SUMA_isSO(SUMAg_DOv[sv->RegistDO[k].dov_ind])) {
2199 SO2 = (SUMA_SurfaceObject *)
2200 SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2201 if (SUMA_isRelated_SO(SO1, SO2, 1)) {
2202 /* only 1st order kinship allowed */
2203 /* related, set flag for remixing SO2 */
2204 kk = 0;
2205 Found = NOPE;
2206 while (!Found && kk < sv->N_ColList) {
2207 if (strcmp (SO2->idcode_str,
2208 sv->ColList[kk]->idcode_str) == 0) {
2209 Found = YUP;
2210 SUMA_LHv("Setting remix for %d\n", kk);
2211 sv->ColList[kk]->Remix = YUP;
2212 }
2213 ++kk;
2214 }
2215 if (!Found) {
2216 SUMA_S_Err("Failed to find surface in ColList structs.");
2217 SUMA_RETURN (NOPE);
2218 }
2219 }
2220 }
2221 }
2222 }
2223 break; }
2224 case VO_type:
2225 case CDOM_type:
2226 case MASK_type:
2227 case TRACT_type: {
2228 SUMA_ALL_DO *ADO = (SUMA_ALL_DO*)pp;
2229 /* search all viewers */
2230 for (i=0; i < N_SVv; ++i) {
2231 if (LocalHead)
2232 fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
2233 sv = &(SVv[i]);
2234 /* search for relatives in RegistDO */
2235 for (k=0; k < sv->N_DO; ++k) {
2236 if (iDO_isTDO(sv->RegistDO[k].dov_ind) ||
2237 iDO_isVO(sv->RegistDO[k].dov_ind)) {
2238 ado2 = (SUMA_ALL_DO *)SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2239 if (SUMA_isRelated(ADO, ado2, 1)) {
2240 SUMA_LHv("%s RELATED to %s\n",
2241 SUMA_ADO_Label(ADO),
2242 SUMA_ADO_Label(ado2));
2243 kk = 0;
2244 Found = NOPE;
2245 while (!Found && kk < sv->N_ColList) {
2246 p2=SUMA_ADO_idcode(ado2);
2247
2248 if ( p2 && !strcmp(p2, sv->ColList[kk]->idcode_str)) {
2249 Found = YUP;
2250 sv->ColList[kk]->Remix = YUP;
2251 }
2252 ++kk;
2253 }
2254 if (!Found) {
2255 SUMA_S_Err("No relative in ColList structs. BAD.");
2256 SUMA_RETURN (NOPE);
2257 }
2258 } else {
2259 SUMA_LHv("%s Not related to %s\n",
2260 SUMA_ADO_Label(ADO),
2261 SUMA_ADO_Label(ado2));
2262 }
2263 }
2264 }
2265 }
2266 break; }
2267 case GDSET_type: {
2268 SUMA_DSET *dset = (SUMA_DSET *)pp;
2269
2270 if (!dset) {
2271 SUMA_S_Errv("Failed to find dset for dset %p, %s\n",
2272 pp, SUMA_ADO_Label((SUMA_ALL_DO *)pp));
2273 SUMA_RETURN(NOPE);
2274 }
2275 /* search all viewers */
2276 for (i=0; i < N_SVv; ++i) {
2277 if (LocalHead)
2278 fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
2279 sv = &(SVv[i]);
2280 /* search for relatives in RegistDO */
2281 for (k=0; k < sv->N_DO; ++k) {
2282 if (iDO_isGLDO(sv->RegistDO[k].dov_ind)) {
2283 ado2 = (SUMA_ALL_DO *)SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2284 if (SUMA_isRelated((SUMA_ALL_DO *)dset, ado2, 1)) {
2285 SUMA_LHv("%s RELATED to %s\n",
2286 SUMA_ADO_Label((SUMA_ALL_DO *)dset),
2287 SUMA_ADO_Label(ado2));
2288 kk = 0;
2289 Found = NOPE;
2290 while (!Found && kk < sv->N_ColList) {
2291 switch (ado2->do_type) {
2292 case GRAPH_LINK_type:
2293 /* The idcode in ColList is that
2294 of the dataset for GLDO */
2295 p2 = SDSET_ID(SUMA_find_GLDO_Dset(
2296 (SUMA_GraphLinkDO *)ado2));
2297 break;
2298 default:
2299 p2=SUMA_ADO_idcode(ado2);
2300 break;
2301 }
2302 if ( p2 && !strcmp(p2, sv->ColList[kk]->idcode_str)) {
2303 Found = YUP;
2304 sv->ColList[kk]->Remix = YUP;
2305 }
2306 ++kk;
2307 }
2308 if (!Found) {
2309 SUMA_S_Err("No relative in ColList structs. BAD.");
2310 SUMA_RETURN (NOPE);
2311 }
2312 } else {
2313 SUMA_LHv("%s Not related to %s\n",
2314 SUMA_ADO_Label((SUMA_ALL_DO *)dset),
2315 SUMA_ADO_Label(ado2));
2316 }
2317 }
2318 }
2319 }
2320 break; }
2321 case GRAPH_LINK_type: {
2322 SUMA_GraphLinkDO *gldo = (SUMA_GraphLinkDO *)pp;
2323 SUMA_DSET *dset = SUMA_find_GLDO_Dset(gldo);
2324 SUMA_S_Warn("So do I need to call function with dset for you?");
2325 SUMA_RETURN (YUP);
2326 break; }
2327 default:
2328 SUMA_S_Errv("Type %d is not welcome here\n", tp);
2329 SUMA_RETURN(NOPE);
2330 }
2331
2332 SUMA_RETURN (YUP);
2333 }
2334
2335 /*!
2336 \brief sets remix flags for all color lists in viewers specified in SVv
2337 Use this function whenever global color changes occur
2338
2339 \sa SUMA_SetRemixFlag for detailed help
2340
2341 */
SUMA_SetAllRemixFlag(SUMA_SurfaceViewer * SVv,int N_SVv)2342 SUMA_Boolean SUMA_SetAllRemixFlag (SUMA_SurfaceViewer *SVv, int N_SVv)
2343 {
2344 static char FuncName[]={"SUMA_SetAllRemixFlag"};
2345 SUMA_SurfaceViewer *sv;
2346 int i, kk;
2347 SUMA_Boolean LocalHead = NOPE;
2348
2349 SUMA_ENTRY;
2350
2351 if (!SVv) {
2352 fprintf (SUMA_STDERR,"Error %s: NULL SVv . BAD\n", FuncName);
2353 SUMA_RETURN (NOPE);
2354 }
2355
2356 /* search all viewers */
2357 for (i=0; i < N_SVv; ++i) {
2358 if (LocalHead)
2359 fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
2360 sv = &(SVv[i]);
2361 for (kk = 0; kk < sv->N_ColList; ++kk) sv->ColList[kk]->Remix = YUP;
2362 }
2363
2364 SUMA_RETURN (YUP);
2365 }
2366
SUMA_SetGLHome(SUMA_SurfaceViewer * sv)2367 SUMA_Boolean SUMA_SetGLHome(SUMA_SurfaceViewer *sv)
2368 {
2369 static char FuncName[]={"SUMA_SetGLHome"};
2370
2371 SUMA_ENTRY;
2372 if (!sv) SUMA_RETURN(NOPE);
2373 SUMA_SET_AS_NEEDED_2D_VIEW_ANGLE(sv);
2374 sv->GVS[sv->StdView].translateVec[0]=0;
2375 sv->GVS[sv->StdView].translateVec[1]=0;
2376 glMatrixMode(GL_PROJECTION);
2377
2378 sv->GVS[sv->StdView].ViewFrom[0] =
2379 sv->GVS[sv->StdView].ViewFromOrig[0];
2380 sv->GVS[sv->StdView].ViewFrom[1] =
2381 sv->GVS[sv->StdView].ViewFromOrig[1];
2382 sv->GVS[sv->StdView].ViewFrom[2] =
2383 sv->GVS[sv->StdView].ViewFromOrig[2];
2384 sv->GVS[sv->StdView].ViewCenter[0] =
2385 sv->GVS[sv->StdView].ViewCenterOrig[0];
2386 sv->GVS[sv->StdView].ViewCenter[1] =
2387 sv->GVS[sv->StdView].ViewCenterOrig[1];
2388 sv->GVS[sv->StdView].ViewCenter[2] =
2389 sv->GVS[sv->StdView].ViewCenterOrig[2];
2390
2391 glMatrixMode(GL_MODELVIEW);
2392 glLoadIdentity();
2393 gluLookAt ( sv->GVS[sv->StdView].ViewFrom[0],
2394 sv->GVS[sv->StdView].ViewFrom[1],
2395 sv->GVS[sv->StdView].ViewFrom[2],
2396 sv->GVS[sv->StdView].ViewCenter[0],
2397 sv->GVS[sv->StdView].ViewCenter[1],
2398 sv->GVS[sv->StdView].ViewCenter[2],
2399 sv->GVS[sv->StdView].ViewCamUp[0],
2400 sv->GVS[sv->StdView].ViewCamUp[1],
2401 sv->GVS[sv->StdView].ViewCamUp[2]);
2402 SUMA_RETURN(YUP);
2403 }
2404
SUMA_Fetch_VisX_Element(char * label,DList * dl)2405 DListElmt *SUMA_Fetch_VisX_Element(char *label, DList *dl)
2406 {
2407 static char FuncName[]={"SUMA_Fetch_VisX_Element"};
2408 DListElmt *el=NULL, *ref=NULL;
2409 SUMA_VIS_XFORM_DATUM *uu=NULL;
2410
2411 SUMA_ENTRY;
2412
2413 if (!label || !dl) {
2414 SUMA_S_Err("NULL label or NULL list");
2415 SUMA_RETURN(ref);
2416 }
2417 if (!dlist_size(dl)) SUMA_RETURN(ref);
2418
2419 el = NULL;
2420 do {
2421 if (!el) el = dlist_head(dl);
2422 else el = dlist_next(el);
2423 uu = (SUMA_VIS_XFORM_DATUM *)el->data;
2424 if (uu && !strcmp(uu->label, label)) {
2425 ref = el;
2426 }
2427 } while(!ref && el != dlist_tail(dl));
2428 SUMA_RETURN(ref);
2429 }
2430
SUMA_Fetch_VisX_Datum(char * label,DList * dl,SUMA_VISX_ADD_POSITIONS add,char * ref_pos_label)2431 SUMA_VIS_XFORM_DATUM *SUMA_Fetch_VisX_Datum (char *label, DList *dl,
2432 SUMA_VISX_ADD_POSITIONS add, char *ref_pos_label)
2433 {
2434 static char FuncName[]={"SUMA_Fetch_VisX_Datum"};
2435 SUMA_VIS_XFORM_DATUM *xx=NULL, *uu=NULL;
2436 DListElmt *el=NULL, *ref=NULL;
2437
2438 SUMA_ENTRY;
2439
2440 if (!label || !dl) {
2441 SUMA_S_Err("NULL label or NULL list");
2442 SUMA_RETURN(xx);
2443 }
2444 if (!dlist_size(dl)) {
2445 if (add != ADD_NOT) {
2446 xx = SUMA_NewVisXdatum(label);
2447 dlist_ins_next(dl, dlist_tail(dl), xx);
2448 } else {
2449 SUMA_RETURN(xx);
2450 }
2451 } else {
2452 if ((el=SUMA_Fetch_VisX_Element(label, dl))) {
2453 if ((xx = (SUMA_VIS_XFORM_DATUM *)el->data)) {
2454 SUMA_RETURN(xx);
2455 }
2456 }
2457
2458 /* should we add, and if so, where ? */
2459 if (add != ADD_NOT) {
2460 if (ref_pos_label) {
2461 ref = SUMA_Fetch_VisX_Element(ref_pos_label, dl);
2462 }
2463 xx = SUMA_NewVisXdatum(label);
2464 if (ref) {
2465 switch (add) {
2466 case ADD_AFTER:
2467 dlist_ins_next(dl, ref, xx);
2468 break;
2469 case ADD_BEFORE:
2470 dlist_ins_prev(dl, ref, xx);
2471 break;
2472 default:
2473 SUMA_S_Errv("Bad add=%d\n", add);
2474 break;
2475 }
2476 } else {
2477 switch (add) {
2478 case ADD_AFTER:
2479 dlist_ins_next(dl, dlist_tail(dl), xx);
2480 break;
2481 case ADD_BEFORE:
2482 dlist_ins_prev(dl, dlist_head(dl), xx);
2483 break;
2484 default:
2485 SUMA_S_Errv("Bad add=%d\n", add);
2486 break;
2487 }
2488 }
2489 }
2490 SUMA_RETURN(xx);
2491 }
2492
2493 /* should not get here...*/
2494 SUMA_RETURN(xx);
2495 }
2496
SUMA_Apply_VisX_Chain(float * xyz,int N,DList * dl,int inv)2497 SUMA_Boolean SUMA_Apply_VisX_Chain(float *xyz, int N, DList *dl, int inv)
2498 {
2499 static char FuncName[]={"SUMA_Apply_VisX_Chain"};
2500 SUMA_VIS_XFORM_DATUM *xx=NULL;
2501 DListElmt *el=NULL;
2502 int ii, iii, N3;
2503 SUMA_Boolean LocalHead = NOPE;
2504
2505 SUMA_ENTRY;
2506
2507 if (!dl || !xyz) {
2508 SUMA_S_Errv("No list (%p) or coords (%p)\n", dl, xyz);
2509 SUMA_RETURN(NOPE);
2510 }
2511 if (!dlist_size(dl)) {
2512 SUMA_S_Err("Empty list");
2513 SUMA_RETURN(NOPE);
2514 }
2515
2516 N3 = 3*N;
2517 if (!inv) {
2518 do {
2519 if (!el) el = dlist_head(dl);
2520 else el = dlist_next(el);
2521 xx = (SUMA_VIS_XFORM_DATUM *)el->data;
2522 switch (xx->XformType) {
2523 case ID:
2524 break;
2525 case SHIFT:
2526 SUMA_LHv("Applying shift %s\n", xx->label);
2527 for (ii=0, iii=0; ii<N; ++ii) {
2528 xyz[iii] += xx->Xform[0][3]; ++iii;
2529 xyz[iii] += xx->Xform[1][3]; ++iii;
2530 xyz[iii] += xx->Xform[2][3]; ++iii;
2531 }
2532 break;
2533 case AFFINE:
2534 SUMA_LHv("Applying affine %s\n", xx->label);
2535 SUMA_Apply_Coord_xform( xyz,N,3,
2536 xx->Xform, 0, NULL);
2537 break;
2538 case DISP:
2539 SUMA_LHv("Applying disp (%p) %s\n", xx->dxyz, xx->label);
2540 if (!xx->dxyz) SUMA_RETURN(NOPE);
2541 for (iii=0; iii<N3; ++iii) {
2542 xyz[iii] += xx->dxyz[iii];
2543 }
2544 break;
2545 default:
2546 SUMA_RETURN(NOPE);
2547 break;
2548 }
2549 } while (el != dlist_tail(dl)) ;
2550 } else {
2551 do {
2552 if (!el) el = dlist_tail(dl);
2553 else el = dlist_prev(el);
2554 xx = (SUMA_VIS_XFORM_DATUM *)el->data;
2555 switch (xx->XformType) {
2556 case ID:
2557 break;
2558 case SHIFT:
2559 SUMA_LHv("Removing shift %s\n", xx->label);
2560 for (ii=0, iii=0; ii<N; ++ii) {
2561 xyz[iii] -= xx->Xform[0][3]; ++iii;
2562 xyz[iii] -= xx->Xform[1][3]; ++iii;
2563 xyz[iii] -= xx->Xform[2][3]; ++iii;
2564 }
2565 break;
2566 case AFFINE:
2567 SUMA_LHv("Removing affine %s\n", xx->label);
2568 SUMA_Apply_Coord_xform( xyz,N,3,
2569 xx->Xform, 1, NULL);
2570 break;
2571 case DISP:
2572 SUMA_LHv("Removing displacement (%p) %s\n", xx->dxyz, xx->label);
2573 if (!xx->dxyz) SUMA_RETURN(NOPE);
2574 for (iii=0; iii<N3; ++iii) {
2575 xyz[iii] -= xx->dxyz[iii];
2576 }
2577 break;
2578 default:
2579 SUMA_RETURN(NOPE);
2580 break;
2581 }
2582 } while (el != dlist_head(dl)) ;
2583 }
2584
2585 SUMA_RETURN(YUP);
2586 }
2587
2588 /*!
2589 Update view points of all viewers with this ADO registered
2590 */
SUMA_UpdateViewPoint_RegisteredADO(SUMA_ALL_DO * ado,byte keepzoom)2591 SUMA_Boolean SUMA_UpdateViewPoint_RegisteredADO(SUMA_ALL_DO *ado, byte keepzoom)
2592 {
2593 static char FuncName[]={"SUMA_UpdateViewPoint_RegisteredADO"};
2594 int ii;
2595 SUMA_SurfaceViewer *sv=NULL;
2596
2597 SUMA_ENTRY;
2598
2599 if (!ado) SUMA_RETURN(NOPE);
2600 for (ii=0; ii<SUMAg_N_SVv; ++ii) {
2601 sv = &(SUMAg_SVv[ii]);
2602 if (SUMA_ADO_isRegistered(sv, ado)) {
2603 SUMA_UpdateViewPoint(sv, SUMAg_DOv, SUMAg_N_DOv, keepzoom);
2604 SUMA_SetGLHome(sv);
2605 }
2606 }
2607
2608 SUMA_RETURN(YUP);
2609 }
2610
2611
2612 /*!
2613 Updates the View Center and view from of SV based on the contents of RegistDO
2614 */
SUMA_UpdateViewPoint(SUMA_SurfaceViewer * SV,SUMA_DO * dov,int N_dov,byte KeepZoom)2615 SUMA_Boolean SUMA_UpdateViewPoint ( SUMA_SurfaceViewer *SV,
2616 SUMA_DO *dov, int N_dov, byte KeepZoom)
2617 {
2618 static char FuncName[]={"SUMA_UpdateViewPoint"};
2619 int i, do_id, TotWeight;
2620 float NewCenter[3], UsedCenter[3], *xyzr, odelta=0.0, oviewd=0.0;
2621 SUMA_SurfaceObject *so_op;
2622 SUMA_DSET *dset=NULL;
2623 SUMA_Boolean LocalHead = NOPE;
2624
2625 SUMA_ENTRY;
2626
2627 NewCenter[0] = 0.0;
2628 NewCenter[1] = 0.0;
2629 NewCenter[2] = 0.0;
2630 TotWeight = 0;
2631
2632 i = 0;
2633 while (i < SV->N_DO) {
2634 do_id = SV->RegistDO[i].dov_ind;
2635 switch (dov[do_id].ObjectType) {
2636 case SO_type:
2637 so_op = (SUMA_SurfaceObject *)dov[do_id].OP;
2638 if (SV->UsePatchDims) {
2639 SUMA_LH("Using patch center");
2640 SUMA_COPY_VEC(so_op->patchCenter, UsedCenter, 3, float, float);
2641 } else {
2642 SUMA_LH("Using center of mass or sphere's center.");
2643 if (!SUMA_IS_GEOM_SYMM(so_op->isSphere) || so_op->VisX.Applied) {
2644 SUMA_COPY_VEC(so_op->Center, UsedCenter, 3, float, float);
2645 } else {
2646 SUMA_COPY_VEC( so_op->SphereCenter, UsedCenter, 3,
2647 float, float);
2648 }
2649 }
2650 if (so_op->VisX.Applied) {
2651 if (!SUMA_Apply_VisX_Chain( UsedCenter,1,so_op->VisX.Xchain, 0)) {
2652 SUMA_S_Warn("Sir! Have you no decency left?");
2653 }
2654 }
2655 if (so_op->ViewCenterWeight) {
2656 NewCenter[0] += so_op->ViewCenterWeight*UsedCenter[0];
2657 NewCenter[1] += so_op->ViewCenterWeight*UsedCenter[1];
2658 NewCenter[2] += so_op->ViewCenterWeight*UsedCenter[2];
2659 TotWeight += so_op->ViewCenterWeight;
2660 }
2661 break;
2662 case GRAPH_LINK_type:
2663 if(!(dset=SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)(dov[do_id].OP)))){
2664 SUMA_S_Err("Gildaaaaaaaaaaaaaaaaaa");
2665 SUMA_RETURN(NOPE);
2666 }
2667
2668 if (!SUMA_IS_REAL_VARIANT(iDO_variant(do_id))) break;
2669 xyzr = SUMA_GDSET_XYZ_Center(dset, iDO_variant(do_id), NULL);
2670 NewCenter[0] += GDSET_N_SEG_POINTS(dset)*xyzr[0];
2671 NewCenter[1] += GDSET_N_SEG_POINTS(dset)*xyzr[1];
2672 NewCenter[2] += GDSET_N_SEG_POINTS(dset)*xyzr[2];
2673 TotWeight += GDSET_N_SEG_POINTS(dset);
2674 break;
2675 case TRACT_type: {
2676 SUMA_TractDO *TDO=(SUMA_TractDO *)dov[do_id].OP;
2677 int N_tracts;
2678 if (TDO_HAS_GRID(TDO)) {
2679 xyzr = SUMA_TDO_Grid_Center(TDO, NULL);
2680 } else {
2681 xyzr = SUMA_TDO_Points_Center(TDO, NULL);
2682 }
2683 N_tracts = SUMA_TDO_N_tracts(TDO);
2684 NewCenter[0] += N_tracts*xyzr[0];
2685 NewCenter[1] += N_tracts*xyzr[1];
2686 NewCenter[2] += N_tracts*xyzr[2];
2687 TotWeight += N_tracts;
2688 break; }
2689 case MASK_type: {
2690 int N_pts;
2691 SUMA_MaskDO *MDO=(SUMA_MaskDO *)dov[do_id].OP;
2692 xyzr = SUMA_MDO_Center(MDO, NULL);
2693 N_pts = SUMA_ADO_N_Datum((SUMA_ALL_DO*)MDO);
2694 NewCenter[0] += N_pts*xyzr[0];
2695 NewCenter[1] += N_pts*xyzr[1];
2696 NewCenter[2] += N_pts*xyzr[2];
2697 TotWeight += N_pts;
2698 break; }
2699 case VO_type: {
2700 SUMA_VolumeObject *VO=(SUMA_VolumeObject *)dov[do_id].OP;
2701 xyzr = SUMA_VO_Grid_Center(VO, NULL);
2702 NewCenter[0] += VO_NVOX(VO)*xyzr[0];
2703 NewCenter[1] += VO_NVOX(VO)*xyzr[1];
2704 NewCenter[2] += VO_NVOX(VO)*xyzr[2];
2705 TotWeight += VO_NVOX(VO);
2706 break; }
2707 default:
2708 SUMA_LHv("Ignoring object %s, variant %s\n",
2709 iDO_label(do_id), iDO_variant(do_id));
2710 break;
2711
2712 }
2713 ++i;
2714 }
2715
2716 odelta = SV->GVS[SV->StdView].ViewFrom[2] -SV->GVS[SV->StdView].ViewCenter[2];
2717 oviewd = SV->GVS[SV->StdView].ViewDistance;
2718 if (TotWeight) {
2719 SV->GVS[SV->StdView].ViewCenter[0] = NewCenter[0]/(float)TotWeight;
2720 SV->GVS[SV->StdView].ViewCenter[1] = NewCenter[1]/(float)TotWeight;
2721 SV->GVS[SV->StdView].ViewCenter[2] = NewCenter[2]/(float)TotWeight;
2722 SV->GVS[SV->StdView].ViewFrom[0] = SV->GVS[SV->StdView].ViewCenter[0];
2723 SV->GVS[SV->StdView].ViewFrom[1] = SV->GVS[SV->StdView].ViewCenter[1];
2724 if (!KeepZoom) {
2725 SV->GVS[SV->StdView].ViewFrom[2] =
2726 SV->GVS[SV->StdView].ViewCenter[2]+
2727 SUMA_DEFAULT_VIEW_FROM/SV->GVS[SV->StdView].DimSclFac;
2728 SV->GVS[SV->StdView].ViewDistance =
2729 SUMA_DEFAULT_VIEW_FROM/SV->GVS[SV->StdView].DimSclFac;
2730 } else {
2731 SV->GVS[SV->StdView].ViewFrom[2] =
2732 SV->GVS[SV->StdView].ViewCenter[2]+odelta;
2733 SV->GVS[SV->StdView].ViewDistance = oviewd;
2734 }
2735 } else {/* default back to o.o, o.o, o.o */
2736 SV->GVS[SV->StdView].ViewCenter[0] =
2737 SV->GVS[SV->StdView].ViewCenter[1] =
2738 SV->GVS[SV->StdView].ViewCenter[2] = 0.0;
2739 SV->GVS[SV->StdView].ViewFrom[0] =
2740 SV->GVS[SV->StdView].ViewFrom[1] = 0.0;
2741 if (!KeepZoom) {
2742 SV->GVS[SV->StdView].ViewFrom[2] =
2743 SUMA_DEFAULT_VIEW_FROM/SV->GVS[SV->StdView].DimSclFac;
2744 SV->GVS[SV->StdView].ViewDistance =
2745 SUMA_DEFAULT_VIEW_FROM/SV->GVS[SV->StdView].DimSclFac;
2746 }
2747 }
2748
2749 /* Store that info in case subjects change things */
2750 SV->GVS[SV->StdView].ViewCenterOrig[0] =
2751 SV->GVS[SV->StdView].ViewCenter[0];
2752 SV->GVS[SV->StdView].ViewCenterOrig[1] =
2753 SV->GVS[SV->StdView].ViewCenter[1];
2754 SV->GVS[SV->StdView].ViewCenterOrig[2] =
2755 SV->GVS[SV->StdView].ViewCenter[2];
2756 SV->GVS[SV->StdView].ViewFromOrig[0] = SV->GVS[SV->StdView].ViewFrom[0];
2757 SV->GVS[SV->StdView].ViewFromOrig[1] = SV->GVS[SV->StdView].ViewFrom[1];
2758 SV->GVS[SV->StdView].ViewFromOrig[2] = SV->GVS[SV->StdView].ViewFrom[2];
2759
2760 SUMA_RETURN (YUP);
2761 }
2762
2763 /*!
2764 Updates the Rotation Center of SV based on the contents of RegistDO
2765 */
SUMA_UpdateRotaCenter(SUMA_SurfaceViewer * SV,SUMA_DO * dov,int N_dov)2766 SUMA_Boolean SUMA_UpdateRotaCenter (
2767 SUMA_SurfaceViewer *SV, SUMA_DO *dov, int N_dov)
2768 {
2769 static char FuncName[]={"SUMA_UpdateRotaCenter"};
2770 int i, do_id, TotWeight;
2771 float NewCenter[3], UsedCenter[3];
2772 float *xyzr;
2773 SUMA_SurfaceObject *so_op;
2774 SUMA_DSET *dset=NULL;
2775 SUMA_Boolean LocalHead = NOPE;
2776
2777 SUMA_ENTRY;
2778
2779 NewCenter[0] = 0.0;
2780 NewCenter[1] = 0.0;
2781 NewCenter[2] = 0.0;
2782 TotWeight = 0;
2783
2784
2785 i = 0;
2786 while (i < SV->N_DO) {
2787 do_id = SV->RegistDO[i].dov_ind;
2788 switch (dov[do_id].ObjectType) {
2789 case SO_type:
2790 so_op = (SUMA_SurfaceObject *)dov[do_id].OP;
2791 if (SV->UsePatchDims) {
2792 SUMA_COPY_VEC(so_op->patchCenter, UsedCenter, 3, float, float);
2793 } else {
2794 if (SUMA_IS_GEOM_SYMM(so_op->isSphere) && !so_op->VisX.Applied) {
2795 SUMA_COPY_VEC(so_op->SphereCenter, UsedCenter,
2796 3, float, float);
2797 } else {
2798 SUMA_COPY_VEC(so_op->Center, UsedCenter, 3, float, float);
2799 }
2800 }
2801 SUMA_LHv("Used Center (%s) Pre Xform: [%f %f %f]\n",
2802 so_op->Label, UsedCenter[0], UsedCenter[1], UsedCenter[2]);
2803 if (so_op->VisX.Applied) {
2804 if (!SUMA_Apply_VisX_Chain( UsedCenter,1,so_op->VisX.Xchain, 0)) {
2805 SUMA_S_Warn("Oh please don't break my heart.");
2806 }
2807 }
2808 SUMA_LHv("Used Center (%s) Post Xform: [%f %f %f]\n",
2809 so_op->Label, UsedCenter[0], UsedCenter[1], UsedCenter[2]);
2810 if (so_op->RotationWeight) {
2811 NewCenter[0] += so_op->RotationWeight*UsedCenter[0];
2812 NewCenter[1] += so_op->RotationWeight*UsedCenter[1];
2813 NewCenter[2] += so_op->RotationWeight*UsedCenter[2];
2814 TotWeight += so_op->RotationWeight;
2815 }
2816 break;
2817 case GRAPH_LINK_type:
2818 if(!(dset=SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)(dov[do_id].OP)))){
2819 SUMA_S_Err("Gildaaaaaaaaaaaaaaaaaa");
2820 SUMA_RETURN(NOPE);
2821 }
2822 if (!SUMA_IS_REAL_VARIANT(iDO_variant(do_id))) break;
2823 xyzr = SUMA_GDSET_XYZ_Center(dset, iDO_variant(do_id), NULL);
2824 NewCenter[0] += GDSET_N_SEG_POINTS(dset)*xyzr[0];
2825 NewCenter[1] += GDSET_N_SEG_POINTS(dset)*xyzr[1];
2826 NewCenter[2] += GDSET_N_SEG_POINTS(dset)*xyzr[2];
2827 TotWeight += GDSET_N_SEG_POINTS(dset);
2828 break;
2829 case MASK_type: {
2830 int N_pts;
2831 SUMA_MaskDO *MDO=(SUMA_MaskDO *)dov[do_id].OP;
2832 xyzr = SUMA_MDO_Center(MDO, NULL);
2833 N_pts = SUMA_ADO_N_Datum((SUMA_ALL_DO *)MDO);
2834 NewCenter[0] += N_pts*xyzr[0];
2835 NewCenter[1] += N_pts*xyzr[1];
2836 NewCenter[2] += N_pts*xyzr[2];
2837 TotWeight += N_pts;
2838 break; }
2839 case TRACT_type: {
2840 SUMA_TractDO *TDO=(SUMA_TractDO *)dov[do_id].OP;
2841 int N_tracts;
2842 if (TDO_HAS_GRID(TDO)) {
2843 xyzr = SUMA_TDO_Grid_Center(TDO, NULL);
2844 } else {
2845 xyzr = SUMA_TDO_Points_Center(TDO, NULL);
2846 }
2847 N_tracts = SUMA_TDO_N_tracts(TDO);
2848 NewCenter[0] += N_tracts*xyzr[0];
2849 NewCenter[1] += N_tracts*xyzr[1];
2850 NewCenter[2] += N_tracts*xyzr[2];
2851 TotWeight += N_tracts;
2852 break; }
2853 case VO_type: {
2854 SUMA_VolumeObject *VO=(SUMA_VolumeObject *)dov[do_id].OP;
2855 xyzr = SUMA_VO_Grid_Center(VO, NULL);
2856
2857 NewCenter[0] += VO_NVOX(VO)*xyzr[0];
2858 NewCenter[1] += VO_NVOX(VO)*xyzr[1];
2859 NewCenter[2] += VO_NVOX(VO)*xyzr[2];
2860 TotWeight += VO_NVOX(VO);
2861 break; }
2862 case CDOM_type: {
2863 int kkk;
2864 xyzr = SUMA_ADO_Center((SUMA_ALL_DO *)dov[do_id].OP, NULL);
2865 kkk = SUMA_ADO_N_Datum((SUMA_ALL_DO *)dov[do_id].OP);
2866 NewCenter[0] += kkk*xyzr[0];
2867 NewCenter[1] += kkk*xyzr[1];
2868 NewCenter[2] += kkk*xyzr[2];
2869 TotWeight += kkk;
2870 break; }
2871 default:
2872 if (SUMA_is_iDO_Selectable(do_id)) {
2873 static int nwarn=0;
2874 if (!nwarn) {
2875 SUMA_S_Warnv("Just ignored DO %s, I hope that's cool\n",
2876 iDO_label(do_id));
2877 }
2878 ++nwarn;
2879 }
2880 SUMA_LHv("Ignoring object %s, variant %s\n",
2881 iDO_label(do_id), iDO_variant(do_id));
2882 break;
2883 }
2884 ++i;
2885 }
2886 if (TotWeight) {
2887 SV->GVS[SV->StdView].RotaCenter[0] = NewCenter[0]/(float)TotWeight;
2888 SV->GVS[SV->StdView].RotaCenter[1] = NewCenter[1]/(float)TotWeight;
2889 SV->GVS[SV->StdView].RotaCenter[2] = NewCenter[2]/(float)TotWeight;
2890 } else
2891 {/* default back to o.o, o.o, o.o */
2892 SV->GVS[SV->StdView].RotaCenter[0] =
2893 SV->GVS[SV->StdView].RotaCenter[1] =
2894 SV->GVS[SV->StdView].RotaCenter[2] = 0.0;
2895 }
2896 SUMA_RETURN (YUP);
2897
2898 }
2899
2900 /*!
2901 output the state variable contents of the Surface Viewer
2902 */
SUMA_Show_SurfaceViewer_Struct(SUMA_SurfaceViewer * SV,FILE * Out,int detail)2903 void SUMA_Show_SurfaceViewer_Struct (SUMA_SurfaceViewer *SV, FILE *Out,
2904 int detail)
2905 {
2906 static char FuncName[]={"SUMA_Show_SurfaceViewer_Struct"};
2907 char *s = NULL;
2908
2909 SUMA_ENTRY;
2910
2911 if (Out == NULL) Out = stdout;
2912
2913 s = SUMA_SurfaceViewer_StructInfo (SV, detail);
2914
2915 if (s) {
2916 fprintf(Out, "%s", s);
2917 SUMA_free(s); s = NULL;
2918 }else {
2919 SUMA_SL_Err("Failed in SUMA_SurfaceViewer_StructInfo");
2920 }
2921
2922 SUMA_RETURNe;
2923 }
2924
SUMA_isViewerStateAnatomical(SUMA_SurfaceViewer * sv)2925 SUMA_Boolean SUMA_isViewerStateAnatomical(SUMA_SurfaceViewer *sv)
2926 {
2927 int i;
2928 if (!sv) return(NOPE);
2929 for (i=0; i < sv->N_VSv; ++i) {
2930 if (!strcmp(sv->State, sv->VSv[i].Name)) return(sv->VSv[i].AnatCorrect);
2931 }
2932 return(NOPE);
2933 }
2934
SUMA_SurfaceViewer_StructInfo(SUMA_SurfaceViewer * SV,int detail)2935 char *SUMA_SurfaceViewer_StructInfo (SUMA_SurfaceViewer *SV, int detail)
2936 {
2937 static char FuncName[]={"SUMA_SurfaceViewer_StructInfo"};
2938 SUMA_STRING *SS = NULL;
2939 char *s=NULL;
2940 int i;
2941 SUMA_Boolean LocalHead = NOPE;
2942
2943 SUMA_ENTRY;
2944
2945 SS = SUMA_StringAppend (NULL, NULL);
2946
2947 if (!SV) {
2948 SS = SUMA_StringAppend (SS,"NULL SV.\n");
2949 SS = SUMA_StringAppend (SS, NULL);
2950 /* copy s pointer and free SS */
2951 s = SS->s;
2952 SUMA_free(SS);
2953 SUMA_RETURN(s);
2954 }
2955
2956 SS = SUMA_StringAppend(SS, "SV contents:\n");
2957 SS = SUMA_StringAppend_va(SS, " verbose = %d\n", SV->verbose);
2958 if (SV->ShowLeft) SS = SUMA_StringAppend_va(SS," Show Left = YES\n");
2959 else SS = SUMA_StringAppend_va(SS," Show Left = NO\n");
2960 if (SV->ShowRight) SS = SUMA_StringAppend_va(SS," Show Right = YES\n");
2961 else SS = SUMA_StringAppend_va(SS," Show Right = NO\n");
2962
2963 if (SV->ortho) SS = SUMA_StringAppend_va(SS," Projection: Orthographic\n");
2964 else SS = SUMA_StringAppend_va(SS," Projection: Perspective\n");
2965 SS = SUMA_StringAppend_va(SS," Display Labels At Crosshair: %s\n",
2966 SV->ShowLabelAtXhair ? "ON": "OFF");
2967 SS = SUMA_StringAppend_va(SS," Aspect = %f\n", SV->Aspect);
2968 SS = SUMA_StringAppend_va( SS," Freeze Zoom across states = %d\n",
2969 SV->FreezeZoomXstates);
2970 SS = SUMA_StringAppend_va(SS, " Dim. Scale Factor = %f\n",
2971 SV->GVS[SV->StdView].DimSclFac);
2972 SS = SUMA_StringAppend_va(SS, " ViewDistance = %f\n",
2973 SV->GVS[SV->StdView].ViewDistance);
2974 SS = SUMA_StringAppend_va(SS, " ViewFrom = [%f %f %f]\n",
2975 SV->GVS[SV->StdView].ViewFrom[0],
2976 SV->GVS[SV->StdView].ViewFrom[1],
2977 SV->GVS[SV->StdView].ViewFrom[2]);
2978 SS = SUMA_StringAppend_va(SS," ViewFromOrig = [%f %f %f]\n",
2979 SV->GVS[SV->StdView].ViewFromOrig[0],
2980 SV->GVS[SV->StdView].ViewFromOrig[1],
2981 SV->GVS[SV->StdView].ViewFromOrig[2]);
2982 SS = SUMA_StringAppend_va(SS," ViewCenter = [%f %f %f]\n",
2983 SV->GVS[SV->StdView].ViewCenter[0],
2984 SV->GVS[SV->StdView].ViewCenter[1],
2985 SV->GVS[SV->StdView].ViewCenter[2]);
2986 SS = SUMA_StringAppend_va(SS," ViewCenterOrig = [%f %f %f]\n",
2987 SV->GVS[SV->StdView].ViewCenterOrig[0],
2988 SV->GVS[SV->StdView].ViewCenterOrig[1],
2989 SV->GVS[SV->StdView].ViewCenterOrig[2]);
2990 SS = SUMA_StringAppend_va(SS," ViewCamUp = [%f %f %f]\n",
2991 SV->GVS[SV->StdView].ViewCamUp[0],
2992 SV->GVS[SV->StdView].ViewCamUp[1],
2993 SV->GVS[SV->StdView].ViewCamUp[2]);
2994 SS = SUMA_StringAppend_va(SS," RotaCenter = [%f %f %f]\n",
2995 SV->GVS[SV->StdView].RotaCenter[0],
2996 SV->GVS[SV->StdView].RotaCenter[1],
2997 SV->GVS[SV->StdView].RotaCenter[2]);
2998 SS = SUMA_StringAppend_va(SS, " Convolution Filter = %d\n [ ",
2999 SV->C_mode);
3000 if (SV->C_filter) {
3001 int ii, jj;
3002 for(jj = 0; jj < SV->C_filter->rows; jj++) {
3003 for(ii = 0; ii < SV->C_filter->cols; ii++) {
3004 SS = SUMA_StringAppend_va(SS, "%.3f ",
3005 SV->C_filter->array[ii + jj * SV->C_filter->cols]);
3006 }
3007 if (jj < SV->C_filter->rows-1)
3008 SS = SUMA_StringAppend(SS, "\n ");
3009 else SS = SUMA_StringAppend(SS, " ]\n" );
3010 }
3011 } else {
3012 SS = SUMA_StringAppend_va(SS, " NULL! ]\n");
3013 }
3014 SS = SUMA_StringAppend_va(SS,
3015 " light0_position = [%f %f %f %f] (lit for %d)\n",
3016 SV->light0_position[0],
3017 SV->light0_position[1],
3018 SV->light0_position[2],
3019 SV->light0_position[3],
3020 SV->lit_for);
3021 SS = SUMA_StringAppend_va(SS," light1_position = [%f %f %f %f]\n",
3022 SV->light1_position[0],
3023 SV->light1_position[1],
3024 SV->light1_position[2],
3025 SV->light1_position[3]);
3026 SS = SUMA_StringAppend_va(SS," ZoomCompensate = %f\n", SV->ZoomCompensate);
3027 SS = SUMA_StringAppend_va(SS," WindWidth/WIDTH/Offset = %d/%d/%d\n",
3028 SV->wWindWidth, SV->X->aWIDTH, SV->DrawAreaWidthOffset);
3029 SS = SUMA_StringAppend_va(SS," WindHeight/HEIGHT/Offset = %d/%d/%d\n",
3030 SV->wWindHeight, SV->X->aHEIGHT, SV->DrawAreaHeightOffset);
3031 SS = SUMA_StringAppend_va(SS," ShowWorldAxis = %d\n", SV->ShowWorldAxis);
3032 if (SV->WAx) {
3033 SS = SUMA_StringAppend_va(SS, " WorldAxis: Center = [%f %f %f] \n"
3034 " BR = [%f %f %f ,\n"
3035 " %f %f %f]\n",
3036 SV->WAx->Center[0], SV->WAx->Center[1],
3037 SV->WAx->Center[2],
3038 SV->WAx->BR[0][0], SV->WAx->BR[1][0],
3039 SV->WAx->BR[2][0],
3040 SV->WAx->BR[0][1], SV->WAx->BR[1][1],
3041 SV->WAx->BR[2][1]);
3042 } else {
3043 SS = SUMA_StringAppend_va(SS," WorldAxis: NULL\n");
3044 }
3045 SS = SUMA_StringAppend_va(SS," currentQuat = [%f %f %f %f]\n",
3046 SV->GVS[SV->StdView].currentQuat[0],
3047 SV->GVS[SV->StdView].currentQuat[1],
3048 SV->GVS[SV->StdView].currentQuat[2],
3049 SV->GVS[SV->StdView].currentQuat[3]);
3050 SS = SUMA_StringAppend_va(SS," deltaQuat = [%f %f %f %f]\n",
3051 SV->GVS[SV->StdView].deltaQuat[0],
3052 SV->GVS[SV->StdView].deltaQuat[1],
3053 SV->GVS[SV->StdView].deltaQuat[2],
3054 SV->GVS[SV->StdView].deltaQuat[3]);
3055 SS = SUMA_StringAppend_va(SS," ApplyMomentum = %d\n",
3056 SV->GVS[SV->StdView].ApplyMomentum);
3057 SS = SUMA_StringAppend_va(SS," MinIdleDelta = %d\n",
3058 SV->GVS[SV->StdView].MinIdleDelta);
3059 SS = SUMA_StringAppend_va(SS," zoomDelta = %f, zoomBegin = %f\n",
3060 SV->GVS[SV->StdView].zoomDelta, SV->GVS[SV->StdView].zoomBegin);
3061 SS = SUMA_StringAppend_va(SS," ArrowRotationAngle=%f rad (%f deg)\n",
3062 SV->ArrowRotationAngle, SV->ArrowRotationAngle * 180.0 / SUMA_PI);
3063 SS = SUMA_StringAppend_va(SS," KeyZoomGain=%f \n", SV->KeyZoomGain);
3064 SS = SUMA_StringAppend_va(SS," FOV_original=%f\n", SV->FOV_original);
3065 SS = SUMA_StringAppend_va(SS," spinDeltaX/Y = %.4f/%.4f\n",
3066 SV->GVS[SV->StdView].spinDeltaX, SV->GVS[SV->StdView].spinDeltaY);
3067 SS = SUMA_StringAppend_va(SS," spinBeginX/Y = %.4f/%.4f\n",
3068 SV->GVS[SV->StdView].spinBeginX, SV->GVS[SV->StdView].spinBeginY);
3069 SS = SUMA_StringAppend_va(SS," TranslateGain = %f\n",
3070 SV->GVS[SV->StdView].TranslateGain);
3071 SS = SUMA_StringAppend_va(SS," ArrowtranslateDeltaX/Y = %f/%f\n",
3072 SV->GVS[SV->StdView].ArrowtranslateDeltaX,
3073 SV->GVS[SV->StdView].ArrowtranslateDeltaY);
3074 SS = SUMA_StringAppend_va(SS," translateBeginX/Y = %.4f/%.4f\n",
3075 SV->GVS[SV->StdView].translateBeginX,
3076 SV->GVS[SV->StdView].translateBeginY);
3077 SS = SUMA_StringAppend_va(SS," translateDeltaX/Y = %f/%f\n",
3078 SV->GVS[SV->StdView].translateDeltaX,
3079 SV->GVS[SV->StdView].translateDeltaY);
3080 SS = SUMA_StringAppend_va(SS," translateVec = [%f %f 0.0]\n",
3081 SV->GVS[SV->StdView].translateVec[0],
3082 SV->GVS[SV->StdView].translateVec[1]);
3083 SS = SUMA_StringAppend_va(SS,
3084 " LHpry = [%f %f %f], LHpry0 = [%f %f %f], LHlol = %d\n",
3085 SV->GVS[SV->StdView].vLHpry[0],
3086 SV->GVS[SV->StdView].vLHpry[1],
3087 SV->GVS[SV->StdView].vLHpry[2],
3088 SV->GVS[SV->StdView].vLHpry0[0],
3089 SV->GVS[SV->StdView].vLHpry0[1],
3090 SV->GVS[SV->StdView].vLHpry0[2],
3091 SV->GVS[SV->StdView].LHlol);
3092 SS = SUMA_StringAppend_va(SS," Show Mesh Axis %d\n", SV->ShowMeshAxis);
3093 SS = SUMA_StringAppend_va(SS," Show Eye Axis %d\n", SV->ShowEyeAxis);
3094 SS = SUMA_StringAppend_va(SS," Show Cross Hair %d\n", SV->ShowCrossHair);
3095 SS = SUMA_StringAppend_va(SS," PolyMode %d\n", SV->PolyMode);
3096 SS = SUMA_StringAppend_va(SS," DO_DrawMask %d\n", SV->DO_DrawMask);
3097 SS = SUMA_StringAppend_va(SS," Blend_Mode %d\n", SV->Blend_Mode);
3098 if (SV->N_otseq) {
3099 SS = SUMA_StringAppend(SS,"Object rendering sequence:\n ");
3100 for (i=0; i<SV->N_otseq; ++i) {
3101 SS = SUMA_StringAppend_va(SS,"%s%s",
3102 SUMA_ObjectTypeCode2ObjectTypeName(SV->otseq[i]),
3103 (i<SV->N_otseq-1)?", ":"");
3104 }
3105 SS = SUMA_StringAppend(SS,"\n");
3106 } else {
3107 SS = SUMA_StringAppend(SS,"No object ordering sequence");
3108 }
3109 SS = SUMA_StringAppend_va(SS," Group Name %s, indexed %d\n",
3110 SV->CurGroupName, SV->iCurGroup);
3111 SS = SUMA_StringAppend_va(SS,
3112 " Current State %s, indexed %d, Anatomical %s\n",
3113 SV->State, SV->iState,
3114 SUMA_isViewerStateAnatomical(SV)?"YES":"NO");
3115 SS = SUMA_StringAppend_va(SS," N_DO = %d\n", SV->N_DO);
3116 SS = SUMA_StringAppend(SS, " RegistDO = ");
3117 for (i=0; i< SV->N_DO; ++i) {
3118 SS = SUMA_StringAppend_va(SS,"[id %d] %s \n%s",
3119 SV->RegistDO[i].dov_ind, iDO_label(SV->RegistDO[i].dov_ind),
3120 (i<(SV->N_DO-1)) ? " ":"");
3121 }
3122 SS = SUMA_StringAppend_va(SS," N_ColList = %d\n", SV->N_ColList);
3123 SS = SUMA_StringAppend(SS, " ColList = ");
3124 for (i = 0; i < SV->N_ColList; ++i) {
3125 SS = SUMA_StringAppend_va(SS,
3126 "[%d] for DO %s, id %s, Remix %d, RemixID %d, %d colors, N_links = %d\n%s",
3127 i, iDO_label(SUMA_whichDO(SV->ColList[i]->idcode_str,
3128 SUMAg_DOv, SUMAg_N_DOv)),
3129 SV->ColList[i]->idcode_str,
3130 SV->ColList[i]->Remix, SV->ColList[i]->RemixID,
3131 SV->ColList[i]->N_glar_ColorList, SV->ColList[i]->N_links,
3132 (i<(SV->N_ColList-1)) ? " ":"");
3133 }
3134 if (SV->X == NULL) SS = SUMA_StringAppend_va(SS," X struct is NULL!\n");
3135 else {
3136 SS = SUMA_StringAppend_va(SS," X struct defined.\n");
3137 }
3138
3139 SS = SUMA_StringAppend_va(SS," DO in focus %d\n", SV->Focus_DO_ID);
3140
3141 /* show some state stuff */
3142 SS = SUMA_StringAppend_va(SS, "\nView States (%d total):\n", SV->N_VSv);
3143 for (i=0; i < SV->N_VSv; ++i) {
3144 SS = SUMA_StringAppend_va(SS,
3145 "\nView State %d/%d (FOV = %f) (autoFOVval = %f):\n",
3146 i, SV->N_VSv-1, SV->FOV[i], SV->auto_FOV_val[i]);
3147 s = SUMA_ViewStateInfo (&(SV->VSv[i]), 0);
3148 if (!s) {
3149 SS = SUMA_StringAppend(SS, "*** Error in SUMA_Show_ViewState ***\n");
3150 } else {
3151 SS = SUMA_StringAppend(SS, s);
3152 SUMA_free(s); s = NULL;
3153 }
3154 }
3155 SS = SUMA_StringAppend_va(SS, "\nStandard viewing mode: %d\n", SV->StdView );
3156 SS = SUMA_StringAppend_va(SS, "\nBackground Modulation Factor= %f\n",
3157 SV->Back_Modfact);
3158 SS = SUMA_StringAppend_va(SS, "\nLast non mappable visited %d\n",
3159 SV->LastNonMapStateID);
3160
3161 s = SUMA_EnablingState_Info(&(SV->SER));
3162 SS = SUMA_StringAppend_va(SS,"Enabling state in sv->SER\n%s",s);
3163 SUMA_free(s); s = NULL;
3164
3165 SS = SUMA_StringAppend(SS,"\n");
3166
3167 /* trim SS */
3168 SS = SUMA_StringAppend (SS, NULL);
3169 /* copy s pointer and free SS */
3170 s = SS->s;
3171 SUMA_free(SS);
3172
3173 SUMA_RETURN(s);
3174 }
3175
3176 /*! Show the ViewState structure */
SUMA_Show_ViewState(SUMA_ViewState * VS,FILE * Out,int detail)3177 SUMA_Boolean SUMA_Show_ViewState(SUMA_ViewState *VS, FILE *Out, int detail)
3178 {
3179 static char FuncName[]={"SUMA_Show_ViewState"};
3180 char *s = NULL;
3181
3182 SUMA_ENTRY;
3183
3184 if (Out == NULL) Out = stdout;
3185
3186 s = SUMA_ViewStateInfo(VS, detail);
3187 if (!s) {
3188 SUMA_SL_Err("Failed in SUMA_ViewStateInfo");
3189 SUMA_RETURN(NOPE);
3190 } else {
3191 fprintf(Out, "%s", s);
3192 SUMA_free(s); s = NULL;
3193 }
3194
3195 SUMA_RETURN(YUP);
3196 }
3197
3198 /*
3199 A function that must be called each time order of objects in
3200 SUMAg_DOv is disturbed
3201 */
SUMA_ViewState_MembsRefresh(SUMA_ViewState * VS)3202 SUMA_Boolean SUMA_ViewState_MembsRefresh(SUMA_ViewState *VS)
3203 {
3204 static char FuncName[]={"SUMA_ViewState_MembsRefresh"};
3205 int ii=0, found = -1;
3206 SUMA_Boolean LocalHead = NOPE;
3207
3208 SUMA_ENTRY;
3209
3210 if (!VS) SUMA_RETURN(NOPE);
3211
3212 ii = 0;
3213 while (ii < VS->N_MembDO) {
3214 if ( VS->MembDO &&
3215 (found = SUMA_whichDOg(VS->MembDO[ii].idcode_str)) >= 0) {
3216 /* A good thing, refresh index mapping */
3217 VS->MembDO[ii].dov_ind = found;
3218 } else {
3219 SUMA_LH("A bad entry in MembDO at index %d/%d, cleaning",
3220 ii, VS->N_MembDO);
3221 if (ii != VS->N_MembDO-1) {
3222 strcpy(VS->MembDO[ii].idcode_str,
3223 VS->MembDO[VS->N_MembDO-1].idcode_str);
3224 }
3225 VS->MembDO[ii].dov_ind = VS->MembDO[VS->N_MembDO-1].dov_ind;
3226 VS->N_MembDO = VS->N_MembDO-1;
3227 VS->MembDO = (SUMA_DO_LOCATOR *)SUMA_realloc(VS->MembDO,
3228 VS->N_MembDO*sizeof(SUMA_DO_LOCATOR));
3229 }
3230 ++ii;
3231 }
3232
3233 SUMA_RETURN(YUP);
3234 }
3235
SUMA_AllViewState_MembsRefresh(void)3236 SUMA_Boolean SUMA_AllViewState_MembsRefresh(void)
3237 {
3238 static char FuncName[]={"SUMA_AllViewState_MembsRefresh"};
3239 int i,j;
3240 SUMA_SurfaceViewer *sv;
3241 SUMA_Boolean state = YUP;
3242
3243 SUMA_ENTRY;
3244
3245 state = YUP;
3246 for (i=0; i<SUMAg_N_SVv; ++i) {
3247 sv = SUMAg_SVv+i;
3248 for (j=0; j<sv->N_VSv; ++j) {
3249 if (!SUMA_ViewState_MembsRefresh(sv->VSv+j)) state = NOPE;
3250 }
3251 }
3252
3253 SUMA_RETURN(state);
3254 }
3255
3256 /*! Search for certain types of DOs members of a particular state*/
SUMA_ViewState_Membs(SUMA_ViewState * VS,SUMA_DO_Types * ttv,int * uN_Membs)3257 int *SUMA_ViewState_Membs(SUMA_ViewState *VS, SUMA_DO_Types *ttv,
3258 int *uN_Membs)
3259 {
3260 static char FuncName[]={"SUMA_ViewState_Membs"};
3261 int ii, jj, N_ttv;
3262 SUMA_DO_Types tt;
3263 int *Membs = NULL, N_Membs = 0;
3264 SUMA_Boolean LocalHead = NOPE;
3265
3266 SUMA_ENTRY;
3267
3268 if (uN_Membs) *uN_Membs = 0;
3269 SUMA_LHv("VS %p, Name %s, MembDOs %p, N_MembDOs %d\n",
3270 VS, (VS && VS->Name) ? VS->Name:"NULL",
3271 (VS && VS->MembDO) ? VS->MembDO:NULL,
3272 (VS && VS->N_MembDO) ? VS->N_MembDO:0);
3273 if (!VS || !VS->MembDO) SUMA_RETURN(Membs);
3274 jj = 0; N_ttv=0;
3275 while (ttv[jj] != NOT_SET_type) { ++N_ttv; ++jj; }
3276 if (!N_ttv) SUMA_RETURN(Membs);
3277
3278 jj = 0;
3279 while (ttv[jj] != NOT_SET_type) { tt = ttv[jj];
3280 for (ii=0; ii<VS->N_MembDO; ++ii) {
3281 SUMA_LHv("Checking %s type %s \n",
3282 iDO_label(VS->MembDO[ii].dov_ind),
3283 SUMA_ObjectTypeCode2ObjectTypeName(tt));
3284 if (iDO_type(VS->MembDO[ii].dov_ind) == tt) {
3285 switch (tt) {
3286 case SO_type:
3287 if (!Membs) Membs = (int *)
3288 SUMA_malloc(N_ttv*(VS->N_MembDO+1)*sizeof(int));
3289 Membs[N_Membs++] = VS->MembDO[ii].dov_ind;
3290 Membs[N_Membs]=-1;/* a plug, if uN_Membs is NULL*/
3291 break;
3292 case GRAPH_LINK_type:
3293 if (!Membs) Membs = (int *)
3294 SUMA_malloc(N_ttv*(VS->N_MembDO+1)*sizeof(int));
3295 Membs[N_Membs++] = VS->MembDO[ii].dov_ind;
3296 Membs[N_Membs]=-1;/* a plug, if uN_Membs is NULL*/
3297 break;
3298 case CDOM_type:
3299 case TRACT_type:
3300 case MASK_type:
3301 case VO_type:
3302 if (!Membs) Membs = (int *)
3303 SUMA_malloc(N_ttv*(VS->N_MembDO+1)*sizeof(int));
3304 Membs[N_Membs++] = VS->MembDO[ii].dov_ind;
3305 Membs[N_Membs]=-1;/* a plug, if uN_Membs is NULL*/
3306 break;
3307 default:
3308 SUMA_S_Err("Not ready for type %d (%s)", tt, SUMA_otc2otn(tt));
3309 break;
3310 } }
3311 } ++jj;}
3312 if (uN_Membs) *uN_Membs = N_Membs;
3313
3314 SUMA_RETURN(Membs);
3315 }
3316
3317 /*! Show the ViewState structure */
SUMA_ViewStateInfo(SUMA_ViewState * VS,int detail)3318 char *SUMA_ViewStateInfo(SUMA_ViewState *VS, int detail)
3319 {
3320 static char FuncName[]={"SUMA_ViewStateInfo"};
3321 int i, ifound;
3322 SUMA_STRING *SS = NULL;
3323 char *s=NULL;
3324
3325 SUMA_ENTRY;
3326
3327 SS = SUMA_StringAppend (NULL, NULL);
3328
3329 if (!VS) {
3330 SS = SUMA_StringAppend (SS,"NULL VS.\n");
3331 SS = SUMA_StringAppend (SS, NULL);
3332 /* copy s pointer and free SS */
3333 s = SS->s;
3334 SUMA_free(SS);
3335 SUMA_RETURN(s);
3336 }
3337
3338 if (VS->Name) SS = SUMA_StringAppend_va(SS,
3339 " Name: %s, Anatomically Correct: %s\n",
3340 VS->Name, VS->AnatCorrect?"YES":"NO");
3341 else SS = SUMA_StringAppend_va(SS, " Name: NULL\n");
3342
3343 if (VS->Group) SS = SUMA_StringAppend_va(SS, " Group: %s\n", VS->Group);
3344 else SS = SUMA_StringAppend_va(SS, " Group: NULL\n");
3345
3346 if (VS->N_MembDO) {
3347 SS = SUMA_StringAppend_va(SS,
3348 " %2d MembDOs in VS->MembDO %p:\n ",
3349 VS->N_MembDO, VS->MembDO);
3350 for (i=0; i < VS->N_MembDO; ++i) {
3351 ifound = SUMA_whichDOg(VS->MembDO[i].idcode_str);
3352 SS = SUMA_StringAppend_va(SS,
3353 "id %s DOv[%d] %s (%s) -- id check: %s\n ",
3354 VS->MembDO[i].idcode_str, VS->MembDO[i].dov_ind,
3355 iDO_label(VS->MembDO[i].dov_ind),
3356 iDO_typename(VS->MembDO[i].dov_ind),
3357 (ifound == VS->MembDO[i].dov_ind)?"OK":"NO - Must run Refresh");
3358 }
3359 } else {
3360 SS = SUMA_StringAppend_va(SS, " No MembDOs in VS->MembDO %p\n",
3361 VS->MembDO);
3362 }
3363
3364 if (VS->Hist) {
3365 } else {
3366 SS = SUMA_StringAppend_va(SS, " Hist is NULL\n");
3367 }
3368
3369 SS = SUMA_StringAppend (SS, NULL);
3370 /* copy s pointer and free SS */
3371 s = SS->s;
3372 SUMA_free(SS);
3373
3374 SUMA_RETURN (s);
3375 }
3376
3377 /*!
3378 Create & free ViewState_Hist structure
3379 */
SUMA_Alloc_ViewState_Hist(void)3380 SUMA_ViewState_Hist *SUMA_Alloc_ViewState_Hist (void)
3381 {
3382 static char FuncName[]={"SUMA_Alloc_ViewState_Hist"};
3383 SUMA_ViewState_Hist *vsh;
3384
3385 SUMA_ENTRY;
3386
3387 vsh = (SUMA_ViewState_Hist *)SUMA_calloc(1,sizeof(SUMA_ViewState_Hist));
3388 if (vsh == NULL) {
3389 fprintf(SUMA_STDERR,"Error %s: Could not allocate for vsh.\n", FuncName);
3390 SUMA_RETURN (NULL);
3391 }
3392 SUMA_RETURN (vsh);
3393 }
3394
SUMA_Free_ViewState_Hist(SUMA_ViewState_Hist * vsh)3395 SUMA_Boolean SUMA_Free_ViewState_Hist (SUMA_ViewState_Hist *vsh)
3396 {
3397 static char FuncName[]={"SUMA_Free_ViewState_Hist"};
3398
3399 SUMA_ENTRY;
3400
3401 if (vsh == NULL) SUMA_RETURN (YUP);
3402 if (vsh) SUMA_free(vsh);
3403 SUMA_RETURN (YUP);
3404 }
3405
3406 /*!
3407 Add a new SUMA_ViewState structure
3408 This is meant to replace SUMA_Alloc_ViewState
3409
3410 - Both csv->VSv and csv->N_VSv are updated here
3411 */
SUMA_New_ViewState(SUMA_SurfaceViewer * cs)3412 SUMA_Boolean SUMA_New_ViewState (SUMA_SurfaceViewer *cs)
3413 {
3414 static char FuncName[]={"SUMA_New_ViewState"};
3415 int i;
3416
3417 SUMA_ENTRY;
3418
3419
3420 if (!cs->VSv) { /* a new baby */
3421 cs->N_VSv = 1;
3422 cs->VSv = (SUMA_ViewState *)SUMA_calloc(1,sizeof(SUMA_ViewState));
3423 } else { /* realloc */
3424 ++cs->N_VSv;
3425 cs->VSv = (SUMA_ViewState *)SUMA_realloc(cs->VSv,
3426 cs->N_VSv*sizeof(SUMA_ViewState) );
3427 }
3428
3429 /* check on allocation */
3430 if (!cs->VSv) {
3431 SUMA_SL_Err("Failed to allocate");
3432 SUMA_RETURN(YUP);
3433 }
3434
3435 /* initialization of last element */
3436 cs->VSv[cs->N_VSv-1].Name = NULL;
3437 cs->VSv[cs->N_VSv-1].AnatCorrect = NOPE;
3438 cs->VSv[cs->N_VSv-1].Group = NULL;
3439 cs->VSv[cs->N_VSv-1].MembDO = NULL;
3440 cs->VSv[cs->N_VSv-1].N_MembDO = 0;
3441 cs->VSv[cs->N_VSv-1].Hist = SUMA_Alloc_ViewState_Hist ();
3442 if (cs->VSv[cs->N_VSv-1].Hist == NULL) {
3443 SUMA_S_Err("Could not allocate for cs->VSv->Hist.");
3444 SUMA_free(cs->VSv);
3445 SUMA_RETURN (NOPE);
3446 }
3447
3448 /* allocate for FOV */
3449 if (!cs->FOV) {
3450 cs->FOV = (float *)SUMA_calloc(cs->N_VSv, sizeof(float));
3451 if (!cs->FOV_last_PickMode) {
3452 cs->FOV_last_PickMode = (float *)SUMA_calloc(cs->N_VSv, sizeof(float));
3453 }
3454 if (!cs->auto_FOV_val) {
3455 cs->auto_FOV_val = (float *)SUMA_calloc(cs->N_VSv, sizeof(float));
3456 }
3457 for (i=0; i < cs->N_VSv; ++i) {
3458 /* This will get reset in SUMA_SetupSVforDOs */
3459 cs->FOV[i] = cs->FOV_original;
3460 cs->auto_FOV_val[i] = -1.0;
3461 }
3462 } else {
3463 cs->FOV = (float *)SUMA_realloc(cs->FOV, cs->N_VSv * sizeof(float));
3464 cs->FOV[cs->N_VSv-1] = cs->FOV[0]; /* used to be = cs->FOV_original,
3465 but it is best to set to 0th view,
3466 gives user ability to set display
3467 before auto-movie making via talk-suma */
3468 cs->FOV_last_PickMode = (float *)SUMA_realloc(cs->FOV_last_PickMode,
3469 cs->N_VSv * sizeof(float));
3470 cs->auto_FOV_val = (float *)SUMA_realloc(cs->auto_FOV_val,
3471 cs->N_VSv * sizeof(float));
3472 cs->auto_FOV_val[cs->N_VSv-1] = -1.0;
3473 }
3474
3475 /* Done */
3476 SUMA_RETURN(YUP);
3477
3478 }
3479
3480 /*!
3481 Create & free SUMA_ViewState structure
3482 */
SUMA_Alloc_ViewState(int N)3483 SUMA_ViewState *SUMA_Alloc_ViewState (int N)
3484 {
3485 SUMA_ViewState *vs;
3486 int i;
3487 static char FuncName[]={"SUMA_Alloc_ViewState"};
3488
3489 SUMA_ENTRY;
3490
3491 SUMA_SL_Err("Should not be using this anymore.\n"
3492 "Start using SUMA_New_ViewState.\n"
3493 " ZSS Jan 12 04 \n");
3494 SUMA_RETURN(NULL);
3495 vs = (SUMA_ViewState *)SUMA_calloc(N,sizeof(SUMA_ViewState));
3496 if (vs == NULL) {
3497 fprintf(SUMA_STDERR,"Error %s: Could not allocate for vs.\n", FuncName);
3498 SUMA_RETURN (NULL);
3499 }
3500 for (i=0; i< N; ++i) {
3501 vs[i].Name = NULL;
3502 vs[i].Group = NULL;
3503 vs[i].MembDO = NULL;
3504 vs[i].N_MembDO = 0;
3505 vs[i].Hist = SUMA_Alloc_ViewState_Hist ();
3506 if (vs[i].Hist == NULL) {
3507 SUMA_S_Err("Could not allocate for vs->Hist.");
3508 SUMA_free(vs);
3509 SUMA_RETURN (NULL);
3510 }
3511 }
3512 SUMA_RETURN (vs);
3513 }
3514
SUMA_Free_ViewState(SUMA_ViewState * vs)3515 SUMA_Boolean SUMA_Free_ViewState (SUMA_ViewState *vs)
3516 {
3517 static char FuncName[]={"SUMA_Free_ViewState"};
3518 SUMA_ENTRY;
3519
3520 if (vs == NULL) SUMA_RETURN (YUP);
3521 if (vs->Name) SUMA_free(vs->Name);
3522 if (vs->Group) SUMA_free(vs->Group);
3523 if (vs->MembDO) SUMA_free(vs->MembDO);
3524 if (vs->Hist) SUMA_Free_ViewState_Hist (vs->Hist);
3525 if (vs) SUMA_free(vs);
3526 SUMA_RETURN (YUP);
3527 }
3528
3529 /*!
3530 locate the index i (into SVv[i]) of sv
3531 -1 if not found
3532 */
SUMA_WhichSV(SUMA_SurfaceViewer * sv,SUMA_SurfaceViewer * SVv,int N_SVv)3533 int SUMA_WhichSV (SUMA_SurfaceViewer *sv, SUMA_SurfaceViewer *SVv, int N_SVv)
3534 {
3535 static char FuncName[]={"SUMA_WhichSV"};
3536 int i = 0;
3537
3538 SUMA_ENTRY;
3539
3540 if (!SVv || !sv) {
3541 fprintf (SUMA_STDERR, "Error %s: NULL SVv or sv.\n", FuncName);
3542 SUMA_RETURN (-1);
3543 }
3544
3545 for (i=0; i<N_SVv; ++i) {
3546 if (&(SVv[i]) == sv) {
3547 SUMA_RETURN (i);
3548 }
3549 }
3550
3551
3552 SUMA_RETURN (-1);
3553 }
3554
SUMA_WhichSVg(SUMA_SurfaceViewer * sv)3555 int SUMA_WhichSVg(SUMA_SurfaceViewer *sv)
3556 {
3557 return(SUMA_WhichSV(sv, SUMAg_SVv, SUMAg_N_SVv));
3558 }
3559
SUMA_WhichSVc(SUMA_SurfaceViewer * sv,SUMA_SurfaceViewer * SVv,int N_SVv)3560 char SUMA_WhichSVc(SUMA_SurfaceViewer *sv, SUMA_SurfaceViewer *SVv, int N_SVv)
3561 {
3562 static char FuncName[]={"SUMA_WhichSVc"};
3563 int isv;
3564
3565 isv = SUMA_WhichSV(sv, SVv, N_SVv);
3566 if (isv >= 0) return(65+isv);
3567 return('\0');
3568 }
3569
3570 /* return 1st viewer that is open and has a
3571 particular surface visible AND in focus
3572 */
SUMA_OneViewerWithSOinFocus(SUMA_SurfaceObject * curSO)3573 SUMA_SurfaceViewer *SUMA_OneViewerWithSOinFocus(
3574 SUMA_SurfaceObject *curSO)
3575 {
3576 static char FuncName[]={"SUMA_OneViewerWithSOinFocus"};
3577 int i=0;
3578 SUMA_SurfaceViewer *sv=NULL;
3579
3580 SUMA_ENTRY;
3581
3582 /* look for 1st viewer that is showing this
3583 surface and has this surface in focus*/
3584 for (i=0; i<SUMAg_N_SVv; ++i) {
3585 if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
3586 /* is this viewer showing curSO ? */
3587 if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
3588 (SUMA_ALL_DO *)curSO)) {
3589 if ((SUMAg_DOv[SUMAg_SVv[i].Focus_DO_ID].OP) == curSO) {
3590 sv = &(SUMAg_SVv[i]);
3591 SUMA_RETURN(sv);
3592 }
3593 }
3594 }
3595 }
3596
3597 SUMA_RETURN(sv);
3598 }
3599
3600 /* return 1st viewer that is open and has a
3601 particular object visible AND in focus
3602 */
SUMA_OneViewerWithADOinFocus(SUMA_ALL_DO * ADO)3603 SUMA_SurfaceViewer *SUMA_OneViewerWithADOinFocus(SUMA_ALL_DO *ADO)
3604 {
3605 static char FuncName[]={"SUMA_OneViewerWithADOinFocus"};
3606 int i=0;
3607 SUMA_SurfaceViewer *sv=NULL;
3608
3609 SUMA_ENTRY;
3610
3611 /* look for 1st viewer that has this ADO in focus*/
3612 for (i=0; i<SUMAg_N_SVv; ++i) {
3613 if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
3614 /* is this viewer showing ADO ? */
3615 if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv, ADO)) {
3616 if ((SUMAg_DOv[SUMAg_SVv[i].Focus_DO_ID].OP) == ADO) {
3617 sv = &(SUMAg_SVv[i]);
3618 SUMA_RETURN(sv);
3619 }
3620 }
3621 }
3622 }
3623
3624 SUMA_RETURN(sv);
3625 }
3626
SUMA_OneViewerWithADOVisible(SUMA_ALL_DO * ADO)3627 SUMA_SurfaceViewer *SUMA_OneViewerWithADOVisible(SUMA_ALL_DO *ADO)
3628 {
3629 static char FuncName[]={"SUMA_OneViewerWithADOVisible"};
3630 int i=0;
3631 SUMA_SurfaceViewer *sv=NULL;
3632
3633 SUMA_ENTRY;
3634
3635 /* look for 1st viewer that is showing this
3636 surface and has this surface in focus*/
3637 for (i=0; i<SUMAg_N_SVv; ++i) {
3638 if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
3639 /* is this viewer showing ADO ? */
3640 if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv, ADO)) {
3641 sv = &(SUMAg_SVv[i]);
3642 SUMA_RETURN(sv);
3643 }
3644 }
3645 }
3646
3647 SUMA_RETURN(sv);
3648 }
3649
SUMA_OneViewerWithSOVisible(SUMA_SurfaceObject * curSO)3650 SUMA_SurfaceViewer *SUMA_OneViewerWithSOVisible(
3651 SUMA_SurfaceObject *curSO)
3652 {
3653 static char FuncName[]={"SUMA_OneViewerWithSOVisible"};
3654 int i=0;
3655 SUMA_SurfaceViewer *sv=NULL;
3656
3657 SUMA_ENTRY;
3658
3659 /* look for 1st viewer that is showing this
3660 surface and has this surface in focus*/
3661 for (i=0; i<SUMAg_N_SVv; ++i) {
3662 if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
3663 /* is this viewer showing curSO ? */
3664 if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
3665 (SUMA_ALL_DO *)curSO)) {
3666 sv = &(SUMAg_SVv[i]);
3667 SUMA_RETURN(sv);
3668 }
3669 }
3670 }
3671
3672 SUMA_RETURN(sv);
3673 }
3674
SUMA_OneViewerWithADORegistered(SUMA_ALL_DO * ADO)3675 SUMA_SurfaceViewer *SUMA_OneViewerWithADORegistered(SUMA_ALL_DO *ADO)
3676 {
3677 static char FuncName[]={"SUMA_OneViewerWithADORegistered"};
3678 int i=0;
3679 SUMA_SurfaceViewer *sv=NULL;
3680
3681 SUMA_ENTRY;
3682
3683 /* look for 1st viewer that is showing this
3684 surface and has this surface in focus*/
3685 for (i=0; i<SUMAg_N_SVv; ++i) {
3686 if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
3687 if (SUMA_ADO_isRegistered(SUMAg_SVv+i, ADO)) {
3688 sv = &(SUMAg_SVv[i]);
3689 SUMA_RETURN(sv);
3690 }
3691 }
3692 }
3693
3694 SUMA_RETURN(sv);
3695 }
3696
SUMA_OneViewerWithSORegistered(SUMA_SurfaceObject * curSO)3697 SUMA_SurfaceViewer *SUMA_OneViewerWithSORegistered(
3698 SUMA_SurfaceObject *curSO)
3699 {
3700 static char FuncName[]={"SUMA_OneViewerWithSORegistered"};
3701 int i=0;
3702 SUMA_SurfaceViewer *sv=NULL;
3703
3704 SUMA_ENTRY;
3705
3706 /* look for 1st viewer that is showing this
3707 surface and has this surface in focus*/
3708 for (i=0; i<SUMAg_N_SVv; ++i) {
3709 if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
3710 /* is this viewer showing curSO ? */
3711 if (SUMA_isRegisteredSO(&(SUMAg_SVv[i]), SUMAg_DOv, curSO)) {
3712 sv = &(SUMAg_SVv[i]);
3713 SUMA_RETURN(sv);
3714 }
3715 }
3716 }
3717
3718 SUMA_RETURN(sv);
3719 }
3720
SUMA_BestViewerForADO(SUMA_ALL_DO * ado)3721 SUMA_SurfaceViewer *SUMA_BestViewerForADO(SUMA_ALL_DO *ado)
3722
3723 {
3724 static char FuncName[]={"SUMA_BestViewerForADO"};
3725 int i=0;
3726 SUMA_SurfaceViewer *sv=NULL;
3727
3728 SUMA_ENTRY;
3729
3730 if (!ado) {
3731 SUMA_RETURN(&(SUMAg_SVv[0]));
3732 }
3733
3734 switch (ado->do_type) {
3735 case SO_type: {
3736 SUMA_SurfaceObject *curSO = (SUMA_SurfaceObject *)ado;
3737 /* best bet, visible, and in focus */
3738 if ((sv=SUMA_OneViewerWithSOinFocus(curSO))) {
3739 SUMA_RETURN(sv);
3740 }
3741 /* just visible */
3742 if ((sv=SUMA_OneViewerWithSOVisible(curSO))) {
3743 SUMA_RETURN(sv);
3744 }
3745 /* registered */
3746 if ((sv=SUMA_OneViewerWithSORegistered(curSO))) {
3747 SUMA_RETURN(sv);
3748 }
3749 /* crap! */
3750 sv = &(SUMAg_SVv[0]);
3751 break; }
3752 case GRAPH_LINK_type:
3753 case GDSET_type:
3754 case CDOM_type:
3755 case VO_type:
3756 case MASK_type:
3757 case TRACT_type:
3758 if ((sv=SUMA_OneViewerWithADOinFocus(ado))) {
3759 SUMA_RETURN(sv);
3760 }
3761 /* just visible */
3762 if ((sv=SUMA_OneViewerWithADOVisible(ado))) {
3763 SUMA_RETURN(sv);
3764 }
3765 /* registered */
3766 if ((sv=SUMA_OneViewerWithADORegistered(ado))) {
3767 SUMA_RETURN(sv);
3768 }
3769 sv = &(SUMAg_SVv[0]);
3770 break;
3771 default:
3772 SUMA_S_Errv("Not ready for %s\n",
3773 SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
3774 sv = &(SUMAg_SVv[0]);
3775 break;
3776 }
3777
3778 SUMA_RETURN(sv);
3779 }
3780
3781 /*!
3782 locate the index i (into csv->VSv[i]) of state
3783 -1 if not found
3784 */
SUMA_WhichState(char * state,SUMA_SurfaceViewer * csv,char * ForceGroup)3785 int SUMA_WhichState (char *state, SUMA_SurfaceViewer *csv, char *ForceGroup)
3786 {
3787 static char FuncName[]={"SUMA_WhichState"};
3788 int i = 0;
3789 SUMA_Boolean LocalHead = NOPE;
3790
3791 SUMA_ENTRY;
3792
3793 if (!ForceGroup || !strcmp(ForceGroup,"ANY")) {
3794 SUMA_LH("Searching for state: %s, %d states\n"
3795 "Viewer %p [%c], %d viewers realized out of %d total",
3796 state, csv->N_VSv, csv,
3797 SUMA_WhichSVc(csv, SUMAg_SVv, SUMA_MAX_SURF_VIEWERS),
3798 SUMAg_N_SVv, SUMA_MAX_SURF_VIEWERS);
3799 while (i < csv->N_VSv) {
3800 if (LocalHead) fprintf(SUMA_STDERR," %d? %s ...\n",
3801 i, csv->VSv[i].Name);
3802
3803 if (!csv->VSv[i].Name || !state) {
3804 SUMA_LH("Null Name or State \n");
3805 SUMA_RETURN (-1);
3806 }
3807 if (strcmp(csv->VSv[i].Name, state) == 0) {
3808 if (LocalHead)
3809 fprintf(SUMA_STDERR,"%s: FOUND, i=%d!\n", FuncName, i);
3810 SUMA_RETURN (i);
3811 }
3812 if (strcmp(state,"ANY_ANATOMICAL") == 0 && csv->VSv[i].AnatCorrect) {
3813 if (LocalHead)
3814 fprintf(SUMA_STDERR,"%s: FOUND, i=%d for ANY_ANATOMICAL!\n",
3815 FuncName, i);
3816 SUMA_RETURN (i);
3817 }
3818 ++i;
3819 }
3820 } else {
3821 if (LocalHead) fprintf(SUMA_STDERR,"%s: Searching for: %s, %s...\n",
3822 FuncName, state, ForceGroup);
3823 while (i < csv->N_VSv) {
3824 if (LocalHead) fprintf(SUMA_STDERR," %d? %s, %s ...\n",
3825 i, csv->VSv[i].Name, csv->VSv[i].Group);
3826 if (!csv->VSv[i].Name || !state || !csv->CurGroupName) {
3827 SUMA_LH("Null Name or State or CurGroupName.\n");
3828 SUMA_RETURN (-1);
3829 }
3830 if (strcmp(csv->VSv[i].Name, state) == 0 &&
3831 (strcmp(csv->VSv[i].Group, ForceGroup) == 0 ||
3832 strcmp(csv->VSv[i].Group, "ANY") == 0 ) ) {
3833 if (LocalHead) fprintf(SUMA_STDERR,"%s: FOUND, i=%d!\n",
3834 FuncName, i);
3835 SUMA_RETURN (i);
3836 }
3837 ++i;
3838 }
3839 }
3840 SUMA_RETURN (-1);
3841 }
3842
3843 /*!
3844 Return the viewer state for a particular displayable object
3845 dov_id (int): Identifier of object by index into SUMAg_DOv
3846 cSV (SUMA_SurfaceViewer *): Viewer in question. I null, all
3847 viewers get the treatment
3848 addifmissing (int): If 1 then add state if not found
3849
3850 Returns the index of the state into cSV->VSv, if cSV was null,
3851 the index would be into SUMAg_SVv[0]
3852 -1 if none were found and adding was not allowed.
3853 -2 in error
3854 */
SUMA_Which_iDO_State(int dov_id,SUMA_SurfaceViewer * cSV,int addifmissing)3855 int SUMA_Which_iDO_State(int dov_id, SUMA_SurfaceViewer *cSV, int addifmissing)
3856 {
3857 static char FuncName[]={"SUMA_Which_iDO_State"};
3858 int is = -2, do_all=0, iic, isd;
3859 char *sid=NULL;
3860 SUMA_Boolean LocalHead = NOPE;
3861
3862 SUMA_ENTRY;
3863
3864 if (SUMAg_N_SVv <= 0) SUMA_RETURN(is);
3865 if (!cSV) do_all=1;
3866 iic=SUMAg_N_SVv-1;
3867 do {
3868 if (do_all) cSV = &(SUMAg_SVv[iic]);
3869 is = SUMA_WhichState (SUMA_iDO_state(dov_id), cSV, SUMA_iDO_group(dov_id));
3870 SUMA_LHv("is %d, addifmissing %d", is, addifmissing);
3871 if (is < 0 && addifmissing) { /* add state, it is a new one */
3872 SUMA_LHv("For DO %s, type %s\n State:%s to be added, group %s\n",
3873 iDO_label(dov_id), iDO_typename(dov_id),
3874 iDO_state(dov_id), iDO_group(dov_id));
3875 SUMA_New_ViewState (cSV);
3876 is = cSV->N_VSv-1;
3877 cSV->VSv[is].Name = SUMA_copy_string(SUMA_iDO_state(dov_id));
3878 cSV->VSv[is].AnatCorrect = SUMA_is_iDO_AnatCorrect(dov_id);
3879 cSV->VSv[is].Group = iDO_group(dov_id);
3880 if (!cSV->VSv[is].Name ||
3881 !cSV->VSv[is].Group) {
3882 SUMA_S_Err("Failed to allocate for cSV->VSv[is]."
3883 "Name or .Group.");
3884 SUMA_RETURN (NOPE);
3885 }
3886 cSV->VSv[is].N_MembDO = 1;
3887 cSV->VSv[is].MembDO =
3888 (SUMA_DO_LOCATOR *)SUMA_calloc(cSV->VSv[is].N_MembDO,
3889 sizeof(SUMA_DO_LOCATOR));
3890 cSV->VSv[is].MembDO[cSV->VSv[is].N_MembDO-1].dov_ind = dov_id;
3891 sid = iDO_idcode(dov_id);
3892 strcpy(cSV->VSv[is].MembDO[cSV->VSv[is].N_MembDO-1].idcode_str, sid);
3893 if (LocalHead) {
3894 char *s = SUMA_ViewStateInfo (&(cSV->VSv[is]), 0);
3895 SUMA_LHv("State Info of cSV->VSv[%d] now:\n%s\n",is, s);
3896 SUMA_ifree(s);
3897 }
3898 }
3899 if (!cSV->State && cSV->N_VSv) {
3900 if (is < 0) isd = 0;
3901 else isd = is;
3902 /* happens if loading DOs without surfaces already loaded
3903 Should always have something decent if you can*/
3904 SUMA_LHv(
3905 "No state yet for cSV %p, defaulting to cSV->VSv[%d].Name -->%s<--\n",
3906 cSV, isd, cSV->VSv[isd].Name);
3907 cSV->State = cSV->VSv[isd].Name;
3908 cSV->iState = isd;
3909 }
3910 --iic;
3911 } while (do_all && iic >= 0);
3912
3913 SUMA_RETURN(is);
3914 }
3915
3916
3917 /*!
3918 register the different view states and surfaces belonging to different
3919 view states in the surface viewer's structure
3920 Essentially, it creates the vector VSv that is a part of the surface
3921 viewer structure
3922 */
SUMA_RegisterSpecSO(SUMA_SurfSpecFile * Spec,SUMA_SurfaceViewer * csv,SUMA_DO * dov,int N_dov,int viewopt)3923 SUMA_Boolean SUMA_RegisterSpecSO (SUMA_SurfSpecFile *Spec,
3924 SUMA_SurfaceViewer *csv,
3925 SUMA_DO* dov, int N_dov, int viewopt)
3926 {
3927 static char FuncName[]={"SUMA_RegisterSpecSO"};
3928 int is, i, old_N_VSv = 0;
3929 char *sid=NULL;
3930 SUMA_SurfaceObject * SO;
3931 SUMA_Boolean LocalHead = NOPE;
3932
3933 SUMA_ENTRY;
3934
3935 if (!viewopt) viewopt = UPDATE_ALL_VIEWING_PARAMS_MASK;
3936
3937 if (LocalHead && SUMA_WhichSV(csv, SUMAg_SVv, SUMA_MAX_SURF_VIEWERS) != 0) {
3938 fprintf(SUMA_STDERR,"%s: Muted for viewer[%c]\n",
3939 FuncName, SUMA_SV_CHAR(csv) );
3940 /* turn off the LocalHead, too much output*/
3941 LocalHead = NOPE;
3942 }
3943
3944
3945 /* allocate for space depending on the number of states present */
3946
3947 if (LocalHead) fprintf(SUMA_STDERR,"%s: Entering, Spec->Group[0] = %s ...\n",
3948 FuncName, Spec->Group[0]);
3949
3950 if (Spec->N_Groups != 1) {
3951 SUMA_SL_Err("A spec file is to have 1 and only 1 group in it");
3952 SUMA_RETURN(NOPE);
3953 }
3954
3955 #if 0
3956 /* the old way */
3957 if (!csv->VSv) { /* first pass */
3958 csv->VSv = SUMA_Alloc_ViewState (Spec->N_States);
3959 if (csv->VSv == NULL) {
3960 fprintf(SUMA_STDERR,
3961 "Error %s: Failed to allocate for VSv.\n", FuncName);
3962 SUMA_RETURN (NOPE);
3963 }
3964 csv->N_VSv = 0;
3965 }
3966 #endif
3967
3968 /* register the various states from each SO in DOv */
3969 SUMA_LHv("Cycling through DOvs, looking for surfaces/DOs of group %s\n",
3970 Spec->Group[0]);
3971 old_N_VSv = csv->N_VSv;
3972 for (i=0; i < N_dov; ++i) {
3973 switch (dov[i].ObjectType) {
3974 case SO_type:
3975 if (SUMA_isSO_G(dov[i], Spec->Group[0])) {
3976 SO = (SUMA_SurfaceObject *)(dov[i].OP);
3977 is = SUMA_WhichState (SO->State, csv, SO->Group);
3978 if (is < 0) {
3979 /* add state if it is a new one */
3980 /* make room */
3981 if (LocalHead) {
3982 fprintf(SUMA_STDERR,
3983 "%s: For %s\nState:%s,Group:%s to be added\n",
3984 FuncName, SO->Label, SO->State, SO->Group);
3985 }
3986 SUMA_New_ViewState (csv);
3987 csv->VSv[csv->N_VSv-1].Name = SUMA_copy_string(SO->State);
3988 csv->VSv[csv->N_VSv-1].AnatCorrect = SO->AnatCorrect;
3989 csv->VSv[csv->N_VSv-1].Group = SUMA_copy_string(SO->Group);
3990 if (!csv->VSv[csv->N_VSv-1].Name ||
3991 !csv->VSv[csv->N_VSv-1].Group) {
3992 SUMA_S_Err("Failed to allocate for csv->VSv[csv->N_VSv-1]."
3993 "Name or .Group.");
3994 SUMA_RETURN (NOPE);
3995 }
3996 csv->VSv[csv->N_VSv-1].N_MembDO = 1;
3997 } else { /* old one, count it */
3998 if (LocalHead) {
3999 fprintf(SUMA_STDERR,
4000 "%s: For %s\n State:%s,Group:%s found\n",
4001 FuncName, SO->Label, SO->State, SO->Group);
4002 }
4003 csv->VSv[is].N_MembDO += 1;
4004 }
4005 }
4006 break;
4007 case TRACT_type:
4008 case MASK_type:
4009 case VO_type:
4010 case CDOM_type:
4011 case GRAPH_LINK_type:
4012 is = SUMA_WhichState (SUMA_iDO_state(i), csv,SUMA_iDO_group(i));
4013 if (is < 0) {
4014 if (LocalHead) {
4015 fprintf(SUMA_STDERR,
4016 "%s: For %s\nState:%s,Group:%s to be added\n",
4017 FuncName, iDO_label(i),
4018 SUMA_iDO_state(i), SUMA_iDO_group(i));
4019 }
4020 SUMA_New_ViewState (csv);
4021 csv->VSv[csv->N_VSv-1].Name = SUMA_copy_string(SUMA_iDO_state(i));
4022 csv->VSv[csv->N_VSv-1].AnatCorrect =
4023 SUMA_isDO_AnatCorrect(&(dov[i]));
4024 csv->VSv[csv->N_VSv-1].Group =
4025 SUMA_copy_string(SUMA_iDO_group(i));
4026 if (!csv->VSv[csv->N_VSv-1].Name ||
4027 !csv->VSv[csv->N_VSv-1].Group) {
4028 SUMA_S_Err("Failed to allocate for csv->VSv[csv->N_VSv-1]."
4029 "Name or .Group.");
4030 SUMA_RETURN (NOPE);
4031 }
4032 csv->VSv[csv->N_VSv-1].N_MembDO = 1;
4033 } else {
4034 if (LocalHead) {
4035 fprintf(SUMA_STDERR,
4036 "%s: For %s\n State:%s,Group:%s found\n",
4037 FuncName, iDO_label(i),
4038 SUMA_iDO_state(i), SUMA_iDO_group(i));
4039 }
4040 csv->VSv[is].N_MembDO += 1;
4041 }
4042 break;
4043 default:
4044 SUMA_LHv("Just ignored DO %s...\n", DO_label(dov[i].OP));
4045 break;
4046 }
4047 }
4048
4049 SUMA_LH("Allocating...");
4050
4051 /* allocate space for MembDOs
4052 counters will be reset for later use */
4053 for (i=0; i < csv->N_VSv; ++i) {
4054
4055 if (!csv->VSv[i].MembDO) {
4056 csv->VSv[i].MembDO = (SUMA_DO_LOCATOR *)
4057 SUMA_calloc(csv->VSv[i].N_MembDO,
4058 sizeof(SUMA_DO_LOCATOR));
4059 } else {
4060 csv->VSv[i].MembDO = (SUMA_DO_LOCATOR *)
4061 SUMA_realloc(csv->VSv[i].MembDO,
4062 csv->VSv[i].N_MembDO * sizeof(SUMA_DO_LOCATOR));
4063 }
4064 if (csv->VSv[i].MembDO == NULL) {
4065 SUMA_S_Err("Failed to allocate for csv->VSv[i].MembDO.\n");
4066 SUMA_RETURN (NOPE);
4067 }
4068
4069 csv->VSv[i].N_MembDO = 0;
4070 }
4071
4072
4073 /*fprintf(SUMA_STDERR,"%s: placement ...\n", FuncName);*/
4074
4075 /* place each SO where it belongs, don't worry about the group they're in */
4076 for (i=0; i < N_dov; ++i) {
4077 switch (dov[i].ObjectType) {
4078 case SO_type:
4079 SO = (SUMA_SurfaceObject *)(dov[i].OP);
4080 /* find out which state it goes in */
4081 if (!SO->State || !SO->Group) {
4082 SUMA_S_Errv("Sent me SO (%s) with null State (%s) "
4083 "or null Group (%s)!\n",
4084 SO->Label, SO->State, SO->Group);
4085 if (LocalHead) SUMA_Print_Surface_Object (SO, NULL);
4086 SUMA_RETURN (NOPE);
4087 }
4088 is = SUMA_WhichState (SO->State, csv, SO->Group);
4089 if (is < 0) {
4090 SUMA_S_Errv("This should not be.\n"
4091 "Failed to find %s %s in csv\n",
4092 SO->State, SO->Group);
4093 SUMA_RETURN (NOPE);
4094 }
4095 if (LocalHead) {
4096 fprintf (SUMA_STDERR,"%s: Trying to house %s in: State[%d]\n", \
4097 FuncName, SO->Label, is);
4098 }
4099 /* store its id as a valid member of the state */
4100 csv->VSv[is].MembDO[csv->VSv[is].N_MembDO].dov_ind = i;
4101 strcpy(csv->VSv[is].MembDO[csv->VSv[is].N_MembDO].idcode_str,
4102 SO->idcode_str);
4103 csv->VSv[is].N_MembDO += 1; /* count it, again */
4104 break;
4105 case TRACT_type:
4106 case MASK_type:
4107 case VO_type:
4108 case GRAPH_LINK_type:
4109 case CDOM_type:
4110 is = SUMA_WhichState (SUMA_iDO_state(i), csv,SUMA_iDO_group(i));
4111 if (is < 0) {
4112 SUMA_S_Errv("This should not be.\n"
4113 "Failed to find %s %s in csv\n",
4114 SUMA_iDO_state(i), SUMA_iDO_group(i));
4115 SUMA_RETURN (NOPE);
4116 }
4117 if (LocalHead) {
4118 fprintf (SUMA_STDERR,"%s: Trying to house %s in: State[%d]\n", \
4119 FuncName, SO->Label, is);
4120 }
4121 /* store its id as a valid member of the state */
4122 csv->VSv[is].MembDO[csv->VSv[is].N_MembDO].dov_ind = i;
4123 sid = iDO_idcode(i);
4124 strcpy(csv->VSv[is].MembDO[csv->VSv[is].N_MembDO].idcode_str, sid);
4125 csv->VSv[is].N_MembDO += 1; /* count it, again */
4126 break;
4127 default:
4128 if (SUMA_is_iDO_Selectable(i)) {
4129 static int nwarn=0;
4130 if (!nwarn) {
4131 SUMA_S_Warnv("Just ignored DO %s, I hope that's cool\n",
4132 iDO_label(i));
4133 }
4134 ++nwarn;
4135 }
4136 SUMA_LHv("Just ignored DO %s...\n", DO_label(dov[i].OP));
4137 break;
4138
4139 }
4140 }
4141
4142 /*fprintf(SUMA_STDERR,"%s: Leaving ...\n", FuncName);*/
4143
4144 SUMA_RETURN (YUP);
4145 }
4146
4147 /*! allocate and intialize SUMA_CommonFields
4148 No fancy allocation, No fancy macros.
4149 \sa SUMA_Free_CommonFields
4150 */
SUMA_Create_CommonFields()4151 SUMA_CommonFields * SUMA_Create_CommonFields ()
4152 {
4153 static char FuncName[]={"SUMA_Create_CommonFields"};
4154 SUMA_CommonFields *cf;
4155 int i, n, pb=-1;
4156 char *eee=NULL;
4157 float dsmw=5*60;
4158 SUMA_Boolean LocalHead = NOPE;
4159
4160 /* This is the function that creates the debugging flags,
4161 do not use them here */
4162 cf = NULL;
4163
4164 /* allocate */
4165 /* DO NOT USE SUMA_malloc here, too early for that */
4166 cf = (SUMA_CommonFields *)calloc(1,sizeof(SUMA_CommonFields));
4167
4168 if (cf == NULL) {
4169 fprintf(SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
4170 return (cf);
4171 }
4172
4173 cf->Dev = NOPE;
4174 cf->Fake_Cmap = NOPE;
4175 cf->InOut_Notify = NOPE;
4176 cf->Echo_KeyPress = NOPE;
4177 cf->InOut_Level = 0;
4178 cf->MemTrace = NOPE;
4179 cf->dcom = NULL;
4180 cf->N_dcom = 0;
4181 /* verify pointer size. I use INT_MAX and LONG_MAX
4182 to guess whether or not we have 64 bit pointers.
4183 I need to guess with #if to do proper type casting and
4184 avoid compiler warnings */
4185 cf->PointerSize = sizeof(void *);
4186 if (INT_MAX < LONG_MAX && cf->PointerSize < 8) {
4187 SUMA_S_Warn("Using INT_MAX and LONG_MAX fails to"
4188 "guess pointer size.");
4189 }
4190
4191 #ifdef USE_SUMA_MALLOC
4192 SUMA_SL_Err("NO LONGER SUPPORTED");
4193 return(NULL);
4194 cf->Mem = SUMA_Create_MemTrace();
4195 #else
4196 cf->Mem = NULL;
4197 #endif
4198
4199
4200 /* communications initialization happens in
4201 SUMA_init_ports_assignments() it cannot
4202 be done here because some parameters
4203 are not available yet.
4204 Setup here is to be sure there is no
4205 garbage lying around. */
4206 for (i=0; i<SUMA_MAX_STREAMS; ++i) {
4207 cf->ns_v[i] = NULL;
4208 cf->ns_to[i] = SUMA_WRITECHECKWAITMAX;
4209 cf->ns_flags_v[i] = 0;
4210 cf->Connected_v[i] = NOPE;
4211 cf->TrackingId_v[i] = 0;
4212 cf->NimlStream_v[i][0] = '\0';
4213 cf->HostName_v[i][0] = '\0';
4214 cf->TalkMode[i] = NI_BINARY_MODE;
4215 cf->TCP_port[i] = 0;
4216 }
4217 cf->Listening = NOPE;
4218 cf->niml_work_on = NOPE;
4219
4220 /* viewer locking */
4221 for (i=0; i<SUMA_MAX_SURF_VIEWERS; ++i) {
4222 cf->Locked[i] = SUMA_I_Lock;
4223 if (SUMA_isEnv("SUMA_LockViewers","YES")) {
4224 cf->ViewLocked[i] = YUP;
4225 } else {
4226 cf->ViewLocked[i] = NOPE;
4227 }
4228 }
4229
4230 eee = getenv("SUMA_SwapButtons_1_3");
4231 if (eee) {
4232 if (strcasecmp (eee, "YES") == 0) cf->SwapButtons_1_3 = YUP;
4233 else cf->SwapButtons_1_3 = NOPE;
4234 } else {
4235 cf->SwapButtons_1_3 = NOPE;
4236 }
4237
4238 cf->X = (SUMA_X_AllView *)calloc(1,sizeof(SUMA_X_AllView));
4239 if (!cf->X) {
4240 fprintf(SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
4241 return (NULL);
4242 }
4243 cf->X->SumaCont = SUMA_CreateSumaContStruct();
4244 cf->X->DrawROI = SUMA_CreateDrawROIStruct();
4245 cf->X->AllMaskCont = NULL;
4246 cf->X->MaskStateID = 0;
4247 cf->X->DPY_controller1 = NULL;
4248 cf->X->Cr = (SUMA_GLCONTEXT_RECORD *)calloc(1, sizeof(SUMA_GLCONTEXT_RECORD));
4249 cf->X->Cr->last_context_DPY = NULL;
4250 cf->X->Cr->last_context_WDW = -1;
4251 cf->X->Cr->setting_function[0] = '\0';
4252 cf->X->Cr->widget_label[0] = '\0';
4253
4254 eee = getenv("SUMA_ColorPattern");
4255 if (eee) {
4256 if (strcmp (eee, "AFNI") == 0) {
4257 cf->X->X_Resources = SXR_Afni;
4258 if (LocalHead) fprintf(SUMA_STDERR,"%s: Afni resources\n", FuncName);
4259 } else if (strcmp (eee, "EURO") == 0) {
4260 cf->X->X_Resources = SXR_Euro;
4261 if (LocalHead) fprintf(SUMA_STDERR,"%s: Euro resources\n", FuncName);
4262 } else if (strcmp (eee, "BONAIRE") == 0) {
4263 cf->X->X_Resources = SXR_Bonaire;
4264 if (LocalHead) fprintf(SUMA_STDERR,"%s: Bonaire resources\n", FuncName);
4265 } else if (strcmp (eee, "DEFAULT") == 0) {
4266 cf->X->X_Resources = SXR_default;
4267 if (LocalHead) fprintf(SUMA_STDERR,"%s: default resources\n", FuncName);
4268 } else if (strcmp (eee, "PRINT") == 0) {
4269 cf->X->X_Resources = SXR_Print;
4270 if (LocalHead) fprintf(SUMA_STDERR,"%s: Print resources\n", FuncName);
4271 } else {
4272 cf->X->X_Resources = SXR_Euro;
4273 fprintf(SUMA_STDERR,
4274 "%s:\nUnrecognized option %s for SUMA_ColorPattern.\n"
4275 "Using default = EURO\n", FuncName, eee);
4276 }
4277 } else {
4278 cf->X->X_Resources = SXR_Euro;
4279 if (LocalHead)
4280 fprintf( SUMA_STDERR,
4281 "%s: Undefined environment. Using default\n", FuncName);
4282 }
4283
4284 cf->X->Help_TextShell = NULL;
4285 cf->X->Help_Cmap_TextShell = NULL;
4286 cf->X->Help_Plot_TextShell = NULL;
4287 cf->X->Whereami_TextShell = NULL;
4288 cf->X->Log_TextShell = NULL;
4289 cf->X->FileSelectDlg = NULL;
4290 cf->X->N_ForeSmooth_prmpt = NULL;
4291 cf->X->N_FinalSmooth_prmpt = NULL;
4292 cf->X->Clip_prmpt = NULL;
4293 cf->X->ClipObj_prmpt = NULL;
4294 cf->X->TableTextFontList = NULL;
4295 cf->X->CommonSurfContTLW = NULL;
4296 cf->X->ButtonDown = 0;
4297 cf->X->roffx = -1; /* Not set */
4298 cf->X->roffy = -1; /* Not set */
4299 {
4300 char *eee = getenv("SUMA_WindowOffset");
4301 float fv3[3];
4302 if (eee) {
4303 if (!strcmp(eee,"Auto")) {
4304 cf->X->roffx = cf->X->roffy = -1;
4305 } else {
4306 if (SUMA_StringToNum (eee, (void *)fv3, 2,1) != 2) {
4307 SUMA_S_Err("Syntax error in environment\n"
4308 "variable SUMA_WindowOffset of (%s). "
4309 "Setting offset to 0", eee);
4310 cf->X->roffx = cf->X->roffy = 0;
4311 } else {
4312 cf->X->roffx = (int)fv3[0];
4313 cf->X->roffy = (int)fv3[1];
4314 }
4315 }
4316 } else { /* leave it for auto setup */
4317 cf->X->roffx = cf->X->roffy = -1;
4318 }
4319 }
4320 cf->X->SC_Notebook = NULL;
4321 cf->X->SameSurfContOpen = 0;
4322 { /* Changed default to YES March 05 2014 */
4323 char *eee = getenv("SUMA_SameSurfCont");
4324 if (eee) {
4325 if (strcmp(eee,"NO") == 0) cf->X->UseSameSurfCont = NOPE;
4326 else if (strcmp(eee,"YES") == 0) cf->X->UseSameSurfCont = YUP;
4327 else {
4328 fprintf (SUMA_STDERR,
4329 "Warning %s:\n"
4330 "Bad value for environment variable UseSameSurfCont\n"
4331 "Assuming default of YES", FuncName);
4332 cf->X->UseSameSurfCont = YUP;
4333 }
4334 } else cf->X->UseSameSurfCont = YUP;
4335 }
4336 {
4337 char *eee = getenv("SUMA_HomeAfterPrying");
4338 if (eee) {
4339 if (strcmp(eee,"NO") == 0) cf->Home_After_Prying = NOPE;
4340 else if (strcmp(eee,"YES") == 0) cf->Home_After_Prying = YUP;
4341 else {
4342 fprintf (SUMA_STDERR,
4343 "Warning %s:\n"
4344 "Bad value for environment variable SUMA_HomeAfterPrying\n"
4345 "Assuming default of YES", FuncName);
4346 cf->Home_After_Prying = YUP;
4347 }
4348 } else cf->Home_After_Prying = YUP;
4349 }
4350 {
4351 char *eee = getenv("SUMA_NumForeSmoothing");
4352 if (eee) {
4353 int rotval = (int)strtod(eee, NULL);
4354 if (rotval >= 0) cf->X->NumForeSmoothing = rotval;
4355 else {
4356 fprintf (SUMA_STDERR,
4357 "Warning %s:\n"
4358 "Bad value for environment variable SUMA_NumForeSmoothing\n"
4359 "Assuming default of 0", FuncName);
4360 cf->X->NumForeSmoothing = 0;
4361 }
4362 } else cf->X->NumForeSmoothing = 0;
4363 }
4364
4365 {
4366 char *eee = getenv("SUMA_NumFinalSmoothing");
4367 if (eee) {
4368 int rotval = (int)strtod(eee, NULL);
4369 if (rotval >= 0) cf->X->NumFinalSmoothing = rotval;
4370 else {
4371 fprintf (SUMA_STDERR,
4372 "Warning %s:\n"
4373 "Bad value for environment variable SUMA_NumFinalSmoothing\n"
4374 "Assuming default of 0", FuncName);
4375 cf->X->NumFinalSmoothing = 0;
4376 }
4377 } else cf->X->NumFinalSmoothing = 0;
4378 }
4379
4380 {
4381 char *eee = getenv("SUMA_ThresholdScalePower");
4382 if (eee) {
4383 cf->SUMA_ThrScalePowerBias = (int)strtod(eee, NULL);
4384 if (cf->SUMA_ThrScalePowerBias < 2) {
4385 fprintf (SUMA_STDERR, "Warning %s:\n"
4386 "Bad value for environment variable\n"
4387 "SUMA_ThresholdScalePower.\n"
4388 "Assuming default of 2", FuncName);
4389 cf->SUMA_ThrScalePowerBias = 2;
4390 }
4391 } else cf->SUMA_ThrScalePowerBias = 2;
4392 }
4393
4394
4395 {
4396 char *eee = getenv("SUMA_SnapshotOverSampling");
4397 if (eee) {
4398 cf->SUMA_SnapshotOverSampling = (int)strtod(eee, NULL);
4399 if ( cf->SUMA_SnapshotOverSampling < 1 ||
4400 cf->SUMA_SnapshotOverSampling>10) {
4401 fprintf (SUMA_STDERR, "Warning %s:\n"
4402 "Bad value for environment variable\n"
4403 "SUMA_SnapshotOverSampling.\n"
4404 "Assuming default of 1", FuncName);
4405 cf->SUMA_SnapshotOverSampling = 1;
4406 }
4407 } else cf->SUMA_SnapshotOverSampling = 1;
4408 }
4409 {
4410 char *eee = getenv("SUMA_WarnBeforeClose");
4411 if (eee) {
4412 if (strcmp(eee,"NO") == 0) cf->X->WarnClose = NOPE;
4413 else if (strcmp(eee,"YES") == 0) cf->X->WarnClose = YUP;
4414 else {
4415 fprintf (SUMA_STDERR,
4416 "Warning %s:\n"
4417 "Bad value for environment variable SUMA_WarnBeforeClose\n"
4418 "Assuming default of YES", FuncName);
4419 cf->X->WarnClose = YUP;
4420 }
4421 } else cf->X->WarnClose = YUP;
4422 }
4423 cf->X->SwitchCmapLst = NULL;
4424
4425 cf->MessageList = SUMA_CreateMessageList ();
4426 #ifdef USE_SUMA_MALLOC
4427 SUMA_SL_Err("NO LONGER SUPPORTED");
4428 return(NULL);
4429 /*SUMA_ShowMemTrace (cf->Mem, NULL);*/
4430 #endif
4431 cf->ROI_mode = NOPE;
4432 cf->ROI_contmode = YUP;
4433 cf->Pen_mode = NOPE;
4434
4435 cf->nimlROI_Datum_type =
4436 NI_rowtype_define("SUMA_NIML_ROI_DATUM", "int,int,int,int[#3]");
4437 if (cf->nimlROI_Datum_type < 0) {
4438 fprintf(SUMA_STDERR,"Error %s: Failed defining niml code.", FuncName);
4439 return(NULL);
4440 }
4441 if (LocalHead)
4442 fprintf(SUMA_STDERR, "%s: roi_type code = %d\n",
4443 FuncName, cf->nimlROI_Datum_type) ;
4444
4445 cf->ROI_CM = NULL;
4446 cf->ROI_FillMode = SUMA_ROI_FILL_TO_THISROI;
4447 cf->ROI2afni = NOPE;
4448
4449 eee = getenv("SUMA_ColorMixingMode");
4450 if (eee) {
4451 if (strcmp (eee, "ORIG") == 0) {
4452 cf->ColMixMode = SUMA_ORIG_MIX_MODE;
4453 } else if (strcmp (eee, "MOD1") == 0) {
4454 cf->ColMixMode = SUMA_4AML;
4455 } else {
4456 cf->ColMixMode = SUMA_ORIG_MIX_MODE;
4457 fprintf(SUMA_STDERR,
4458 "%s:\nUnrecognized option %s for SUMA_ColorMixingMode.\n"
4459 "Using default = ORIG\n", FuncName, eee);
4460 }
4461 } else {
4462 cf->ColMixMode = SUMA_ORIG_MIX_MODE;
4463 }
4464
4465
4466 cf->GroupList = NULL;
4467 cf->N_Group = -1;
4468 SUMA_RegisterGroup(cf,"ANY"); /* register a default group that would
4469 match any group*/
4470
4471 cf->scm = NULL;
4472 cf->DsetList = (DList *)SUMA_calloc(1,sizeof(DList));
4473 dlist_init (cf->DsetList, SUMA_FreeDset);
4474 {
4475 char *eee = getenv("SUMA_AllowDsetReplacement");
4476 if (eee) {
4477 if (strcmp(eee,"NO") == 0) cf->Allow_Dset_Replace = NOPE;
4478 else if (strcmp(eee,"YES") == 0) cf->Allow_Dset_Replace = YUP;
4479 else {
4480 fprintf (SUMA_STDERR,
4481 "Warning %s:\n"
4482 "Bad value for environment variable SUMA_AllowDsetReplacement\n"
4483 "Assuming default of YES", FuncName);
4484 cf->Allow_Dset_Replace = YUP;
4485 }
4486 } else cf->Allow_Dset_Replace = YUP;
4487 }
4488
4489 cf->IgnoreVolreg = NOPE;
4490 cf->isGraphical = NOPE;
4491
4492 cf->N_ClipPlanes = 0;
4493 for (i=0; i<SUMA_MAX_N_CLIP_PLANES; ++i) {
4494 cf->ClipPlanes[4*i] =
4495 cf->ClipPlanes[4*i+1] =
4496 cf->ClipPlanes[4*i+2] =
4497 cf->ClipPlanes[4*i+3]= 0.0;
4498 cf->ClipPlaneType[i] = SUMA_NO_CLIP_PLANE_TYPE;
4499 cf->ClipPlanesLabels[i][0]='\0';
4500 }
4501
4502 for (i=0; i<SUMA_MAX_N_TIMER;++i) {
4503 cf->Timer[i].name[0] = '\0';
4504 cf->Timer[i].lastcall = -1.0;
4505 }
4506 cf->N_Timer = 0;
4507
4508 {
4509 char *eee = getenv("SUMA_NoDuplicatesInRecorder");
4510 if (eee) {
4511 if (strcmp(eee,"NO") == 0) cf->NoDuplicatesInRecorder = 0;
4512 else if (strcmp(eee,"YES") == 0) cf->NoDuplicatesInRecorder = 1;
4513 else {
4514 fprintf (SUMA_STDERR, "Warning %s:\n"
4515 "Bad value for environment variable:\n"
4516 " SUMA_NoDuplicatesInRecorder\n"
4517 "Assuming default of YES", FuncName);
4518 cf->NoDuplicatesInRecorder = 1;
4519 }
4520 } else cf->NoDuplicatesInRecorder = 1;
4521 }
4522 /* if (SUMAg_CF->NoDuplicatesInRecorder)
4523 SNAP_NoDuplicates();
4524 else SNAP_OkDuplicates();
4525 */
4526 cf->cwd = SUMA_getcwd();
4527
4528 {
4529 char *eee = getenv("SUMA_ColorMapRotationFraction");
4530 if (eee) {
4531 cf->CmapRotaFrac = atof(eee);
4532 if (cf->CmapRotaFrac < 0.01 || cf->CmapRotaFrac > 0.99) {
4533 SUMA_S_Warn(
4534 "Values for environment variable SUMA_ColorMapRotationFraction\n"
4535 "are outside valid range of [0.01 .. 0.99]. \n"
4536 "Setting value to default of 0.05.");
4537 cf->CmapRotaFrac = 0.05;
4538 }
4539 } else {
4540 cf->CmapRotaFrac = 0.05;
4541 }
4542 }
4543 {
4544 char *eee = getenv("SUMA_Transparency_Step");
4545 if (eee) {
4546 cf->TransModeStep = atof(eee);
4547 if (cf->TransModeStep < 1 || cf->TransModeStep > 8) {
4548 SUMA_S_Warn(
4549 "Values for environment variable SUMA_Transparency_Step\n"
4550 "are outside valid range of [1 .. 8]. \n"
4551 "Setting value to default of 4.");
4552 cf->TransModeStep = 4;
4553 }
4554 } else {
4555 cf->TransModeStep = 4;
4556 }
4557 }
4558
4559 cf->xforms = (DList *)SUMA_calloc(1,sizeof(DList));
4560 dlist_init (cf->xforms, SUMA_FreeXform);
4561 cf->callbacks = (DList *)SUMA_calloc(1,sizeof(DList));
4562 dlist_init (cf->callbacks, SUMA_FreeCallback);
4563 cf->HoldClickCallbacks = 0;
4564 cf->PointerLastInViewer = -1;
4565
4566 cf->giset = NULL;
4567 cf->ITset = NULL;
4568
4569 cf->autorecord = SUMA_SetAutoRecord(getenv("SUMA_AutoRecordPrefix"));
4570
4571 cf->SaveList = NULL;
4572
4573 cf->YokeIntToNode = 0;
4574
4575 cf->lev = NULL;
4576 return (cf);
4577
4578 }
4579
SUMA_SetAutoRecord(char * pref)4580 SUMA_PARSED_NAME *SUMA_SetAutoRecord(char *pref)
4581 {
4582 static char FuncName[]={"SUMA_SetAutoRecord"};
4583 SUMA_PARSED_NAME *pn=NULL;
4584
4585 SUMA_ENTRY;
4586
4587 if (!pref) SUMA_RETURN(SUMA_ParseFname("./autorecord", NULL));
4588
4589 if (!(pn = SUMA_ParseFname(pref, NULL))) {
4590 SUMA_S_Errv("Failed to parse %s\n", pref);
4591 SUMA_RETURN(SUMA_ParseFname("./autorecord", NULL));
4592 }
4593
4594
4595 SUMA_RETURN(pn);
4596 }
4597
4598 /*!
4599 \brief creates the structure for storing the radio buttons used to control viewer locking
4600 Do not use CommonFields structure here.
4601
4602 */
SUMA_CreateLock_rbg(int N_rb_group,int N_but)4603 SUMA_rb_group *SUMA_CreateLock_rbg (int N_rb_group, int N_but)
4604 {
4605 static char FuncName[]={"SUMA_CreateLock_rbg"};
4606 SUMA_rb_group *Lock_rb;
4607
4608 Lock_rb = (SUMA_rb_group *) calloc(1,sizeof(SUMA_rb_group));
4609 if (!Lock_rb) {
4610 fprintf (SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
4611 return(NULL);
4612 }
4613 Lock_rb->N_rb_group = N_rb_group;
4614 Lock_rb->N_but = N_but;
4615 Lock_rb->tb = (Widget *) calloc(N_rb_group*N_but, sizeof(Widget));
4616 Lock_rb->rb = (Widget *) calloc(N_rb_group, sizeof(Widget));
4617 Lock_rb->atb = (Widget *) calloc(N_but, sizeof(Widget));
4618 Lock_rb->arb = NULL;
4619 if (!Lock_rb->tb || !Lock_rb->rb || !Lock_rb->atb) {
4620 fprintf (SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
4621 return(NULL);
4622 }
4623 return(Lock_rb);
4624
4625 }
4626
4627 /*!
4628 free SUMA_rb_group *
4629 Do not use CommonFields structure here.
4630 */
SUMA_FreeLock_rbg(SUMA_rb_group * Lock_rb)4631 void * SUMA_FreeLock_rbg (SUMA_rb_group *Lock_rb)
4632 {
4633 static char FuncName[]={"SUMA_FreeLock_rb"};
4634
4635 if (Lock_rb->rb) free(Lock_rb->rb);
4636 if (Lock_rb->tb) free(Lock_rb->tb);
4637 if (Lock_rb->atb) free (Lock_rb->atb);
4638 if (Lock_rb) free(Lock_rb);
4639
4640 return (NULL);
4641 }
4642
4643 /*!
4644 \brief DrawROI = SUMA_CreateDrawROIStruct();
4645 allocates and initializes structure of type
4646
4647 \return SUMA_X_DrawROI *
4648 */
SUMA_CreateDrawROIStruct(void)4649 SUMA_X_DrawROI *SUMA_CreateDrawROIStruct (void)
4650 {
4651 static char FuncName[]={"SUMA_CreateDrawROIStruct"};
4652 SUMA_X_DrawROI *DrawROI = NULL;
4653
4654 /* do not use commonfields related stuff here for obvious reasons */
4655 DrawROI = (SUMA_X_DrawROI *)calloc (1, sizeof(SUMA_X_DrawROI));
4656 DrawROI->AppShell = NULL;
4657 DrawROI->ROIval =
4658 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4659 DrawROI->ROIlbl =
4660 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4661 DrawROI->curDrawnROI = NULL; /* DO NOT FREE THIS POINTER */
4662 DrawROI->SwitchROIlst = NULL;
4663 DrawROI->Delete_first = YUP;
4664 DrawROI->SaveMode = SW_DrawROI_SaveModeNIML;
4665 DrawROI->SaveWhat = SW_DrawROI_SaveWhatRelated;
4666 DrawROI->WhatDist = SW_DrawROI_WhatDistNothing;
4667 return (DrawROI);
4668 }
4669
4670 /*!
4671 \brief SumaCont = SUMA_CreateSumaContStruct();
4672 allocates and initializes structure of type SUMA_X_SumaCont
4673 \return SUMA_X_SumaCont *
4674
4675 */
SUMA_CreateSumaContStruct(void)4676 SUMA_X_SumaCont *SUMA_CreateSumaContStruct (void)
4677 {
4678 static char FuncName[]={"SUMA_CreateSumaContStruct"};
4679 SUMA_X_SumaCont *SumaCont = NULL;
4680 /* do not use commonfields related stuff here for obvious reasons */
4681 SumaCont = (SUMA_X_SumaCont *)calloc(1,sizeof(SUMA_X_SumaCont));
4682 SumaCont->AppShell = NULL;
4683 SumaCont->quit_pb = NULL;
4684 SumaCont->quit_first = YUP;
4685 SumaCont->Lock_rbg = SUMA_CreateLock_rbg (SUMA_MAX_SURF_VIEWERS, 3);
4686 if (!SumaCont->Lock_rbg) {
4687 fprintf (SUMA_STDERR,
4688 "Error %s: Failed in SUMA_CreateLock_rb.\n", FuncName);
4689 return (NULL);
4690 }
4691 SumaCont->LockView_tbg =
4692 (Widget *)calloc (SUMA_MAX_SURF_VIEWERS, sizeof(Widget));
4693 SumaCont->LockAllView_tb = NULL;
4694 SumaCont->SumaInfo_TextShell = NULL;
4695 return (SumaCont);
4696 }
4697
4698 /*!
4699 \brief frees structure SUMA_X_SumaCont, returns null
4700
4701 */
SUMA_FreeSumaContStruct(SUMA_X_SumaCont * SumaCont)4702 void *SUMA_FreeSumaContStruct (SUMA_X_SumaCont *SumaCont)
4703 {
4704 static char FuncName[]={"SUMA_FreeSumaContStruct"};
4705
4706 /* do not use commonfields related stuff here for obvious reasons */
4707 if (SumaCont->Lock_rbg) SUMA_FreeLock_rbg (SumaCont->Lock_rbg);
4708 if (SumaCont->LockView_tbg) free (SumaCont->LockView_tbg);
4709 if (SumaCont->SumaInfo_TextShell) { SUMA_SL_Warn("SumaCont->SumaInfo_TextShell is not being freed") };
4710 if (SumaCont) free(SumaCont);
4711 return (NULL);
4712 }
4713
4714 /*!
4715 \brief frees structure SUMA_X_DrawROI, returns null
4716 */
SUMA_FreeDrawROIStruct(SUMA_X_DrawROI * DrawROI)4717 void *SUMA_FreeDrawROIStruct (SUMA_X_DrawROI *DrawROI)
4718 {
4719 static char FuncName[]={"SUMA_FreeDrawROIStruct"};
4720
4721 /* do not use commonfields related stuff here for obvious reasons,
4722 Well, you can, it is no big deal, memory tracing variables are wiped out at the end*/
4723 if (DrawROI->ROIval) free (DrawROI->ROIval);
4724 if (DrawROI->ROIlbl) free (DrawROI->ROIlbl);
4725 if (DrawROI->SwitchROIlst) SUMA_FreeScrolledList (DrawROI->SwitchROIlst);
4726 if (DrawROI) free(DrawROI);
4727
4728 return (NULL);
4729 }
4730 /*!
4731 \brief ViewCont = SUMA_CreateViewContStruct();
4732 allocates and initializes structure of type SUMA_X_ViewCont
4733 \return SUMA_X_ViewCont *
4734
4735 */
SUMA_CreateViewContStruct(void)4736 SUMA_X_ViewCont *SUMA_CreateViewContStruct (void)
4737 {
4738 static char FuncName[]={"SUMA_CreateViewContStruct"};
4739 SUMA_X_ViewCont *ViewCont = NULL;
4740 /* do not use commonfields related stuff here for obvious reasons */
4741 ViewCont = (SUMA_X_ViewCont *)calloc(1,sizeof(SUMA_X_ViewCont));
4742 ViewCont->TopLevelShell = NULL;
4743 ViewCont->ViewerInfo_TextShell = NULL;
4744 ViewCont->Info_lb = NULL;
4745 ViewCont->ViewerInfo_pb = NULL;
4746 ViewCont->Mainform = NULL;
4747 ViewCont->SwitchGrouplst = NULL;
4748 ViewCont->SwitchStatelst = NULL;
4749 ViewCont->ViewerInfo_pb = NULL;
4750 return (ViewCont);
4751 }
4752
4753 /*!
4754 \brief frees structure SUMA_X_ViewCont, returns null
4755
4756 */
SUMA_FreeViewContStruct(SUMA_X_ViewCont * ViewCont)4757 void *SUMA_FreeViewContStruct (SUMA_X_ViewCont *ViewCont)
4758 {
4759 static char FuncName[]={"SUMA_FreeViewContStruct"};
4760
4761 /* do not use commonfields related stuff here for obvious reasons */
4762 if (ViewCont->TopLevelShell) {
4763 SUMA_SL_Warn("ViewCont->TopLevelShell is not being freed");
4764 }
4765 if (ViewCont->SwitchGrouplst)
4766 ViewCont->SwitchGrouplst = SUMA_FreeScrolledList(ViewCont->SwitchGrouplst);
4767 if (ViewCont->SwitchStatelst)
4768 ViewCont->SwitchStatelst = SUMA_FreeScrolledList(ViewCont->SwitchStatelst);
4769 if (ViewCont) free(ViewCont);
4770 return (NULL);
4771 }
4772
4773 /*!
4774 \brief SurfCont = SUMA_CreateSurfContStruct();
4775 allocates and initializes structure of type SUMA_X_SurfCont
4776 \return SUMA_X_SurfCont *
4777
4778 This function is now creating controllers for other types of
4779 displayable objects too.
4780 */
SUMA_CreateSurfContStruct(char * idcode_str,SUMA_DO_Types tp)4781 SUMA_X_SurfCont *SUMA_CreateSurfContStruct (char *idcode_str, SUMA_DO_Types tp)
4782 {
4783 static char FuncName[]={"SUMA_CreateSurfContStruct"};
4784 SUMA_X_SurfCont *SurfCont = NULL;
4785 char wname[64]={"UNNAMED"}, *s=NULL;
4786
4787 /* do not use commonfields related stuff here for obvious reasons */
4788 SurfCont = (SUMA_X_SurfCont *)malloc(sizeof(SUMA_X_SurfCont));
4789 memset(SurfCont, 0, sizeof(SUMA_X_SurfCont));
4790
4791 /* take care of linking fields */
4792 if (idcode_str) sprintf(SurfCont->owner_id, "%s", idcode_str);
4793 else SurfCont->owner_id[0] = '\0';
4794 SurfCont->N_links = 0;
4795 SurfCont->Open = 0;
4796 SurfCont->LinkedPtrType = SUMA_LINKED_SURFCONT_TYPE;
4797 SurfCont->do_type = tp;
4798
4799 SurfCont->DsetMap_fr = NULL;
4800 SurfCont->ColPlane_fr = NULL;
4801 SurfCont->DispFrame = NULL;
4802 SurfCont->SurfFrame = NULL;
4803 SurfCont->Xhair_fr = NULL;
4804 SurfCont->TLS = NULL;
4805 SurfCont->Mainform = NULL;
4806 SurfCont->Page = NULL;
4807 SurfCont->SurfInfo_pb = NULL;
4808 SurfCont->SurfInfo_label = NULL;
4809 SurfCont->SurfInfo_TextShell = NULL;
4810 SurfCont->SurfContPage_label = NULL;
4811 SurfCont->SurfContPage =
4812 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4813 SurfCont->NodeRadGainAF =
4814 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4815 SurfCont->EdgeThickGainAF =
4816 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4817 SurfCont->ColPlaneOrder =
4818 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4819 SurfCont->ColPlaneOpacity =
4820 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4821 SurfCont->ColPlaneDimFact =
4822 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4823 SurfCont->ColPlaneAlphaThresh =
4824 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4825 SurfCont->TractMaskGray =
4826 (SUMA_ARROW_TEXT_FIELD *)calloc(1, sizeof(SUMA_ARROW_TEXT_FIELD));
4827
4828 s = SUMA_do_type_2_contwname(SurfCont->do_type);
4829 snprintf(wname,63,"%s->XhairTable", s);
4830 SurfCont->XhairTable = SUMA_AllocTableField(wname);
4831 snprintf(wname,63,"%s->MaskTable", s);
4832 SurfCont->MaskTable = SUMA_AllocTableField(wname);
4833 snprintf(wname,63,"%s->MaskEvalTable", s);
4834 SurfCont->MaskEvalTable = SUMA_AllocTableField(wname);
4835 SurfCont->MaskEval_tb = NULL;
4836 snprintf(wname,63,"%s->MaskLenTable", s);
4837 SurfCont->MaskLenTable = SUMA_AllocTableField(wname);
4838 SurfCont->MaskLen_tb = NULL;
4839 SurfCont->UseMaskEval = 0;
4840 SurfCont->DeleteMask_pb = NULL;
4841 SurfCont->DeleteMask_first = YUP;
4842 SurfCont->DeleteMask_row = -1;
4843 snprintf(wname,63,"%s->SetRangeTable", s);
4844 SurfCont->SetRangeTable = SUMA_AllocTableField(wname);
4845 snprintf(wname,63,"%s->SetThrScaleTable", s);
4846 SurfCont->SetThrScaleTable = SUMA_AllocTableField(wname);
4847 snprintf(wname,63,"%s->RangeTable", s);
4848 SurfCont->RangeTable = SUMA_AllocTableField(wname);
4849 snprintf(wname,63,"%s->NodeTable", s);
4850 SurfCont->NodeTable = SUMA_AllocTableField(wname);
4851 snprintf(wname,63,"%s->FaceTable", s);
4852 SurfCont->FaceTable = SUMA_AllocTableField(wname);
4853 snprintf(wname,63,"%s->DataTable", s);
4854 SurfCont->DataTable = SUMA_AllocTableField(wname);
4855 snprintf(wname,63,"%s->LabelTable", s);
4856 SurfCont->LabelTable = SUMA_AllocTableField(wname);
4857 /* SurfCont->ColPlaneShow_tb = NULL; Obsolete */
4858 SurfCont->ColPlaneShowOneFore_tb = NULL;
4859 SurfCont->SymIrange_tb = NULL;
4860 SurfCont->AbsThresh_tb = NULL;
4861 SurfCont->ShowZero_tb = NULL;
4862 SurfCont->SwitchDsetlst = NULL;
4863 snprintf(wname,63,"%s->ColPlaneLabelTable", s);
4864 SurfCont->ColPlaneLabelTable = SUMA_AllocTableField(wname);
4865 snprintf(wname,63,"%s->SetClustTable", s);
4866 SurfCont->SetClustTable = SUMA_AllocTableField(wname);
4867 snprintf(wname,63,"%s->Ax_slc", s);
4868 SurfCont->Ax_slc = SUMA_AllocSliceField(wname);
4869 snprintf(wname,63,"%s->Sa_slc", s);
4870 SurfCont->Sa_slc = SUMA_AllocSliceField(wname);
4871 snprintf(wname,63,"%s->Co_slc", s);
4872 SurfCont->Co_slc = SUMA_AllocSliceField(wname);
4873 snprintf(wname,63,"%s->VR", s);
4874 SurfCont->VR_fld = SUMA_AllocVRField(wname);
4875 SurfCont->curColPlane = NULL;
4876 {
4877 char *eee = getenv("SUMA_ShowOneOnly");
4878 if (eee) {
4879 SUMA_TO_LOWER(eee);
4880 if (strcmp (eee, "yes") == 0) SurfCont->ShowCurForeOnly = YUP;
4881 else SurfCont->ShowCurForeOnly = NOPE;
4882 } else {
4883 SurfCont->ShowCurForeOnly = YUP;
4884 }
4885 }
4886 {
4887 char *eee = getenv("SUMA_GraphHidden");
4888 if (eee) {
4889 SUMA_TO_LOWER(eee);
4890 if (strcmp (eee, "yes") == 0) SurfCont->GraphHidden = YUP;
4891 else SurfCont->GraphHidden = NOPE;
4892 } else {
4893 SurfCont->GraphHidden = YUP;
4894 }
4895 }
4896
4897 SurfCont->prv_curDOp = (void **)calloc(1, sizeof(void*));
4898 SurfCont->prv_variant = NULL;
4899 SurfCont->PosRef = NULL;
4900 SurfCont->cmp_ren =
4901 (SUMA_CMAP_RENDER_AREA *)SUMA_calloc(1, sizeof(SUMA_CMAP_RENDER_AREA));
4902 SurfCont->cmp_ren->CrappyDrawable = 0;
4903 SurfCont->cmp_ren->cmap_wid = NULL;
4904 SurfCont->cmp_ren->FOV = SUMA_CMAP_FOV_INITIAL;
4905 SurfCont->cmp_ren->cmap_context = NULL;
4906 SurfCont->cmp_ren->translateVec[0] =
4907 SurfCont->cmp_ren->translateVec[0] =
4908 SurfCont->cmp_ren->translateVec[1] = 0.0;
4909 SurfCont->thr_sc = NULL;
4910 SurfCont->brt_sc = NULL;
4911 SurfCont->thr_lb = NULL;
4912 SurfCont->thrstat_lb = NULL;
4913 SurfCont->cmaptit_lb = NULL;
4914 SurfCont->cmapswtch_pb = NULL;
4915 SurfCont->CmapLoad_pb = NULL;
4916 SurfCont->SwitchIntMenu = NULL;
4917 SurfCont->SwitchBrtMenu = NULL;
4918 SurfCont->SwitchThrMenu = NULL;
4919 #if 0 /* Now in SwitchIntMenu */
4920 SurfCont->SwitchIntLst = NULL;
4921 SurfCont->SwitchThrLst = NULL;
4922 SurfCont->SwitchBrtLst = NULL;
4923 SurfCont->SwitchIntArrow = NULL;
4924 SurfCont->SwitchBrtArrow = NULL;
4925 SurfCont->SwitchThrArrow = NULL;
4926 #endif
4927 SurfCont->SwitchCmapMenu = NULL;
4928 SurfCont->Fake_pbar = NULL;
4929 SurfCont->rc_CmapCont = NULL;
4930 SurfCont->CoordBiasMenu = SUMA_Alloc_Menu_Widget(SW_N_CoordBias);
4931 SurfCont->LinkModeMenu = SUMA_Alloc_Menu_Widget(SW_N_LinkMode);
4932 SurfCont->CmapModeMenu = SUMA_Alloc_Menu_Widget(SW_N_CmapMode);
4933 SurfCont->opts_rc = NULL;
4934 SurfCont->opts_form = NULL;
4935 SurfCont->rcvo = NULL;
4936 SurfCont->rcsw = NULL;
4937 SurfCont->rcsw_v1 = NULL;
4938 SurfCont->rcsw_v2 = NULL;
4939 SurfCont->rcswr = NULL;
4940 SurfCont->rccm = NULL;
4941 SurfCont->rccm_swcmap = NULL;
4942 SurfCont->IntRange_lb = NULL;
4943 SurfCont->Int_tb = NULL;
4944 SurfCont->Thr_tb = NULL;
4945 SurfCont->Brt_tb = NULL;
4946 SurfCont->IntRangeLocked = 0;
4947 SurfCont->BrtRangeLocked = 0;
4948 SurfCont->rcclust = NULL;
4949
4950 SurfCont->tract_length_mask[0] = 0.0;
4951 /* SUMA_floatEnv("TEMP_MIN_LENGTH", 0.0); */
4952 SurfCont->tract_length_mask[1] = -1.0;
4953 /* SUMA_floatEnv("TEMP_MAX_LENGTH", -1.0); */
4954 if (SurfCont->tract_length_mask[1]>=
4955 SurfCont->tract_length_mask[0])
4956 SurfCont->UseMaskLen = 0; /* leave it off, let it be activated in GUI */
4957 else
4958 SurfCont->UseMaskLen = 0;
4959
4960 return (SurfCont);
4961 }
4962
SUMA_GlobalMaskContStruct(char * idcode)4963 SUMA_X_SurfCont *SUMA_GlobalMaskContStruct(char *idcode)
4964 {
4965 static char FuncName[]={"SUMA_GlobalMaskContStruct"};
4966 if (!SUMAg_CF->X->AllMaskCont) {
4967 if (!(SUMAg_CF->X->AllMaskCont =
4968 SUMA_CreateSurfContStruct(idcode, MASK_type))){
4969 fprintf(SUMA_STDERR,
4970 "Error %s: Failed to create global mask controller struct",
4971 FuncName);
4972 return(NULL);
4973 }
4974 }
4975 /* Return a link to that struct */
4976 return((SUMA_X_SurfCont*)
4977 SUMA_LinkToPointer((void *)SUMAg_CF->X->AllMaskCont));
4978 }
4979
4980 /*!
4981 \brief frees structure SUMA_X_SurfCont, returns null
4982
4983 */
SUMA_FreeSurfContStruct(SUMA_X_SurfCont * SurfCont)4984 void *SUMA_FreeSurfContStruct (SUMA_X_SurfCont *SurfCont)
4985 {
4986 static char FuncName[]={"SUMA_FreeSurfContStruct"};
4987
4988 /* do not use commonfields related stuff here for obvious reasons */
4989 if (!SurfCont) return(NULL);
4990
4991 if (SurfCont->N_links) {
4992 SurfCont = (SUMA_X_SurfCont*)SUMA_UnlinkFromPointer((void *)SurfCont);
4993 return (NULL);
4994 }
4995
4996 /* no more links, go for it */
4997 if (SurfCont->TractMaskGray) free (SurfCont->TractMaskGray);
4998 if (SurfCont->SurfContPage) free (SurfCont->SurfContPage);
4999 if (SurfCont->NodeRadGainAF) free (SurfCont->NodeRadGainAF);
5000 if (SurfCont->EdgeThickGainAF) free (SurfCont->EdgeThickGainAF);
5001 if (SurfCont->ColPlaneOrder) free (SurfCont->ColPlaneOrder);
5002 if (SurfCont->ColPlaneOpacity) free (SurfCont->ColPlaneOpacity);
5003 if (SurfCont->ColPlaneDimFact) free (SurfCont->ColPlaneDimFact);
5004 if (SurfCont->ColPlaneAlphaThresh) free (SurfCont->ColPlaneAlphaThresh);
5005 if (SurfCont->SetRangeTable) SUMA_FreeTableField (SurfCont->SetRangeTable);
5006 if (SurfCont->RangeTable) SUMA_FreeTableField (SurfCont->RangeTable);
5007 if (SurfCont->MaskTable) SUMA_FreeTableField (SurfCont->MaskTable);
5008 if (SurfCont->MaskEvalTable) SUMA_FreeTableField (SurfCont->MaskEvalTable);
5009 if (SurfCont->MaskLenTable) SUMA_FreeTableField (SurfCont->MaskLenTable);
5010 if (SurfCont->XhairTable) SUMA_FreeTableField (SurfCont->XhairTable);
5011 if (SurfCont->NodeTable) SUMA_FreeTableField (SurfCont->NodeTable);
5012 if (SurfCont->FaceTable) SUMA_FreeTableField (SurfCont->FaceTable);
5013 if (SurfCont->DataTable) SUMA_FreeTableField (SurfCont->DataTable);
5014 if (SurfCont->LabelTable) SUMA_FreeTableField (SurfCont->LabelTable);
5015 if (SurfCont->Ax_slc) SUMA_FreeSliceField (SurfCont->Ax_slc);
5016 if (SurfCont->Sa_slc) SUMA_FreeSliceField (SurfCont->Sa_slc);
5017 if (SurfCont->Co_slc) SUMA_FreeSliceField (SurfCont->Co_slc);
5018 if (SurfCont->VR_fld) SUMA_FreeVRField (SurfCont->VR_fld);
5019 if (SurfCont->ColPlaneLabelTable)
5020 SUMA_FreeTableField (SurfCont->ColPlaneLabelTable);
5021 if (SurfCont->SetClustTable) SUMA_FreeTableField (SurfCont->SetClustTable);
5022 if (SurfCont->SwitchDsetlst) SUMA_FreeScrolledList (SurfCont->SwitchDsetlst);
5023 if (SurfCont->SurfInfo_TextShell) {
5024 SUMA_SL_Warn("SurfCont->SurfInfo_TextShell is not being freed") };
5025 SurfCont->SwitchIntMenu = SUMA_Free_Menu_Widget(SurfCont->SwitchIntMenu);
5026 SurfCont->SwitchThrMenu = SUMA_Free_Menu_Widget(SurfCont->SwitchThrMenu);
5027 SurfCont->SwitchBrtMenu = SUMA_Free_Menu_Widget(SurfCont->SwitchBrtMenu);
5028 SurfCont->SwitchCmapMenu = SUMA_Free_Menu_Widget(SurfCont->SwitchCmapMenu);
5029 SurfCont->DsetNodeRadMenu = SUMA_Free_Menu_Widget(SurfCont->DsetNodeRadMenu);
5030 SurfCont->DsetEdgeThickMenu =
5031 SUMA_Free_Menu_Widget(SurfCont->DsetEdgeThickMenu);
5032 SurfCont->DsetEdgeStipMenu =
5033 SUMA_Free_Menu_Widget(SurfCont->DsetEdgeStipMenu);
5034 SurfCont->TractStyleMenu =
5035 SUMA_Free_Menu_Widget(SurfCont->TractStyleMenu);
5036 SurfCont->DsetAlphaValMenu =
5037 SUMA_Free_Menu_Widget(SurfCont->DsetAlphaValMenu);
5038 SurfCont->TractMaskMenu = SUMA_Free_Menu_Widget(SurfCont->TractMaskMenu);
5039 if (SurfCont->prv_curDOp) free(SurfCont->prv_curDOp);
5040 if (SurfCont->prv_variant) free(SurfCont->prv_variant);
5041 if (SurfCont->cmp_ren) free(SurfCont->cmp_ren);
5042 if (SurfCont) free(SurfCont);
5043 return (NULL);
5044 }
5045
SUMA_Free_Menu_Widget(SUMA_MENU_WIDGET * smw)5046 SUMA_MENU_WIDGET *SUMA_Free_Menu_Widget(SUMA_MENU_WIDGET *smw)
5047 {
5048 static char FuncName[]={"SUMA_Free_Menu_Widget"};
5049 if (!smw) return(NULL);
5050 if (smw->mw) {
5051 XtDestroyWidget(smw->mw[0]);
5052 SUMA_free(smw->mw);
5053 }
5054 if (smw->lw) {
5055 SUMA_cb_CloseSwitchLst (NULL, (XtPointer)smw->lw, NULL);
5056 smw->lw = SUMA_FreeScrolledList(smw->lw);
5057 }
5058 if (smw) SUMA_free(smw);
5059 return(NULL);
5060 }
5061
SUMA_Alloc_Menu_Widget(int nw)5062 SUMA_MENU_WIDGET *SUMA_Alloc_Menu_Widget(int nw)
5063 {
5064 SUMA_MENU_WIDGET *smw=NULL;
5065 smw = (SUMA_MENU_WIDGET *)SUMA_calloc(1, sizeof(SUMA_MENU_WIDGET));
5066 if (nw) {
5067 smw->mw = (Widget *)SUMA_calloc(nw, sizeof(Widget));
5068 smw->N_mw = nw;
5069 }
5070 return(smw);
5071 }
5072
5073 /*! free SUMA_CommonFields
5074 NOTE: the SUMA_CommonFields * itself is not freed. You'll have to free it manually with free function;
5075 \sa SUMA_Create_CommonFields
5076 */
SUMA_Free_CommonFields(SUMA_CommonFields * cf)5077 SUMA_Boolean SUMA_Free_CommonFields (SUMA_CommonFields *cf)
5078 {
5079 static char FuncName[]={"SUMA_Free_CommonFields"};
5080 int i;
5081
5082 /* do not use commonfields related stuff here for obvious reasons */
5083 if (cf->cwd) SUMA_free(cf->cwd); cf->cwd = NULL;
5084 if (cf->GroupList) {
5085 for (i=0; i< cf->N_Group; ++i)
5086 if (cf->GroupList[i]) SUMA_free(cf->GroupList[i]);
5087 SUMA_free(cf->GroupList); cf->GroupList = NULL;
5088 }
5089 #if 0 /* not anymore!, that is now a pointer copy */
5090 if (cf->ROI_CM) SUMA_Free_ColorMap(cf->ROI_CM); /* free the colormap */
5091 #endif
5092 cf->ROI_CM = NULL;
5093 if (cf->X->FileSelectDlg)
5094 SUMA_FreeFileSelectionDialogStruct(cf->X->FileSelectDlg);
5095 cf->X->FileSelectDlg = NULL;
5096 if (cf->X->AllMaskCont) SUMA_FreeSurfContStruct(cf->X->AllMaskCont);
5097 SUMA_ifree(cf->X->Cr);
5098 for (i=0; i<cf->N_dcom; ++i) { SUMA_ifree(cf->dcom[i]); }
5099 SUMA_ifree(cf->dcom);
5100
5101 if (cf->X->SumaCont)
5102 SUMA_FreeSumaContStruct (cf->X->SumaCont);
5103 SUMA_free_DocumentedWidgets();
5104
5105 cf->X->SumaCont = NULL;
5106 if (cf->X->DrawROI)
5107 SUMA_FreeDrawROIStruct (cf->X->DrawROI);
5108 cf->X->DrawROI = NULL;
5109 if (cf->X->N_ForeSmooth_prmpt)
5110 SUMA_FreePromptDialogStruct (cf->X->N_ForeSmooth_prmpt);
5111 cf->X->N_ForeSmooth_prmpt = NULL;
5112 if (cf->X->N_FinalSmooth_prmpt)
5113 SUMA_FreePromptDialogStruct (cf->X->N_FinalSmooth_prmpt);
5114 cf->X->N_FinalSmooth_prmpt = NULL;
5115 if (cf->X->Clip_prmpt)
5116 SUMA_FreePromptDialogStruct (cf->X->Clip_prmpt);
5117 cf->X->Clip_prmpt = NULL;
5118 if (cf->X->ClipObj_prmpt)
5119 SUMA_FreePromptDialogStruct (cf->X->ClipObj_prmpt);
5120 cf->X->ClipObj_prmpt = NULL;
5121 if (cf->X->SwitchCmapLst) SUMA_FreeScrolledList (cf->X->SwitchCmapLst);
5122 if (cf->X) free(cf->X); cf->X = NULL;
5123 if (cf->MessageList)
5124 SUMA_EmptyDestroyList(cf->MessageList);
5125 cf->MessageList = NULL;
5126 if (cf->scm) cf->scm = SUMA_DestroyAfniColors (cf->scm); cf->scm = NULL;
5127 if (cf->DsetList) {
5128 dlist_destroy(cf->DsetList); SUMA_free(cf->DsetList);
5129 cf->DsetList = NULL;
5130 }
5131 if (cf->xforms) {
5132 dlist_destroy(cf->xforms); SUMA_free(cf->xforms);
5133 }
5134 if (cf->callbacks) {
5135 dlist_destroy(cf->callbacks); SUMA_free(cf->callbacks);
5136 }
5137 #ifdef USE_SUMA_MALLOC
5138 SUMA_SL_Err("NO LONGER SUPPORTED");
5139 return(NOPE);
5140 if (cf->Mem) SUMA_Free_MemTrace (cf->Mem); cf->Mem = NULL;/* always free this right before the end */
5141 #endif
5142
5143
5144 if (cf->giset) {
5145 if (cf->giset->dset) {
5146 SUMA_S_Warn("dset is not being freed");
5147 }
5148 DESTROY_GICOR_setup(cf->giset); cf->giset=NULL;
5149 }
5150
5151 if (cf->ITset) {
5152 Free_Insta_Tract_Setup(cf->ITset);
5153 SUMA_ifree(cf->ITset);
5154 }
5155
5156 if (cf->autorecord) {
5157 cf->autorecord = SUMA_Free_Parsed_Name(cf->autorecord);
5158 }
5159
5160 if (cf->SaveList) {
5161 dlist_destroy(cf->SaveList); SUMA_free(cf->SaveList);
5162 }
5163
5164 if (cf->lev) {
5165 SUMA_free(cf->lev); cf->lev = NULL;
5166 }
5167
5168 /* if (cf) free(cf); */ /* don't free this stupid pointer since it is used
5169 when main returns with SUMA_ RETURN
5170 (typo on purpose to avoid upsetting AnalyzeTrace.
5171 It is not quite a leak since the OS will clean it up
5172 after exit Thu Apr 8 2004*/
5173
5174 return (YUP);
5175 }
5176
SUMA_Show_Clip_Planes(SUMA_CommonFields * cf,FILE * out)5177 void SUMA_Show_Clip_Planes (SUMA_CommonFields *cf, FILE *out)
5178 {
5179 static char FuncName[]={"SUMA_Show_Clip_Planes"};
5180 char *s=NULL;
5181
5182 SUMA_ENTRY;
5183
5184 s = SUMA_Show_Clip_Planes_Info (cf);
5185
5186 /* //Don't output number of planes or their equations
5187 if (!out) fprintf(SUMA_STDERR,"%s", s);
5188 else fprintf(out,"%s", s);
5189 */
5190
5191 SUMA_free(s);
5192
5193 SUMA_RETURNe;
5194 }
5195
SUMA_Clip_Type_to_Clip_Name(SUMA_CLIP_PLANE_TYPES tp)5196 const char * SUMA_Clip_Type_to_Clip_Name (SUMA_CLIP_PLANE_TYPES tp)
5197 {
5198 switch (tp) {
5199 case SUMA_NO_CLIP_PLANE_TYPE:
5200 return("No_type");
5201 case SUMA_SCREEN_CLIP:
5202 return("Screen_Clip");
5203 case SUMA_ALL_OBJECT_CLIP:
5204 return("All_Objects_Clip");
5205 default:
5206 return("Bad value");
5207 }
5208 }
5209
SUMA_Show_Clip_Planes_Info(SUMA_CommonFields * cf)5210 char * SUMA_Show_Clip_Planes_Info (SUMA_CommonFields *cf)
5211 {
5212 static char FuncName[]={"SUMA_Show_Clip_Planes_Info"};
5213 int i;
5214 char *s=NULL;
5215 SUMA_STRING *SS=NULL;
5216
5217 SUMA_ENTRY;
5218
5219 SS = SUMA_StringAppend_va(NULL, NULL);
5220
5221 if (cf == NULL) {
5222 SS = SUMA_StringAppend_va(SS," NULL cf structure.\n");
5223 SS = SUMA_StringAppend_va(SS, NULL);
5224 s = SS->s; SUMA_free(SS); SS= NULL;
5225 SUMA_RETURN(s);
5226 }
5227
5228 SS = SUMA_StringAppend_va(SS," Number of Clip Planes: %d\n", cf->N_ClipPlanes);
5229 for (i=0; i<cf->N_ClipPlanes; ++i) {
5230 SS = SUMA_StringAppend_va(SS," %d: Clip plane >>%s<< of type %s. Eq: %.4fX + %.4fY + %.4fZ + %.4f = 0\n",
5231 i, cf->ClipPlanesLabels[i], SUMA_Clip_Type_to_Clip_Name(cf->ClipPlaneType[i]),
5232 (float)cf->ClipPlanes[4*i], (float)cf->ClipPlanes[4*i+1], (float)cf->ClipPlanes[4*i+2], (float)cf->ClipPlanes[4*i+3]);
5233 }
5234
5235 SS = SUMA_StringAppend_va(SS, NULL);
5236 s = SS->s; SUMA_free(SS); SS= NULL;
5237
5238 SUMA_RETURN(s);
5239 }
5240
SUMA_Show_CommonFields(SUMA_CommonFields * cf,FILE * out)5241 void SUMA_Show_CommonFields (SUMA_CommonFields *cf, FILE *out)
5242 {
5243 static char FuncName[]={"SUMA_Show_CommonFields"};
5244 char *s=NULL;
5245
5246 SUMA_ENTRY;
5247
5248 s = SUMA_CommonFieldsInfo (cf,1);
5249
5250 if (!out) fprintf(SUMA_STDERR,"%s", s);
5251 else fprintf(out,"%s", s);
5252
5253 SUMA_free(s);
5254
5255 SUMA_RETURNe;
5256 }
5257
SUMA_CommonFieldsInfo(SUMA_CommonFields * cf,int detail)5258 char * SUMA_CommonFieldsInfo (SUMA_CommonFields *cf, int detail)
5259 {
5260 static char FuncName[]={"SUMA_CommonFieldsInfo"};
5261 int i;
5262 char *s=NULL;
5263 SUMA_DSET *dset=NULL;
5264 DListElmt *el=NULL;
5265 SUMA_STRING *SS=NULL;
5266
5267 SUMA_ENTRY;
5268
5269 SS = SUMA_StringAppend_va(NULL, NULL);
5270
5271 if (cf == NULL) {
5272 SS = SUMA_StringAppend_va(SS," NULL cf structure.\n");
5273 SS = SUMA_StringAppend_va(SS, NULL);
5274 s = SS->s; SUMA_free(SS); SS= NULL;
5275 SUMA_RETURN(s);
5276 }
5277
5278 SS = SUMA_StringAppend_va(SS," CWD: %s\n", cf->cwd);
5279 for (i=0; i < SUMA_MAX_STREAMS; ++i) {
5280 SS = SUMA_StringAppend_va(SS," HostName: %s\n", cf->HostName_v[i]);
5281 SS = SUMA_StringAppend_va(SS," NimlStream: %s\n", cf->NimlStream_v[i]);
5282 }
5283
5284 if (cf->X) {
5285 SS = SUMA_StringAppend_va(SS," X struct\n",
5286 " NumForeSmoothing %d, NumFinalSmmothing %d\n"
5287 " WarnClose %d, UseSameSurfCont %d, \n"
5288 " SameSurfContOpen %d ButtonDown %d, WinOffsets %d %d\n"
5289 , cf->X->NumForeSmoothing, cf->X->NumFinalSmoothing,
5290 cf->X->WarnClose, cf->X->UseSameSurfCont,
5291 cf->X->SameSurfContOpen, cf->X->ButtonDown,
5292 cf->X->roffx, cf->X->roffy);
5293 } else {
5294 SS = SUMA_StringAppend(SS," NULL X struct\n");
5295 }
5296 SS = SUMA_StringAppend_va(SS," Available Groups: %d\n", cf->N_Group);
5297 for (i=0; i<cf->N_Group; ++i) {
5298 SS = SUMA_StringAppend_va(SS," Group[%d]: %s\n", i, cf->GroupList[i]);
5299 }
5300
5301 #ifdef USE_SUMA_MALLOC
5302 SUMA_SL_Err("NO LONGER SUPPORTED");
5303 SUMA_RETURN(NULL);
5304 #else
5305 SS = SUMA_StringAppend_va(SS," DBG_trace = %d\n", DBG_trace);
5306 SS = SUMA_StringAppend_va(SS," InOut_Notify = %d\n", cf->InOut_Notify);
5307 SS = SUMA_StringAppend_va(SS," Echo_KeyPress = %d\n", cf->Echo_KeyPress);
5308 SS = SUMA_StringAppend_va(SS," MemTrace = %d\n", cf->MemTrace);
5309 #endif
5310 SS = SUMA_StringAppend_va(SS," PointerSize = %d\n", cf->PointerSize);
5311
5312 /* add the displayable objects Info */
5313 s = SUMA_DOv_Info(SUMAg_DOv, SUMAg_N_DOv, 0);
5314 SS = SUMA_StringAppend_va(SS, "%s\n", s); SUMA_free(s); s = NULL;
5315
5316 if (cf->DsetList) {
5317 SS = SUMA_StringAppend_va( SS, "DsetList (Allow Replacement = %d):\n",
5318 cf->Allow_Dset_Replace);
5319 el = NULL;
5320 do {
5321 if (!el) el = dlist_head(cf->DsetList);
5322 else el = dlist_next(el);
5323 if (el) {
5324 dset = (SUMA_DSET *)el->data;
5325 if (!dset) {
5326 SUMA_SLP_Err("Unexpected NULL dset element in list!\n"
5327 "Please report this occurrence to saadz@mail.nih.gov.");
5328 } else {
5329 s = SUMA_DsetInfo (dset,0);
5330 SS = SUMA_StringAppend_va(SS, "\n%s\n", s); SUMA_free(s); s = NULL;
5331 }
5332 } else {
5333 SUMA_S_Err("Unexpected nullness");
5334 }
5335 } while ( (el != dlist_tail(cf->DsetList)));
5336 } else {
5337 SS = SUMA_StringAppend_va(SS, "NULL DsetList\n");
5338 }
5339
5340 SS = SUMA_StringAppend_va( SS,
5341 "SUMA's list of environment variables:\n");
5342 s = SUMA_env_list_help(0, TXT);
5343 SS = SUMA_StringAppend( SS, s); SUMA_free(s); s = NULL;
5344 SS = SUMA_StringAppend( SS, "\n");
5345
5346 /* add the colormap info */
5347 if (cf->scm) {
5348 SS = SUMA_StringAppend(SS, " Colormaps:\n");
5349 s = SUMA_ColorMapVec_Info (cf->scm->CMv,
5350 cf->scm->N_maps, detail);
5351 SS = SUMA_StringAppend_va( SS, "%s\n",s); SUMA_free(s); s = NULL;
5352 } else {
5353 SS = SUMA_StringAppend_va(SS, " No Colormaps.\n");
5354 }
5355
5356 /* add xforms and callbacks */
5357 s = SUMA_Xforms_Info(cf->xforms, detail);
5358 SS = SUMA_StringAppend_va( SS, "%s\n",s); SUMA_free(s); s = NULL;
5359 s = SUMA_Callbacks_Info(cf->callbacks, detail);
5360 SS = SUMA_StringAppend_va( SS, "%s\n",s); SUMA_free(s); s = NULL;
5361
5362 SS = SUMA_StringAppend_va(SS,
5363 "Pointer last seen in viewer: %d\n", cf->PointerLastInViewer);
5364
5365 s = SUMA_GISET_Info(cf->giset, 0);
5366
5367 SS = SUMA_StringAppend_va(SS, "%s\n",s); SUMA_free(s); s = NULL;
5368
5369 SS = SUMA_StringAppend_va(SS, "autorecord: %s\n",
5370 cf->autorecord ? cf->autorecord->FullName:"NULL");
5371
5372 SS = SUMA_StringAppend_va(SS, "SaveList: %d elements\n",
5373 cf->SaveList ? dlist_size(cf->SaveList):0);
5374
5375 SS = SUMA_StringAppend_va(SS, "Documented Widgets:\n%s",
5376 SUMA_get_DocumentedWidgets() ?
5377 SUMA_get_DocumentedWidgets():"NULL");
5378 /* clean up */
5379 SS = SUMA_StringAppend_va(SS, NULL);
5380 s = SS->s; SUMA_free(SS); SS= NULL;
5381
5382 SUMA_RETURN(s);
5383 }
5384
5385 /*!
5386 This function determines the most suitable standard view of a surface viewer
5387 This is based on the surface objects being displayed and
5388 their embedding dimension.
5389 The highest Embedding dimension of the lot determines what view to use
5390 ans = SUMA_BestStandardView (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int N_dov)
5391
5392 \param sv (SUMA_SurfaceViewer *) Surface viewer structure
5393 \param dov (SUMA_DO *) vector of displayable objects
5394 \param N_dov (int) number of displayable objects
5395 \ret ans (SUMA_STANDARD_VIEWS) recommended view
5396
5397 */
SUMA_BestStandardView(SUMA_SurfaceViewer * sv,SUMA_DO * dov,int N_dov)5398 SUMA_STANDARD_VIEWS SUMA_BestStandardView ( SUMA_SurfaceViewer *sv,
5399 SUMA_DO *dov, int N_dov)
5400 {
5401 static char FuncName[] = {"SUMA_BestStandardView"};
5402 SUMA_STANDARD_VIEWS ans;
5403 int N_MembSOs, *MembSOs=NULL, i, maxdim = -1, is, balls, vslice=0;
5404 SUMA_SurfaceObject *SO = NULL;
5405 char *variant=NULL;
5406 SUMA_DO_Types ttv[10]={SO_type, GRAPH_LINK_type, TRACT_type,
5407 VO_type, CDOM_type, MASK_type, NOT_SET_type};
5408 SUMA_SO_SIDE side=SUMA_NO_SIDE;
5409 SUMA_Boolean LocalHead = NOPE;
5410
5411 SUMA_ENTRY;
5412
5413 is = sv->iState;
5414 if (is < 0) {
5415 fprintf(SUMA_STDERR, "Error %s: sv->iState undefined.\n", FuncName);
5416 SUMA_RETURN (SUMA_N_STANDARD_VIEWS);
5417 }
5418
5419 side = SUMA_LEFT;
5420 balls = 0; vslice = 0;
5421 MembSOs = SUMA_ViewState_Membs(&(sv->VSv[is]), ttv, &N_MembSOs);
5422 SUMA_LHv("Working on %d members\n", N_MembSOs);
5423 for (i=0; i<N_MembSOs; ++i) {
5424 switch (dov[MembSOs[i]].ObjectType) {
5425 case SO_type:
5426 SO = (SUMA_SurfaceObject *)(dov[MembSOs[i]].OP);
5427 if (SO == NULL) {
5428 fprintf(SUMA_STDERR,"Error %s: SO is null ???\n.", FuncName);
5429 SUMA_RETURN (SUMA_N_STANDARD_VIEWS);
5430 }
5431 if (SO->EmbedDim > maxdim) maxdim = SO->EmbedDim;
5432 if (SO->Side != SUMA_LEFT) side = SUMA_RIGHT;
5433 if (SUMA_IS_GEOM_SYMM(SO->isSphere)) balls = 1;
5434 break;
5435 case GRAPH_LINK_type:
5436 maxdim = 3;
5437 variant = SUMA_ADO_variant((SUMA_ALL_DO *)dov[MembSOs[i]].OP);
5438 if (!strcmp(variant,"GMATRIX")) {
5439 vslice = 1; /* a slice viewed from above */
5440 }
5441 break;
5442 case VO_type:
5443 case CDOM_type:
5444 case MASK_type:
5445 case TRACT_type:
5446 maxdim = 3;
5447 break;
5448 default:
5449 SUMA_S_Err("Should not be here");
5450 break;
5451 }
5452 }
5453 SUMA_ifree(MembSOs);
5454
5455 switch (maxdim) {
5456 case 2:
5457 if (side == SUMA_LEFT) { /* left flat maps*/
5458 SUMA_RETURN (SUMA_2D_Z0L);
5459 } else { /* default */
5460 SUMA_RETURN (SUMA_2D_Z0);
5461 }
5462 case 3:
5463 if (!balls && !vslice) SUMA_RETURN(SUMA_3D);
5464 else SUMA_RETURN(SUMA_3D_Z0);
5465 default:
5466 fprintf(SUMA_STDERR,
5467 "Error %s: No provision for a maximum embedding dimension of %d.\n",
5468 FuncName, maxdim);
5469 SUMA_RETURN(SUMA_N_STANDARD_VIEWS);
5470 }
5471
5472 }
5473
5474 /*!
5475 \brief Apply the group of a surface to the surface viewer
5476 */
SUMA_AdoptSurfGroup(SUMA_SurfaceViewer * csv,SUMA_SurfaceObject * SO)5477 SUMA_Boolean SUMA_AdoptSurfGroup(SUMA_SurfaceViewer *csv, SUMA_SurfaceObject *SO)
5478 {
5479 static char FuncName[]={"SUMA_AdoptSurfGroup"};
5480
5481 SUMA_ENTRY;
5482
5483 csv->iCurGroup = SUMA_WhichGroup(SUMAg_CF, SO->Group);
5484 if (csv->iCurGroup < 0) {
5485 SUMA_SL_Err("Bad, unexpected error.\nGroup was not found");
5486 SUMA_RETURN(NOPE);
5487 }
5488 if (csv->CurGroupName) SUMA_free(csv->CurGroupName);
5489
5490 csv->CurGroupName = SUMA_copy_string(SO->Group);
5491 SUMA_RETURN(YUP);
5492 }
5493
5494 /*!
5495 \brief Apply a group to the surface viewer
5496 */
SUMA_AdoptGroup(SUMA_SurfaceViewer * csv,char * group)5497 SUMA_Boolean SUMA_AdoptGroup(SUMA_SurfaceViewer *csv, char *group)
5498 {
5499 static char FuncName[]={"SUMA_AdoptGroup"};
5500
5501 SUMA_ENTRY;
5502
5503 csv->iCurGroup = SUMA_WhichGroup(SUMAg_CF, group);
5504 if (csv->iCurGroup < 0) {
5505 SUMA_SL_Err("Bad, unexpected error.\nGroup was not found");
5506 SUMA_RETURN(NOPE);
5507 }
5508 if (csv->CurGroupName) SUMA_free(csv->CurGroupName);
5509
5510 csv->CurGroupName = SUMA_copy_string(SUMAg_CF->GroupList[csv->iCurGroup]);
5511 SUMA_RETURN(YUP);
5512 }
5513
5514 SUMA_Boolean
SUMA_SetViewerLightsForSO(SUMA_SurfaceViewer * cSV,SUMA_SurfaceObject * SO)5515 SUMA_SetViewerLightsForSO(SUMA_SurfaceViewer *cSV, SUMA_SurfaceObject *SO)
5516 {
5517 static char FuncName[]={"SUMA_SetViewerLightsForSO"};
5518 SUMA_Boolean LocalHead = NOPE;
5519
5520 SUMA_ENTRY;
5521
5522 if (!cSV || !SO) SUMA_RETURN(NOPE);
5523
5524 if (cSV->lit_for == 0) { /* olde way */
5525 /* if surface is SureFit , flip lights */
5526 if (SO->normdir == 0 && ( SO->FileType == SUMA_SUREFIT ||
5527 SO->FileType == SUMA_OPENDX_MESH ||
5528 SO->FileType == SUMA_OBJ_MESH ||
5529 SO->FileType == SUMA_BRAIN_VOYAGER)) {
5530 SUMA_LH("Flippo for safety");
5531 cSV->light0_position[0] *= -1;
5532 cSV->light0_position[1] *= -1;
5533 cSV->light0_position[2] *= -1;
5534 glLightfv(GL_LIGHT0, GL_POSITION, cSV->light0_position);
5535 } else if (SO->normdir == -1) {
5536 SUMA_LH("Flippo for safety");
5537 cSV->light0_position[0] *= -1;
5538 cSV->light0_position[1] *= -1;
5539 cSV->light0_position[2] *= -1;
5540 glLightfv(GL_LIGHT0, GL_POSITION, cSV->light0_position);
5541 }
5542 } else {
5543 SUMA_LHv("Auto Flippo for safety, %d, %d\n", cSV->lit_for , SO->normdir);
5544 if (cSV->lit_for * SO->normdir < 0) {
5545 cSV->light0_position[0] *= -1;
5546 cSV->light0_position[1] *= -1;
5547 cSV->light0_position[2] *= -1;
5548 cSV->lit_for *= -1;
5549 glLightfv(GL_LIGHT0, GL_POSITION, cSV->light0_position);
5550 }
5551 }
5552
5553 SUMA_RETURN(YUP);
5554 }
5555
5556
5557 /*!
5558 ans = SUMA_SetupSVforDOs (Spec, DOv, N_DOv, cSV, vo);
5559
5560 This functions registers all surfaces in a spec file with a surface viewer.
5561 The following steps are performed:
5562 SUMA_RegisterSpecSO (register info on all surfaces loaded)
5563 SUMA_RegisterDO (only Surface Objects)
5564 SUMA_RegisterDO (all non SO objects)
5565 SUMA_BestStandardView (decide on best standard view)
5566 SUMA_UpdateRotaCenter (based on surfaces in first view) if vo & UPDATE_ROT_MASK
5567 SUMA_UpdateViewPoint (based on surfaces in first view) if vo & UPDATE_VIEW_POINT_MASK
5568 SUMA_EyeAxisStandard (based on surfaces in first view) if vo & UPDATE_EYE_AXIS_STD_MASK
5569
5570 Set the Current SO pointer to the first surface object
5571 if surface is SureFit, flip lights
5572 \param Spec (SUMA_SurfSpecFile *)
5573 \param DOv (SUMA_DO *) Pointer to vector of displayable objects
5574 \param N_DOv (int) Number of displayable objects in DOv
5575 \param cSV (SUMA_SurfaceViewer *) Surface viewer structure
5576 \ret ans (SUMA_Boolean) YUP/NOPE
5577 */
5578
SUMA_SetupSVforDOs(SUMA_SurfSpecFile * Spec,SUMA_DO * DOv,int N_DOv,SUMA_SurfaceViewer * cSV,int viewopt)5579 SUMA_Boolean SUMA_SetupSVforDOs (SUMA_SurfSpecFile *Spec, SUMA_DO *DOv,
5580 int N_DOv,
5581 SUMA_SurfaceViewer *cSV, int viewopt)
5582 {
5583 static char FuncName[] = {"SUMA_SetupSVforDOs"};
5584 int kar, ws, i;
5585 SUMA_SurfaceObject *SO;
5586 SUMA_Axis *EyeAxis;
5587 SUMA_DO_Types ttv[10]={SO_type, GRAPH_LINK_type, TRACT_type,
5588 MASK_type, VO_type, CDOM_type, NOT_SET_type};
5589 int EyeAxis_ID, *MembDOs=NULL, N_MembDOs=0;
5590 int haveSpec=0;
5591 SUMA_Boolean LocalHead = NOPE;
5592
5593 SUMA_ENTRY;
5594
5595 if (!viewopt) {
5596 viewopt = UPDATE_ALL_VIEWING_PARAMS_MASK;
5597 }
5598
5599 if (Spec && Spec->N_Groups > 0) haveSpec=1;
5600
5601 /* register all surface specs */
5602 /* find out what group the viewer will have and assign the current
5603 group to be that of the new surfaces */
5604 if (LocalHead) {
5605 fprintf (SUMA_STDERR, "%s: Registering DOs with viewer [%d]%p, %d\n",
5606 FuncName, SUMA_WhichSV(cSV, SUMAg_SVv, SUMA_MAX_SURF_VIEWERS),
5607 cSV, SUMAg_N_SVv);
5608 if (haveSpec) {
5609 SUMA_LHv("HaveSpec, %d surfs, %d DOs, Group %s\n",
5610 Spec->N_Surfs, Spec->N_DO, Spec->Group[0]);
5611 }
5612 }
5613
5614
5615 cSV->iCurGroup = SUMA_WhichGroup(SUMAg_CF, haveSpec ? Spec->Group[0]:NULL);
5616 /* only one group per spec */
5617 if (cSV->iCurGroup < 0) {
5618 SUMA_SL_Err("Group not found.\n");
5619 SUMA_RETURN(NOPE);
5620 } else {
5621 cSV->CurGroupName =
5622 SUMA_copy_string(SUMAg_CF->GroupList[cSV->iCurGroup]);
5623 }
5624
5625
5626 if (haveSpec && !SUMA_RegisterSpecSO(Spec, cSV, DOv, N_DOv, viewopt)) {
5627 SUMA_S_Err("Failed in SUMA_RegisterSpecSO.");
5628 SUMA_RETURN(NOPE);
5629 }
5630
5631 /* register all SOs of the first state if no state is current
5632 or register all surfaces if they are of the current state and group
5633 (it is possible that no new surfaces are registered, but
5634 overhead is tiny)
5635
5636 The logic fails when you load two different groups with the one surface
5637 in each having the same state as in the other.
5638 {G1, SO->State='a'} {G2, SO->State='a'} in that case both surfaces will
5639 show up at the same time when first loaded. You'll need to switch groups
5640 before you see just the one surface from that group.
5641
5642 For now, I don't care to set this up properly since no one uses
5643 multi-group business.
5644 */
5645 if (!SUMA_IS_GOOD_STATE(cSV->State)) {
5646 SUMA_LHv("Looking for something better than %s\n", CNS(cSV->State));
5647 ws = SUMA_FirstGoodState(cSV);
5648 } else {
5649 ws = SUMA_WhichState (cSV->State, cSV, cSV->CurGroupName) ;
5650 }
5651 if ( ws < 0) {
5652 /* This happens for example when running @DO.examples */
5653 SUMA_LH("No good state at this stage? Defaulting to ws = 0;");
5654 ws = 0;
5655 }
5656
5657 /* Make sure we have something */
5658 do {
5659 SUMA_LHv("Seeking members of state %s\n", CNS(cSV->VSv[ws].Name) );
5660 MembDOs = SUMA_ViewState_Membs(&(cSV->VSv[ws]), ttv, &N_MembDOs);
5661 if (!N_MembDOs) ++ws;
5662 } while (!N_MembDOs && ws < cSV->N_VSv);
5663
5664 if (!N_MembDOs) {
5665 SUMA_S_Err("Nothing to see (check ttv for necessary types)");
5666 SUMA_RETURN(NOPE);
5667 }
5668 SUMA_LHv("Registering All DOs of the %dth state %s...\n"
5669 " N_MembDOs = %d\n",
5670 ws, cSV->VSv[ws].Name, N_MembDOs);
5671 cSV->State = cSV->VSv[ws].Name;
5672 cSV->iState = ws;
5673 for (kar=0; kar < N_MembDOs; ++ kar) {
5674 SUMA_LHv(" About to register DOv[%d] ...\n",
5675 MembDOs[kar]);
5676 switch (DOv[MembDOs[kar]].ObjectType) {
5677 case SO_type:
5678 SO = (SUMA_SurfaceObject *)DOv[MembDOs[kar]].OP;
5679 SUMA_LHv("SO->Group %s, cSV->CurGroupName %s\n",
5680 SO->Group, cSV->CurGroupName);
5681 if (!SUMA_RegisterDO(MembDOs[kar], cSV)) {
5682 SUMA_error_message (FuncName,"Failed to register DO", 1);
5683 SUMA_RETURN(NOPE);
5684 }
5685 break;
5686 case GRAPH_LINK_type:
5687 SUMA_LH(
5688 "Registration was done after loading in SUMA_LoadDsetOntoSO_eng\n"
5689 "No further action needed here");
5690 break;
5691 case TRACT_type:
5692 SUMA_LH(
5693 "Registration was done after loading in SUMA_LoadSegDO\n"
5694 "No further action needed here");
5695 break;
5696 case MASK_type:
5697 case CDOM_type:
5698 case VO_type:
5699 SUMA_LH(
5700 "Registration was done after loading in object\n"
5701 "No further action needed here");
5702 break;
5703 default:
5704 SUMA_S_Err("Ney, no good");
5705 break;
5706 }
5707 }
5708
5709 /* Set the index Current SO pointer to the first surface object read of
5710 the first state, tiz NOT (Fri Jan 31 15:18:49 EST 2003) a surface of course*/
5711 cSV->Focus_DO_ID = MembDOs[0];
5712
5713 SUMA_ifree(MembDOs);
5714
5715 if (LocalHead) fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);
5716
5717 /* register all non SO objects */
5718 if (LocalHead)
5719 fprintf(SUMA_STDERR,"%s: Registering All Non SO ...", FuncName);
5720 for (kar=0; kar < N_DOv; ++kar) {
5721 if (!SUMA_isSO(DOv[kar]))
5722 {
5723 /*fprintf(SUMA_STDERR," About to register DOv[%d] ...\n", kar);*/
5724 if (!SUMA_RegisterDO(kar, cSV)) {
5725 SUMA_error_message (FuncName,"Failed to register DO", 1);
5726 SUMA_RETURN(NOPE);
5727 }
5728 }
5729 }
5730 if (LocalHead) fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);
5731
5732 /* decide what the best state is */
5733 if (viewopt & UPDATE_STANDARD_VIEW_MASK) {
5734 cSV->StdView = SUMA_BestStandardView (cSV, DOv, N_DOv);
5735 if (LocalHead)
5736 fprintf(SUMA_STDERR,
5737 "%s: Standard View Now %d\n", FuncName, cSV->StdView);
5738 if (cSV->StdView == SUMA_N_STANDARD_VIEWS) {
5739 fprintf(SUMA_STDERR,
5740 "Error %s: Could not determine the best standard view. "
5741 "Choosing default SUMA_3D\n", FuncName);
5742 cSV->StdView = SUMA_3D;
5743 }
5744 }
5745
5746 if (viewopt & UPDATE_ROT_MASK) {
5747 /* Set the Rotation Center */
5748 if (LocalHead)
5749 fprintf(SUMA_STDERR,"%s: Setting the Rotation Center \n", FuncName);
5750 if (!SUMA_UpdateRotaCenter(cSV, DOv, N_DOv)) {
5751 fprintf (SUMA_STDERR,
5752 "Error %s: Failed to update center of rotation\n", FuncName);
5753 SUMA_RETURN(NOPE);
5754 }
5755 }
5756
5757 if (viewopt & UPDATE_VIEW_POINT_MASK) {
5758 /* set the viewing points */
5759 SUMA_LH("setting the viewing points");
5760 if (!SUMA_UpdateViewPoint(cSV, DOv, N_DOv, 0)) {
5761 SUMA_S_Err("Failed to update view point");
5762 SUMA_RETURN(NOPE);
5763 }
5764 }
5765
5766 if (viewopt & UPDATE_EYE_AXIS_STD_MASK) {
5767 /* Change the defaults of the eye axis to fit standard EyeAxis */
5768 SUMA_LH("Changing defaults of the eye axis to fit standard EyeAxis");
5769 EyeAxis_ID = SUMA_GetEyeAxis (cSV, DOv);
5770 if (EyeAxis_ID < 0) {
5771 fprintf (SUMA_STDERR,"Error %s: Failed to get Eye Axis.\n", FuncName);
5772 SUMA_RETURN(NOPE);
5773 }
5774 SUMA_EyeAxisStandard ((SUMA_Axis *)DOv[EyeAxis_ID].OP, cSV);
5775 }
5776
5777
5778
5779 /*set the GroupName info of the viewer correctly */
5780 if ((SO = SUMA_SV_Focus_SO(cSV))) {
5781 if (!SUMA_AdoptSurfGroup(cSV,SO)) {
5782 SUMA_SL_Err("Failed to adopt surface's group");
5783 SUMA_RETURN(NOPE);
5784 }
5785
5786 if (!SUMA_SetViewerLightsForSO(cSV, SO)) {
5787 SUMA_S_Warn("Failed to set viewer lights.\n"
5788 "Use 'F' key to flip lights in SUMA if necessary.");
5789 }
5790 }
5791
5792 /* do the axis setup */
5793 SUMA_WorldAxisStandard (cSV->WAx, cSV);
5794
5795 /* do the FOV thingy */
5796 if (cSV->FOV[cSV->iState] == cSV->FOV_original || cSV->FOV[cSV->iState] < 0) {
5797 cSV->FOV[cSV->iState] = SUMA_sv_auto_fov(cSV);
5798 }
5799
5800 SUMA_RETURN(YUP);
5801 }
5802
5803 /*!
5804 \brief updates the cursor in all viewers
5805 */
SUMA_UpdateAllViewerCursor()5806 void SUMA_UpdateAllViewerCursor()
5807 {
5808 static char FuncName[]={"SUMA_UpdateAllViewerCursor"};
5809 int i;
5810
5811 SUMA_ENTRY;
5812
5813 for (i=0; i<SUMAg_N_SVv; ++i) {
5814 if (SUMAg_SVv[i].X) {
5815 SUMA_UpdateViewerCursor(&(SUMAg_SVv[i]));
5816 }
5817 }
5818
5819 SUMA_RETURNe;
5820 }
5821
5822 /*!
5823 \brief updates the cursor in one viewer
5824 */
SUMA_UpdateViewerCursor(SUMA_SurfaceViewer * sv)5825 void SUMA_UpdateViewerCursor(SUMA_SurfaceViewer *sv)
5826 {
5827 static char FuncName[]={"SUMA_UpdateViewerCursor"};
5828 SUMA_Boolean LocalHead = NOPE;
5829
5830 SUMA_ENTRY;
5831
5832 if (!sv->X) SUMA_RETURNe;
5833 if (!sv->X->GLXAREA) SUMA_RETURNe;
5834 if (SUMAg_CF->ROI_mode) {
5835 if (SUMAg_CF->Pen_mode)
5836 MCW_set_widget_cursor( sv->X->GLXAREA , -XC_pencil ) ;
5837 else MCW_set_widget_cursor( sv->X->GLXAREA , -XC_target ) ;
5838 } else {
5839 if (0) {
5840 MCW_set_widget_cursor( sv->X->GLXAREA , -XC_dotbox);
5841 } else {
5842 MCW_set_widget_cursor( sv->X->GLXAREA , -XC_top_left_arrow ) ;
5843 }
5844 }
5845 SUMA_RETURNe;
5846 }
5847
5848 /*!
5849 \brief updates the title string of a viewer window
5850 */
5851
SUMA_UpdateViewerTitle_old(SUMA_SurfaceViewer * sv)5852 void SUMA_UpdateViewerTitle_old(SUMA_SurfaceViewer *sv)
5853 {
5854 static char FuncName[]={"SUMA_UpdateViewerTitle_old"};
5855 int isv, i, N_SOlist, nalloc;
5856 char slabel[30], sside[30], srec[10], cl='\0', cr='\0', smoment[30];
5857 SUMA_SurfaceObject *SO = NULL;
5858 int SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS];
5859 SUMA_Boolean LeftSide, RightSide, RightShown, LeftShown;
5860 SUMA_Boolean LocalHead = NOPE;
5861
5862 SUMA_ENTRY;
5863
5864 if (!sv->X) SUMA_RETURNe;
5865 if (!sv->X->TOPLEVEL) SUMA_RETURNe;
5866
5867 isv = SUMA_WhichSV (sv, SUMAg_SVv, SUMAg_N_SVv);
5868
5869 if (sv->X->Title) SUMA_free(sv->X->Title);
5870 sv->X->Title = NULL;
5871
5872 if (isv >= 0) sprintf(slabel,"[%c] SUMA", 65+isv);
5873 else sprintf(slabel,"[DOH] SUMA");
5874
5875 N_SOlist = SUMA_RegisteredSOs(sv, SUMAg_DOv, SOlist);
5876
5877 i = 0;
5878 nalloc = 0;
5879 LeftSide = NOPE;
5880 LeftShown = NOPE;
5881 RightSide = NOPE;
5882 RightShown = NOPE;
5883 while (i < N_SOlist) {
5884 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);
5885 if (SO->Label) {
5886 nalloc += (strlen(SO->Label)+5);
5887 }
5888 if (SO->Side == SUMA_LEFT) {
5889 SUMA_LH("Left found");
5890 LeftSide = YUP;
5891 if (sv->ShowLeft) LeftShown = YUP;
5892 } else if (SO->Side == SUMA_RIGHT) {
5893 SUMA_LH("Right found");
5894 RightSide = YUP;
5895 if (sv->ShowRight) RightShown = YUP;
5896 }
5897
5898 ++i;
5899 }
5900 if (LeftSide && LeftShown) cl = 'L';
5901 else if (LeftSide && !LeftShown) cl = 'h';
5902 else cl = 'x';
5903 if (RightSide && RightShown) cr = 'R';
5904 else if (RightSide && !RightShown) cr = 'h';
5905 else cr = 'x';
5906
5907
5908 sprintf(sside, ":%c%c:", cl, cr);
5909
5910 if (sv->Record==1) sprintf(srec,":Rec");
5911 else if (sv->Record==2) sprintf(srec,":REC");
5912 else srec[0] = '\0';
5913
5914 if (sv->GVS[sv->StdView].ApplyMomentum) sprintf(smoment,":M");
5915 else smoment[0] = '\0';
5916
5917 if (LocalHead)
5918 fprintf (SUMA_STDERR,
5919 "%s: Found %d surface models.\n", FuncName, N_SOlist);
5920
5921 i = 0;
5922 if (N_SOlist >= 0) {
5923 SUMA_LH("title surfaces found");
5924 sv->X->Title =
5925 (char *)SUMA_calloc(nalloc + strlen(slabel)+ 130, sizeof(char));
5926 sv->X->Title[0] = '\0';
5927 while (i < N_SOlist) {
5928 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);
5929 SUMA_LHv("sv->Focus_DO_ID = %d, SOlist[%d] = %d\n",
5930 sv->Focus_DO_ID, i, SOlist[i]);
5931 if (!i) {
5932 if (sv->Focus_DO_ID == SOlist[i]) {
5933 sprintf (sv->X->Title,"%s%s%s%s [%s]",
5934 slabel, srec, smoment, sside, SO->Label);
5935 } else {
5936 sprintf (sv->X->Title,"%s%s%s%s %s",
5937 slabel, srec, smoment, sside, SO->Label);
5938 }
5939 } else {
5940 sv->X->Title = strcat (sv->X->Title, " & ");
5941 if (sv->Focus_DO_ID == SOlist[i]) {
5942 sv->X->Title = strcat (sv->X->Title, " [");
5943 sv->X->Title = strcat (sv->X->Title, SO->Label);
5944 sv->X->Title = strcat (sv->X->Title, "] ");
5945 } else {
5946 sv->X->Title = strcat (sv->X->Title, SO->Label);
5947 }
5948 }
5949 ++i;
5950 }
5951 } else {
5952 SUMA_LH("No title could be made up");
5953 sv->X->Title = (char *)SUMA_calloc(strlen(slabel)+3, sizeof(char));
5954 sprintf (sv->X->Title,"%s:-", slabel);
5955 }
5956
5957 XtVaSetValues(sv->X->TOPLEVEL,
5958 XmNtitle, sv->X->Title,
5959 NULL);
5960
5961 SUMA_RETURNe;
5962 }
5963 /*!
5964 \brief updates the title string of a viewer window
5965 */
5966
SUMA_UpdateViewerTitle(SUMA_SurfaceViewer * sv)5967 void SUMA_UpdateViewerTitle(SUMA_SurfaceViewer *sv)
5968 {
5969 static char FuncName[]={"SUMA_UpdateViewerTitle"};
5970 int isv, i, N_SOlist;
5971 char cl='\0', cr='\0', *s=NULL;
5972 SUMA_SurfaceObject *SO = NULL;
5973 int SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS];
5974 SUMA_STRING *SS = NULL;
5975 SUMA_Boolean LeftSide, RightSide, RightShown, LeftShown;
5976 SUMA_Boolean LocalHead = NOPE;
5977
5978 SUMA_ENTRY;
5979
5980 if (!sv->X) SUMA_RETURNe;
5981 if (!sv->X->TOPLEVEL) SUMA_RETURNe;
5982
5983 SUMA_LH("Finding SV");
5984 isv = SUMA_WhichSV (sv, SUMAg_SVv, SUMAg_N_SVv);
5985
5986 if (sv->X->Title) SUMA_free(sv->X->Title);
5987 sv->X->Title = NULL;
5988
5989 SS = SUMA_StringAppend_va(NULL, NULL);
5990
5991 SUMA_LH("Number");
5992 if (isv >= 0) {
5993 if ((i = get_user_np_bloc())>-1) {
5994 SS = SUMA_StringAppend_va(SS, "[%c%d] SUMA", 65+isv, i);
5995 } else {
5996 SS = SUMA_StringAppend_va(SS, "[%c] SUMA", 65+isv);
5997 }
5998 } else SS = SUMA_StringAppend_va(SS,"[DOH] SUMA");
5999
6000 SUMA_LH("Rec");
6001 if (sv->Record == 1) SS = SUMA_StringAppend_va(SS,":Rec");
6002 else if (sv->Record == 2) SS = SUMA_StringAppend_va(SS,":REC");
6003
6004 SUMA_LH("Momentum");
6005 if (sv->GVS[sv->StdView].ApplyMomentum) SS = SUMA_StringAppend_va(SS,":M");
6006
6007 SUMA_LH("ClippingPlane");
6008 // if (sv->GVS[sv->StdView].ClippingPlane) SS = SUMA_StringAppend_va(SS,":C");
6009 if (sv->GVS[sv->StdView].ClippingPlane){
6010 char strTmp[32];
6011 sprintf(strTmp, ":C:Inc=%.4f", sv->clippingPlaneIncrement);
6012 SS = SUMA_StringAppend_va(SS,strTmp);
6013 }
6014
6015 SUMA_LH("Surf List");
6016 N_SOlist = SUMA_RegisteredSOs(sv, SUMAg_DOv, SOlist);
6017
6018 i = 0;
6019 LeftSide = NOPE;
6020 LeftShown = NOPE;
6021 RightSide = NOPE;
6022 RightShown = NOPE;
6023 while (i < N_SOlist) {
6024 SUMA_LH(" + +");
6025 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);
6026 if (SO->Side == SUMA_LEFT) {
6027 SUMA_LH("Left found");
6028 LeftSide = YUP;
6029 if (sv->ShowLeft) LeftShown = YUP;
6030 } else if (SO->Side == SUMA_RIGHT) {
6031 SUMA_LH("Right found");
6032 RightSide = YUP;
6033 if (sv->ShowRight) RightShown = YUP;
6034 }
6035
6036 ++i;
6037 }
6038
6039 if (LeftSide && LeftShown) cl = 'L';
6040 else if (LeftSide && !LeftShown) cl = 'h';
6041 else cl = 'x';
6042 if (RightSide && RightShown) cr = 'R';
6043 else if (RightSide && !RightShown) cr = 'h';
6044 else cr = 'x';
6045
6046 SUMA_LH("Sides");
6047
6048 SS = SUMA_StringAppend_va(SS, ":%c%c:", cl, cr);
6049
6050 SUMA_LHv("Found %d surface models.\n", N_SOlist);
6051
6052 /* add the group's name */
6053 if (LocalHead) {
6054 if (sv->CurGroupName) {
6055 SUMA_S_Notev("Calling with sv->CurGroupName = %p\n", sv->CurGroupName);
6056 } else {
6057 SUMA_S_Note("Calling with NULL sv->CurGroupName\n");
6058 }
6059 }
6060
6061 if (sv->CurGroupName) SS = SUMA_StringAppend_va(SS," %s:", sv->CurGroupName);
6062 else SS = SUMA_StringAppend_va(SS," xx:");
6063
6064 i = 0;
6065 if (N_SOlist >= 0) {
6066 SUMA_LH("title surfaces found");
6067 while (i < N_SOlist) {
6068 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);
6069 SUMA_LHv("sv->Focus_DO_ID = %d, SOlist[%d] = %d\n",
6070 sv->Focus_DO_ID, i, SOlist[i]);
6071 if (!i) {
6072 if (sv->Focus_DO_ID == SOlist[i]) {
6073 SS = SUMA_StringAppend_va(SS," [%s]", SO->Label);
6074 } else {
6075 SS = SUMA_StringAppend_va(SS," %s", SO->Label);
6076 }
6077 } else {
6078 SS = SUMA_StringAppend_va(SS," & ");
6079 if (sv->Focus_DO_ID == SOlist[i]) {
6080 SS = SUMA_StringAppend_va(SS, " [");
6081 SS = SUMA_StringAppend_va(SS, "%s", SO->Label);
6082 SS = SUMA_StringAppend_va(SS, "] ");
6083 } else {
6084 SS = SUMA_StringAppend_va(SS, "%s", SO->Label);
6085 }
6086 }
6087 ++i;
6088 }
6089 } else {
6090 SUMA_LH("No title could be made up");
6091 SS = SUMA_StringAppend_va(SS,":-");
6092 }
6093
6094 /* compact SS */
6095 SS = SUMA_StringAppend_va(SS, NULL);
6096
6097 sv->X->Title = SS->s;
6098
6099 SUMA_free(SS); SS= NULL;
6100
6101 XtVaSetValues(sv->X->TOPLEVEL,
6102 XmNtitle, sv->X->Title,
6103 NULL);
6104
6105 SUMA_RETURNe;
6106 }
6107
6108 /*!
6109 \brief finds the index into the grouplist of a certain group
6110 */
SUMA_WhichGroup(SUMA_CommonFields * cf,char * nm)6111 int SUMA_WhichGroup (SUMA_CommonFields *cf, char *nm)
6112 {
6113 static char FuncName[]={"SUMA_WhichGroup"};
6114 int i = -1;
6115
6116 SUMA_ENTRY;
6117
6118 if (!cf) {
6119 SUMA_SL_Err("Null nm");
6120 SUMA_RETURN(i);
6121 }
6122 if (!nm) nm = "ANY";
6123
6124 if (cf->N_Group <=0) { SUMA_RETURN(i); }
6125
6126 for (i=0; i<cf->N_Group; ++i) {
6127 if (!strcmp(cf->GroupList[i], nm)) SUMA_RETURN(i);
6128 }
6129
6130 SUMA_RETURN(-1);
6131 }
6132
SUMA_RegisterSpecGroup(SUMA_CommonFields * cf,SUMA_SurfSpecFile * spec)6133 SUMA_Boolean SUMA_RegisterSpecGroup (SUMA_CommonFields *cf,
6134 SUMA_SurfSpecFile *spec)
6135 {
6136 static char FuncName[]={"SUMA_RegisterSpecGroup"};
6137
6138 SUMA_ENTRY;
6139
6140 if (!spec || spec->N_Groups != 1) {
6141 SUMA_SL_Err("!Spec || Spec->N_Groups != 1. This is unacceptable.\n");
6142 SUMA_RETURN(NOPE);
6143 }
6144
6145 SUMA_RETURN(SUMA_RegisterGroup(cf, spec->Group[0]));
6146 }
6147 /*!
6148 \brief Register a new group with SUMA
6149 */
SUMA_RegisterGroup(SUMA_CommonFields * cf,char * gname)6150 SUMA_Boolean SUMA_RegisterGroup (SUMA_CommonFields *cf, char *gname)
6151 {
6152 static char FuncName[]={"SUMA_RegisterGroup"};
6153 int n=0;
6154 SUMA_Boolean LocalHead = NOPE;
6155
6156 SUMA_ENTRY;
6157
6158 if (!gname || !cf) {
6159 SUMA_S_Err("NULL gname or !cf")
6160 SUMA_RETURN(NOPE);
6161 }
6162
6163 if (!cf->GroupList){
6164 cf->GroupList = (char **) SUMA_malloc(sizeof(char*)*SUMA_MAX_N_GROUPS);
6165 for (n=0; n<SUMA_MAX_N_GROUPS; ++n) cf->GroupList[n]=NULL;
6166 cf->N_Group = 0;
6167 }
6168
6169 /* does the group exist already ? */
6170 if (SUMA_WhichGroup (cf, gname) < 0) {
6171 /* new group */
6172 SUMA_LH("Adding group");
6173 if (cf->N_Group >= SUMA_MAX_N_GROUPS) {
6174 SUMA_SL_Err("Exceeding maximum number of groups allowed.\n");
6175 SUMA_RETURN(NOPE);
6176 }
6177 cf->GroupList[cf->N_Group] = SUMA_copy_string(gname);
6178 ++cf->N_Group;
6179 } else{
6180 /* an old group */
6181 SUMA_LH("Group exists already");
6182 }
6183 SUMA_RETURN(YUP);
6184
6185 }
6186
6187 /*!
6188 \brief Returns a list of the Groups available to a viewer.
6189
6190 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer
6191
6192 \return clist (SUMA_ASSEMBLE_LIST_STRUCT *) pointer to structure containing results
6193
6194 \sa SUMA_FreeAssembleListStruct
6195 \sa SUMA_CreateAssembleListStruct
6196
6197 */
SUMA_AssembleGroupList(SUMA_SurfaceViewer * sv)6198 SUMA_ASSEMBLE_LIST_STRUCT * SUMA_AssembleGroupList (SUMA_SurfaceViewer *sv)
6199 {
6200 static char FuncName[]={"SUMA_AssembleGroupList"};
6201 SUMA_ASSEMBLE_LIST_STRUCT *clist_str = NULL;
6202 int i=-1, N_clist=-1;
6203 char *store=NULL;
6204 char **clist=NULL;
6205 void **oplist=NULL;
6206 DList *list=NULL, *listop = NULL;
6207 DListElmt *Elm = NULL, *Elmop = NULL;
6208 SUMA_Boolean Found = NOPE;
6209 SUMA_Boolean LocalHead = NOPE;
6210
6211 SUMA_ENTRY;
6212
6213 list = (DList *)SUMA_malloc(sizeof(DList));
6214 listop = (DList *)SUMA_malloc(sizeof(DList));
6215
6216 clist = NULL;
6217 N_clist = -1;
6218
6219 dlist_init(list, NULL);
6220 dlist_init(listop, NULL);
6221
6222 for (i=0; i< SUMAg_CF->N_Group; ++i) {
6223 store = SUMA_copy_string(SUMAg_CF->GroupList[i]);
6224 if (!list->size) {
6225 dlist_ins_next(list, dlist_tail(list), (void*)store);
6226 dlist_ins_next(listop, dlist_tail(listop), NULL);
6227 } else { /* must sort first */
6228 Elm = NULL;
6229 Elmop = NULL;
6230 do {
6231 Found = NOPE;
6232 if (!Elm) {
6233 Elm = dlist_head(list);
6234 Elmop = dlist_head(listop);
6235 } else {
6236 Elm = dlist_next(Elm);
6237 Elmop = dlist_next(Elmop);
6238 }
6239
6240 if (strcmp(store, (char*)Elm->data) <= 0) {
6241 dlist_ins_prev(list, Elm, (void *)store);
6242 dlist_ins_prev(listop, Elmop, NULL);
6243 Found = YUP;
6244 } else if (Elm == dlist_tail(list)) {
6245 /* reached the end, append */
6246 dlist_ins_next(list, Elm, (void *)store);
6247 dlist_ins_next(listop, Elmop, NULL);
6248 Found = YUP;
6249 }
6250 } while (!Found);
6251 }
6252 }
6253
6254 if (!list->size) { /* Nothing found */
6255 N_clist = 0;
6256
6257 }else {
6258
6259 Elm = NULL;
6260 Elmop = NULL;
6261 clist = (char **)SUMA_calloc(list->size, sizeof(char *));
6262 oplist = (void **)SUMA_calloc(list->size, sizeof(void*));
6263 for (i=0; i< list->size; ++i) {
6264 if (!Elm) {
6265 Elm = dlist_head(list);
6266 Elmop = dlist_head(listop);
6267 } else {
6268 Elm = dlist_next(Elm);
6269 Elmop = dlist_next(Elmop);
6270 }
6271 clist[i] = (char*)Elm->data;
6272 oplist[i] = Elmop->data;
6273 }
6274
6275 N_clist = list->size;
6276 /* destroy list */
6277 dlist_destroy(list);SUMA_free(list);
6278 dlist_destroy(listop);SUMA_free(listop);
6279
6280
6281 }
6282
6283 clist_str = SUMA_CreateAssembleListStruct();
6284 clist_str->clist = clist;
6285 clist_str->oplist = oplist;
6286 clist_str->N_clist = N_clist;
6287
6288 /* return */
6289 SUMA_RETURN (clist_str);
6290 }
6291
6292 /*!
6293 \brief Switch viewer between two groups
6294 */
SUMA_SwitchGroups(SUMA_SurfaceViewer * sv,char * group)6295 SUMA_Boolean SUMA_SwitchGroups (SUMA_SurfaceViewer *sv, char *group)
6296 {
6297 static char FuncName[]={"SUMA_SwitchGroups"};
6298 int ig, i, nxtstateID;
6299 SUMA_SurfaceObject *SO = NULL;
6300 DList *list = NULL;
6301 SUMA_Boolean LocalHead = NOPE;
6302
6303 SUMA_ENTRY;
6304
6305 if (!group) {
6306 SUMA_SL_Err("NULL group");
6307 SUMA_RETURN(NOPE);
6308 }
6309
6310 if (!strcmp(group, sv->CurGroupName)) {
6311 SUMA_LH("Same group, nothing to do.");
6312 SUMA_RETURN(YUP);
6313 }
6314
6315 if (SUMAg_CF->N_Group == 1) {
6316 SUMA_LH("One group, nothing to do.");
6317 SUMA_RETURN(YUP);
6318 }
6319
6320 /* which group are we going to ? */
6321 ig = SUMA_WhichGroup (SUMAg_CF, group);
6322
6323 if (ig < 0) {
6324 SUMA_SL_Err("No such group");
6325 SUMA_RETURN(NOPE);
6326 }
6327
6328 /* It does not seem necessary to close surface controllers or ROI controllers*/
6329
6330 /* find me a surface in that new group */
6331 SO = NULL;
6332 i = 0;
6333 while (!SUMA_isSO_G(SUMAg_DOv[i], group) && i < SUMAg_N_DOv) {
6334 ++i;
6335 }
6336 if (i < SUMAg_N_DOv) { /* found a surface */
6337 SO = (SUMA_SurfaceObject *)SUMAg_DOv[i].OP;
6338 } else {
6339 SUMA_SL_Err("No candidate surface");
6340 SUMA_RETURN(NOPE);
6341 }
6342
6343 /* what is the state ID of that surface ? */
6344 nxtstateID = SUMA_WhichState(SO->State, sv, SO->Group);
6345 if (nxtstateID < 0) {
6346 SUMA_SL_Err("Bad! State not found.");
6347 SUMA_RETURN(NOPE);
6348 }
6349
6350 if (!SUMA_SwitchState (SUMAg_DOv, SUMAg_N_DOv, sv, nxtstateID, group)) {
6351 SUMA_SL_Err("Failed to switch states");
6352 SUMA_RETURN(NOPE);
6353 }
6354
6355 /* home call */
6356
6357 #if 0
6358 /* now redisplay (won't work alone with multiple viewers, GL state problems) */
6359 if (!list) list = SUMA_CreateList();
6360 /* SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Home, SES_Suma, sv); */
6361 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay, SES_Suma, sv);
6362
6363 if (!SUMA_Engine (&list)) {
6364 fprintf(stderr, "Error %s: SUMA_Engine call failed.\n", FuncName);
6365 }
6366 #elif 0
6367 /* redisplay all others (won't work alone with multiple viewers, GL state problems) */
6368 if (!list) list = SUMA_CreateList ();
6369 SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list,
6370 SE_RedisplayNow_AllOtherVisible, SES_SumaWidget, sv);
6371 SUMA_Engine (&list);
6372
6373 /* redisplay . DO NOT REDISPLAY WITH SE_Redisplay_AllVisible
6374 or you will have GL state synchronization problems */
6375 sv->ResetGLStateVariables = YUP;
6376 SUMA_handleRedisplay((XtPointer)sv->X->GLXAREA);
6377 #elif 1
6378
6379 /* got to do this, in addition to SE_Redisplay_AllVisible
6380 to get the views to look good. I don't know why that is yet */
6381 for (i=0; i < SUMAg_N_SVv; ++i) {
6382 SUMA_SurfaceViewer *svtmp= &(SUMAg_SVv[i]);
6383 if (!svtmp->isShaded && svtmp->X->TOPLEVEL) {
6384 if (!list) list = SUMA_CreateList();
6385 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Home,
6386 SES_Suma, svtmp);
6387 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_RedisplayNow,
6388 SES_Suma, svtmp);
6389 if (!SUMA_Engine (&list)) {
6390 SUMA_S_Err("SUMA_Engine call failed.");
6391 }
6392 }
6393 }
6394
6395 if (!list) list = SUMA_CreateList();
6396 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
6397 SES_Suma, sv);
6398 if (!SUMA_Engine (&list)) {
6399 SUMA_S_Err("SUMA_Engine call failed.");
6400 }
6401
6402 #endif
6403
6404 /* update titles */
6405 SUMA_UpdateViewerTitle(sv);
6406
6407
6408 SUMA_RETURN(YUP);
6409 }
6410
6411 /* Return a viewer's surface in focus, if there is a surface and it is
6412 in focus */
SUMA_SV_Focus_SO(SUMA_SurfaceViewer * sv)6413 SUMA_SurfaceObject *SUMA_SV_Focus_SO(SUMA_SurfaceViewer *sv)
6414 {
6415 static char FuncName[]={"SUMA_SV_Focus_SO"};
6416 if (!sv || sv->Focus_DO_ID < 0) return(NULL);
6417 if (SUMAg_DOv[sv->Focus_DO_ID].ObjectType == SO_type) {
6418 return((SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_DO_ID].OP));
6419 }
6420 return(NULL);
6421 }
6422
SUMA_SV_Focus_any_SO(SUMA_SurfaceViewer * sv,int * dov_id)6423 SUMA_SurfaceObject *SUMA_SV_Focus_any_SO(SUMA_SurfaceViewer *sv, int *dov_id)
6424 {
6425 static char FuncName[]={"SUMA_SV_Focus_any_SO"};
6426 SUMA_SurfaceObject *SO=NULL;
6427 int ii;
6428
6429 if (dov_id) *dov_id = -1;
6430
6431 if (sv && sv->Focus_DO_ID >= 0 &&
6432 SUMAg_DOv[sv->Focus_DO_ID].ObjectType == SO_type) {
6433 if (dov_id) *dov_id = sv->Focus_DO_ID;
6434 return((SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_DO_ID].OP));
6435 }
6436
6437 /* give me anything */
6438 SO = SUMA_findanySOp_inDOv(SUMAg_DOv, SUMAg_N_DOv, dov_id);
6439 return(SO);
6440 }
6441
SUMA_SV_Focus_ADO(SUMA_SurfaceViewer * sv)6442 SUMA_ALL_DO *SUMA_SV_Focus_ADO(SUMA_SurfaceViewer *sv)
6443 {
6444 static char FuncName[]={"SUMA_SV_Focus_ADO"};
6445 if (!sv || sv->Focus_DO_ID < 0) return(NULL);
6446 return((SUMA_ALL_DO *)(SUMAg_DOv[sv->Focus_DO_ID].OP));
6447 return(NULL);
6448 }
6449
SUMA_findanyFocusable_ADO(int * dov_id)6450 SUMA_ALL_DO *SUMA_findanyFocusable_ADO(int *dov_id)
6451 {
6452 static char FuncName[]={"SUMA_findanyFocusable_ADO"};
6453 SUMA_ALL_DO *ado=NULL;
6454 int ii;
6455 void *pp;
6456
6457 if (dov_id) *dov_id = -1;
6458 if ((ado = (SUMA_ALL_DO *)SUMA_findanySOp_inDOv(
6459 SUMAg_DOv, SUMAg_N_DOv, dov_id))) return(ado);
6460 if ((ado = (SUMA_ALL_DO *)SUMA_FindDset_eng("NA",
6461 SUMAg_CF->DsetList, NULL, "isGraphDset"))) return(ado);
6462 if ((ado = (SUMA_ALL_DO *)SUMA_findanyVOp_inDOv(
6463 SUMAg_DOv, SUMAg_N_DOv, dov_id))) return(ado);
6464 if ((ado = (SUMA_ALL_DO *)SUMA_findanyTDOp_inDOv(
6465 SUMAg_DOv, SUMAg_N_DOv, dov_id))) return(ado);
6466 return(NULL);
6467 }
6468
SUMA_SV_Focus_any_ADO(SUMA_SurfaceViewer * sv,int * dov_id)6469 SUMA_ALL_DO *SUMA_SV_Focus_any_ADO(SUMA_SurfaceViewer *sv, int *dov_id)
6470 {
6471 static char FuncName[]={"SUMA_SV_Focus_any_ADO"};
6472 SUMA_ALL_DO *ado=NULL;
6473 int ii;
6474
6475 if (dov_id) *dov_id = -1;
6476
6477 if (sv && sv->Focus_DO_ID >= 0) {
6478 if (dov_id) *dov_id = sv->Focus_DO_ID;
6479 return((SUMA_ALL_DO *)(SUMAg_DOv[sv->Focus_DO_ID].OP));
6480 }
6481
6482 /* give me anything */
6483 ado = SUMA_findanyFocusable_ADO(dov_id);
6484 return(ado);
6485 }
6486
SUMA_SV_any_ADO_WithSurfContWidget(SUMA_SurfaceViewer * sv,int * dov_id,SUMA_DO_Types thisdotp)6487 SUMA_ALL_DO *SUMA_SV_any_ADO_WithSurfContWidget(SUMA_SurfaceViewer *sv,
6488 int *dov_id, SUMA_DO_Types thisdotp)
6489 {
6490 static char FuncName[]={"SUMA_SV_any_ADO_WithSurfContWidget"};
6491 SUMA_ALL_DO *ado=NULL;
6492 SUMA_X_SurfCont *SurfCont=NULL;
6493 int ii;
6494
6495 if (dov_id) *dov_id = -1;
6496
6497 if (sv && sv->Focus_DO_ID >= 0 &&
6498 (SurfCont = SUMA_ADO_Cont(
6499 (SUMA_ALL_DO *)(SUMAg_DOv[sv->Focus_DO_ID].OP))) &&
6500 SurfCont->TLS) {
6501 if (dov_id) *dov_id = sv->Focus_DO_ID;
6502 return((SUMA_ALL_DO *)(SUMAg_DOv[sv->Focus_DO_ID].OP));
6503 }
6504
6505 /* give me anything */
6506 ado = SUMA_findany_ADO_WithSurfContWidget(dov_id, thisdotp);
6507 return(ado);
6508 }
6509
SUMA_findany_ADO_WithSurfContWidget(int * dov_id,SUMA_DO_Types thisdotp)6510 SUMA_ALL_DO *SUMA_findany_ADO_WithSurfContWidget(int *dov_id,
6511 SUMA_DO_Types thisdotp)
6512 {
6513 static char FuncName[]={"SUMA_findany_ADO_WithSurfContWidget"};
6514 SUMA_ALL_DO *ado=NULL;
6515 SUMA_DO_Types ttv[N_DO_TYPES] = { SO_type, GRAPH_LINK_type,
6516 VO_type, TRACT_type, CDOM_type,
6517 NOT_SET_type };
6518 int ii, tt;
6519 void *pp;
6520 SUMA_X_SurfCont *SurfCont=NULL;
6521
6522 if (dov_id) *dov_id = -1;
6523 if (thisdotp != NOT_SET_type) {
6524 ttv[0] = thisdotp;
6525 ttv[1] = NOT_SET_type;
6526 }
6527
6528 tt = 0;
6529 while (ttv[tt] != NOT_SET_type) {
6530 for (ii=0; ii<SUMAg_N_DOv; ++ii) {
6531 if (iDO_type(ii) == ttv[tt]) {
6532 ado = iDO_ADO(ii);
6533 if ((SurfCont = SUMA_ADO_Cont(ado)) &&
6534 SurfCont->TLS) {
6535 if (dov_id) *dov_id = ii;
6536 return(ado);
6537 }
6538 }
6539 }
6540 ++tt;
6541 }
6542 return(NULL);
6543 }
6544
SUMA_SurfCont_GetcurDOp(SUMA_X_SurfCont * SurfCont)6545 SUMA_ALL_DO *SUMA_SurfCont_GetcurDOp(SUMA_X_SurfCont *SurfCont)
6546 {
6547 static char FuncName[]={"SUMA_SurfCont_GetcurDOp"};
6548 SUMA_Boolean LocalHead = NOPE;
6549
6550 if (SurfCont && SurfCont->prv_curDOp) {
6551 SUMA_ALL_DO *ado = (SUMA_ALL_DO *)*(SurfCont->prv_curDOp);
6552 if (!ado) return(NULL); /* This will happen if controller not yet open */
6553 SUMA_LHv("ADO Type name %s, variant %s\n",
6554 ADO_TNAME(ado), SurfCont->prv_variant);
6555 switch (ado->do_type) {
6556 case GRAPH_LINK_type:
6557 SUMA_S_Err("This should not be, See SUMA_SurfCont_SetcurDOp");
6558 return(NULL);
6559 break;
6560 case GDSET_type:
6561 return((SUMA_ALL_DO *)SUMA_find_Dset_GLDO((SUMA_DSET *)ado,
6562 SurfCont->prv_variant,NULL));
6563 break;
6564 default:
6565 return(ado);
6566 break;
6567 }
6568 }
6569 return(NULL);
6570 }
6571
SUMA_SurfCont_SetcurDOp(SUMA_X_SurfCont * SurfCont,SUMA_ALL_DO * ado)6572 SUMA_Boolean SUMA_SurfCont_SetcurDOp(SUMA_X_SurfCont *SurfCont, SUMA_ALL_DO *ado)
6573 {
6574 static char FuncName[]={"SUMA_SurfCont_SetcurDOp"};
6575 SUMA_Boolean LocalHead = NOPE;
6576
6577 if (!(SurfCont && SurfCont->prv_curDOp && ado)) return(NOPE);
6578
6579 switch(ado->do_type) {
6580 case SO_type:
6581 *(SurfCont->prv_curDOp) = (void *)ado;
6582 return(YUP);
6583 break;
6584 case GRAPH_LINK_type: /* Store the GDSET, a pointer of some permanence,
6585 NOT gldo which has no right to property*/
6586 *(SurfCont->prv_curDOp) =
6587 (void *)SUMA_find_GLDO_Dset((SUMA_GraphLinkDO*)ado);
6588 SurfCont->prv_variant = SUMA_replace_string(SurfCont->prv_variant,
6589 SUMA_ADO_variant(ado));
6590 SUMA_LHv("Now have %p, %s\n",
6591 *(SurfCont->prv_curDOp), SurfCont->prv_variant);
6592 return(YUP);
6593 break;
6594 case GDSET_type:
6595 SUMA_S_Err( "You should not set the current DOp to a DO that has\n"
6596 "ambiguous rendering\n");
6597 return(NOPE);
6598 break;
6599 SUMA_S_Err("Have to figure out this machinery");
6600 return(NOPE);
6601 break;
6602 case CDOM_type:
6603 case TRACT_type:
6604 *(SurfCont->prv_curDOp) = (void *)ado;
6605 return(YUP);
6606 break;
6607 case MASK_type:
6608 case VO_type:
6609 *(SurfCont->prv_curDOp) = (void *)ado;
6610 return(YUP);
6611 break;
6612 default:
6613 SUMA_S_Warnv("Not ready for the likes of %s\n",
6614 SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
6615 return(NOPE);
6616 break;
6617 }
6618 return(NOPE);
6619
6620 }
6621
6622
SUMA_SetMouseMode(SUMA_SurfaceViewer * sv,SUMA_MOUSE_MODES mmode,void * val)6623 SUMA_Boolean SUMA_SetMouseMode(SUMA_SurfaceViewer *sv,
6624 SUMA_MOUSE_MODES mmode, void *val)
6625 {
6626 static char FuncName[]={"SUMA_SetMouseMode"};
6627 int ival;
6628 SUMA_ALL_DO *ado;
6629 SUMA_Boolean LocalHead = NOPE;
6630
6631 SUMA_ENTRY;
6632
6633 if (!sv) SUMA_RETURN(NOPE);
6634
6635 SUMA_LH("Should this function handle cross hair modification?");
6636
6637 switch (mmode) {
6638 case SUMA_ROI_MMODE:
6639 ival = (int)(long int)val; /* Double cast to quiet compiler warning */
6640 if (ival) {
6641 if (SUMAg_CF->ROI_mode==YUP) { /* nothing to do */
6642 SUMA_RETURN(YUP);
6643 } else {
6644 /* Need to turn on ROI_mode, and kill other modes */
6645 SUMAg_CF->ROI_mode = YUP; // [PT: Feb 22, 2021] fix '='
6646 sv->MouseMode = SUMA_DEF_MMODE;
6647 SUMA_RETURN(YUP);
6648 }
6649 } else {
6650 if (SUMAg_CF->ROI_mode==NOPE) { /* nothing to do */
6651 SUMA_RETURN(YUP);
6652 } else {
6653 /* Need to turn off ROI_mode */
6654 SUMAg_CF->ROI_mode = NOPE; // [PT: Feb 22, 2021] fix '='
6655 SUMA_RETURN(YUP);
6656 }
6657 }
6658 break;
6659 case SUMA_MASK_MANIP_MMODE:
6660 if (val) {
6661 if (SUMAg_CF->ROI_mode == YUP) SUMAg_CF->ROI_mode = NOPE;
6662 sv->MouseMode = SUMA_MASK_MANIP_MMODE;
6663 if ((ado=SUMA_whichADOg(sv->MouseMode_ado_idcode_str)) &&
6664 ado->do_type == MASK_type) {
6665 SUMA_MDO_New_parent((SUMA_MaskDO*)ado, val, -1);
6666 }
6667 SUMA_ifree(sv->MouseMode_ado_idcode_str);
6668 sv->MouseMode_ado_idcode_str = SUMA_copy_string((char*)val);
6669 } else if (sv->MouseMode == SUMA_MASK_MANIP_MMODE) {
6670 sv->MouseMode = SUMA_DEF_MMODE;
6671 SUMA_ifree(sv->MouseMode_ado_idcode_str);
6672 if ((ado=SUMA_whichADOg(sv->MouseMode_ado_idcode_str)) &&
6673 ado->do_type == MASK_type) {
6674 SUMA_MDO_New_parent((SUMA_MaskDO*)ado, NULL, -1);
6675 }
6676 }
6677 SUMA_RETURN(YUP);
6678 break;
6679 case SUMA_DEF_MMODE:
6680 sv->MouseMode = SUMA_DEF_MMODE;
6681 SUMA_RETURN(YUP);
6682 break;
6683 default:
6684 SUMA_S_Err("Not ready for %d", mmode);
6685 break;
6686 }
6687 SUMA_RETURN(NOPE);
6688 }
6689
SUMA_ADO_ContName(SUMA_ALL_DO * ado)6690 char *SUMA_ADO_ContName(SUMA_ALL_DO *ado)
6691 {
6692 if (!ado) return("NULL");
6693 switch(ado->do_type) {
6694 case MASK_type:
6695 return ("Mask");
6696 case GRAPH_LINK_type:
6697 return ("Graph");
6698 case TRACT_type:
6699 return ("Network");
6700 case VO_type:
6701 return ("Volume");
6702 case SO_type:
6703 return ("Surface");
6704 default:
6705 return ("Not set");
6706 }
6707 return("Should not get here");
6708 }
6709
6710