Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

SUMA_SVmanip.c

Go to the documentation of this file.
00001 
00002 #include "SUMA_suma.h"
00003 
00004 extern SUMA_CommonFields *SUMAg_CF;
00005 extern int SUMAg_N_DOv; 
00006 extern SUMA_DO *SUMAg_DOv;
00007 extern SUMA_SurfaceViewer *SUMAg_SVv;
00008 extern int SUMAg_N_SVv;
00009 
00010 /* This is used to hold the functions that manipulate SV, Surface Viewer Structures */
00011 /*! 
00012 \brief returns a string corresponding to the link type
00013 
00014 SUMA_Boolean SUMA_LockEnum_LockType (SUMA_LINK_TYPES i, char *Name);
00015 \param i (SUMA_LINK_TYPES) see enum type in SUMA_define.h
00016 \param Name (char *) a preallocated character string (no more than 50 chars)
00017 \return YUP/NOPE OK, error
00018 */
00019 SUMA_Boolean SUMA_LockEnum_LockType (SUMA_LINK_TYPES i, char *Name)
00020 {
00021    static char FuncName[]={"SUMA_LockEnum_LockType"};
00022    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);   
00023    
00024    switch (i) {
00025       case SUMA_No_Lock:
00026          sprintf (Name, "No Lock");
00027          break;
00028       case SUMA_I_Lock:
00029          sprintf (Name, "Index Lock");
00030          break;
00031       case SUMA_XYZ_Lock:
00032          sprintf (Name, "XYZ Lock");
00033          break;
00034       default:
00035          sprintf (Name, "?");
00036          SUMA_RETURN (NOPE);
00037          
00038    }
00039    
00040    SUMA_RETURN (YUP);
00041 }
00042 /*!
00043 Create a SurfaceViewer data structure
00044 */
00045 SUMA_SurfaceViewer *SUMA_Alloc_SurfaceViewer_Struct (int N)
00046 {
00047    SUMA_SurfaceViewer *SV, *SVv;
00048    static char FuncName[]={"SUMA_Alloc_SurfaceViewer_Struct"};
00049    int i, j;
00050    
00051    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00052 
00053    SVv =  (SUMA_SurfaceViewer *)SUMA_malloc(sizeof(SUMA_SurfaceViewer)*N);
00054    if (SVv == NULL) {
00055       fprintf(SUMA_STDERR,"Error %s: Failed to SUMA_malloc SV\n", FuncName);
00056       SUMA_RETURN (NULL);
00057    }
00058    for (i=0; i < N; ++i) {
00059       SV = &(SVv[i]);
00060       
00061       SV->N_GVS = SUMA_N_STANDARD_VIEWS;
00062       SV->GVS = (SUMA_GEOMVIEW_STRUCT *)SUMA_malloc(sizeof(SUMA_GEOMVIEW_STRUCT)*SV->N_GVS);
00063       if (!SV->GVS) {
00064          fprintf(SUMA_STDERR,"Error %s: Could not allocate for N_GVS.\n", FuncName);
00065          SUMA_RETURN (NULL);
00066       }
00067       SV->StdView = SUMA_3D; /* default */
00068       
00069       /* set the standards for all viewing modes here */
00070       SV->verbose = 1;
00071       SV->Aspect = 1.0;
00072       SV->FOV = NULL;
00073       for (j=0; j < SV->N_GVS; ++j) {
00074          switch (j) {
00075             case SUMA_2D_Z0:
00076                SV->GVS[j].currentQuat[0] = 0.252199;
00077                SV->GVS[j].currentQuat[1] = -0.129341;
00078                SV->GVS[j].currentQuat[2] = -0.016295;
00079                SV->GVS[j].currentQuat[3] = 0.958854;
00080 
00081                SV->GVS[j].ApplyMomentum = False;
00082 
00083                SV->GVS[j].MinIdleDelta = 1;
00084                SV->GVS[j].TranslateGain = TRANSLATE_GAIN;
00085                SV->GVS[j].ArrowtranslateDeltaX = ARROW_TRANSLATE_DELTAX;
00086                SV->GVS[j].ArrowtranslateDeltaY = ARROW_TRANSLATE_DELTAY;
00087 
00088                SV->GVS[j].ViewCamUp[0] = 0.0;
00089                SV->GVS[j].ViewCamUp[1] = 1.0;
00090                SV->GVS[j].ViewCamUp[2] = 0.0;
00091 
00092                SV->GVS[j].ViewFrom[0] = 0.0;
00093                SV->GVS[j].ViewFrom[1] = 0.0;
00094                SV->GVS[j].ViewFrom[2] = SUMA_DEFAULT_VIEW_FROM;
00095 
00096                SV->GVS[j].ViewCenter[0] = 0.0;
00097                SV->GVS[j].ViewCenter[1] = 0.0;
00098                SV->GVS[j].ViewCenter[2] = 0.0;
00099 
00100                SV->GVS[j].RotaCenter[0] = 0.0;
00101                SV->GVS[j].RotaCenter[1] = 0.0;
00102                SV->GVS[j].RotaCenter[2] = 0.0;
00103                break;
00104             case SUMA_3D:
00105                SV->GVS[j].currentQuat[0] = 0.252199;
00106                SV->GVS[j].currentQuat[1] = -0.129341;
00107                SV->GVS[j].currentQuat[2] = -0.016295;
00108                SV->GVS[j].currentQuat[3] = 0.958854;
00109 
00110                SV->GVS[j].ApplyMomentum = False;
00111 
00112                SV->GVS[j].MinIdleDelta = 1;
00113                SV->GVS[j].TranslateGain = TRANSLATE_GAIN;
00114                SV->GVS[j].ArrowtranslateDeltaX = ARROW_TRANSLATE_DELTAX;
00115                SV->GVS[j].ArrowtranslateDeltaY = ARROW_TRANSLATE_DELTAY;
00116 
00117                SV->GVS[j].ViewCamUp[0] = 0.0;
00118                SV->GVS[j].ViewCamUp[1] = 1.0;
00119                SV->GVS[j].ViewCamUp[2] = 0.0;
00120 
00121                SV->GVS[j].ViewFrom[0] = 0.0;
00122                SV->GVS[j].ViewFrom[1] = 0.0;
00123                SV->GVS[j].ViewFrom[2] = 0.0;
00124 
00125                SV->GVS[j].ViewCenter[0] = 0.0;
00126                SV->GVS[j].ViewCenter[1] = 0.0;
00127                SV->GVS[j].ViewCenter[2] = 0.0;
00128 
00129                SV->GVS[j].RotaCenter[0] = 0.0;
00130                SV->GVS[j].RotaCenter[1] = 0.0;
00131                SV->GVS[j].RotaCenter[2] = 0.0;
00132                
00133                SV->GVS[j].translateVec[0] = 0.0;
00134                SV->GVS[j].translateVec[1] = 0.0;
00135                break;
00136             default:
00137                fprintf(SUMA_STDERR,"Error %s: Undefined viewing mode.\n", FuncName);
00138                SUMA_RETURN (NULL);
00139                
00140          }
00141       }
00142       
00143 
00144       SV->light0_position[0] = 0.0;
00145       SV->light0_position[1] = 0.0;
00146       
00147       SV->light0_position[2] = 1.0 * SUMA_INTITIAL_LIGHT0_SWITCH; 
00148       SV->light0_position[3] = 0.0;
00149 
00150       SV->light1_position[0] = 1.0;
00151       SV->light1_position[1] = 1.0;
00152       SV->light1_position[2] = 1.0;
00153       SV->light1_position[3] = 0.0;
00154 
00155       SV->clear_color[0] = SUMA_CLEAR_COLOR_R;
00156       SV->clear_color[1] = SUMA_CLEAR_COLOR_G;
00157       SV->clear_color[2] = SUMA_CLEAR_COLOR_B;
00158       SV->clear_color[3] = SUMA_CLEAR_COLOR_A;
00159       
00160       SV->WindWidth = 350;
00161       SV->WindHeight = 350;
00162       
00163       SV->Open = NOPE;
00164       
00165       SV->ShowDO = (int *)SUMA_calloc( SUMA_MAX_DISPLAYABLE_OBJECTS, sizeof(int));
00166       if (SV->ShowDO == NULL) {
00167          fprintf(stderr,"Error SUMA_Alloc_SurfaceViewer_Struct: Failed to SUMA_malloc SV->ShowDO\n");
00168          SUMA_RETURN (NULL);
00169       }
00170       SV->N_DO = 0; /* Nothing is registered with the viewer yet */
00171 
00172       SV->ColList = (SUMA_COLORLIST_STRUCT *) SUMA_malloc( sizeof(SUMA_COLORLIST_STRUCT) * SUMA_MAX_DISPLAYABLE_OBJECTS);
00173       SV->N_ColList = 0; /* this number reflects the number of surfaces that have colorlist structures in SV */
00174       /* initialize fields */
00175       for (j=0; j<SUMA_MAX_DISPLAYABLE_OBJECTS; ++j) {
00176          SV->ColList[j].idcode_str = NULL;
00177          SV->ColList[j].glar_ColorList = NULL;
00178          SV->ColList[j].N_glar_ColorList = 0;
00179          SV->ColList[j].Remix = NOPE;
00180       }
00181       
00182       
00183       SV->ShowEyeAxis = 1;
00184       SV->ShowMeshAxis = 1;
00185       
00186       SV->Ch = SUMA_Alloc_CrossHair ();
00187       if (SV->Ch == NULL) {
00188          fprintf(stderr,"Error SUMA_Alloc_SurfaceViewer_Struct: Failed in SUMA_Alloc_CrossHair\n");
00189          SUMA_RETURN (NULL); 
00190       } else SV->ShowCrossHair = 1;
00191       
00192       SV->X = (SUMA_X *)SUMA_malloc(sizeof(SUMA_X));
00193       if (SV->X == NULL) {
00194          fprintf(stderr,"Error SUMA_Alloc_SurfaceViewer_Struct: Failed to SUMA_malloc SV->X\n");
00195          SUMA_RETURN (NULL);
00196       }
00197 
00198       SV->X->Title = NULL;
00199       SV->X->LookAt_prmpt = NULL;
00200       SV->X->JumpIndex_prmpt = NULL;
00201       SV->X->JumpXYZ_prmpt = NULL;
00202       SV->X->JumpFocusNode_prmpt = NULL;
00203       SV->X->JumpFocusFace_prmpt = NULL;
00204       SV->X->HighlightBox_prmpt = NULL;
00205       SV->X->TOPLEVEL = NULL;
00206       SV->X->MOMENTUMID = 0;
00207       SV->X->REDISPLAYPENDING = 0;
00208       SV->X->DOUBLEBUFFER = True;
00209       SV->X->WIDTH = SV->X->HEIGHT = 300; /* if you change this, make sure you do so for fallbackResources in SUMA_display */
00210       SV->X->ViewCont = SUMA_CreateViewContStruct();
00211       
00212       SV->Focus_SO_ID = -1;
00213       SV->Focus_DO_ID = -1;
00214       
00215       SV->VSv = NULL;
00216       SV->N_VSv = 0;
00217       SV->LastNonMapStateID = -1;
00218       
00219       SV->PolyMode = SRM_Fill;
00220       
00221       #if SUMA_BACKFACE_CULL
00222          SV->BF_Cull = YUP;
00223       #else
00224          SV->BF_Cull = NOPE;
00225       #endif
00226 
00227       SV->ShowForeground = YUP;
00228       SV->ShowBackground = YUP;
00229       SV->Back_Modfact = SUMA_BACKGROUND_MODULATION_FACTOR;
00230       
00231       SV->isShaded = NOPE; 
00232       
00233       SV->LinkAfniCrossHair = YUP;
00234       
00235       SV->ResetGLStateVariables = YUP;
00236       
00237       SV->BS = NULL;
00238    }
00239    SUMA_RETURN (SVv);
00240 }
00241 
00242 SUMA_Boolean SUMA_Free_SurfaceViewer_Struct (SUMA_SurfaceViewer *SV)
00243 {
00244    static char FuncName[]={"SUMA_Free_SurfaceViewer_Struct"};
00245    int i;
00246    
00247    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00248 
00249    if (SV->Ch) SUMA_Free_CrossHair (SV->Ch);
00250    if (SV->X->Title) SUMA_free(SV->X->Title);
00251    if (SV->X->LookAt_prmpt) SUMA_FreePromptDialogStruct (SV->X->LookAt_prmpt);
00252    if (SV->X->JumpIndex_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpIndex_prmpt);
00253    if (SV->X->JumpXYZ_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpXYZ_prmpt);
00254    if (SV->X->JumpFocusNode_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpFocusNode_prmpt);
00255    if (SV->X->JumpFocusFace_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpFocusFace_prmpt);
00256    if (SV->X->HighlightBox_prmpt) SUMA_FreePromptDialogStruct (SV->X->HighlightBox_prmpt);
00257    if (SV->X->ViewCont) SUMA_FreeViewContStruct(SV->X->ViewCont);
00258    if (SV->X) SUMA_free(SV->X);
00259    if (SV->ShowDO) SUMA_free(SV->ShowDO);
00260    if (SV->VSv) {
00261       for (i=0; i < SV->N_VSv; ++i) {
00262          if (!SUMA_Free_ViewState (&(SV->VSv[i]))) {
00263             fprintf (SUMA_STDERR,"Error %s: failed in SUMA_Free_ViewState.\n", FuncName);
00264          }
00265       }
00266    }
00267    if (SV->GVS) SUMA_free(SV->GVS);
00268    if (SV->State) SV->State = NULL; /* never free that one */ 
00269    if (SV->ColList) {
00270       for (i=0; i < SV->N_ColList; ++i) {
00271          if (!SUMA_EmptyColorList (SV, NULL)) fprintf (SUMA_STDERR,"Error %s: failed in SUMA_EmptyColorList.\n", FuncName);
00272       }
00273       /* done dumping structure contents, now free pointer */
00274       SUMA_free(SV->ColList); 
00275       SV->ColList = NULL; 
00276       SV->N_ColList = 0;
00277    }
00278    
00279    if (SV->BS) {
00280       SUMA_EmptyDestroyList(SV->BS);
00281    }
00282    
00283    SUMA_RETURN(YUP);
00284 }
00285 
00286 SUMA_Boolean SUMA_Free_SurfaceViewer_Struct_Vect (SUMA_SurfaceViewer *SVv, int N)
00287 {
00288    static char FuncName[]={"SUMA_Free_SurfaceViewer_Struct_Vect"};
00289    int i;
00290    SUMA_Boolean Ret= YUP;
00291    
00292    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00293 
00294    for (i=0; i < N; ++i)  {
00295       if (&SVv[i] != NULL) {
00296          Ret = Ret * SUMA_Free_SurfaceViewer_Struct (&SVv[i]);
00297       }
00298    }
00299    
00300    if (SVv) SUMA_free(SVv);
00301    SUMA_RETURN(Ret);
00302 }
00303 
00304 /*!
00305 \brief ans = SUMA_FillColorList (sv, so);
00306 Creates a colorlist structure for a certain surface.   
00307 
00308 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer
00309 \param so (SUMA_SurfaceObject *) pointer to surface object
00310 
00311 Remix flag is set to YUP since this function is called when surfaces are beging registered
00312 with a viewer and a remix is highly likely.
00313 
00314 \return ans YUP/NOPE
00315 
00316 */
00317 SUMA_Boolean SUMA_FillColorList (SUMA_SurfaceViewer *sv, SUMA_SurfaceObject *SO)
00318 {
00319    static char FuncName[]={"SUMA_FillColorList"};
00320    int i;
00321    SUMA_Boolean LocalHead = NOPE;
00322    
00323    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00324    
00325    if (LocalHead) fprintf (SUMA_STDERR,"%s: Filling a color list for surface %s (%s).\n", FuncName, SO->Label, SO->idcode_str);
00326 
00327    if (!SO->idcode_str) {
00328       fprintf (SUMA_STDERR,"Error %s: SO->idcode_str is NULL.\n", FuncName);
00329       SUMA_RETURN (NOPE);
00330    }
00331    
00332    /* make sure SO->idcode_str is not in the list already */
00333    for (i=0; i<sv->N_ColList; ++i) {
00334       if (strcmp (SO->idcode_str, sv->ColList[i].idcode_str) == 0) {
00335          fprintf (SUMA_STDERR,"Error %s: SO->idcode_str is already in sv->ColList.\n", FuncName);
00336          SUMA_RETURN (NOPE);
00337       }
00338    }
00339    
00340    /* create the ColList struct */
00341    if (sv->ColList[sv->N_ColList].glar_ColorList) {
00342       fprintf (SUMA_STDERR,"Error %s: glar_ColorList is not NULL. Cannot reallocate.\n", FuncName);
00343       SUMA_RETURN (NOPE);
00344    }
00345    
00346    sv->ColList[sv->N_ColList].glar_ColorList = (GLfloat *) SUMA_calloc (SO->N_Node*4, sizeof(GLfloat));
00347    sv->ColList[sv->N_ColList].idcode_str = (char *)SUMA_malloc((strlen(SO->idcode_str)+1) * sizeof(char));
00348    
00349    if (!sv->ColList[sv->N_ColList].glar_ColorList || !sv->ColList[sv->N_ColList].idcode_str) {
00350       fprintf (SUMA_STDERR,"Error %s: Failed to allocate for glar_ColorList or idcode_str.\n", FuncName);
00351       SUMA_RETURN (NOPE);
00352    }
00353    
00354    sv->ColList[sv->N_ColList].idcode_str = strcpy (sv->ColList[sv->N_ColList].idcode_str, SO->idcode_str);
00355    if (LocalHead) fprintf (SUMA_STDERR, "%s: sv->ColList[%d].idcode_str=%s is about to be filled.\n", \
00356                FuncName, sv->N_ColList, sv->ColList[sv->N_ColList].idcode_str);
00357 
00358    /* fill up with blanks, may be unecessary ... */
00359    sv->ColList[sv->N_ColList].N_glar_ColorList = SO->N_Node*4;
00360    i=0;
00361    while (i < sv->ColList[sv->N_ColList].N_glar_ColorList) {
00362       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_GRAY_NODE_COLOR; ++i;
00363       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_GRAY_NODE_COLOR; ++i;
00364       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_GRAY_NODE_COLOR; ++i;
00365       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_NODE_ALPHA; ++i;
00366    }
00367    sv->ColList[sv->N_ColList].Remix = YUP; 
00368 
00369    ++sv->N_ColList;
00370    
00371    SUMA_RETURN (YUP);
00372 
00373 }
00374 
00375 /*!
00376    glar_ColorList = SUMA_GetColorList (sv, DO_idstr);
00377    returns the pointer to the colorlist of the DO (or SO) with ID string DO_idstr
00378    
00379    \param sv (SUMA_SurfaceViewer *) pointer to surface viewer in question
00380    \param DO_idstr (char *) ID string of DO (usually a Surface Object) 
00381    \return glar_ColorList (GLfloat *) a pointer to the array containing node colors 
00382 */
00383 GLfloat * SUMA_GetColorList (SUMA_SurfaceViewer *sv, char *DO_idstr)
00384 {
00385    static char FuncName[]={"SUMA_GetColorList"};
00386    int i;
00387    GLfloat * glar_ColorList = NULL;
00388    SUMA_Boolean Found = NOPE;
00389    
00390    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00391    
00392    if (!DO_idstr) {
00393       fprintf (SUMA_STDERR,"Error %s: DO_idstr is NULL, this should not be.\n", FuncName);
00394       SUMA_RETURN (NULL);
00395    }
00396    
00397    /* find the culprit */
00398    Found = NOPE;
00399    i = 0;
00400    while (!Found && i < sv->N_ColList) {
00401       if (strcmp (DO_idstr, sv->ColList[i].idcode_str) == 0) {
00402          Found = YUP;
00403          SUMA_RETURN (sv->ColList[i].glar_ColorList);      
00404       }
00405       ++i;
00406    }
00407    
00408    if (!Found) {
00409       fprintf (SUMA_STDERR,"Error %s: DO_idstr was not found.\n", FuncName);
00410       SUMA_RETURN (NULL);
00411    }
00412    
00413    /* should not get to this point */
00414    fprintf (SUMA_STDERR,"Error %s: Logic error. Should not get here.\n", FuncName);
00415    SUMA_RETURN (NULL);
00416 
00417 }
00418 
00419 /*!
00420 
00421 \brief Empty a colorlist structure 
00422 
00423 ans = SUMA_EmptyColorList (sv, DO_idstr)
00424 
00425 \param sv (SUMA_SurfaceViewer *) pointer to surface viewer in question
00426 \param DO_idstr (char *) ID string of DO (usually a Surface Object) If you want to delete all 
00427                         color lists, set this pointer to NULL
00428 \return ans (SUMA_Boolean) YUP/NOPE 
00429 
00430 */
00431 SUMA_Boolean SUMA_EmptyColorList (SUMA_SurfaceViewer *sv, char *DO_idstr)
00432 {
00433    static char FuncName[]={"SUMA_EmptyColorList"};
00434    int i;
00435    SUMA_Boolean Found = NOPE;
00436    
00437    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00438    
00439    if (!sv->ColList) {
00440       fprintf (SUMA_STDERR,"Error %s: sv->ColList is NULL, this should not be.\n", FuncName);
00441       SUMA_RETURN (NOPE);
00442    } 
00443    
00444    if (!DO_idstr) {
00445       /* empty them all */
00446       for (i=0; i < sv->N_ColList; ++i) {
00447          if (sv->ColList[i].glar_ColorList) SUMA_free(sv->ColList[i].glar_ColorList);
00448          sv->ColList[i].glar_ColorList = NULL;
00449          sv->ColList[i].N_glar_ColorList = 0;
00450          if (sv->ColList[i].idcode_str) SUMA_free(sv->ColList[i].idcode_str); 
00451          sv->ColList[i].idcode_str = NULL;
00452          sv->ColList[i].Remix = NOPE;
00453       }   
00454    } else { /* just empty one */
00455       Found = NOPE;
00456       i = 0;
00457       while (!Found && i < sv->N_ColList) {
00458          if (strcmp (DO_idstr, sv->ColList[i].idcode_str) == 0) {
00459             Found = YUP;
00460             /* empty the load */
00461             if (sv->ColList[i].glar_ColorList) SUMA_free(sv->ColList[i].glar_ColorList);
00462             sv->ColList[i].glar_ColorList = NULL;
00463             sv->ColList[i].N_glar_ColorList = 0;
00464             if (sv->ColList[i].idcode_str) SUMA_free(sv->ColList[i].idcode_str); 
00465             sv->ColList[i].idcode_str = NULL;
00466             sv->ColList[i].Remix = NOPE;
00467             /* copy the last in the list here */
00468             if (i < sv->N_ColList) {
00469                sv->ColList[i].glar_ColorList = sv->ColList[sv->N_ColList-1].glar_ColorList;
00470                sv->ColList[i].N_glar_ColorList = sv->ColList[sv->N_ColList-1].N_glar_ColorList;
00471                sv->ColList[i].idcode_str = sv->ColList[sv->N_ColList-1].idcode_str;
00472                sv->ColList[i].Remix = sv->ColList[sv->N_ColList-1].Remix;
00473                
00474                /* mark the last element as empty */
00475                sv->ColList[sv->N_ColList-1].glar_ColorList = NULL;
00476                sv->ColList[sv->N_ColList-1].N_glar_ColorList = 0;
00477                sv->ColList[sv->N_ColList-1].idcode_str = NULL;
00478                sv->ColList[sv->N_ColList-1].Remix = NOPE;
00479                
00480                /* decrement the number of full elements in ColList */
00481                --sv->N_ColList;
00482             }
00483          } 
00484          ++i;
00485       }
00486       if (!Found) {
00487          fprintf (SUMA_STDERR,"Error %s: item %s was not found, this should not be.\n", FuncName, DO_idstr);
00488          SUMA_RETURN (NOPE);
00489       }
00490    }
00491    
00492    SUMA_RETURN (YUP);
00493 }
00494 
00495 /*!
00496    ans = SUMA_SetShownLocalRemixFlag (SUMA_SurfaceViewer *sv)
00497    Set Remix flags for all surfaces in sv->ShowDO regardless of their relationship.
00498    This is useful when you change the settings for background color modulation and the like.
00499    \param sv (SUMA_SurfaceViewer *) pointer to surface viewer 
00500    \return ans (SUMA_Boolean) YUP/NOPE
00501    \sa SUMA_SetRemixFlag
00502    \sa SUMA_SetLocalRemixFlag
00503 
00504 */
00505 SUMA_Boolean SUMA_SetShownLocalRemixFlag (SUMA_SurfaceViewer *sv)
00506 {
00507    static char FuncName[]={"SUMA_SetShownLocalRemixFlag"};
00508    int k;
00509       
00510    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00511    
00512    for (k=0; k < sv->N_ColList; ++k) {
00513       sv->ColList[k].Remix = YUP;
00514    }
00515    
00516    SUMA_RETURN (YUP);
00517 }
00518 
00519 /*!
00520    ans = SUMA_SetLocalRemixFlag (char *idcode_str, SUMA_SurfaceViewer *sv);
00521    Search ShowDO for sv and if a Surface in ShowDO is related 
00522    to DO_idcode_str then its remix flag is set to yes.
00523    
00524    \param idcode_str (char *) IDcode of the surface that had its colorplanes modified
00525    \param sv (SUMA_SurfaceViewer *) pointer to surface viewer 
00526    \return ans (SUMA_Boolean) YUP/NOPE
00527    \sa SUMA_SetRemixFlag
00528    \sa SUMA_SetShownLocalRemixFlag
00529    
00530    Will I ever use that one, not common to have related surfaces in one view ... ?
00531 */
00532 SUMA_Boolean SUMA_SetLocalRemixFlag (char *SO_idcode_str, SUMA_SurfaceViewer *sv)
00533 {  
00534    static char FuncName[]={"SUMA_SetLocalRemixFlag"};
00535    SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
00536    int k, kk, dov_id;   
00537    SUMA_Boolean Found = NOPE;
00538    
00539    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00540    
00541    if (!SO_idcode_str || !sv) {
00542       fprintf (SUMA_STDERR,"Error %s: NULL sv or SO_idcode_str. BAD\n", FuncName);
00543       SUMA_RETURN (NOPE);
00544    }
00545 
00546    dov_id = SUMA_findSO_inDOv (SO_idcode_str, SUMAg_DOv, SUMAg_N_DOv);
00547    if (dov_id < 0) {
00548       fprintf (SUMA_STDERR,"Error %s: Failed to find object with idcode %s.\n", FuncName, SO_idcode_str);
00549       SUMA_RETURN (NOPE);
00550    }
00551    SO1 = (SUMA_SurfaceObject *)SUMAg_DOv[dov_id].OP;
00552    
00553    /* search for relatives in ShowDO */
00554    for (k=0; k < sv->N_DO; ++k) {
00555       SO2 = (SUMA_SurfaceObject *)SUMAg_DOv[sv->ShowDO[k]].OP;
00556       if (SUMA_isRelated (SO1, SO2)) {
00557          /* related, set flag for remixing SO2 */
00558          kk = 0;
00559          Found = NOPE;
00560          while (!Found && kk < sv->N_ColList) {
00561             if (strcmp (SO2->idcode_str, sv->ColList[kk].idcode_str) == 0) {
00562                Found = YUP;
00563                sv->ColList[kk].Remix = YUP;
00564             }
00565             ++kk;
00566          }
00567          if (!Found) {
00568             fprintf (SUMA_STDERR,"Error %s: Failed to find surface in ColList structs. BAD.\n", FuncName);
00569             SUMA_RETURN (NOPE);
00570          }
00571       }  
00572    } 
00573    
00574    SUMA_RETURN (YUP);
00575 }
00576 
00577 
00578 
00579 /*!
00580    ans = SUMA_SetRemixFlag (char *idcode_str, SUMA_SurfaceViewer *SVv, int N_SVv);
00581    Search ShowDO for each Surface Viewer and if a Surface in ShowDO is related 
00582    to DO_idcode_str then its remix flag is set to yes.
00583    
00584    \param idcode_str (char *) IDcode of the surface that had its colorplanes modified
00585    \param SVv (SUMA_SurfaceViewer *) vector of existing surface viewers (typically, that is SUMAg_SVv)
00586    \param N_SVv (int) number of surface viewers (typically that is N_SUMAg_SVv)
00587    \return ans (SUMA_Boolean) YUP/NOPE
00588    \sa SUMA_SetLocalRemixFlag
00589    \sa SUMA_SetShownLocalRemix
00590 
00591    DO NOT SET THE REMIXFLAG unless you have modified the colorplanes of a certain surface. This function will
00592    set a remix flags to all related surfaces that are being displayed in all viewers. You want to do this
00593    when one (or all) of the colorplanes is changed. Alternately, if you make changes that only affect the 
00594    surface as is it shown in the viewer (change background modulation for example), you want to do the remixing
00595    for the concerned surface or surfaces only in that viewer and not in all viewers open. Perhaps I should write 
00596    a function to set the remix flags for surfaces within the viewer only. Something like SUMA_SetLocalRemixFlag or 
00597    SUMA_SetShownLocalRemix.
00598    
00599 */
00600 SUMA_Boolean SUMA_SetRemixFlag (char *SO_idcode_str, SUMA_SurfaceViewer *SVv, int N_SVv)
00601 {
00602    static char FuncName[]={"SUMA_SetRemixFlag"};
00603    SUMA_SurfaceViewer *sv;
00604    SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
00605    int i, k, kk, dov_id;   
00606    SUMA_Boolean Found = NOPE, LocalHead = NOPE;
00607    
00608    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00609    
00610    if (!SO_idcode_str || !SVv) {
00611       fprintf (SUMA_STDERR,"Error %s: NULL SVv or SO_idcode_str. BAD\n", FuncName);
00612       SUMA_RETURN (NOPE);
00613    }
00614    
00615    dov_id = SUMA_findSO_inDOv (SO_idcode_str, SUMAg_DOv, SUMAg_N_DOv);
00616    if (dov_id < 0) {
00617       fprintf (SUMA_STDERR,"Error %s: Failed to find object with idcode %s.\n", FuncName, SO_idcode_str);
00618       SUMA_RETURN (NOPE);
00619    }
00620    SO1 = (SUMA_SurfaceObject *)SUMAg_DOv[dov_id].OP;
00621    
00622    /* search all viewers */
00623    for (i=0; i < N_SVv; ++i) {
00624       if (LocalHead) fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
00625       sv = &(SVv[i]);
00626       /* search for relatives in ShowDO */
00627       for (k=0; k < sv->N_DO; ++k) {
00628          if (SUMA_isSO(SUMAg_DOv[sv->ShowDO[k]])) {
00629             SO2 = (SUMA_SurfaceObject *)SUMAg_DOv[sv->ShowDO[k]].OP;
00630             if (SUMA_isRelated (SO1, SO2)) {
00631                /* related, set flag for remixing SO2 */
00632                kk = 0;
00633                Found = NOPE;
00634                while (!Found && kk < sv->N_ColList) {
00635                   if (strcmp (SO2->idcode_str, sv->ColList[kk].idcode_str) == 0) {
00636                      Found = YUP;
00637                      sv->ColList[kk].Remix = YUP;
00638                   }
00639                   ++kk;
00640                }
00641                if (!Found) {
00642                   fprintf (SUMA_STDERR,"Error %s: Failed to find surface in ColList structs. BAD.\n", FuncName);
00643                   SUMA_RETURN (NOPE);
00644                }
00645             }
00646          }  
00647       } 
00648    }
00649    
00650    SUMA_RETURN (YUP);
00651 }
00652 /*!
00653 Updates the View Center and view from of SV based on the contents of ShowDO
00654 */
00655 
00656 SUMA_Boolean SUMA_UpdateViewPoint (SUMA_SurfaceViewer *SV, SUMA_DO *dov, int N_dov)
00657 {
00658    int i, do_id, TotWeight;
00659    float NewCenter[3];
00660    SUMA_SurfaceObject *so_op;
00661    static char FuncName[]={"SUMA_UpdateViewPoint"};
00662       
00663    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00664 
00665    NewCenter[0] = 0.0;
00666    NewCenter[1] = 0.0;
00667    NewCenter[2] = 0.0;
00668    TotWeight = 0;
00669    
00670    i = 0;
00671    while (i < SV->N_DO) {
00672       do_id = SV->ShowDO[i];
00673       switch (dov[do_id].ObjectType) {
00674          case SO_type:
00675             so_op = (SUMA_SurfaceObject *)dov[do_id].OP;
00676             if (so_op->ViewCenterWeight) {
00677                NewCenter[0] += so_op->ViewCenterWeight*so_op->Center[0];
00678                NewCenter[1] += so_op->ViewCenterWeight*so_op->Center[1];
00679                NewCenter[2] += so_op->ViewCenterWeight*so_op->Center[2];
00680                TotWeight += so_op->ViewCenterWeight;
00681             }
00682             break;
00683          default:
00684             break;
00685       } 
00686       ++i;
00687    }
00688    if (TotWeight) {
00689       SV->GVS[SV->StdView].ViewCenter[0] = NewCenter[0]/(float)TotWeight;
00690       SV->GVS[SV->StdView].ViewCenter[1] = NewCenter[1]/(float)TotWeight;
00691       SV->GVS[SV->StdView].ViewCenter[2] = NewCenter[2]/(float)TotWeight;
00692       SV->GVS[SV->StdView].ViewFrom[0] = SV->GVS[SV->StdView].ViewCenter[0];
00693       SV->GVS[SV->StdView].ViewFrom[1] = SV->GVS[SV->StdView].ViewCenter[1];
00694       SV->GVS[SV->StdView].ViewFrom[2] = SV->GVS[SV->StdView].ViewCenter[2]+SUMA_DEFAULT_VIEW_FROM;   
00695       SV->GVS[SV->StdView].ViewDistance = SUMA_DEFAULT_VIEW_FROM;   
00696       
00697    } else
00698    {/* default back to o.o, o.o, o.o */
00699       SV->GVS[SV->StdView].ViewCenter[0] = SV->GVS[SV->StdView].ViewCenter[1] = SV->GVS[SV->StdView].ViewCenter[2] = 0.0;
00700       SV->GVS[SV->StdView].ViewFrom[0] = SV->GVS[SV->StdView].ViewFrom[1] = 0.0; SV->GVS[SV->StdView].ViewFrom[2] = SUMA_DEFAULT_VIEW_FROM;
00701       SV->GVS[SV->StdView].ViewDistance = SUMA_DEFAULT_VIEW_FROM;   
00702    }
00703    
00704       /* Store that info in case subjects change things */
00705       SV->GVS[SV->StdView].ViewCenterOrig[0] = SV->GVS[SV->StdView].ViewCenter[0];
00706       SV->GVS[SV->StdView].ViewCenterOrig[1] = SV->GVS[SV->StdView].ViewCenter[1];
00707       SV->GVS[SV->StdView].ViewCenterOrig[2] = SV->GVS[SV->StdView].ViewCenter[2];
00708       SV->GVS[SV->StdView].ViewFromOrig[0] = SV->GVS[SV->StdView].ViewFrom[0];
00709       SV->GVS[SV->StdView].ViewFromOrig[1] = SV->GVS[SV->StdView].ViewFrom[1];
00710       SV->GVS[SV->StdView].ViewFromOrig[2] = SV->GVS[SV->StdView].ViewFrom[2];
00711 
00712    SUMA_RETURN (YUP);
00713    
00714    
00715 }
00716 /*!
00717 Updates the Rotation Center of SV based on the contents of ShowDO
00718 */
00719 SUMA_Boolean SUMA_UpdateRotaCenter (SUMA_SurfaceViewer *SV, SUMA_DO *dov, int N_dov)
00720 {
00721    int i, do_id, TotWeight;
00722    float NewCenter[3];
00723    SUMA_SurfaceObject *so_op;
00724    static char FuncName[]={"SUMA_UpdateRotaCenter"};
00725    
00726    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00727 
00728    NewCenter[0] = 0.0;
00729    NewCenter[1] = 0.0;
00730    NewCenter[2] = 0.0;
00731    TotWeight = 0;
00732    
00733    i = 0;
00734    while (i < SV->N_DO) {
00735       do_id = SV->ShowDO[i];
00736       switch (dov[do_id].ObjectType) {
00737          case SO_type:
00738             so_op = (SUMA_SurfaceObject *)dov[do_id].OP;
00739             if (so_op->RotationWeight) {
00740                NewCenter[0] += so_op->RotationWeight*so_op->Center[0];
00741                NewCenter[1] += so_op->RotationWeight*so_op->Center[1];
00742                NewCenter[2] += so_op->RotationWeight*so_op->Center[2];
00743                TotWeight += so_op->RotationWeight;
00744             }
00745             break;
00746          default:
00747             break;
00748       } 
00749       ++i;
00750    }
00751    if (TotWeight) {
00752       SV->GVS[SV->StdView].RotaCenter[0] = NewCenter[0]/(float)TotWeight;
00753       SV->GVS[SV->StdView].RotaCenter[1] = NewCenter[1]/(float)TotWeight;
00754       SV->GVS[SV->StdView].RotaCenter[2] = NewCenter[2]/(float)TotWeight;
00755    } else
00756    {/* default back to o.o, o.o, o.o */
00757       SV->GVS[SV->StdView].RotaCenter[0] = SV->GVS[SV->StdView].RotaCenter[1] = SV->GVS[SV->StdView].RotaCenter[2] = 0.0;
00758    }
00759    SUMA_RETURN (YUP);
00760    
00761 }
00762 
00763 /*!
00764 output the state variable contents of the Surface Viewer 
00765 */
00766 void SUMA_Show_SurfaceViewer_Struct (SUMA_SurfaceViewer *SV, FILE *Out)
00767 {
00768    int i;
00769    static char FuncName[]={"SUMA_Show_SurfaceViewer_Struct"};
00770    
00771    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00772 
00773    if (Out == NULL) Out = stdout;
00774    
00775    fprintf(Out,"\nSV contents:\n");
00776    fprintf(Out,"\tverbose = %d\n", SV->verbose);
00777    fprintf(Out,"\tAspect = %f\n", SV->Aspect);
00778    fprintf(Out,"\tViewFrom = [%f %f %f]\n", SV->GVS[SV->StdView].ViewFrom[0], SV->GVS[SV->StdView].ViewFrom[1], SV->GVS[SV->StdView].ViewFrom[2]);
00779    fprintf(Out,"\tViewFromOrig = [%f %f %f]\n", SV->GVS[SV->StdView].ViewFromOrig[0], SV->GVS[SV->StdView].ViewFromOrig[1], SV->GVS[SV->StdView].ViewFromOrig[2]);
00780    fprintf(Out,"\tViewCenter = [%f %f %f]\n", SV->GVS[SV->StdView].ViewCenter[0], SV->GVS[SV->StdView].ViewCenter[1], SV->GVS[SV->StdView].ViewCenter[2]);
00781    fprintf(Out,"\tViewCenterOrig = [%f %f %f]\n", SV->GVS[SV->StdView].ViewCenterOrig[0], SV->GVS[SV->StdView].ViewCenterOrig[1], SV->GVS[SV->StdView].ViewCenterOrig[2]);
00782    fprintf(Out,"\tViewCamUp = [%f %f %f]\n", SV->GVS[SV->StdView].ViewCamUp[0], SV->GVS[SV->StdView].ViewCamUp[1], SV->GVS[SV->StdView].ViewCamUp[2]);
00783    fprintf(Out,"\tRotaCenter = [%f %f %f]\n", SV->GVS[SV->StdView].RotaCenter[0], SV->GVS[SV->StdView].RotaCenter[1], SV->GVS[SV->StdView].RotaCenter[2]);
00784    fprintf(Out,"\tlight0_position = [%f %f %f %f]\n", SV->light0_position[0], SV->light0_position[1], SV->light0_position[2], SV->light0_position[3]);
00785    fprintf(Out,"\tlight1_position = [%f %f %f %f]\n", SV->light1_position[0], SV->light1_position[1], SV->light1_position[2], SV->light1_position[3]);
00786    fprintf(Out,"\tWindWidth = %d\n", SV->WindWidth);
00787    fprintf(Out,"\tWindHeight = %d\n", SV->WindHeight);
00788    fprintf(Out,"\tcurrentQuat = [%f %f %f %f]\n", SV->GVS[SV->StdView].currentQuat[0], SV->GVS[SV->StdView].currentQuat[1], SV->GVS[SV->StdView].currentQuat[2], SV->GVS[SV->StdView].currentQuat[3]);
00789    fprintf(Out,"\tdeltaQuat = [%f %f %f %f]\n", SV->GVS[SV->StdView].deltaQuat[0], SV->GVS[SV->StdView].deltaQuat[1], SV->GVS[SV->StdView].deltaQuat[2], SV->GVS[SV->StdView].deltaQuat[3]);
00790    fprintf(Out,"\tApplyMomentum = %d\n", SV->GVS[SV->StdView].ApplyMomentum);
00791    fprintf(Out,"\tMinIdleDelta = %d\n", SV->GVS[SV->StdView].MinIdleDelta);
00792    fprintf(Out,"\tzoomDelta = %f, zoomBegin = %f\n", SV->GVS[SV->StdView].zoomDelta, SV->GVS[SV->StdView].zoomBegin);
00793    fprintf(Out,"\tspinDeltaX/Y = %d/%d\n", SV->GVS[SV->StdView].spinDeltaX, SV->GVS[SV->StdView].spinDeltaY);
00794    fprintf(Out,"\tspinBeginX/Y = %d/%d\n", SV->GVS[SV->StdView].spinBeginX, SV->GVS[SV->StdView].spinBeginY);   
00795    fprintf(Out,"\tTranslateGain = %f\n", SV->GVS[SV->StdView].TranslateGain);
00796    fprintf(Out,"\tArrowtranslateDeltaX/Y = %f/%f\n", SV->GVS[SV->StdView].ArrowtranslateDeltaX, SV->GVS[SV->StdView].ArrowtranslateDeltaY);
00797    fprintf(Out,"\ttranslateBeginX/Y = %d/%d\n", SV->GVS[SV->StdView].translateBeginX, SV->GVS[SV->StdView].translateBeginY);
00798    fprintf(Out,"\ttranslateDeltaX/Y = %f/%f\n", SV->GVS[SV->StdView].translateDeltaX, SV->GVS[SV->StdView].translateDeltaY);
00799    fprintf(Out,"\ttranslateVec = [%f %f 0.0]\n", SV->GVS[SV->StdView].translateVec[0], SV->GVS[SV->StdView].translateVec[1]);
00800    fprintf(Out,"\tShow Mesh Axis %d\n", SV->ShowMeshAxis);
00801    fprintf(Out,"\tShow Eye Axis %d\n", SV->ShowEyeAxis);
00802    fprintf(Out,"\tShow Cross Hair %d\n", SV->ShowCrossHair);
00803    fprintf(Out,"\tPolyMode %d\n", SV->PolyMode);
00804    
00805    fprintf(Out,"\tN_DO = %d\n", SV->N_DO);
00806    fprintf(Out,"\tShowDO = [");
00807    for (i=0; i< SV->N_DO; ++i)
00808       fprintf(Out,"%d, ", SV->ShowDO[i]);
00809    fprintf(Out,"]\n");
00810    if (SV->X == NULL) fprintf(Out,"\tX struct is NULL!\n");
00811    else {
00812    fprintf(Out,"\tX struct defined.\n");
00813    }
00814    fprintf(Out,"\tSO in focus %d\n", SV->Focus_SO_ID);
00815    fprintf(Out,"\tDO in focus %d\n", SV->Focus_DO_ID);
00816    /* show some state stuff */
00817    fprintf(Out,"\nView States:\n");
00818    for (i=0; i < SV->N_VSv; ++i) {
00819       fprintf(Out,"\nView State %d/%d (FOV = %f):\n", i, SV->N_VSv, SV->FOV[i]);
00820       if (!SUMA_Show_ViewState (&(SV->VSv[i]), Out)) {
00821          fprintf(Out,"Error in SUMA_Show_ViewState\n");
00822       }
00823    }
00824    fprintf(Out, "\nStandard viewing mode: %d\n", SV->StdView );
00825    fprintf(Out, "\nBackground Modulation Factor= %f\n", SV->Back_Modfact);
00826    fprintf(Out, "\nLast non mappable visited %d\n", SV->LastNonMapStateID);
00827    
00828    /*fprintf(Out,"\t\n", SV->);
00829    fprintf(Out,"\t\n", SV->);
00830    fprintf(Out,"\t\n", SV->);
00831    fprintf(Out,"\t\n", SV->);*/
00832    fprintf(Out,"\n");
00833    SUMA_RETURNe;
00834 }
00835 
00836 /*! Show the ViewState structure */
00837 SUMA_Boolean SUMA_Show_ViewState(SUMA_ViewState *VS, FILE *Out) 
00838 {
00839    static char FuncName[]={"SUMA_Show_ViewState"};
00840    int i;
00841    
00842    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00843 
00844    if (Out == NULL) Out = stdout;
00845 
00846    if (VS == NULL) {
00847       fprintf(Out,"VS is NULL\n");      
00848       SUMA_RETURN(NOPE);
00849    }
00850 
00851    if (VS->Name) fprintf(Out,"\tName: %s\n", VS->Name);
00852    else fprintf(Out,"\tName: NULL\n");
00853    
00854    if (VS->N_MembSOs) {
00855       fprintf(Out,"\t%d MembSOs: ", VS->N_MembSOs);
00856       for (i=0; i < VS->N_MembSOs; ++i) fprintf(Out,"%d, ", VS->MembSOs[i]);
00857       fprintf(Out,"\n");
00858    } else {
00859       fprintf(Out,"\tNo MembSOs\n");
00860    }
00861    
00862    if (VS->Hist) {
00863       if (VS->Hist->N_DO) {
00864          fprintf(Out,"\tHist->N_DO = %d\nHist->ShowDO: ", VS->Hist->N_DO);
00865          for (i=0; i < VS->Hist->N_DO; ++i) {
00866             fprintf(Out,"\t%d, ", VS->Hist->ShowDO[i]);
00867          }
00868       }
00869    } else {
00870       fprintf(Out,"\tHist is NULL\n");
00871    }
00872    
00873    SUMA_RETURN (YUP);
00874 }
00875 
00876 /*!
00877    Create & free ViewState_Hist structure 
00878 */
00879 SUMA_ViewState_Hist *SUMA_Alloc_ViewState_Hist (void)
00880 {
00881    static char FuncName[]={"SUMA_Alloc_ViewState_Hist"};
00882    SUMA_ViewState_Hist *vsh;
00883    
00884    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00885 
00886    vsh = (SUMA_ViewState_Hist *)SUMA_malloc(sizeof(SUMA_ViewState_Hist));
00887    if (vsh == NULL) {
00888       fprintf(SUMA_STDERR,"Error %s: Could not allocate for vsh.\n", FuncName);
00889       SUMA_RETURN (NULL);
00890    }
00891    vsh->ShowDO = NULL;
00892    vsh->N_DO = 0;
00893    SUMA_RETURN (vsh);
00894 }   
00895 SUMA_Boolean SUMA_Free_ViewState_Hist (SUMA_ViewState_Hist *vsh)
00896 {
00897    static char FuncName[]={"SUMA_Free_ViewState_Hist"};
00898    
00899    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00900 
00901    if (vsh == NULL) SUMA_RETURN (YUP);
00902    if (vsh->ShowDO) SUMA_free(vsh->ShowDO);
00903    if (vsh) SUMA_free(vsh);
00904    SUMA_RETURN (YUP);
00905 }
00906 
00907 /*!
00908    Create & free SUMA_ViewState structure 
00909 */
00910 SUMA_ViewState *SUMA_Alloc_ViewState (int N)
00911 {
00912    SUMA_ViewState *vs;
00913    int i;
00914    static char FuncName[]={"SUMA_Alloc_ViewState"};
00915    
00916    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00917 
00918    vs = (SUMA_ViewState *)SUMA_malloc(sizeof(SUMA_ViewState)*N);
00919    if (vs == NULL) {
00920       fprintf(SUMA_STDERR,"Error %s: Could not allocate for vs.\n", FuncName);
00921       SUMA_RETURN (NULL);
00922    }
00923    for (i=0; i< N; ++i) {
00924       vs[i].Name = NULL;
00925       vs[i].MembSOs = NULL;
00926       vs[i].N_MembSOs = 0;
00927       vs[i].Hist = SUMA_Alloc_ViewState_Hist ();
00928       if (vs[i].Hist == NULL) {
00929          fprintf(SUMA_STDERR,"Error %s: Could not allocate for vs->Hist.\n", FuncName);
00930          SUMA_free(vs);
00931          SUMA_RETURN (NULL);
00932       }
00933    }
00934    SUMA_RETURN (vs);
00935 }   
00936 
00937 SUMA_Boolean SUMA_Free_ViewState (SUMA_ViewState *vs)
00938 {
00939    static char FuncName[]={"SUMA_Free_ViewState"};
00940    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00941 
00942    if (vs == NULL) SUMA_RETURN (YUP);
00943    if (vs->Name) SUMA_free(vs->Name);
00944    if (vs->MembSOs) SUMA_free(vs->MembSOs);
00945    if (vs->Hist) SUMA_Free_ViewState_Hist (vs->Hist);
00946    if (vs) SUMA_free(vs);
00947    SUMA_RETURN (YUP);
00948 }
00949 
00950 /*! 
00951    locate the index i (into SVv[i]) of sv 
00952    -1 if not found
00953 */
00954 int SUMA_WhichSV (SUMA_SurfaceViewer *sv, SUMA_SurfaceViewer *SVv, int N_SVv)
00955 {
00956    static char FuncName[]={"SUMA_WhichSV"};
00957    int i = 0;
00958    
00959    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00960    
00961    if (!SVv || !sv) {
00962       fprintf (SUMA_STDERR, "Error %s: NULL SVv or sv.\n", FuncName);
00963       SUMA_RETURN (-1);
00964    }
00965    
00966    for (i=0; i<N_SVv; ++i) {
00967       if (&(SVv[i]) == sv) {
00968          SUMA_RETURN (i);
00969       } 
00970    }
00971    
00972    
00973    SUMA_RETURN (-1);
00974 }
00975 
00976 /*! 
00977    locate the index i (into csv->VSv[i]) of state 
00978    -1 if not found
00979 */
00980 int SUMA_WhichState (char *state, SUMA_SurfaceViewer *csv)
00981 {
00982    static char FuncName[]={"SUMA_WhichState"};
00983    int i = 0;
00984    SUMA_Boolean LocalHead = NOPE;
00985    
00986    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00987 
00988    while (i < csv->N_VSv) {
00989       if (LocalHead) fprintf(SUMA_STDERR,"%s: comparing csv->VSv[%d].Name = %s to %s ...\n", FuncName, i, csv->VSv[i].Name, state);
00990       if (strcmp(csv->VSv[i].Name, state) == 0) {
00991          if (LocalHead) fprintf(SUMA_STDERR,"%s: FOUND, i=%d!\n", FuncName, i);
00992          SUMA_RETURN (i);
00993       }
00994       ++i;
00995    }
00996    SUMA_RETURN (-1);
00997 }
00998 
00999 /*! 
01000    register the different view states and surfaces belonging to different 
01001    view states in the surface viewer's structure
01002    Essentially, it creates the vector VSv that is a part of the surface viewer structure
01003 */
01004 SUMA_Boolean SUMA_RegisterSpecSO (SUMA_SurfSpecFile *Spec, SUMA_SurfaceViewer *csv, SUMA_DO* dov, int N_dov)
01005 {
01006    static char FuncName[]={"SUMA_RegisterSpecSO"};
01007    int is, i;
01008    SUMA_SurfaceObject * SO;
01009    SUMA_Boolean LocalHead = NOPE;
01010    
01011    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01012 
01013    /* allocate for space depending on the number of states present */
01014    
01015    if (LocalHead) fprintf(SUMA_STDERR,"%s: Entering ...\n", FuncName);
01016    
01017    csv->VSv = SUMA_Alloc_ViewState (Spec->N_States);
01018    if (csv->VSv == NULL) {
01019       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VSv.\n", FuncName);
01020       SUMA_RETURN (NOPE);
01021    }
01022    csv->N_VSv = 0;
01023    
01024    /* register the various states from each SO in DOv */
01025    for (i=0; i < N_dov; ++i) {
01026       if (SUMA_isSO(dov[i])) {
01027          SO = (SUMA_SurfaceObject *)(dov[i].OP);
01028          if (csv->N_VSv == 0) {
01029             /* delaware encountered, snag it*/
01030             csv->VSv[csv->N_VSv].Name = (char *)SUMA_malloc(sizeof(char)*(strlen(SO->State)+1));
01031             if (csv->VSv[csv->N_VSv].Name == NULL) {
01032                fprintf(SUMA_STDERR,"Error %s: Failed to allocate for csv->VSv[csv->N_VSv].Name.\n", FuncName);
01033                SUMA_RETURN (NOPE);
01034             }
01035             csv->VSv[csv->N_VSv].Name = strcpy (csv->VSv[csv->N_VSv].Name, SO->State);  
01036             csv->VSv[csv->N_VSv].N_MembSOs = 1;
01037             csv->N_VSv += 1;
01038          }else {
01039             is = SUMA_WhichState (SO->State, csv);
01040             if (is < 0) {
01041                /* add state if it is a new one */
01042                csv->VSv[csv->N_VSv].Name = (char *)SUMA_malloc(sizeof(char)*(strlen(SO->State)+1));
01043                if (csv->VSv[csv->N_VSv].Name == NULL) {
01044                   fprintf(SUMA_STDERR,"Error %s: Failed to allocate for csv->VSv[csv->N_VSv].Name.\n", FuncName);
01045                   SUMA_RETURN (NOPE);
01046                }   
01047                csv->VSv[csv->N_VSv].Name = strcpy (csv->VSv[csv->N_VSv].Name, SO->State); 
01048                csv->VSv[csv->N_VSv].N_MembSOs = 1;
01049                csv->N_VSv += 1;
01050             } else { /* old one, count it */
01051                csv->VSv[is].N_MembSOs += 1;
01052             }
01053          }
01054       
01055       }
01056    }
01057    
01058    
01059    /*fprintf(SUMA_STDERR,"%s: allocating ...\n", FuncName);*/
01060    
01061    /* allocate for FOV */
01062    csv->FOV = (float *)SUMA_calloc(csv->N_VSv, sizeof(float));
01063    
01064    /* allocate space for MembSOs counters will be reset for later use counting proceeds
01065    also initialize FOV*/
01066    for (i=0; i < csv->N_VSv; ++i) {
01067       csv->FOV[i] = FOV_INITIAL;
01068       csv->VSv[i].MembSOs = (int *) SUMA_calloc(csv->VSv[i].N_MembSOs, sizeof(int));
01069       if (csv->VSv[i].MembSOs == NULL) {
01070          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for csv->VSv[i].MembSOs.\n", FuncName);
01071          SUMA_RETURN (NOPE);
01072       }   
01073       csv->VSv[i].N_MembSOs = 0;
01074    }
01075 
01076    
01077    /*fprintf(SUMA_STDERR,"%s: placement ...\n", FuncName);*/
01078    
01079    /* now place each SO where it belongs */
01080    for (i=0; i < N_dov; ++i) {
01081       if (SUMA_isSO(dov[i])) {
01082          SO = (SUMA_SurfaceObject *)(dov[i].OP);
01083          /* find out which state it goes in */
01084          is = SUMA_WhichState (SO->State, csv);
01085          if (is < 0) {
01086             fprintf(SUMA_STDERR,"Error %s: This should not be.\n", FuncName);
01087             SUMA_RETURN (NOPE);
01088          }
01089          /*
01090          fprintf (SUMA_STDERR,"%s: Performing csv->VSv[%d].MembSOs[%d] = %d ...\n", \
01091             FuncName, is, csv->VSv[is].N_MembSOs, i);
01092          */
01093          /* store it where it should be */
01094          csv->VSv[is].MembSOs[csv->VSv[is].N_MembSOs] = i; /* store it's id as valid member of the state*/
01095          csv->VSv[is].N_MembSOs += 1; /* count it, again */ 
01096       }
01097    }
01098    
01099    /*fprintf(SUMA_STDERR,"%s: Leaving ...\n", FuncName);*/
01100 
01101    SUMA_RETURN (YUP);
01102 }
01103 
01104 /*! allocate and intialize SUMA_CommonFields 
01105 \sa SUMA_Free_CommonFields
01106 */
01107 SUMA_CommonFields * SUMA_Create_CommonFields ()
01108 {
01109    static char FuncName[]={"SUMA_Create_CommonFields"};
01110    SUMA_CommonFields *cf;
01111    int i;
01112    SUMA_Boolean LocalHead = NOPE;
01113    
01114    /* This is the function that creates the debugging flags, do not use them here */
01115    cf = NULL;
01116    
01117    /* allocate */
01118    /* DO NOT USE SUMA_malloc here, too early for that */
01119    cf = (SUMA_CommonFields *)malloc(sizeof(SUMA_CommonFields));
01120    
01121    if (cf == NULL) {
01122       fprintf(SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01123       SUMA_RETURN (cf);
01124    }
01125    
01126    cf->Dev = NOPE;
01127    cf->InOut_Notify = NOPE;
01128    cf->InOut_Level = 0;
01129    cf->MemTrace = NOPE;
01130    cf->Mem = SUMA_Create_MemTrace();
01131    
01132    cf->ns = NULL;
01133    cf->Connected = NOPE;
01134    for (i=0; i<SUMA_MAX_SURF_VIEWERS; ++i) {
01135       cf->Locked[i] = SUMA_I_Lock;
01136       cf->ViewLocked[i] = NOPE;
01137    }
01138    
01139    cf->SwapButtons_1_3 = SUMA_SWAP_BUTTONS_1_3;
01140    
01141    cf->X = (SUMA_X_AllView *)malloc(sizeof(SUMA_X_AllView));
01142    if (!cf->X) {
01143      fprintf(SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01144      return (NULL); 
01145    }
01146    cf->X->SumaCont = SUMA_CreateSumaContStruct();
01147    cf->X->DrawROI = SUMA_CreateDrawROIStruct();
01148    cf->X->DPY_controller1 = NULL;
01149    cf->X->X_Resources = SXR_NP;
01150    cf->X->Help_TextShell = NULL;
01151    cf->X->Log_TextShell = NULL;
01152    cf->X->FileSelectDlg = NULL;
01153    cf->MessageList = SUMA_CreateMessageList ();
01154    /*SUMA_ShowMemTrace (cf->Mem, NULL);*/
01155    cf->ROI_mode = NOPE;
01156    
01157    cf->nimlROI_Datum_type = NI_rowtype_define("SUMA_NIML_ROI_DATUM", "int,int,int,int[#3]");
01158    if (cf->nimlROI_Datum_type < 0) {
01159       fprintf(SUMA_STDERR,"Error %s: Failed defining niml code.", FuncName);
01160       return(NULL);
01161    }
01162    if (LocalHead) fprintf(SUMA_STDERR, "%s: roi_type code = %d\n", FuncName, cf->nimlROI_Datum_type) ;
01163    
01164    return (cf);
01165 
01166 }
01167 
01168 /*!
01169 \brief creates the structure for storing the radio buttons used to control viewer locking
01170    Do not use CommonFields structure here.
01171 
01172 */ 
01173 SUMA_rb_group *SUMA_CreateLock_rbg (int N_rb_group, int N_but) 
01174 {
01175    static char FuncName[]={"SUMA_CreateLock_rbg"};
01176    SUMA_rb_group *Lock_rb;
01177 
01178    Lock_rb = (SUMA_rb_group *) malloc(sizeof(SUMA_rb_group));
01179    if (!Lock_rb) { 
01180       fprintf (SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01181       return(NULL);
01182    }
01183    Lock_rb->N_rb_group = N_rb_group;
01184    Lock_rb->N_but = N_but;
01185    Lock_rb->tb = (Widget *) calloc(N_rb_group*N_but, sizeof(Widget));
01186    Lock_rb->rb = (Widget *) calloc(N_rb_group, sizeof(Widget));
01187    Lock_rb->atb = (Widget *) calloc(N_but, sizeof(Widget));
01188    Lock_rb->arb = NULL;
01189    if (!Lock_rb->tb || !Lock_rb->rb || !Lock_rb->atb) {
01190       fprintf (SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01191       return(NULL);
01192    }
01193    return(Lock_rb);
01194 
01195 }
01196 
01197 /*!
01198    free SUMA_rb_group *
01199    Do not use CommonFields structure here.
01200 */
01201 void * SUMA_FreeLock_rbg (SUMA_rb_group *Lock_rb)
01202 {
01203   static char FuncName[]={"SUMA_FreeLock_rb"};
01204   
01205   if (Lock_rb->rb) free(Lock_rb->rb);
01206   if (Lock_rb->tb) free(Lock_rb->tb);
01207   if (Lock_rb->atb) free (Lock_rb->atb);
01208   if (Lock_rb) free(Lock_rb);
01209 
01210   return (NULL);
01211 }
01212 
01213 /*!
01214    \brief DrawROI = SUMA_CreateDrawROIStruct();
01215    allocates and initializes structure of type 
01216    
01217    \return SUMA_X_DrawROI *
01218 */
01219 SUMA_X_DrawROI *SUMA_CreateDrawROIStruct (void) 
01220 {
01221    static char FuncName[]={"SUMA_CreateDrawROIStruct"};
01222    SUMA_X_DrawROI *DrawROI = NULL;
01223    
01224    /* do not use commonfields related stuff here for obvious reasons */
01225    DrawROI = (SUMA_X_DrawROI *)malloc (sizeof(SUMA_X_DrawROI));
01226    DrawROI->AppShell = NULL;
01227    DrawROI->ROIval = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01228    DrawROI->ROIlbl = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01229    DrawROI->curDrawnROI = NULL;  /* DO NOT FREE THIS POINTER */
01230    DrawROI->SwitchROIlst = NULL;
01231    DrawROI->Delete_first = YUP;
01232    DrawROI->SaveMode = SW_DrawROI_SaveMode1D;
01233    DrawROI->SaveWhat = SW_DrawROI_SaveWhatThis;
01234    return (DrawROI);
01235 }
01236 
01237 /*!
01238    \brief SumaCont = SUMA_CreateSumaContStruct();
01239    allocates and initializes structure of type SUMA_X_SumaCont
01240    \return SUMA_X_SumaCont *
01241    
01242 */
01243 SUMA_X_SumaCont *SUMA_CreateSumaContStruct (void) 
01244 {
01245    static char FuncName[]={"SUMA_CreateSumaContStruct"};
01246    SUMA_X_SumaCont *SumaCont = NULL;
01247    /* do not use commonfields related stuff here for obvious reasons */
01248    SumaCont = (SUMA_X_SumaCont *)malloc(sizeof(SUMA_X_SumaCont));
01249    SumaCont->AppShell = NULL;
01250    SumaCont->quit_pb = NULL;
01251    SumaCont->quit_first = YUP;
01252    SumaCont->Lock_rbg = SUMA_CreateLock_rbg (SUMA_MAX_SURF_VIEWERS, 3);
01253    if (!SumaCont->Lock_rbg) {
01254       fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateLock_rb.\n", FuncName);
01255       return (NULL);
01256    }
01257    SumaCont->LockView_tbg = (Widget *)calloc (SUMA_MAX_SURF_VIEWERS, sizeof(Widget));
01258    SumaCont->LockAllView_tb = NULL;
01259    
01260    return (SumaCont);
01261 }
01262 
01263 /*!
01264    \brief frees structure SUMA_X_SumaCont, returns null
01265    
01266 */
01267 void *SUMA_FreeSumaContStruct (SUMA_X_SumaCont *SumaCont)
01268 {
01269    static char FuncName[]={"SUMA_FreeSumaContStruct"};
01270 
01271    /* do not use commonfields related stuff here for obvious reasons */
01272    if (SumaCont->Lock_rbg) SUMA_FreeLock_rbg (SumaCont->Lock_rbg);
01273    if (SumaCont->LockView_tbg) free (SumaCont->LockView_tbg);
01274    if (SumaCont) free(SumaCont);
01275    return (NULL);
01276 }
01277 
01278 /*!
01279    \brief frees structure SUMA_X_DrawROI, returns null
01280 */
01281 void *SUMA_FreeDrawROIStruct (SUMA_X_DrawROI *DrawROI)
01282 {  
01283    static char FuncName[]={"SUMA_FreeDrawROIStruct"};
01284    
01285    /* do not use commonfields related stuff here for obvious reasons,
01286    Well, you can, it is no big deal, memory tracing variables are wiped out at the end*/
01287    if (DrawROI->ROIval) free (DrawROI->ROIval);
01288    if (DrawROI->ROIlbl) free (DrawROI->ROIlbl);
01289    if (DrawROI->SwitchROIlst) SUMA_FreeScrolledList (DrawROI->SwitchROIlst);
01290    if (DrawROI) free(DrawROI);
01291    
01292    return (NULL);
01293 }
01294 /*!
01295    \brief ViewCont = SUMA_CreateViewContStruct();
01296    allocates and initializes structure of type SUMA_X_ViewCont
01297    \return SUMA_X_ViewCont *
01298    
01299 */
01300 SUMA_X_ViewCont *SUMA_CreateViewContStruct (void) 
01301 {
01302    static char FuncName[]={"SUMA_CreateViewContStruct"};
01303    SUMA_X_ViewCont *ViewCont = NULL;
01304    /* do not use commonfields related stuff here for obvious reasons */
01305    ViewCont = (SUMA_X_ViewCont *)malloc(sizeof(SUMA_X_ViewCont));
01306    ViewCont->TopLevelShell = NULL;
01307    
01308    return (ViewCont);
01309 }
01310 
01311 /*!
01312    \brief frees structure SUMA_X_ViewCont, returns null
01313    
01314 */
01315 void *SUMA_FreeViewContStruct (SUMA_X_ViewCont *ViewCont)
01316 {
01317    static char FuncName[]={"SUMA_FreeViewContStruct"};
01318 
01319    /* do not use commonfields related stuff here for obvious reasons */
01320    if (ViewCont) free(ViewCont);
01321    return (NULL);
01322 }
01323 
01324 /*!
01325    \brief SurfCont = SUMA_CreateSurfContStruct();
01326    allocates and initializes structure of type SUMA_X_SurfCont
01327    \return SUMA_X_SurfCont *
01328    
01329 */
01330 SUMA_X_SurfCont *SUMA_CreateSurfContStruct (void) 
01331 {
01332    static char FuncName[]={"SUMA_CreateSurfContStruct"};
01333    SUMA_X_SurfCont *SurfCont = NULL;
01334    
01335    /* do not use commonfields related stuff here for obvious reasons */
01336    SurfCont = (SUMA_X_SurfCont *)malloc(sizeof(SUMA_X_SurfCont));
01337    SurfCont->ColPlane_fr = NULL;
01338    SurfCont->TopLevelShell = NULL;
01339    SurfCont->SurfInfo_pb = NULL;
01340    SurfCont->SurfInfo_TextShell = NULL;
01341    SurfCont->ColPlaneOrder = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01342    SurfCont->ColPlaneOpacity = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01343    SurfCont->ColPlaneShow_tb = NULL;
01344    SurfCont->SwitchColPlanelst = NULL;
01345    SurfCont->ColPlaneLabel_Parent_lb = NULL;
01346    SurfCont->curColPlane = NULL;
01347    SurfCont->PosRef = NULL;
01348    
01349    return (SurfCont);
01350 }
01351 
01352 /*!
01353    \brief frees structure SUMA_X_SurfCont, returns null
01354    
01355 */
01356 void *SUMA_FreeSurfContStruct (SUMA_X_SurfCont *SurfCont)
01357 {
01358    static char FuncName[]={"SUMA_FreeSurfContStruct"};
01359 
01360    /* do not use commonfields related stuff here for obvious reasons */
01361    if (!SurfCont) return(NULL);
01362    
01363    if (SurfCont->ColPlaneOrder) free (SurfCont->ColPlaneOrder);
01364    if (SurfCont->ColPlaneOpacity) free (SurfCont->ColPlaneOpacity);
01365    if (SurfCont->SwitchColPlanelst) SUMA_FreeScrolledList (SurfCont->SwitchColPlanelst);
01366 
01367    if (SurfCont) free(SurfCont);
01368    return (NULL);
01369 }
01370 
01371 /*! free SUMA_CommonFields 
01372 \sa SUMA_Create_CommonFields
01373 */
01374 SUMA_Boolean SUMA_Free_CommonFields (SUMA_CommonFields *cf)
01375 {
01376    static char FuncName[]={"SUMA_Free_CommonFields"};
01377    
01378    /* do not use commonfields related stuff here for obvious reasons */
01379    
01380    if (cf->X->FileSelectDlg) SUMA_FreeFileSelectionDialogStruct(cf->X->FileSelectDlg);
01381    if (cf->X->SumaCont) SUMA_FreeSumaContStruct (cf->X->SumaCont);
01382    if (cf->X->DrawROI) SUMA_FreeDrawROIStruct (cf->X->DrawROI);
01383    if (cf->X) free(cf->X);
01384    if (cf->MessageList) SUMA_EmptyDestroyList(cf->MessageList);
01385    if (cf->Mem) SUMA_Free_MemTrace (cf->Mem); /* always free this right before the end */
01386    if (cf) free(cf);
01387    
01388    return (YUP);
01389 }
01390 
01391 void SUMA_Show_CommonFields (SUMA_CommonFields *cf)
01392 {
01393    static char FuncName[]={"SUMA_Show_CommonFields"};
01394    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01395 
01396    if (cf == NULL) {
01397       fprintf (SUMA_STDOUT,"%s: NULL structure.\n", FuncName);
01398       SUMA_RETURNe;
01399    }
01400    fprintf (SUMA_STDOUT,"%s: AfniHostName: %s\n", FuncName, cf->AfniHostName);
01401    fprintf (SUMA_STDOUT,"%s: NimlAfniStream: %s\n", FuncName, cf->NimlAfniStream);
01402    SUMA_RETURNe;
01403 }
01404 /*! assign new afni host name 
01405     SUMA_Assign_AfniHostName (cf, AfniHostName)
01406    
01407    Assigns a new AfniHostName for niml communication
01408    
01409    \param cf (SUMA_CommonFields *) pointer to Common Fields structure, field AfniHostName will be modified here
01410    \param AfniHostName (char *) hostname in IP number form, or name form afni.nimh.nih.gov or afni (if in /etc/hosts file)
01411                                  NULL to set cf->AfniHostName to localhost
01412    \ret ans (SUMA_Boolean) YUP/NOPE
01413    
01414    
01415 */
01416 SUMA_Boolean SUMA_Assign_AfniHostName (SUMA_CommonFields *cf, char *AfniHostName)
01417 {
01418    static char FuncName[]={"SUMA_Assign_AfniHostName"};
01419 
01420    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01421 
01422    if (AfniHostName == NULL)
01423       sprintf(cf->AfniHostName, "localhost");
01424    else {   
01425       if (strlen(AfniHostName) > SUMA_MAX_NAME_LENGTH - 20) {
01426          fprintf(SUMA_STDERR,"Error %s: too long a host name (> %d chars).\n", FuncName, SUMA_MAX_NAME_LENGTH - 20);
01427          SUMA_RETURN (NOPE);
01428       }
01429       sprintf(cf->AfniHostName,"%s", AfniHostName);
01430    }
01431 
01432    sprintf(cf->NimlAfniStream,"tcp:%s:53211", cf->AfniHostName);
01433 
01434    fprintf(SUMA_STDOUT, "%s: Set AfniHostName to %s (stream name: %s)\n", FuncName, cf->AfniHostName, cf->NimlAfniStream);
01435    SUMA_RETURN (YUP);
01436 }
01437 
01438 /*!
01439    This function determines the most suitable standard view of a surface viewer
01440    This is based on the surface objects being displayed and their embedding dimension.
01441    The highest Embedding dimension of the lot determines what view to use 
01442    ans = SUMA_BestStandardView (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int N_dov)
01443    
01444    \param sv (SUMA_SurfaceViewer *) Surface viewer structure
01445    \param dov (SUMA_DO *) vector of displayable objects
01446    \param N_dov (int) number of displayable objects
01447    \ret ans (SUMA_STANDARD_VIEWS) recommended view
01448    
01449 */   
01450 SUMA_STANDARD_VIEWS SUMA_BestStandardView (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int N_dov)
01451 {
01452    static char FuncName[] = {"SUMA_BestStandardView"};
01453    SUMA_STANDARD_VIEWS ans;
01454    int i, maxdim = -1, is;
01455    SUMA_SurfaceObject *SO = NULL;
01456    
01457    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01458 
01459    is = sv->iState;
01460    if (is < 0) {
01461       fprintf(SUMA_STDERR, "Error %s: sv->iState undefined.\n", FuncName);
01462       SUMA_RETURN (SUMA_Dunno); 
01463    }
01464    
01465    for (i=0; i<sv->VSv[is].N_MembSOs; ++i) {   
01466       SO = (SUMA_SurfaceObject *)(dov[sv->VSv[is].MembSOs[i]].OP);
01467       if (SO == NULL) {
01468          fprintf(SUMA_STDERR,"Error %s: SO is null ???\n.", FuncName);
01469          SUMA_RETURN (SUMA_Dunno);
01470       }
01471       if (SO->EmbedDim > maxdim) maxdim = SO->EmbedDim;
01472    }
01473    
01474    switch (maxdim) {
01475       case 2:
01476          SUMA_RETURN (SUMA_2D_Z0);
01477       case 3:
01478          SUMA_RETURN(SUMA_3D);
01479       default:
01480          fprintf(SUMA_STDERR,"Error %s: No provision for such a maximum embedding dimension.\n", FuncName);
01481          SUMA_RETURN(SUMA_Dunno);
01482    }
01483 
01484 }
01485 
01486 /*!
01487 ans = SUMA_SetupSVforDOs (Spec, DOv, N_DOv, cSV);
01488 
01489 This functions registers all surfaces in a spec file with a surface viewer. 
01490 The following steps are performed:
01491 SUMA_RegisterSpecSO (register info on all surfaces loaded)
01492 SUMA_RegisterDO (only Surface Objects)
01493 SUMA_RegisterDO (all non SO objects)
01494 SUMA_BestStandardView (decide on best standard view)
01495 SUMA_UpdateRotaCenter (based on surfaces in first view)
01496 SUMA_UpdateViewPoint (based on surfaces in first view)
01497 SUMA_EyeAxisStandard (based on surfaces in first view)
01498 Set the Current SO pointer to the first surface object 
01499 if surface is SureFit, flip lights
01500 \param Spec (SUMA_SurfSpecFile)
01501 \param DOv (SUMA_DO *) Pointer to vector of displayable objects
01502 \param N_DOv (int) Number of displayable objects in DOv
01503 \param cSV (SUMA_SurfaceViewer *) Surface viewer structure
01504 \ret ans (SUMA_Boolean) YUP/NOPE
01505 */
01506 
01507 SUMA_Boolean SUMA_SetupSVforDOs (SUMA_SurfSpecFile Spec, SUMA_DO *DOv, int N_DOv, SUMA_SurfaceViewer *cSV)
01508 {
01509    static char FuncName[] = {"SUMA_SetupSVforDOs"};
01510    int kar;
01511    SUMA_SurfaceObject *SO;
01512    SUMA_Axis *EyeAxis;
01513    int EyeAxis_ID;
01514    
01515    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01516 
01517    #if 0
01518    /* adds DOs individually, left for reference purposes */
01519    /* Register all DOs with SV */
01520    for (kar=0; kar < N_DOv; ++kar) {
01521       if (!SUMA_RegisterDO(kar, cSV)) {
01522          SUMA_error_message (FuncName,"Failed to register DO", 1);
01523          SUMA_RETURN(NOPE);
01524       }
01525    }
01526 
01527    /* register only the first surface and the remaining DOs */
01528    {
01529       SUMA_Boolean SurfIn = NOPE;
01530       for (kar=0; kar < N_DOv; ++kar) {
01531          if (!SUMA_isSO(DOv[kar]) || !SurfIn)
01532          { /* register the first surface only and other non SO objects */
01533             /*fprintf(SUMA_STDERR," to register DOv[%d] ...\n", kar);*/
01534             if (!SUMA_RegisterDO(kar, cSV)) {
01535                SUMA_error_message (FuncName,"Failed to register DO", 1);
01536                SUMA_RETURN(NOPE);
01537             }
01538          }
01539          if (SUMA_isSO(DOv[kar])) { SurfIn = YUP; }
01540       }
01541    }   
01542    #endif 
01543 
01544    #if 1
01545    /* register all surface specs */
01546       /*fprintf(SUMA_STDERR,"%s: Registering SpecSO ...", FuncName);*/
01547       if (!SUMA_RegisterSpecSO(&Spec, cSV, DOv, N_DOv)) {
01548          fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_RegisterSpecSO.\n", FuncName);
01549          SUMA_RETURN(NOPE);
01550       } 
01551       /*fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);*/
01552 
01553    /* register all SOs of the first state */   
01554       /*fprintf(SUMA_STDERR,"%s: Registering All SO of the first group ...", FuncName);*/
01555       cSV->State = cSV->VSv[0].Name;
01556       cSV->iState = 0;
01557       for (kar=0; kar < cSV->VSv[0].N_MembSOs; ++ kar) {
01558          /*fprintf(SUMA_STDERR," About to register DOv[%d] ...\n", cSV->VSv[0].MembSOs[kar]);*/
01559             if (!SUMA_RegisterDO(cSV->VSv[0].MembSOs[kar], cSV)) {
01560                SUMA_error_message (FuncName,"Failed to register DO", 1);
01561                SUMA_RETURN(NOPE);
01562             }
01563       }
01564    /*   fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);*/
01565 
01566    /* register all non SO objects */
01567    /*   fprintf(SUMA_STDERR,"%s: Registering All Non SO ...", FuncName);*/
01568       for (kar=0; kar < N_DOv; ++kar) {
01569          if (!SUMA_isSO(DOv[kar]))
01570          { 
01571             /*fprintf(SUMA_STDERR," About to register DOv[%d] ...\n", kar);*/
01572             if (!SUMA_RegisterDO(kar, cSV)) {
01573                SUMA_error_message (FuncName,"Failed to register DO", 1);
01574                SUMA_RETURN(NOPE);
01575             }
01576          }
01577       }
01578    /*   fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);*/
01579    #endif
01580 
01581    /* decide what the best state is */
01582    cSV->StdView = SUMA_BestStandardView (cSV, DOv, N_DOv);
01583    /*fprintf(SUMA_STDOUT,"%s: Standard View Now %d\n", FuncName, cSV->StdView);*/
01584    if (cSV->StdView == SUMA_Dunno) {
01585       fprintf(SUMA_STDERR,"Error %s: Could not determine the best standard view. Choosing default SUMA_3D\n", FuncName);
01586       cSV->StdView = SUMA_3D;
01587    }
01588 
01589    /* Set the Rotation Center */
01590    if (!SUMA_UpdateRotaCenter(cSV, DOv, N_DOv)) {
01591       fprintf (SUMA_STDERR,"Error %s: Failed to update center of rotation", FuncName);
01592       SUMA_RETURN(NOPE);
01593    }
01594 
01595    /* set the viewing points */
01596    if (!SUMA_UpdateViewPoint(cSV, DOv, N_DOv)) {
01597       fprintf (SUMA_STDERR,"Error %s: Failed to update view point", FuncName);
01598       SUMA_RETURN(NOPE);
01599    }
01600 
01601    /* Change the defaults of the eye axis to fit standard EyeAxis */
01602    EyeAxis_ID = SUMA_GetEyeAxis (cSV, DOv);
01603    if (EyeAxis_ID < 0) {
01604       fprintf (SUMA_STDERR,"Error %s: Failed to get Eye Axis.\n", FuncName);
01605       SUMA_RETURN(NOPE);
01606    }
01607    SUMA_EyeAxisStandard ((SUMA_Axis *)DOv[EyeAxis_ID].OP, cSV);
01608 
01609 
01610    /* Set the index Current SO pointer to the first surface object read of the first state, tiz NOT (Fri Jan 31 15:18:49 EST 2003) a surface of course*/
01611    cSV->Focus_SO_ID = cSV->VSv[0].MembSOs[0];
01612 
01613 
01614    /* if surface is SureFit, flip lights */
01615    SO = (SUMA_SurfaceObject *)(DOv[cSV->Focus_SO_ID].OP);
01616    if (SO->FileType == SUMA_SUREFIT) {
01617       cSV->light0_position[2] *= -1;
01618    }
01619 
01620 
01621    SUMA_RETURN(YUP);
01622 }
01623 
01624 /*!
01625    \brief updates the title string of a viewer window
01626 */
01627 
01628 void SUMA_UpdateViewerTitle(SUMA_SurfaceViewer *sv)   
01629 {  
01630    static char FuncName[]={"SUMA_UpdateViewerTitle"};
01631    int isv, i, N_SOlist, nalloc;  
01632    char slabel[30];   
01633    SUMA_SurfaceObject *SO = NULL;   
01634    int SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS];   
01635    SUMA_Boolean LocalHead = NOPE;
01636    
01637    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01638 
01639    if (!sv->X) SUMA_RETURNe;
01640    if (!sv->X->TOPLEVEL) SUMA_RETURNe;
01641 
01642    isv = SUMA_WhichSV (sv, SUMAg_SVv, SUMAg_N_SVv);   
01643    
01644    if (sv->X->Title) SUMA_free(sv->X->Title);
01645    sv->X->Title = NULL;
01646       
01647    if (isv >= 0) sprintf(slabel,"[%c] SUMA", 65+isv); 
01648    else sprintf(slabel,"[DOH] SUMA"); 
01649    
01650    N_SOlist = SUMA_ShownSOs(sv, SUMAg_DOv, SOlist);   
01651    
01652    i = 0; 
01653    nalloc = 0;  
01654    while (i < N_SOlist) {   
01655       SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[0]].OP);   
01656       if (SO->Label) { 
01657          nalloc +=  (strlen(SO->Label)+5);  
01658       }  
01659       ++i;   
01660    }
01661    
01662    if (LocalHead) fprintf (SUMA_STDERR, "%s: Found %d surface models.\n", FuncName, N_SOlist);
01663    
01664    i = 0; 
01665    if (N_SOlist >= 0) {   
01666       SUMA_LH("title surfaces found");
01667       sv->X->Title = (char *)SUMA_calloc(nalloc + strlen(slabel)+3, sizeof(char));      
01668       sv->X->Title[0] = '\0';
01669       while (i < N_SOlist) {   
01670          SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);   
01671          if (!i)  {
01672             sprintf (sv->X->Title,"%s:%s", slabel, SO->Label); 
01673          } else {
01674             sv->X->Title = strcat (sv->X->Title, " & ");
01675             sv->X->Title = strcat (sv->X->Title, SO->Label); 
01676          }
01677          ++i;   
01678       }  
01679    } else {   
01680       SUMA_LH("No title could be made up");
01681       sv->X->Title = (char *)SUMA_calloc(strlen(slabel)+3, sizeof(char));  
01682       sprintf (sv->X->Title,"%s:-", slabel);   
01683    }  
01684    
01685    XtVaSetValues(sv->X->TOPLEVEL,  
01686             XmNtitle, sv->X->Title,  
01687             NULL);
01688             
01689    SUMA_RETURNe;   
01690 }

Generated on Tue May 27 18:23:18 2003 for SUMA Source Code by doxygen1.2.12-20011209 written by Dimitri van Heesch, © 1997-2001