00001 #define DEBUG_1
00002 #ifdef DEBUG_1
00003    #define DEBUG_2
00004    #define DEBUG_3
00005 #endif
00006    
00007 
00008    
00009 #include "SUMA_suma.h"
00010 
00011    
00012 extern SUMA_DO *SUMAg_DOv;   
00013 extern int SUMAg_N_DOv; 
00014 extern SUMA_CommonFields *SUMAg_CF;
00015 extern SUMA_SurfaceViewer *SUMAg_SVv;
00016 extern int SUMAg_N_SVv;
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 SUMA_Boolean SUMA_Engine (DList **listp)
00035 {
00036    static char FuncName[]={"SUMA_Engine"};
00037    char tmpcom[SUMA_MAX_COMMAND_LENGTH], sfield[100], sdestination[100];
00038    const char *NextCom;
00039    int NextComCode, ii, i, id, ND, ip, NP;
00040    SUMA_SurfaceObject *SO = NULL;
00041    float delta_t;
00042    struct  timeval tt;
00043    int it, Wait_tot, nn=0, N_SOlist, SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS], iv200[200];
00044    float ft, **fm, fv15[15];
00045    XtPointer elvis=NULL;
00046    NI_element *nel;
00047    SUMA_Boolean Found;
00048    SUMA_SurfaceViewer *svi;
00049    SUMA_SurfaceViewer *sv = NULL;
00050    static char Command[]={"OBSOLETE-since:Thu Jan 23 16:55:03 EST 2003"};
00051    SUMA_EngineData *EngineData=NULL, *ED = NULL; 
00052  
00053    DListElmt *NextElem_CANT_TOUCH_THIS, *LocElm=NULL;
00054    DList *list= NULL;
00055    SUMA_CREATE_TEXT_SHELL_STRUCT *TextShell = NULL, *LogShell=NULL;
00056    SUMA_Boolean LocalHead = NOPE;
00057    
00058    
00059 
00060  
00061    
00062    
00063    SUMA_ENTRY;
00064    
00065    list = *listp; 
00066    
00067    if (!list) {
00068       fprintf (SUMA_STDERR, "Error %s: Nothing to do.\n", FuncName);
00069       SUMA_RETURN (NOPE);
00070    }
00071    
00072    if (LocalHead) fprintf (SUMA_STDOUT,"%s: ", FuncName);
00073    while (list->size) {
00074       if (LocalHead) fprintf (SUMA_STDERR,"%s: Fetching next element\n", FuncName);
00075      
00076       NextElem_CANT_TOUCH_THIS = dlist_head(list);
00077       EngineData = (SUMA_EngineData *)NextElem_CANT_TOUCH_THIS->data;
00078       
00079       
00080       sv = NULL;
00081       switch (EngineData->Src) {
00082          case SES_Suma: 
00083          case SES_SumaFromAfni:
00084          case SES_SumaWidget:
00085          case SES_SumaFromAny:
00086             sv = (SUMA_SurfaceViewer *)EngineData->Srcp;
00087          case SES_Afni:
00088             break;
00089          default:  
00090             break;
00091       } 
00092       
00093       NextComCode = EngineData->CommandCode;
00094       if (!NextComCode) {
00095          fprintf (stderr, "%s Error: Bad next element code\n", FuncName);
00096          SUMA_RETURN (NOPE);
00097       } 
00098       NextCom = SUMA_CommandString (NextComCode);
00099       if (LocalHead) fprintf (SUMA_STDERR,"->%s<-\t", NextCom);
00100       switch (NextComCode) {
00101          case SE_SendColorMapToAfni:
00102             
00103             {
00104                SUMA_COLOR_MAP *cmap;
00105                NI_element *nel=NULL;
00106                int i;
00107                char sbuf[50], *stmp=NULL;
00108                
00109                if (EngineData->i_Dest != NextComCode ) {
00110                   fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00111                    FuncName, NextCom, NextComCode);
00112                   break;
00113                }
00114                
00115                
00116                if (!(cmap = SUMA_GetStandardMap (EngineData->i))) {
00117                   SUMA_SLP_Err("Failed to create colormap");
00118                   break;
00119                }
00120                
00121                if (cmap->N_Col > 128) {
00122                   SUMA_SLP_Err(  "Cannot send more\n"
00123                                  "than 128 colors to\n"
00124                                  "AFNI.");
00125                   SUMA_Free_ColorMap(cmap); cmap = NULL;
00126                   break;
00127                }
00128                
00129                
00130                nel = NI_new_data_element("ni_do", 0);
00131                NI_set_attribute ( nel, "ni_verb", "DRIVE_AFNI");
00132                stmp = SUMA_append_string("DEFINE_COLORSCALE ", cmap->Name);
00133                
00134 
00135                for (i=cmap->N_Col-1; i >= 0; --i) {
00136                   sprintf(sbuf,"rgbi:%f/%f/%f", 
00137                            cmap->M[i][0], cmap->M[i][1], cmap->M[i][2]);
00138                   stmp = SUMA_append_replace_string(stmp, sbuf, " ", 1);
00139                }
00140                SUMA_LH(stmp);
00141                NI_set_attribute ( nel, "ni_object", stmp);
00142                
00143                
00144                
00145                if (NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel, NI_BINARY_MODE ) < 0) {
00146                   SUMA_SLP_Err("Failed to send CMAP to afni");
00147                   NI_free_element(nel) ; nel = NULL;
00148                   if (stmp) SUMA_free(stmp); stmp = NULL;
00149                   SUMA_Free_ColorMap(cmap); cmap = NULL;
00150                   break;
00151                }
00152                
00153                NI_free_element(nel) ; nel = NULL;
00154                if (stmp) SUMA_free(stmp); stmp = NULL;
00155                
00156                
00157                nel = NI_new_data_element("ni_do", 0);
00158                NI_set_attribute ( nel, "ni_verb", "DRIVE_AFNI");
00159                stmp = SUMA_append_string("SET_PBAR_ALL ", "A.+99");
00160                sprintf(sbuf, " 1 %s", cmap->Name);
00161                stmp = SUMA_append_replace_string(stmp, sbuf, "", 1);
00162                NI_set_attribute ( nel, "ni_object", stmp);
00163                
00164                
00165                
00166                if (NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel, NI_BINARY_MODE ) < 0) {
00167                   SUMA_SLP_Err("Failed to send CMAP to afni");
00168                   NI_free_element(nel) ; nel = NULL;
00169                   if (stmp) SUMA_free(stmp); stmp = NULL;
00170                   SUMA_Free_ColorMap(cmap); cmap = NULL;
00171                   break;
00172                }
00173                
00174                NI_free_element(nel) ; nel = NULL;
00175                if (stmp) SUMA_free(stmp); stmp = NULL;
00176               
00177                
00178                nel = NI_new_data_element("ni_do", 0);
00179                NI_set_attribute ( nel, "ni_verb", "DRIVE_AFNI");
00180                NI_set_attribute ( nel, "ni_object", "SET_FUNC_AUTORANGE A.-");
00181                if (NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel, NI_BINARY_MODE ) < 0) {
00182                   SUMA_SLP_Err("Failed to send CMAP to afni");
00183                   NI_free_element(nel) ; nel = NULL;
00184                   SUMA_Free_ColorMap(cmap); cmap = NULL;
00185                   break;
00186                }
00187                
00188                NI_free_element(nel) ; nel = NULL;
00189                
00190                
00191                nel = NI_new_data_element("ni_do", 0);
00192                NI_set_attribute ( nel, "ni_verb", "DRIVE_AFNI");
00193                sprintf(sbuf," %d", cmap->N_Col);
00194                stmp = SUMA_append_string("SET_FUNC_RANGE A.", sbuf);
00195                NI_set_attribute ( nel, "ni_object", stmp);
00196                if (NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel, NI_BINARY_MODE ) < 0) {
00197                   SUMA_SLP_Err("Failed to send CMAP to afni");
00198                   NI_free_element(nel) ; nel = NULL;
00199                   if (stmp) SUMA_free(stmp); stmp = NULL;
00200                   SUMA_Free_ColorMap(cmap); cmap = NULL;
00201                   break;
00202                }
00203                NI_free_element(nel) ; nel = NULL;
00204                if (stmp) SUMA_free(stmp); stmp = NULL;
00205                
00206                SUMA_Free_ColorMap(cmap); cmap = NULL;
00207             }
00208             break;
00209          case SE_OpenDrawnROIFileSelection:
00210             
00211 
00212             if (EngineData->vp_Dest != NextComCode || EngineData->ip_Dest != NextComCode ) {
00213                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00214                   FuncName, NextCom, NextComCode);
00215                break;
00216             }
00217             
00218             if (!sv) sv = &(SUMAg_SVv[0]);
00219             if (!EngineData->ip) {
00220                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_OPEN, YUP,
00221                                                         SUMA_OpenDrawnROI, (void *)EngineData->vp,
00222                                                         NULL, NULL,
00223                                                         "*.roi",
00224                                                         SUMAg_CF->X->FileSelectDlg);
00225             } else {
00226                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_OPEN, YUP,
00227                                                         SUMA_OpenDrawnROI, (void *)EngineData->vp,
00228                                                         NULL, NULL,
00229                                                         "*.roi",
00230                                                         SUMAg_CF->X->FileSelectDlg);
00231             }
00232             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select ROI File to Open", &SUMAg_CF->X->FileSelectDlg);
00233             break;
00234             
00235          case SE_SaveDrawnROIFileSelection:
00236             
00237 
00238             if (EngineData->vp_Dest != NextComCode || EngineData->ip_Dest != NextComCode ) {
00239                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00240                   FuncName, NextCom, NextComCode);
00241                break;
00242             }
00243             
00244             
00245             if (!sv) sv = &(SUMAg_SVv[0]);
00246             if (!EngineData->ip) {
00247                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_SAVE, YUP,
00248                                                         SUMA_SaveDrawnROI, (void *)EngineData->vp,
00249                                                         NULL, NULL,
00250                                                         "*.roi",
00251                                                         SUMAg_CF->X->FileSelectDlg);
00252             } else {
00253                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_SAVE, YUP,
00254                                                         SUMA_SaveDrawnROI, (void *)EngineData->vp,
00255                                                         NULL, NULL,
00256                                                         "*.roi",
00257                                                         SUMAg_CF->X->FileSelectDlg);
00258             }
00259             
00260             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select ROI Filename", &SUMAg_CF->X->FileSelectDlg);
00261             
00262             break;
00263 
00264          case SE_SaveSOFileSelection:
00265             
00266             
00267             if (EngineData->vp_Dest != NextComCode || EngineData->ip_Dest != NextComCode ) {
00268                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00269                   FuncName, NextCom, NextComCode);
00270                break;
00271             }
00272             if (!sv) sv = &(SUMAg_SVv[0]);
00273             
00274             {
00275                SUMA_SAVESO_STRUCT *SaveSO_data = NULL;
00276                
00277                SaveSO_data = (SUMA_SAVESO_STRUCT *) SUMA_malloc(sizeof(SUMA_SAVESO_STRUCT)); 
00278 
00279 
00280                SaveSO_data->SO = (SUMA_SurfaceObject *)EngineData->vp;
00281                SaveSO_data->sv = sv;
00282                
00283                if (!EngineData->ip) {
00284                   SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_SAVE, YUP,
00285                                                            SUMA_SaveSOascii, (void *)SaveSO_data,
00286                                                            NULL, NULL,
00287                                                            "*.1D.xyz",
00288                                                            SUMAg_CF->X->FileSelectDlg);
00289                } else {
00290                   SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_SAVE, YUP,
00291                                                            SUMA_SaveSOascii, (void *)SaveSO_data,
00292                                                            NULL, NULL,
00293                                                            "*.1D.xyz",
00294                                                            SUMAg_CF->X->FileSelectDlg);
00295                }
00296 
00297                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select SO file prefix.", &SUMAg_CF->X->FileSelectDlg);
00298             }
00299             break;
00300             
00301          case SE_LoadSegDO:
00302             if (EngineData->ip_Dest != NextComCode ) {
00303                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00304                   FuncName, NextCom, NextComCode);
00305                break;
00306             }
00307             if (!sv) sv = &(SUMAg_SVv[0]);
00308             if (!EngineData->ip) {
00309                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_OPEN, YUP,
00310                                                         SUMA_LoadSegDO, (void *)sv,
00311                                                         NULL, NULL,
00312                                                         "*",
00313                                                         SUMAg_CF->X->FileSelectDlg);
00314             } else {
00315                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_OPEN, YUP,
00316                                                         SUMA_LoadSegDO, (void *)sv,
00317                                                         NULL, NULL,
00318                                                         "*",
00319                                                         SUMAg_CF->X->FileSelectDlg);
00320             }
00321             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select Segment File", &SUMAg_CF->X->FileSelectDlg);
00322             break;
00323             
00324          case SE_LoadViewFileSelection:
00325             
00326 
00327             
00328             if (EngineData->ip_Dest != NextComCode ) {
00329                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00330                   FuncName, NextCom, NextComCode);
00331                break;
00332             }
00333             if (!sv) sv = &(SUMAg_SVv[0]);
00334             if (!EngineData->ip) {
00335                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_OPEN, YUP,
00336                                                         SUMA_LoadVisualState, (void *)sv,
00337                                                         NULL, NULL,
00338                                                         "*.vvs",
00339                                                         SUMAg_CF->X->FileSelectDlg);
00340             } else {
00341                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_OPEN, YUP,
00342                                                         SUMA_LoadVisualState, (void *)sv,
00343                                                         NULL, NULL,
00344                                                         "*.vvs",
00345                                                         SUMAg_CF->X->FileSelectDlg);
00346             }
00347             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select Viewer Settings File", &SUMAg_CF->X->FileSelectDlg);
00348             break;
00349             
00350          case SE_SaveViewFileSelection:
00351             
00352 
00353             
00354             if (EngineData->ip_Dest != NextComCode ) {
00355                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00356                   FuncName, NextCom, NextComCode);
00357                break;
00358             }
00359             if (!sv) sv = &(SUMAg_SVv[0]);
00360             if (!EngineData->ip) {
00361                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_SAVE, YUP,
00362                                                         SUMA_SaveVisualState, (void *)sv,
00363                                                         NULL, NULL,
00364                                                         "*.vvs",
00365                                                         SUMAg_CF->X->FileSelectDlg);
00366             } else {
00367                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_SAVE, YUP,
00368                                                         SUMA_SaveVisualState, (void *)sv,
00369                                                         NULL, NULL,
00370                                                         "*.vvs",
00371                                                         SUMAg_CF->X->FileSelectDlg);
00372             }
00373             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select Viewer Settings File", &SUMAg_CF->X->FileSelectDlg);
00374             break;
00375             
00376          case SE_OpenDsetFileSelection:
00377             
00378 
00379             
00380             if (EngineData->vp_Dest != NextComCode || EngineData->ip_Dest != NextComCode ) {
00381                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00382                   FuncName, NextCom, NextComCode);
00383                break;
00384             }
00385             
00386             
00387             if (!sv) sv = &(SUMAg_SVv[0]);
00388             if (!EngineData->ip) {
00389                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_OPEN, YUP,
00390                                                         SUMA_LoadDsetFile, (void *)EngineData->vp,
00391                                                         NULL, NULL,
00392                                                         "*.dset",
00393                                                         SUMAg_CF->X->FileSelectDlg);
00394             } else {
00395                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_OPEN, YUP,
00396                                                         SUMA_LoadDsetFile, (void *)EngineData->vp,
00397                                                         NULL, NULL,
00398                                                         "*.dset",
00399                                                         SUMAg_CF->X->FileSelectDlg);
00400             }
00401             
00402             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select Dset File", &SUMAg_CF->X->FileSelectDlg);
00403             
00404             break;
00405          
00406          case SE_OpenCmapFileSelection:
00407             
00408 
00409             
00410             if (EngineData->vp_Dest != NextComCode || EngineData->ip_Dest != NextComCode ) {
00411                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00412                   FuncName, NextCom, NextComCode);
00413                break;
00414             }
00415             
00416             
00417             if (!sv) sv = &(SUMAg_SVv[0]);
00418             if (!EngineData->ip) {
00419                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_OPEN, YUP,
00420                                                         SUMA_LoadCmapFile, (void *)EngineData->vp,
00421                                                         NULL, NULL,
00422                                                         "*.cmap",
00423                                                         SUMAg_CF->X->FileSelectDlg);
00424             } else {
00425                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_OPEN, YUP,
00426                                                         SUMA_LoadCmapFile, (void *)EngineData->vp,
00427                                                         NULL, NULL,
00428                                                         "*.cmap",
00429                                                         SUMAg_CF->X->FileSelectDlg);
00430             }
00431             
00432             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select Cmap File", &SUMAg_CF->X->FileSelectDlg);
00433             
00434             break;
00435          case SE_OpenColFileSelection:
00436             
00437 
00438             
00439             if (EngineData->vp_Dest != NextComCode || EngineData->ip_Dest != NextComCode ) {
00440                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00441                   FuncName, NextCom, NextComCode);
00442                break;
00443             }
00444             
00445             
00446             if (!sv) sv = &(SUMAg_SVv[0]);
00447             if (!EngineData->ip) {
00448                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct (sv->X->TOPLEVEL, SUMA_FILE_OPEN, YUP,
00449                                                         SUMA_LoadColorPlaneFile, (void *)EngineData->vp,
00450                                                         NULL, NULL,
00451                                                         "*.col",
00452                                                         SUMAg_CF->X->FileSelectDlg);
00453             } else {
00454                SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialogStruct ((Widget) EngineData->ip, SUMA_FILE_OPEN, YUP,
00455                                                         SUMA_LoadColorPlaneFile, (void *)EngineData->vp,
00456                                                         NULL, NULL,
00457                                                         "*.col",
00458                                                         SUMAg_CF->X->FileSelectDlg);
00459             }
00460             
00461             SUMAg_CF->X->FileSelectDlg = SUMA_CreateFileSelectionDialog ("Select Node Color File", &SUMAg_CF->X->FileSelectDlg);
00462             
00463             break;
00464          
00465             
00466          case SE_OpenDrawROI:
00467             
00468             {
00469                SUMA_DRAWN_ROI *DrawnROI=NULL;
00470                
00471                if (!sv) {
00472                   fprintf (SUMA_STDERR, "Error %s: Null sv.\n", FuncName);
00473                   SUMA_RETURN(NOPE);
00474                }   
00475                
00476                
00477                DrawnROI = NULL;
00478                
00479                if (sv->Focus_SO_ID >= 0) {
00480                   SO = (SUMA_SurfaceObject *)SUMAg_DOv[sv->Focus_SO_ID].OP;
00481                   DrawnROI = SUMA_FetchROI_InCreation (SO, SUMAg_DOv,  SUMAg_N_DOv); 
00482                }
00483                if (!DrawnROI) { 
00484                   N_SOlist = SUMA_RegisteredSOs(sv, SUMAg_DOv, SOlist);
00485                   if (N_SOlist) {
00486                      it = 0;
00487                      do {
00488                         DrawnROI = SUMA_FetchROI_InCreation (SO, SUMAg_DOv,  SUMAg_N_DOv);
00489                         ++it;
00490                      } while (!DrawnROI && it < N_SOlist);
00491                   }
00492                }
00493                
00494                
00495                if (!SUMA_OpenDrawROIWindow (DrawnROI)) {
00496                   SUMA_RegisterMessage (SUMAg_CF->MessageList, "Failed to open Draw ROI window", FuncName, 
00497                                        SMT_Error, SMA_LogAndPopup);
00498 
00499                }
00500                break;
00501             
00502             }
00503          case SE_SetRenderMode:
00504             { 
00505                SO = (SUMA_SurfaceObject *)EngineData->vp;
00506                SO->PolyMode = EngineData->i;                  
00507             }  
00508             break;
00509             
00510          case SE_UpdateLog:
00511             
00512             {
00513                if (SUMAg_CF->X->Log_TextShell) {
00514                   char *s = NULL;
00515                   s = SUMA_BuildMessageLog (SUMAg_CF->MessageList);
00516                   SUMAg_CF->X->Log_TextShell->CursorAtBottom = YUP;
00517                   (void) SUMA_CreateTextShell (s, "Message Log", SUMAg_CF->X->Log_TextShell);
00518                   XRaiseWindow(SUMAg_CF->X->DPY_controller1, XtWindow(SUMAg_CF->X->Log_TextShell->toplevel));
00519                   if (s) SUMA_free(s);
00520                }
00521             }
00522             break;
00523             
00524          case SE_Log:
00525             
00526             {
00527                char *s = NULL;
00528                if (SUMAg_CF->X->Log_TextShell) { 
00529                   XRaiseWindow(SUMAg_CF->X->DPY_controller1, XtWindow(SUMAg_CF->X->Log_TextShell->toplevel));
00530                   break;
00531                }else { 
00532                   s = SUMA_BuildMessageLog (SUMAg_CF->MessageList);
00533                   if (LocalHead) fprintf (SUMA_STDERR,"%s: Message string:\n%s\n", FuncName, s);
00534                   LogShell =  SUMA_CreateTextShellStruct (SUMA_Message_open, NULL, 
00535                                                           SUMA_Message_destroyed, NULL);
00536                   if (!LogShell) {
00537                      fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateTextShellStruct.\n", FuncName);
00538                      break;
00539                   }
00540                   SUMAg_CF->X->Log_TextShell = SUMA_CreateTextShell(s, "SUMA log", LogShell);
00541                   SUMA_free(s);
00542                }
00543             }
00544             break;
00545             
00546          case SE_Help:
00547             
00548             {
00549                char *s = NULL;
00550                if (SUMAg_CF->X->Help_TextShell) { 
00551                      XRaiseWindow(SUMAg_CF->X->DPY_controller1, XtWindow(SUMAg_CF->X->Help_TextShell->toplevel));
00552                      break;
00553                }
00554                   
00555                s = SUMA_help_message_Info();
00556                if (!s) {
00557                   fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_help_message_Info.\n", FuncName);
00558                   break;
00559                }else {
00560                   TextShell =  SUMA_CreateTextShellStruct (SUMA_Help_open, NULL, 
00561                                                            SUMA_Help_destroyed, NULL);
00562                   if (!TextShell) {
00563                      fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateTextShellStruct.\n", FuncName);
00564                      break;
00565                   }
00566                   SUMAg_CF->X->Help_TextShell = SUMA_CreateTextShell(s, "SUMA help", TextShell);
00567                   SUMA_free(s);   
00568                }
00569             }
00570             break;
00571          case SE_Help_Cmap:
00572             
00573             {
00574                char *s = NULL;
00575                SUMA_COLOR_MAP *Cmp;
00576                if (EngineData->vp_Dest != NextComCode) {
00577                   fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n", \
00578                      FuncName, NextCom, NextComCode);
00579                   break;
00580                } 
00581                Cmp = (SUMA_COLOR_MAP *)EngineData->vp;
00582                if (SUMAg_CF->X->Help_Cmap_TextShell) { 
00583                      XRaiseWindow(SUMAg_CF->X->DPY_controller1, XtWindow(SUMAg_CF->X->Help_Cmap_TextShell->toplevel));
00584                      break;
00585                }
00586                   
00587                s = SUMA_help_Cmap_message_Info(Cmp);
00588                if (!s) {
00589                   fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_help_Cmap_message_Info.\n", FuncName);
00590                   break;
00591                }else {
00592                   TextShell =  SUMA_CreateTextShellStruct (SUMA_Help_Cmap_open, NULL, 
00593                                                            SUMA_Help_Cmap_destroyed, NULL);
00594                   if (!TextShell) {
00595                      fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateTextShellStruct.\n", FuncName);
00596                      break;
00597                   }
00598                   SUMAg_CF->X->Help_Cmap_TextShell = SUMA_CreateTextShell(s, "SUMA Colormap help", TextShell);
00599                   SUMA_free(s);   
00600                }
00601             }
00602             break;
00603          case SE_Load_Group:
00604             
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612             
00613             if (EngineData->cp_Dest != NextComCode || EngineData->vp_Dest != NextComCode 
00614                || EngineData->iv15_Dest != NextComCode || EngineData->i_Dest != NextComCode
00615                || EngineData->ip_Dest != NextComCode || EngineData->f_Dest != NextComCode) {
00616                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n%d %d %d %d %d %d\n", \
00617                   FuncName, NextCom, NextComCode, EngineData->cp_Dest, EngineData->vp_Dest, 
00618                   EngineData->iv15_Dest, EngineData->i_Dest , EngineData->ip_Dest, EngineData->f_Dest);
00619                break;
00620             } 
00621             {
00622                       SUMA_SurfSpecFile Spec;   
00623                char *VolParName = NULL, *specfilename = NULL;
00624                
00625                VolParName = (char *)EngineData->vp;
00626                specfilename = EngineData->cp;
00627                
00628                if (specfilename) {
00629                   
00630                             if (LocalHead) fprintf (SUMA_STDERR, "%s: Reading Spec File ...\n", FuncName);
00631                   if (!SUMA_Read_SpecFile (specfilename, &Spec)) {
00632                                     fprintf(SUMA_STDERR,"Error %s: Error in SUMA_Read_SpecFile.\n", FuncName);
00633                                     exit(1);
00634                             }   
00635                } else {
00636                   if (!EngineData->ip) {
00637                      fprintf(SUMA_STDERR,"Error %s: Nothing in ip, nothing to do !\n", FuncName); exit(1);
00638                   }
00639                   Spec = *((SUMA_SurfSpecFile *)EngineData->ip); 
00640                }
00641                
00642                
00643                          if (Spec.N_Groups != 1) {
00644                                  fprintf(SUMA_STDERR,"Error %s: One and only one group of surfaces is allowed at the moment (%d found).\n", FuncName, Spec.N_Groups);
00645                                  exit(1);
00646                          }
00647 
00648                          if (!EngineData->f) {
00649                                           
00650                             if (LocalHead) fprintf (SUMA_STDERR, "%s: Loading Surfaces in Spec File ...\n", FuncName);
00651                             if (!SUMA_LoadSpec_eng (&Spec, SUMAg_DOv, &SUMAg_N_DOv, VolParName, 0, SUMAg_CF->DsetList)) {
00652                                     fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_LoadSpec.\n", FuncName);
00653                                     exit(1);
00654                             }
00655                }
00656                
00657                
00658                
00659                if (!SUMA_RegisterGroup(SUMAg_CF, &Spec)) {
00660                   SUMA_SL_Err("Failed to register group");
00661                   break;
00662                }
00663                
00664                     
00665                     if (LocalHead) fprintf (SUMA_STDERR, "%s: Registering surfaces with surface viewers ...\n", FuncName);
00666                
00667                for (ii = 0; ii < EngineData->i; ++ii) {
00668                   if (!SUMA_SetupSVforDOs (Spec, SUMAg_DOv, SUMAg_N_DOv, &(SUMAg_SVv[EngineData->iv15[ii]]))) {
00669                                     fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SetupSVforDOs function.\n", FuncName);
00670                                     exit(1);
00671                             }
00672                     }
00673 
00674                if (LocalHead) fprintf (SUMA_STDERR, "%s: Adding call to Home and Redisplay \n", FuncName);
00675                
00676                if (!list) {
00677                   fprintf (SUMA_STDERR, "Error %s: Should not be inside SUMA_Engine: ZSS Feb 02 05.\n", FuncName);
00678                   
00679                   break;
00680                }else {
00681                   SUMA_LH("Appending to list ");
00682                }
00683                ED = SUMA_InitializeEngineListData (SE_Home_AllVisible);
00684                if (!SUMA_RegisterEngineListCommand (  list, ED, 
00685                                                       SEF_Empty, NULL, 
00686                                                       SES_Afni, NULL, NOPE, 
00687                                                       SEI_Tail, NULL )) {
00688                   fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
00689                   break;
00690                }
00691                ED = SUMA_InitializeEngineListData (SE_Redisplay_AllVisible);
00692                if (!SUMA_RegisterEngineListCommand (  list, ED, 
00693                                                       SEF_Empty, NULL, 
00694                                                       SES_Afni, NULL, NOPE, 
00695                                                       SEI_Tail, NULL )) {
00696                   fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
00697                   break;
00698                }
00699    
00700             }
00701             if (LocalHead) fprintf (SUMA_STDERR, "%s: Done in SE_Load_Spec.\n", FuncName);
00702             break;
00703             
00704          case SE_SetLookAt:
00705             
00706             if (EngineData->fv3_Dest != NextComCode) {
00707                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
00708                break;
00709             }
00710             
00711             {
00712                float ulook_old[3], ulook_new[3];
00713                int Step = 10, iStep;
00714                float fracUp, fracDown;
00715               
00716                ulook_old[0] = sv->GVS[sv->StdView].ViewFrom[0] - sv->GVS[sv->StdView].ViewCenter[0];
00717                ulook_old[1] = sv->GVS[sv->StdView].ViewFrom[1] - sv->GVS[sv->StdView].ViewCenter[1];
00718                ulook_old[2] = sv->GVS[sv->StdView].ViewFrom[2] - sv->GVS[sv->StdView].ViewCenter[2];
00719                ulook_new[0] = ulook_new[1] = ulook_new[2] = 0.0;
00720                fm = (float **)SUMA_allocate2D(4,4,sizeof(float));
00721                
00722                for (iStep = Step; iStep >= 1; --iStep) {
00723                   fracUp = (float)(iStep)/(float)Step;
00724                   fracDown = (float)(Step - iStep)/(float)Step;
00725                   if (LocalHead) fprintf (SUMA_STDERR,"%s:%d, fracUp %f, fracDown %f, fv3[%f %f %f]\n", 
00726                                  FuncName, iStep, fracUp, fracDown, EngineData->fv3[0], 
00727                                  EngineData->fv3[1], EngineData->fv3[2]);
00728                   ulook_new[0] = (EngineData->fv3[0] * fracUp + sv->GVS[sv->StdView].ViewFrom[0] * fracDown) \
00729                                  - sv->GVS[sv->StdView].ViewCenter[0];
00730                   ulook_new[1] = (EngineData->fv3[1] * fracUp + sv->GVS[sv->StdView].ViewFrom[1] * fracDown) \
00731                                  - sv->GVS[sv->StdView].ViewCenter[1];
00732                   ulook_new[2] = (EngineData->fv3[2] * fracUp + sv->GVS[sv->StdView].ViewFrom[2] * fracDown) \
00733                                  - sv->GVS[sv->StdView].ViewCenter[2];
00734                   if (fm == NULL) {
00735                      fprintf (SUMA_STDERR,"Error %s: Failed to allocate fm.\n",FuncName);
00736                      break;
00737                   }
00738                   if (!SUMA_FromToRotation (ulook_new, ulook_old, fm)) {
00739                      fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_FromToRotation.\n",FuncName);
00740                      break;
00741                   }
00742                   
00743                   
00744                   ED = SUMA_InitializeEngineListData (SE_SetRotMatrix);
00745                   ED->N_cols = 4;
00746                   ED->N_rows = 4;
00747                   if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED, 
00748                                                          SEF_fm, (void *)fm, 
00749                                                          EngineData->Src, EngineData->Srcp, NOPE, 
00750                                                          SEI_Head, NULL ))) {
00751                      fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
00752                      break;
00753                   }
00754                                     
00755                   
00756                   ED = SUMA_InitializeEngineListData (SE_RedisplayNow);
00757                   if (!SUMA_RegisterEngineListCommand (  list, ED, 
00758                                                          SEF_Empty, NULL, 
00759                                                          EngineData->Src, EngineData->Srcp, NOPE, 
00760                                                          SEI_After, LocElm )) {
00761                      fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName);
00762                      break;
00763                   }
00764                   
00765                }
00766                
00767                SUMA_free2D((char **)fm, 4);
00768             }
00769             break;
00770          
00771          case SE_StartListening:
00772             
00773             if (!SUMAg_CF->Listening) {
00774                SUMAg_CF->Listening = !SUMAg_CF->Listening;
00775                fprintf(SUMA_STDERR,"%s: Starting to listen ...\n", FuncName);
00776                
00777                if (!SUMAg_CF->niml_work_on) {
00778                   SUMA_LH("registering SUMA_niml_workproc...");
00779                   SUMA_register_workproc(SUMA_niml_workproc, (XtPointer)sv);
00780                } else {
00781                   SUMA_LH("SUMA_niml_workproc Already on.");
00782                }
00783             } else {
00784                
00785                
00786                fprintf(SUMA_STDERR,"%s: Closing streams, but still listening ...\n", FuncName);
00787                
00788                for (ii=0; ii< SUMA_MAX_STREAMS; ++ii) {
00789                   if (ii != SUMA_AFNI_STREAM_INDEX) {  
00790                      NI_stream_close( SUMAg_CF->ns_v[ii] ) ;
00791                      SUMAg_CF->ns_v[ii] = NULL ;
00792                      SUMAg_CF->ns_flags_v[ii] = 0;
00793                      SUMAg_CF->TrackingId_v[ii] = 0;
00794                   }
00795                }
00796             } 
00797             break;
00798             
00799          case SE_ToggleConnected:
00800             
00801             if (!SUMA_CanTalkToAfni (SUMAg_DOv, SUMAg_N_DOv)) {
00802                fprintf(SUMA_STDOUT,"%s: Cannot connect to AFNI.\n\tNot one of the surfaces is mappable and has a Surface Volume.\n\tDid you use the -sv option when launching SUMA ?\n", FuncName);
00803                break;
00804             }
00805                
00806             SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX] = !SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX];
00807             if (SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX]) {
00808                if (!SUMA_niml_call (SUMAg_CF, SUMA_AFNI_STREAM_INDEX, YUP)) {
00809                   
00810                   break;
00811                }
00812                   
00813                
00814                if (!SUMAg_CF->niml_work_on) {
00815                   SUMA_LH("registering SUMA_niml_workproc...");
00816                   SUMA_register_workproc(SUMA_niml_workproc, (XtPointer)sv); 
00817                } else {
00818                   SUMA_LH("SUMA_niml_workproc Already on.");
00819                }
00820 
00821                
00822                if (LocalHead) fprintf(SUMA_STDERR,"Notifying Afni of New surface...\n");
00823                ED = SUMA_InitializeEngineListData (SE_SetAfniSurf);
00824                SUMA_RegisterEngineListCommand (list, ED, 
00825                                                 SEF_Empty, NULL,
00826                                                 SES_Suma, (void *)sv, NOPE,
00827                                                 SEI_Head, NULL); 
00828                break;
00829             } else {
00830                fprintf(SUMA_STDOUT,"%s: Disconnecting from afni.\n", FuncName);
00831 
00832                if (!SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX]) {
00833                   
00834                   fprintf(SUMA_STDERR,"Warning %s: sv->ns is null, stream must have gotten closed. Cleaning up ...\n", FuncName);
00835                   ED = SUMA_InitializeEngineListData (SE_CloseStream4All);
00836                   ii = SUMA_AFNI_STREAM_INDEX;
00837                   SUMA_RegisterEngineListCommand (list, ED, 
00838                                                 SEF_i, (void*)&ii,
00839                                                 SES_Suma, (void *)sv, NOPE,
00840                                                 SEI_Head, NULL); 
00841 
00842                   break;
00843                }
00844 
00845 
00846                
00847 
00848 
00849 
00850                if (SUMAg_N_SVv == 1) {
00851                   fprintf(SUMA_STDERR,"%s: Nobody wants to talk to AFNI anymore, closing stream ...\n", FuncName);
00852                   NI_stream_close(SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX]);
00853                   SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] = NULL;
00854                   SUMAg_CF->ns_flags_v[SUMA_AFNI_STREAM_INDEX] = 0;
00855                   SUMAg_CF->TrackingId_v[SUMA_AFNI_STREAM_INDEX] = 0;
00856                }
00857                break;
00858             }
00859    
00860          case SE_CloseStream4All:
00861             
00862             if (EngineData->i_Dest != NextComCode) {
00863                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
00864                break;
00865             }   
00866             
00867             if (EngineData->i == SUMA_AFNI_STREAM_INDEX) {
00868                for (ii=0; ii<SUMAg_N_DOv; ++ii) {
00869                   if (SUMA_isSO(SUMAg_DOv[ii])) {
00870                      SO = (SUMA_SurfaceObject *)(SUMAg_DOv[ii].OP);
00871                      if (SO->SentToAfni) SO->SentToAfni = NOPE;
00872                   }
00873                }
00874             }
00875             
00876             
00877             
00878             nn = NI_stream_goodcheck(SUMAg_CF->ns_v[EngineData->i] , 1 ) ;
00879             
00880             if( nn >= 0 ){ 
00881                fprintf(stderr,"Error %s: Stream still alive, this should not be. Closing anyway.\n", FuncName); 
00882                NI_stream_close(SUMAg_CF->ns_v[EngineData->i]); 
00883             }
00884             
00885                      
00886             SUMAg_CF->ns_v[EngineData->i] = NULL;
00887             SUMAg_CF->ns_flags_v[EngineData->i] = 0;
00888             SUMAg_CF->TrackingId_v[EngineData->i] = 0;
00889  
00890             break;
00891             
00892          case SE_SetForceAfniSurf:
00893             
00894             
00895             #if 0 
00896             for (ii=0; ii<sv->N_DO; ++ii) {
00897                if (SUMA_isSO(SUMAg_DOv[sv->RegisteredDO[ii]])) {
00898                   SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->RegisteredDO[ii]].OP);
00899                   if (SO->SentToAfni) SO->SentToAfni = NOPE;
00900                }
00901             }
00902             #else
00903                
00904                for (ii=0; ii<SUMAg_N_DOv; ++ii) {
00905                   if (SUMA_isSO(SUMAg_DOv[ii])) {
00906                      SO = (SUMA_SurfaceObject *)(SUMAg_DOv[ii].OP);
00907                      if (SO->AnatCorrect && SO->SentToAfni) SO->SentToAfni = NOPE;
00908                   }
00909                }
00910             #endif
00911             
00912             ED = SUMA_InitializeEngineListData (SE_SetAfniSurf);
00913             SUMA_RegisterEngineListCommand (list, ED, 
00914                                             SEF_Empty, NULL,
00915                                             SES_Suma, (void *)sv, NOPE,
00916                                             SEI_Head, NULL); 
00917             break;
00918             
00919          case SE_SetAfniSurfList:
00920             
00921             { int nels_sent, N_Send, *SendList;
00922                
00923                if (EngineData->ivec_Dest != NextComCode || EngineData->s_Dest != NextComCode || EngineData->i_Dest != NextComCode) {
00924                   fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
00925                   break;
00926                }
00927                N_Send = EngineData->ivec->n;
00928                SendList = EngineData->ivec->v; 
00929                
00930                if (N_Send) {
00931                   for (ii=0; ii<N_Send; ++ii) {
00932                      nels_sent = 0;
00933                      SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SendList[ii]].OP);
00934                      if (EngineData->i && SO->Label) fprintf(SUMA_STDERR,"%s: Sending surface %s (%s)...\n", FuncName, SO->Label, EngineData->s);
00935                      if (SUMA_iswordin(EngineData->s,"NodeList") == 1) {
00936                         nel = SUMA_makeNI_SurfIXYZ (SO);
00937                         if (!nel) {
00938                            fprintf(SUMA_STDERR,"Error %s: SUMA_makeNI_SurfIXYZ failed\n", FuncName);
00939                            break;
00940                         }
00941                         
00942                         if (LocalHead) fprintf(SUMA_STDERR,"%s: Sending SURF_iXYZ nel...\n ", FuncName) ;
00943                         nn = NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel , NI_BINARY_MODE ) ;
00944 
00945                         if( nn < 0 ){
00946                              fprintf(SUMA_STDERR,"Error %s: NI_write_element failed\n", FuncName);
00947                         }
00948 
00949                         #if 0
00950                            {
00951                               NI_stream nstdout;
00952                                nstdout = NI_stream_open( "fd:1","w");
00953                                 if( nstdout == NULL ){ fprintf(SUMA_STDERR,"Can't open fd:1\n"); break; }
00954                                  NI_write_element( nstdout , nel , NI_TEXT_MODE ) ;
00955                                NI_stream_close(nstdout);
00956                            }
00957                         #endif
00958 
00959                         NI_free_element(nel);
00960                         nel = NULL;
00961                         ++nels_sent;
00962                      }
00963                      if (SUMA_iswordin(EngineData->s,"NodeNormList") == 1) {
00964                         
00965                         nel = SUMA_makeNI_SurfINORM (SO);
00966                         if (!nel) {
00967                            fprintf(SUMA_STDERR,"Error %s: SUMA_makeNI_SurfINORM failed\n", FuncName);
00968                            break;
00969                         }
00970                         
00971                         if (LocalHead) fprintf(SUMA_STDERR,"%s: Sending SURF_NORM nel ...\n", FuncName) ;
00972                         nn = NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel , NI_BINARY_MODE ) ;
00973 
00974                         if( nn < 0 ){
00975                              fprintf(SUMA_STDERR,"Error %s: NI_write_element failed\n", FuncName);
00976                         }
00977                         NI_free_element(nel);
00978                         nel = NULL;
00979                         ++nels_sent;
00980                      }
00981                      
00982                      if (SUMA_iswordin(EngineData->s,"FaceSetList") == 1) {
00983                         
00984                         nel = SUMA_makeNI_SurfIJK (SO);
00985                         if (!nel) {
00986                            fprintf(SUMA_STDERR,"Error %s: SUMA_makeNI_SurfIJK failed\n", FuncName);
00987                            break;
00988                         }
00989                         
00990                         if (LocalHead) fprintf(SUMA_STDERR,"%s: Sending SURF_IJK nel ...\n", FuncName) ;
00991                         nn = NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel , NI_BINARY_MODE ) ;
00992 
00993                         if( nn < 0 ){
00994                              fprintf(SUMA_STDERR,"Error %s: NI_write_element failed\n", FuncName);
00995                         }
00996                         NI_free_element(nel);
00997                         nel = NULL;
00998                         ++nels_sent;
00999                      }
01000                      if (nels_sent) {
01001                         
01002                         SO->SentToAfni = YUP;
01003                      } else {
01004                         SUMA_SL_Warn("Nothing sent dude, what's happening?");
01005                      }
01006                   }
01007                }
01008 
01009                break;
01010             }
01011             
01012          case SE_SetAfniSurf:
01013             
01014             {  int N_Send, *SendList, ti=1;
01015                SUMA_IVEC ivec;
01016                
01017                
01018 
01019                
01020 
01021                
01022                SendList = SUMA_FormSOListToSendToAFNI(SUMAg_DOv , SUMAg_N_DOv, &N_Send);
01023                if (N_Send) {
01024                   ivec.v = SendList;
01025                   ivec.n = N_Send;
01026                   ED = SUMA_InitializeEngineListData (SE_SetAfniSurfList);
01027                   if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED,
01028                                                          SEF_ivec, (void *)(&ivec), 
01029                                                          SES_Suma, (void *)sv, NOPE, 
01030                                                          SEI_Tail, NULL))) {
01031                      fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01032                      break;
01033                   }
01034                   if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED,
01035                                                          SEF_s, (void *)("NodeList, FaceSetList, NodeNormList"), 
01036                                                          SES_Suma, (void *)sv, NOPE, 
01037                                                          SEI_In, LocElm))) {
01038                      fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01039                      break;
01040                   }
01041                   if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED,
01042                                                          SEF_i, (void *)&ti, 
01043                                                          SES_Suma, (void *)sv, NOPE, 
01044                                                          SEI_In, LocElm))) {
01045                      fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01046                      break;
01047                   }
01048                   if (SendList) SUMA_free(SendList); SendList = NULL;   
01049                }
01050 
01051                break;
01052             }
01053          
01054          case SE_SetAfniThisSurf:
01055             
01056             {
01057                SUMA_IVEC ivec;
01058                if (EngineData->s_Dest != NextComCode || EngineData->cp_Dest != NextComCode || EngineData->i_Dest != NextComCode) {
01059                   fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s ((%d %d %d) %d).\n",
01060                      FuncName, NextCom,  EngineData->s_Dest, EngineData->cp_Dest, EngineData->i_Dest, NextComCode);
01061                   break;
01062                }
01063                i = SUMA_findSO_inDOv(EngineData->cp, SUMAg_DOv, SUMAg_N_DOv);
01064                if (i<0) {
01065                   SUMA_SL_Err("Surface Not Found!");
01066                   break;
01067                }
01068                ivec.n = 1;
01069                ivec.v = (int*)SUMA_malloc(ivec.n*sizeof(int));
01070                ivec.v[0] = i;
01071                ED = SUMA_InitializeEngineListData (SE_SetAfniSurfList);
01072                if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED,
01073                                                       SEF_ivec, (void *)(&ivec), 
01074                                                       SES_Suma, (void *)sv, NOPE, 
01075                                                       SEI_Tail, NULL))) {
01076                   fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01077                   break;
01078                }
01079                if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED,
01080                                                       SEF_s, (void *)(EngineData->s), 
01081                                                       SES_Suma, (void *)sv, NOPE, 
01082                                                       SEI_In, LocElm))) {
01083                   fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01084                   break;
01085                }
01086                if (!(LocElm = SUMA_RegisterEngineListCommand (  list, ED,
01087                                                          SEF_i, (void *)&(EngineData->i), 
01088                                                          SES_Suma, (void *)sv, NOPE, 
01089                                                          SEI_In, LocElm))) {
01090                   fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01091                   break;
01092                }
01093                SUMA_free(ivec.v);
01094                break;
01095             }
01096                
01097          case SE_ToggleShowSelectedNode:
01098             
01099             {
01100                int CommonState = -1;
01101                
01102                for (ii=0; ii<sv->N_DO; ++ii) {
01103                   if (SUMA_isSO(SUMAg_DOv[sv->RegisteredDO[ii]])) {
01104                      if (CommonState < 0) {
01105                         SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->RegisteredDO[ii]].OP);
01106                         SO->ShowSelectedNode = !SO->ShowSelectedNode;
01107                         CommonState = SO->ShowSelectedNode;
01108                         fprintf(SUMA_STDOUT,"SO->ShowSelectedNode = %d\n", SO->ShowSelectedNode);
01109                      } else {
01110                         SO->ShowSelectedNode = CommonState;
01111                      }
01112                   }
01113                 
01114                }
01115             
01116             XmToggleButtonSetState (sv->X->ViewMenu[SW_ViewNodeInFocus], 
01117                   CommonState, NOPE); 
01118                 
01119             }
01120             break;
01121          
01122          case SE_SetSelectedNode:
01123             
01124             if (EngineData->i_Dest != NextComCode) {
01125                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01126                break;
01127             } 
01128             SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_SO_ID].OP);
01129             if (EngineData->i >= 0 && EngineData->i < SO->N_Node) {
01130                SO->SelectedNode = EngineData->i;
01131             } else {
01132                
01133                if (EngineData->i != -1) { SUMA_SLP_Err("Node index < 0 || > Number of nodes in surface"); }
01134                break;
01135             }
01136             SUMA_UpdateNodeField(SO);
01137             break;
01138             
01139          case SE_ToggleShowSelectedFaceSet:
01140             
01141             { int CommonState = -1;
01142                for (ii=0; ii<sv->N_DO; ++ii) {
01143                   if (SUMA_isSO(SUMAg_DOv[sv->RegisteredDO[ii]])) {
01144                      SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->RegisteredDO[ii]].OP);
01145                      if (CommonState < 0) { 
01146                         SO->ShowSelectedFaceSet = !SO->ShowSelectedFaceSet;
01147                         CommonState = SO->ShowSelectedFaceSet;
01148                         fprintf(SUMA_STDOUT,"SO->ShowSelectedFaceSet = %d\n", \
01149                            SO->ShowSelectedFaceSet);
01150                       }else {
01151                         SO->ShowSelectedFaceSet = CommonState;
01152                      }
01153                   }
01154                }
01155             XmToggleButtonSetState (sv->X->ViewMenu[SW_ViewSelectedFaceset], 
01156                   CommonState, NOPE);  
01157             }          
01158             break;
01159          
01160          case SE_SetSelectedFaceSet:
01161             
01162             if (EngineData->i_Dest != NextComCode) {
01163                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01164                break;
01165             } 
01166             SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_SO_ID].OP);
01167             if (EngineData->i < 0 || EngineData->i >= SO->N_FaceSet) {
01168                if (EngineData->i != -1) { 
01169                   SUMA_SLP_Err("Node index < 0 || > Number of FaceSets in surface");
01170                } 
01171                break;
01172             }
01173             ND = SO->NodeDim;
01174             NP = SO->FaceSetDim;
01175             ip = NP * EngineData->i;
01176             id = ND * SO->FaceSetList[ip];
01177             SO->FaceSetMarker->n0[0] = SO->NodeList[id];
01178             SO->FaceSetMarker->n0[1] = SO->NodeList[id+1];
01179             SO->FaceSetMarker->n0[2] = SO->NodeList[id+2];
01180             id = ND * SO->FaceSetList[ip+1];
01181             SO->FaceSetMarker->n1[0] = SO->NodeList[id];
01182             SO->FaceSetMarker->n1[1] = SO->NodeList[id+1];
01183             SO->FaceSetMarker->n1[2] = SO->NodeList[id+2];
01184             id = ND * SO->FaceSetList[ip+2];
01185             SO->FaceSetMarker->n2[0] = SO->NodeList[id];
01186             SO->FaceSetMarker->n2[1] = SO->NodeList[id+1];
01187             SO->FaceSetMarker->n2[2] = SO->NodeList[id+2];
01188             SO->FaceSetMarker->NormVect[0] = SO->FaceNormList[ip];
01189             SO->FaceSetMarker->NormVect[1] = SO->FaceNormList[ip+1];
01190             SO->FaceSetMarker->NormVect[2] = SO->FaceNormList[ip+2];
01191             
01192             SO->SelectedFaceSet = EngineData->i;
01193             SUMA_UpdateTriField(SO);
01194             break;
01195             
01196          case SE_ToggleCrossHair:
01197             
01198             sv->ShowCrossHair = !sv->ShowCrossHair;
01199             XmToggleButtonSetState (sv->X->ViewMenu[SW_ViewCrossHair], 
01200                sv->ShowCrossHair, NOPE);            
01201             break;
01202             
01203          case SE_SetCrossHair:
01204             
01205             if (EngineData->fv3_Dest != NextComCode) {
01206                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01207                break;
01208             }
01209             if (LocalHead) fprintf(SUMA_STDERR,"%s: Setting cross hair at %f %f %f\n", FuncName, EngineData->fv3[0], EngineData->fv3[1],EngineData-> fv3[2]);
01210             sv->Ch->c[0] = EngineData->fv3[0]; sv->Ch->c[1]= EngineData->fv3[1]; sv->Ch->c[2]= EngineData->fv3[2];
01211             
01212             SUMA_UpdateXhairField(sv); 
01213             break;
01214          
01215          case SE_BindCrossHair:
01216             
01217             if (EngineData->iv3_Dest != NextComCode) {
01218                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01219                break;
01220             }
01221             sv->Ch->SurfaceID = EngineData->iv3[0];
01222             sv->Ch->NodeID = EngineData->iv3[1];
01223             
01224             break;
01225          
01226          case SE_SetSOinFocus:
01227             
01228             if (EngineData->i_Dest != NextComCode) {
01229                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01230                break;
01231             }
01232             if (sv->Focus_SO_ID != EngineData->i) {
01233                
01234                sv->Focus_SO_ID = EngineData->i;
01235                SUMA_UpdateViewerTitle(sv);
01236            }
01237             break;
01238             
01239          case SE_ToggleLockView:
01240             
01241             
01242             if (EngineData->i_Dest != NextComCode) {
01243                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01244                break;
01245             }
01246             SUMAg_CF->ViewLocked[EngineData->i] = !SUMAg_CF->ViewLocked[EngineData->i];
01247             
01248             if (EngineData->Src != SES_SumaWidget) {
01249                XmToggleButtonSetState (SUMAg_CF->X->SumaCont->LockView_tbg[EngineData->i], SUMAg_CF->ViewLocked[EngineData->i], NOPE);
01250             }
01251             
01252             
01253             SUMA_set_LockView_atb ();
01254             
01255             break;
01256          
01257          case SE_ToggleLockAllViews:
01258             
01259             
01260             
01261             {
01262                SUMA_Boolean CurState;
01263                CurState = XmToggleButtonGetState (SUMAg_CF->X->SumaCont->LockAllView_tb);
01264                for (ii=0; ii< SUMA_MAX_SURF_VIEWERS; ++ii) { 
01265                   XmToggleButtonSetState (SUMAg_CF->X->SumaCont->LockView_tbg[ii], CurState, NOPE);
01266                   SUMAg_CF->ViewLocked[ii] = CurState;
01267                }
01268             }
01269             break;
01270          
01271          case SE_ToggleLockAllCrossHair:
01272             
01273             {
01274                char LockName[100];
01275                SUMA_LockEnum_LockType (SUMAg_CF->Locked[0], LockName);
01276                fprintf (SUMA_STDERR,"%s: Switching Locktype from %s", FuncName, LockName);
01277                
01278                SUMAg_CF->Locked[0] = (int)fmod(SUMAg_CF->Locked[0]+1, SUMA_N_Lock_Types);
01279                SUMA_LockEnum_LockType (SUMAg_CF->Locked[0], LockName);
01280                fprintf (SUMA_STDERR," %s\n", LockName);
01281                
01282                SUMA_set_Lock_rb (SUMAg_CF->X->SumaCont->Lock_rbg, 0, SUMAg_CF->Locked[0]);
01283                
01284                for (ii=1; ii< SUMA_MAX_SURF_VIEWERS; ++ii) {
01285                   SUMAg_CF->Locked[ii] = SUMAg_CF->Locked[0];                  
01286                   SUMA_set_Lock_rb (SUMAg_CF->X->SumaCont->Lock_rbg, ii, SUMAg_CF->Locked[ii]);
01287                }
01288 
01289                
01290                SUMA_set_Lock_arb (SUMAg_CF->X->SumaCont->Lock_rbg);
01291 
01292             }
01293             break;
01294          
01295          case SE_SetLockAllCrossHair:
01296             
01297             if (EngineData->i_Dest != NextComCode) {
01298                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01299                break;
01300             }
01301             {
01302                
01303                
01304                for (ii=0; ii< SUMA_MAX_SURF_VIEWERS; ++ii) {
01305                   SUMAg_CF->Locked[ii] = EngineData->i;                  
01306                   SUMA_set_Lock_rb (SUMAg_CF->X->SumaCont->Lock_rbg, ii, SUMAg_CF->Locked[ii]);
01307                }
01308 
01309                
01310                SUMA_set_Lock_arb (SUMAg_CF->X->SumaCont->Lock_rbg);
01311             }
01312             break;
01313             
01314          case SE_LockCrossHair:
01315             
01316 
01317             
01318 
01319             
01320             ii = SUMA_WhichSV(sv, SUMAg_SVv, SUMAg_N_SVv);
01321             if (ii < 0) {
01322                fprintf (SUMA_STDERR,"Error %s: Failed to find index of sv.\n", FuncName);
01323                break;
01324             }
01325             if (SUMAg_CF->Locked[ii]) { 
01326                for (i=0; i < SUMAg_N_SVv; ++i) {
01327                   svi = &SUMAg_SVv[i];
01328                   if (i != ii) {
01329                      switch (SUMAg_CF->Locked[i]) { 
01330                         case SUMA_No_Lock:
01331                            if (LocalHead) fprintf (SUMA_STDERR, "%s: No lock for viewer %d.\n", FuncName, i);
01332                            break;
01333                         case SUMA_XYZ_Lock:
01334                            if (LocalHead) fprintf (SUMA_STDERR, "%s: Try to XYZ lock viewer %d.\n", FuncName, i);
01335                            
01336                            svi->Ch->c[0] = sv->Ch->c[0];
01337                            svi->Ch->c[1] = sv->Ch->c[1];
01338                            svi->Ch->c[2] = sv->Ch->c[2];
01339                            svi->Ch->NodeID = -1;
01340                            svi->Ch->SurfaceID = -1;
01341                            
01342                            svi->ResetGLStateVariables = YUP;
01343                            SUMA_handleRedisplay((XtPointer)svi->X->GLXAREA);                           
01344                            break;
01345                         case SUMA_I_Lock: 
01346                            {
01347                               SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
01348                               
01349                               if (LocalHead) fprintf (SUMA_STDERR, "%s: Try to I lock viewer %d to node %d.\n", FuncName, i, sv->Ch->NodeID);
01350                               
01351                               
01352                               N_SOlist = SUMA_RegisteredSOs(svi, SUMAg_DOv, SOlist);
01353 
01354                               
01355                               if (sv->Ch->SurfaceID < 0) {
01356                                  fprintf (SUMA_STDERR, "%s: Cannot link from this viewer's cross hair. No bound surface.\n", FuncName);
01357                                  break;
01358                               }
01359                               if (sv->Ch->NodeID < 0) {
01360                                  fprintf (SUMA_STDERR, "%s: Cannot link from this viewer's cross hair. No NodeID.\n", FuncName);
01361                                  break;
01362                               }
01363                               SO1 = (SUMA_SurfaceObject *)SUMAg_DOv[sv->Ch->SurfaceID].OP;
01364                               Found = NOPE;
01365                               it = 0;
01366                               while (it < N_SOlist && !Found) {
01367                                  SO2 = (SUMA_SurfaceObject *)SUMAg_DOv[SOlist[it]].OP;
01368                                  if (SUMA_isRelated (SO1, SO2, 2)) { 
01369                                     svi->Ch->SurfaceID = SOlist[it];
01370                                     if (sv->Ch->NodeID > SO2->N_Node) {
01371                                        fprintf (SUMA_STDERR,"Error %s: NodeID is larger than N_Node. Setting NodeID to 0.\n", FuncName);
01372                                        svi->Ch->NodeID = 0;
01373                                     }else{
01374                                        svi->Ch->NodeID = sv->Ch->NodeID;
01375                                     }
01376                                     
01377                                     
01378                                     svi->Ch->c[0] = SO2->NodeList[SO2->NodeDim*svi->Ch->NodeID];
01379                                     svi->Ch->c[1] = SO2->NodeList[SO2->NodeDim*svi->Ch->NodeID+1];
01380                                     svi->Ch->c[2] = SO2->NodeList[SO2->NodeDim*svi->Ch->NodeID+2];
01381                                     fprintf (SUMA_STDERR,"%s: new XYZ %f %f %f\n", FuncName, 
01382                                        svi->Ch->c[0], svi->Ch->c[1], svi->Ch->c[2]); 
01383                                     Found = YUP;
01384                                  }
01385                                  ++it;
01386                               }
01387                               if (!Found) {
01388                                  if (LocalHead) fprintf (SUMA_STDERR,"%s: No related surfaces found in viewer, cross hair will not be touched .\n", FuncName);
01389                                  break;
01390                               } else {
01391                                  
01392                                  svi->ResetGLStateVariables = YUP;
01393                                  SUMA_handleRedisplay((XtPointer)svi->X->GLXAREA);
01394                               }
01395                               
01396                            }
01397                            break;
01398                         default:
01399                            fprintf(SUMA_STDERR,"Error %s: Lock type (%d) undefined.\n", FuncName, SUMAg_CF->Locked[ii]);
01400                            break;
01401                      }
01402                   }
01403                }
01404             }else{
01405                
01406             }
01407             break;
01408                         
01409          case SE_SetAfniCrossHair:
01410             
01411             
01412             
01413             nel = SUMA_makeNI_CrossHair (sv);
01414             if (!nel) {
01415                fprintf(SUMA_STDERR,"Error %s: SUMA_makeNI_CrossHair failed\n", FuncName);
01416                break;
01417                }
01418             
01419             
01420             nn = NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel , NI_TEXT_MODE ) ;
01421             
01422       
01423             if( nn < 0 ){
01424                    fprintf(SUMA_STDERR,"Error %s: NI_write_element failed\n", FuncName);
01425             }
01426             
01427             NI_free_element(nel);
01428 
01429             break;
01430                   
01431          case SE_SetLookAtNode:
01432             
01433 
01434             if (EngineData->fv15_Dest != NextComCode) {
01435                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01436                break;
01437             } 
01438             
01439             { float CurrentDistance;
01440               float fm2_3[2][3], *dir;
01441               
01442             
01443             CurrentDistance = sqrt((sv->GVS[sv->StdView].ViewFrom[0]-sv->GVS[sv->StdView].ViewCenter[0])*(sv->GVS[sv->StdView].ViewFrom[0]-sv->GVS[sv->StdView].ViewCenter[0]) +\
01444                                     (sv->GVS[sv->StdView].ViewFrom[1]-sv->GVS[sv->StdView].ViewCenter[1])*(sv->GVS[sv->StdView].ViewFrom[1]-sv->GVS[sv->StdView].ViewCenter[1]) +\
01445                                     (sv->GVS[sv->StdView].ViewFrom[2]-sv->GVS[sv->StdView].ViewCenter[2])*(sv->GVS[sv->StdView].ViewFrom[2]-sv->GVS[sv->StdView].ViewCenter[2]));
01446             
01447             
01448             sv->GVS[sv->StdView].ViewCenter[0] = EngineData->fv15[0];
01449             sv->GVS[sv->StdView].ViewCenter[1] = EngineData->fv15[1]; 
01450             sv->GVS[sv->StdView].ViewCenter[2] = EngineData->fv15[2];
01451             
01452             
01453             dir = &(EngineData->fv15[3]);
01454             SUMA_POINT_AT_DISTANCE(dir, sv->GVS[sv->StdView].ViewCenter, CurrentDistance, fm2_3);
01455             
01456             fprintf(SUMA_STDOUT,"\nPoints: %f %f %f\n%f %f %f\n", \
01457                fm2_3[0][0], fm2_3[0][1], fm2_3[0][2], \
01458                fm2_3[1][0], fm2_3[1][1], fm2_3[1][2]);
01459             
01460             sv->GVS[sv->StdView].ViewFrom[0] = fm2_3[0][0]; 
01461             sv->GVS[sv->StdView].ViewFrom[1] = fm2_3[0][1]; 
01462             sv->GVS[sv->StdView].ViewFrom[2] = fm2_3[0][2]; 
01463                         
01464             gluLookAt (sv->GVS[sv->StdView].ViewFrom[0], sv->GVS[sv->StdView].ViewFrom[1], sv->GVS[sv->StdView].ViewFrom[2], sv->GVS[sv->StdView].ViewCenter[0], sv->GVS[sv->StdView].ViewCenter[1], sv->GVS[sv->StdView].ViewCenter[2], sv->GVS[sv->StdView].ViewCamUp[0], sv->GVS[sv->StdView].ViewCamUp[1], sv->GVS[sv->StdView].ViewCamUp[2]);
01465             }
01466             
01467             break;
01468          case SE_SetLookFrom:
01469             
01470             if (EngineData->fv3_Dest != NextComCode) {
01471                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01472                break;
01473             } 
01474             
01475             sv->GVS[sv->StdView].ViewFrom[0] = EngineData->fv3[0];
01476             sv->GVS[sv->StdView].ViewFrom[1] = EngineData->fv3[1]; 
01477             sv->GVS[sv->StdView].ViewFrom[2] = EngineData->fv3[2];
01478             gluLookAt (sv->GVS[sv->StdView].ViewFrom[0], sv->GVS[sv->StdView].ViewFrom[1], sv->GVS[sv->StdView].ViewFrom[2], sv->GVS[sv->StdView].ViewCenter[0], sv->GVS[sv->StdView].ViewCenter[1], sv->GVS[sv->StdView].ViewCenter[2], sv->GVS[sv->StdView].ViewCamUp[0], sv->GVS[sv->StdView].ViewCamUp[1], sv->GVS[sv->StdView].ViewCamUp[2]);
01479             break;
01480 
01481          case SE_Redisplay_AllVisible:
01482             
01483             
01484             for (ii=0; ii<SUMAg_N_SVv; ++ii) {
01485                if (LocalHead) fprintf (SUMA_STDERR,"%s: Checking viewer %d.\n", FuncName, ii);
01486                if (!SUMAg_SVv[ii].isShaded && SUMAg_SVv[ii].X->TOPLEVEL) {
01487                   
01488 
01489                   if (LocalHead) fprintf (SUMA_STDERR,"%s: Redisplaying viewer %d.\n", FuncName, ii);
01490                   SUMAg_SVv[ii].ResetGLStateVariables = YUP;
01491                   SUMA_postRedisplay(SUMAg_SVv[ii].X->GLXAREA, NULL, NULL);
01492                }
01493             }
01494             break;
01495             
01496          
01497          case SE_Redisplay:
01498             
01499             
01500             if (LocalHead) fprintf (SUMA_STDOUT,"%s: Redisplay ...", FuncName);
01501             SUMA_postRedisplay(sv->X->GLXAREA, NULL, NULL);
01502             if (LocalHead) fprintf (SUMA_STDOUT," Done\n");
01503             break;
01504          
01505          case SE_RedisplayNow:
01506             
01507             
01508             if (LocalHead) fprintf (SUMA_STDOUT,"%s: Redisplaying NOW ...", FuncName);
01509             sv->ResetGLStateVariables = YUP;
01510             SUMA_handleRedisplay((XtPointer)sv->X->GLXAREA);
01511             if (LocalHead) fprintf (SUMA_STDOUT," Done\n");
01512             break;
01513             
01514          case SE_RedisplayNow_AllVisible:
01515             
01516             
01517             for (ii=0; ii<SUMAg_N_SVv; ++ii) {
01518                if (LocalHead) fprintf (SUMA_STDERR,"%s: Checking viewer %d.\n", FuncName, ii);
01519                if (!SUMAg_SVv[ii].isShaded && SUMAg_SVv[ii].X->TOPLEVEL) {
01520                   
01521 
01522                   if (LocalHead) fprintf (SUMA_STDERR,"%s: Redisplaying viewer %d.\n", FuncName, ii);
01523                   SUMAg_SVv[ii].ResetGLStateVariables = YUP;
01524                   SUMA_handleRedisplay((XtPointer)SUMAg_SVv[ii].X->GLXAREA);
01525                }
01526             }
01527             break;
01528          
01529          case SE_RedisplayNow_AllOtherVisible:
01530             
01531             
01532             for (ii=0; ii<SUMAg_N_SVv; ++ii) {
01533                if (LocalHead) fprintf (SUMA_STDERR,"%s: Checking viewer %d.\n", FuncName, ii);
01534                if (!SUMAg_SVv[ii].isShaded && SUMAg_SVv[ii].X->TOPLEVEL && &(SUMAg_SVv[ii]) != sv) {
01535                   
01536 
01537                   if (LocalHead) fprintf (SUMA_STDERR,"%s: Redisplaying viewer %d.\n", FuncName, ii);
01538                   SUMAg_SVv[ii].ResetGLStateVariables = YUP;
01539                   SUMA_handleRedisplay((XtPointer)SUMAg_SVv[ii].X->GLXAREA);
01540                }
01541             }
01542             break;
01543 
01544          case SE_ResetOpenGLState:
01545             
01546             
01547             if (EngineData->vp_Dest != NextComCode) {
01548                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01549                break;
01550             } 
01551             if (LocalHead) fprintf (SUMA_STDOUT,"%s: Resetting OpenGL state variables.\n", FuncName);
01552             
01553             
01554             svi = (SUMA_SurfaceViewer *)EngineData->vp;
01555             svi->ResetGLStateVariables = YUP;
01556             break;
01557             
01558          case SE_ToggleForeground:
01559             
01560             
01561             sv->ShowForeground = !sv->ShowForeground;
01562             if (!sv->ShowForeground) {
01563                fprintf(SUMA_STDOUT,"%s: Foreground Colors Off.\n", FuncName);
01564             } else {
01565                fprintf(SUMA_STDOUT,"%s: Foreground Colors ON.\n", FuncName);
01566             }
01567             
01568             if (!SUMA_SetShownLocalRemixFlag (sv)) {
01569                fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SetShownLocalRemixFlag.\n", FuncName);
01570                break;
01571             }
01572             break;
01573          
01574          case SE_ToggleBackground:
01575             
01576             
01577             sv->ShowBackground = !sv->ShowBackground;
01578             if (!sv->ShowBackground) {
01579                fprintf(SUMA_STDOUT,"%s: Background Colors OFF.\n", FuncName);
01580             } else {
01581                fprintf(SUMA_STDOUT,"%s: Background Colors ON.\n", FuncName);
01582             }
01583             
01584             if (!SUMA_SetShownLocalRemixFlag (sv)) {
01585                fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SetShownLocalRemixFlag.\n", FuncName);
01586                break;
01587             }
01588             break;
01589                      
01590          case SE_Home:
01591             
01592             sv->GVS[sv->StdView].translateVec[0]=0; sv->GVS[sv->StdView].translateVec[1]=0;
01593             glMatrixMode(GL_PROJECTION);
01594             
01595             sv->GVS[sv->StdView].ViewFrom[0] = sv->GVS[sv->StdView].ViewFromOrig[0];
01596             sv->GVS[sv->StdView].ViewFrom[1] = sv->GVS[sv->StdView].ViewFromOrig[1];
01597             sv->GVS[sv->StdView].ViewFrom[2] = sv->GVS[sv->StdView].ViewFromOrig[2];
01598             sv->GVS[sv->StdView].ViewCenter[0] = sv->GVS[sv->StdView].ViewCenterOrig[0];
01599             sv->GVS[sv->StdView].ViewCenter[1] = sv->GVS[sv->StdView].ViewCenterOrig[1];
01600             sv->GVS[sv->StdView].ViewCenter[2] = sv->GVS[sv->StdView].ViewCenterOrig[2];
01601             
01602             glMatrixMode(GL_MODELVIEW);
01603             glLoadIdentity();
01604             gluLookAt (sv->GVS[sv->StdView].ViewFrom[0], sv->GVS[sv->StdView].ViewFrom[1], sv->GVS[sv->StdView].ViewFrom[2], sv->GVS[sv->StdView].ViewCenter[0], sv->GVS[sv->StdView].ViewCenter[1], sv->GVS[sv->StdView].ViewCenter[2], sv->GVS[sv->StdView].ViewCamUp[0], sv->GVS[sv->StdView].ViewCamUp[1], sv->GVS[sv->StdView].ViewCamUp[2]);
01605             break;
01606          
01607          case SE_Home_AllVisible:
01608             
01609             {
01610                for (ii=0; ii<SUMAg_N_SVv; ++ii) {
01611                   if (LocalHead) fprintf (SUMA_STDERR,"%s: Checking viewer %d.\n", FuncName, ii);
01612                   if (!SUMAg_SVv[ii].isShaded && SUMAg_SVv[ii].X->TOPLEVEL) {
01613                      
01614 
01615                      if (LocalHead) fprintf (SUMA_STDERR,"%s: Home call viewer %d.\n", FuncName, ii);
01616                      if (!list) {
01617                         fprintf (SUMA_STDERR, "Error %s: Should not be inside SUMA_Engine: ZSS Feb 02 05.\n", FuncName);
01618                         
01619                         break;
01620                      }
01621                      SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Home, SES_Suma, &SUMAg_SVv[ii]);
01622                   }
01623                }
01624             }
01625             break;
01626          
01627          case SE_FOVreset:
01628             
01629             sv->FOV[sv->iState] = FOV_INITIAL;   
01630             break;
01631             
01632          case SE_SetNodeColor:
01633             
01634 
01635             if (EngineData->fm_Dest != NextComCode) {
01636                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01637                break;
01638             }
01639             SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_SO_ID].OP);
01640             {
01641                GLfloat *glar_ColorList;
01642                glar_ColorList = SUMA_GetColorList(sv, SO->idcode_str);
01643                if (!glar_ColorList) {
01644                   fprintf (SUMA_STDERR,"Error %s: NULL color list array. Trouble.\n", FuncName);
01645                   break;
01646                }
01647                for (i=0; i < EngineData->N_rows; ++i){
01648                   ii = (int)(EngineData->fm[i][0]);
01649                   glar_ColorList[4*ii] = EngineData->fm[i][1];
01650                   glar_ColorList[4*ii+1] = EngineData->fm[i][2];
01651                   glar_ColorList[4*ii+2] = EngineData->fm[i][3];
01652                   glar_ColorList[4*ii+3] = 0.5;
01653                }
01654             }
01655             break;
01656             
01657          case SE_FlipLight0Pos:
01658             
01659             sv->light0_position[0] *= -1;
01660             sv->light0_position[1] *= -1;
01661             sv->light0_position[2] *= -1;
01662             glLightfv(GL_LIGHT0, GL_POSITION, sv->light0_position);
01663             break;
01664          
01665          case SE_SetLight0Pos:
01666             
01667             if (EngineData->fv3_Dest != NextComCode) {
01668                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01669                break;
01670             }
01671             sv->light0_position[0] = EngineData->fv3[0];
01672             sv->light0_position[1] = EngineData->fv3[1];
01673             sv->light0_position[2] = EngineData->fv3[2];
01674             glLightfv(GL_LIGHT0, GL_POSITION, sv->light0_position);
01675             break;
01676             
01677          case SE_HighlightNodes:
01678             
01679             
01680 
01681             if (EngineData->fv15_Dest != NextComCode) {
01682                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01683                break;
01684             }
01685             {
01686                SUMA_ISINBOX IB;
01687                
01688                SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_SO_ID].OP);
01689                ND = SO->NodeDim;
01690             
01691                SUMA_etime (&tt, 0);
01692                IB = SUMA_isinbox (SO->NodeList, SO->N_Node, &(EngineData->fv15[0]), &(EngineData->fv15[3]),  YUP);
01693                delta_t = SUMA_etime (&tt, 1);
01694                fprintf (SUMA_STDOUT,"Elapsed time for isinbox operation: %f\n", delta_t);
01695                fprintf (SUMA_STDOUT,"\t%d nodes (out of %d) found in box\n",IB.nIsIn, SO->N_Node);
01696                
01697                if (IB.nIsIn) { 
01698                   
01699                   SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, ft, it);
01700                   
01701                   
01702                   #ifdef STUFF
01703                      
01704 
01705                      id = ND * IB.IsIn[it];
01706                      EngineData->fv15[0] = SO->NodeList[id];
01707                      EngineData->fv15[1] = SO->NodeList[id+1];
01708                      EngineData->fv15[2] = SO->NodeList[id+2];
01709                      EngineData->fv15[3] = SO->NodeNormList[id];
01710                      EngineData->fv15[4] = SO->NodeNormList[id+1];
01711                      EngineData->fv15[5] = SO->NodeNormList[id+2];
01712                   #endif
01713                   
01714                   fm = (float **)SUMA_allocate2D(IB.nIsIn, 4, sizeof(float));
01715                   if (fm == NULL) {
01716                      fprintf(SUMA_STDERR,"Error %s: Could not allocate for fm.\n", FuncName);
01717                      break;
01718                   }
01719                   for (i=0; i < IB.nIsIn; ++i) {
01720                       
01721                       
01722 
01723                      
01724                      fm[i][0] = (float)IB.IsIn[i];
01725                      fm[i][1] = 0; 
01726                      fm[i][2] = 0.4;
01727                      fm[i][3] = 0.4; 
01728                   }
01729 
01730                   
01731                   ED = SUMA_InitializeEngineListData (SE_SetNodeColor);
01732                   ED->N_cols = 4;
01733                   ED->N_rows = IB.nIsIn;
01734                   if (!SUMA_RegisterEngineListCommand (  list, ED, 
01735                                                          SEF_fm, (void*)fm,
01736                                                          SES_Suma, (void *)sv, NOPE,
01737                                                          SEI_Head, NULL)) {
01738                      fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01739                      break;                                      
01740                   } 
01741                   ED = SUMA_InitializeEngineListData (SE_Redisplay);
01742                   SUMA_RegisterEngineListCommand (  list, ED, 
01743                                                     SEF_Empty, NULL,
01744                                                     SES_Suma, (void *)sv, NOPE, 
01745                                                     SEI_Head, NULL);
01746 
01747                   
01748                   if (fm) SUMA_free2D ((char **)fm, IB.nIsIn);
01749                   
01750                   
01751                   if (!SUMA_Free_IsInBox (&IB)) {
01752                      fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName);
01753                   }
01754                } else { 
01755                   
01756                   fprintf (SUMA_STDOUT,"\nNo nodes found inside the specified box.\n");
01757                }
01758             }
01759             break;
01760 
01761          case SE_GetNearestNode:
01762             
01763             
01764 
01765             if (EngineData->fv15_Dest != NextComCode) {
01766                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01767                break;
01768             }
01769             {
01770                SUMA_ISINBOX IB;
01771                
01772                SO = (SUMA_SurfaceObject *)(SUMAg_DOv[sv->Focus_SO_ID].OP);
01773                ND = SO->NodeDim;
01774                SUMA_etime (&tt, 0);
01775                IB = SUMA_isinbox (SO->NodeList, SO->N_Node, &(EngineData->fv15[0]), &(EngineData->fv15[3]),  YUP);
01776                delta_t = SUMA_etime (&tt, 1);
01777                fprintf (SUMA_STDOUT,"Elapsed time for isinbox operation: %f\n", delta_t);
01778                fprintf (SUMA_STDOUT,"\t%d nodes (out of %d) found in box\n",IB.nIsIn, SO->N_Node);
01779                
01780                if (IB.nIsIn) { 
01781                   
01782                   SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, ft, it);
01783                   
01784                   
01785                   id = ND * IB.IsIn[it];
01786                   fv15[0] = SO->NodeList[id];
01787                   fv15[1] = SO->NodeList[id+1];
01788                   fv15[2] = SO->NodeList[id+2];
01789                   fv15[3] = SO->NodeNormList[id];
01790                   fv15[4] = SO->NodeNormList[id+1];
01791                   fv15[5] = SO->NodeNormList[id+2];
01792                   
01793                   ED = SUMA_InitializeEngineListData (SE_SetLookAtNode);
01794                   if (!SUMA_RegisterEngineListCommand (  list, ED,
01795                                                          SEF_fv15, (void *)fv15, 
01796                                                          SES_Suma, (void *)sv, NOPE, 
01797                                                          SEI_Head, NULL)) {
01798                      fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName);
01799                      break;
01800                   }
01801                   
01802                   
01803                   if (!SUMA_Free_IsInBox (&IB)) {
01804                      fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName);
01805                   }
01806                } else { 
01807                   
01808                }
01809             }
01810             break;
01811             
01812          case SE_SetRotMatrix:
01813             
01814             
01815 
01816             if (EngineData->fm_Dest != NextComCode) {
01817                fprintf (SUMA_STDERR,"Error %s: Data not destined correctly for %s (%d).\n",FuncName, NextCom, NextComCode);
01818                break;
01819             }
01820             if (EngineData->N_rows != 4 || EngineData->N_cols != 4) {
01821                fprintf(SUMA_STDERR,"Error %s: fm must have 4 cols and 4 rows in SetRotMatrix\n", FuncName);
01822                break;
01823             }
01824             if (!SUMA_mattoquat (EngineData->fm, sv->GVS[sv->StdView].currentQuat))
01825                {
01826                   fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_mattoquat\n", FuncName);
01827                   break;
01828                }
01829             break;
01830             
01831          
01832 
01833 
01834          case SE_BadCode:
01835             fprintf(SUMA_STDERR,"Error SUMA_Engine: Command ->%s<- Not understood. Perhaps Code is not defined in SUMA_CommandCode\n", NextCom);
01836             break;
01837          
01838       } 
01839       
01840       
01841       if (LocalHead) fprintf (SUMA_STDERR, "\n%s: Releasing Engine Element.\n", FuncName);
01842       if (!SUMA_ReleaseEngineListElement (list, NextElem_CANT_TOUCH_THIS)) {
01843             fprintf(SUMA_STDERR,"Error SUMA_Engine: Failed to Release element \n");
01844          }
01845          
01846    } 
01847    
01848    if (LocalHead) fprintf (SUMA_STDERR, "\n%s: Destroying List.\n", FuncName);
01849    
01850    list = SUMA_DestroyList (list);
01851    *listp = NULL; 
01852    
01853    SUMA_RETURN (YUP);
01854 }
01855 
01856 
01857 
01858 
01859 
01860 
01861 
01862 
01863 
01864 
01865 
01866 int SUMA_RegisteredSOs (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int *SO_IDs)
01867 {
01868    static char FuncName[]={"SUMA_RegisteredSOs"};
01869    int i, k = 0;
01870    
01871    SUMA_ENTRY;
01872 
01873    for (i=0; i< sv->N_DO; ++i) {
01874       if (SUMA_isSO_G(dov[sv->RegisteredDO[i]], sv->CurGroupName)) {
01875          if (SO_IDs != NULL) SO_IDs[k] = sv->RegisteredDO[i];
01876          ++k;
01877       }
01878    }
01879 
01880    SUMA_RETURN (k);
01881 }
01882 
01883 
01884 
01885 
01886 
01887 
01888 
01889 
01890 
01891 
01892 
01893 
01894 
01895 
01896 int SUMA_VisibleSOs (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int *SO_IDs)
01897 {
01898    static char FuncName[]={"SUMA_VisibleSOs"};
01899    SUMA_SurfaceObject *SO=NULL;
01900    int i, k = 0;
01901    
01902    SUMA_ENTRY;
01903 
01904    for (i=0; i< sv->N_DO; ++i) {
01905       if (SUMA_isSO_G(dov[sv->RegisteredDO[i]], sv->CurGroupName)) {
01906          SO = (SUMA_SurfaceObject *)dov[sv->RegisteredDO[i]].OP;
01907          if (SO->Show) {
01908             if ( SO->Side == SUMA_NO_SIDE || SO->Side == SUMA_SIDE_ERROR ) {
01909                if (SO_IDs) {
01910                   SO_IDs[k] = sv->RegisteredDO[i];
01911                }
01912                ++k;
01913             } else if (  (SO->Side == SUMA_RIGHT && sv->ShowRight) || 
01914                          (SO->Side == SUMA_LEFT && sv->ShowLeft) ) {
01915                if (SO_IDs) {
01916                   SO_IDs[k] = sv->RegisteredDO[i];
01917                }
01918                ++k;
01919             }
01920          }
01921       }
01922    }
01923 
01924    SUMA_RETURN (k);
01925 }
01926 
01927 
01928 
01929 
01930 
01931 SUMA_Boolean SUMA_isVisibleSO (SUMA_SurfaceViewer *sv, SUMA_DO *dov, SUMA_SurfaceObject *curSO)
01932 {
01933    static char FuncName[]={"SUMA_isVisibleSO"};
01934    SUMA_SurfaceObject *SO=NULL;
01935    int i, k = 0;
01936    
01937    SUMA_ENTRY;
01938    
01939    for (i=0; i< sv->N_DO; ++i) {
01940       if (SUMA_isSO_G(dov[sv->RegisteredDO[i]], sv->CurGroupName)) {
01941          SO = (SUMA_SurfaceObject *)dov[sv->RegisteredDO[i]].OP;
01942          if (curSO == SO) {
01943             if (SO->Show) {
01944                if ( SO->Side == SUMA_NO_SIDE || SO->Side == SUMA_SIDE_ERROR ) {
01945                   SUMA_RETURN(YUP);
01946                   ++k;
01947                } else if (  (SO->Side == SUMA_RIGHT && sv->ShowRight) || 
01948                             (SO->Side == SUMA_LEFT && sv->ShowLeft) ) {
01949                   SUMA_RETURN(YUP);
01950                   ++k;
01951                }
01952             }
01953          }
01954       }
01955    }
01956    
01957    SUMA_RETURN(NOPE);
01958    
01959 }
01960 
01961 
01962 
01963 
01964 
01965 
01966 
01967 
01968 
01969 
01970 int SUMA_NextState(SUMA_SurfaceViewer *sv)
01971 {
01972    static char FuncName[] = {"SUMA_NextState"};
01973    int inxt, icur;
01974    SUMA_Boolean LocalHead = NOPE;
01975    
01976    SUMA_ENTRY;
01977    
01978    icur = SUMA_WhichState (sv->State, sv, sv->CurGroupName);
01979    if (icur < 0) {
01980       fprintf(SUMA_STDERR,"Error %s: SUMA_WhichState failed.\n", FuncName);
01981       SUMA_RETURN (-1);
01982    } else {
01983       inxt = (icur + 1) % sv->N_VSv;
01984       do {
01985          
01986          if (inxt == icur) {
01987             
01988             SUMA_RETURN(inxt);
01989          } else {
01990             if (!strcmp(sv->VSv[inxt].Group, sv->CurGroupName)) { 
01991                SUMA_RETURN(inxt);
01992             }
01993          }
01994          inxt = (inxt + 1) % sv->N_VSv;
01995       } while (1);
01996    }
01997    
01998    
01999    SUMA_SL_Err("Flow error");
02000    SUMA_RETURN (-1);
02001 }
02002 
02003 
02004 
02005 
02006 
02007 
02008 int SUMA_PrevState(SUMA_SurfaceViewer *sv)
02009 {
02010    static char FuncName[] = {"SUMA_PrevState"};
02011    int inxt, icur;
02012    SUMA_Boolean LocalHead = NOPE;
02013    
02014    SUMA_ENTRY;
02015    
02016    icur = SUMA_WhichState (sv->State, sv, sv->CurGroupName);   
02017    if (icur < 0) {
02018       fprintf(SUMA_STDERR,"Error %s: SUMA_WhichState failed.\n", FuncName);
02019       SUMA_RETURN (-1);
02020    } else {
02021       inxt = icur -1; if (inxt < 0) inxt = sv->N_VSv + inxt;
02022       do {
02023          
02024          if (inxt == icur) {
02025             
02026             SUMA_RETURN(inxt);
02027          } else {
02028             if (!strcmp(sv->VSv[inxt].Group, sv->CurGroupName)) { 
02029                SUMA_RETURN(inxt);
02030             }
02031          }
02032          inxt = inxt -1; if (inxt < 0) inxt = sv->N_VSv + inxt;
02033       } while (1);
02034    }
02035    
02036    SUMA_RETURN (-1);
02037 }
02038 
02039 
02040 
02041 
02042 
02043 
02044 
02045 
02046 
02047 
02048 
02049 
02050 
02051 int SUMA_NextSO (SUMA_DO *dov, int n_dov, char *idcode, SUMA_SurfaceObject *SOnxt)
02052 {
02053    static char FuncName[] = {"SUMA_NextSO"};
02054    int icur, icheck, ncheck;
02055 
02056    SUMA_ENTRY;
02057 
02058    if (SOnxt != NULL) {
02059       fprintf(SUMA_STDERR,"Error %s: SOnxt should be null when you call this function.\n", FuncName);
02060       SUMA_RETURN (-1);
02061    }
02062    if (n_dov < 1) {
02063       fprintf(SUMA_STDERR,"Error %s: dov contains no elements.\n", FuncName);
02064       SUMA_RETURN (-1);
02065    }
02066    icur = SUMA_findSO_inDOv (idcode, dov, n_dov);
02067    if (icur < 0) {
02068       fprintf (SUMA_STDERR,"Error %s: idcode not found in dov.\n", FuncName);
02069       SUMA_RETURN (-1);
02070    }
02071    
02072    ncheck = 0;
02073    icheck = icur;
02074    while (ncheck < n_dov) {
02075       icheck = (icheck + 1) % n_dov;
02076       
02077       if (SUMA_isSO(dov[icheck])) {
02078          
02079          SOnxt = (SUMA_SurfaceObject *)dov[icheck].OP;
02080          SUMA_RETURN (icheck);
02081       }
02082       ++ncheck;
02083    }
02084    
02085    SUMA_RETURN (-1);
02086 }
02087 
02088 
02089 
02090 
02091 
02092 SUMA_Boolean SUMA_SwitchSO (SUMA_DO *dov, int N_dov, int SOcurID, int SOnxtID, SUMA_SurfaceViewer *sv)
02093 {
02094    static char FuncName[]={"SUMA_SwitchSO"};
02095    SUMA_Axis *EyeAxis;
02096    int EyeAxis_ID;
02097    char CommString[100];
02098    SUMA_EngineData ED;
02099    DList *list = NULL;
02100    
02101    SUMA_ENTRY;
02102 
02103    
02104    
02105    if (!SUMA_UnRegisterDO(SOcurID, sv)) {
02106       fprintf(SUMA_STDERR,"Error %s: Failed to UnRegisterDO.\n", FuncName);
02107       SUMA_RETURN (NOPE);
02108    }
02109 
02110    
02111    sv->Focus_SO_ID = SOnxtID;
02112 
02113    
02114    
02115    if (!SUMA_RegisterDO(sv->Focus_SO_ID, sv)) {
02116       fprintf(SUMA_STDERR,"Error %s: Failed to RegisterDO.\n", FuncName);
02117       SUMA_RETURN (NOPE);
02118    }
02119 
02120    
02121    if (!SUMA_UpdateRotaCenter(sv, dov, N_dov)) {
02122       fprintf (SUMA_STDERR,"Error %s: Failed to update center of rotation", FuncName);
02123       SUMA_RETURN (NOPE);
02124    }
02125    
02126    
02127    if (!SUMA_UpdateViewPoint(sv, dov, N_dov)) {
02128       fprintf (SUMA_STDERR,"Error %s: Failed to update view point", FuncName);
02129       SUMA_RETURN (NOPE);
02130    }
02131    
02132    
02133    EyeAxis_ID = SUMA_GetEyeAxis (sv, dov);
02134 
02135    if (EyeAxis_ID < 0) {
02136       fprintf(SUMA_STDERR,"Error %s: No Eye Axis. %d\n", FuncName, EyeAxis_ID);
02137    } else {
02138       EyeAxis = (SUMA_Axis *)(dov[EyeAxis_ID].OP);
02139       SUMA_EyeAxisStandard (EyeAxis, sv);
02140    }
02141    
02142    
02143    SUMA_WorldAxisStandard (sv->WAx, sv);
02144 
02145 
02146    
02147    if (!list) list = SUMA_CreateList();
02148    SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Home, SES_Suma, sv);
02149 
02150    if (!SUMA_Engine (&list)) {
02151       fprintf(stderr, "Error SUMA_input: SUMA_Engine call failed.\n");
02152    }
02153 
02154    
02155    
02156 
02157    
02158    
02159    SUMA_RETURN (YUP);
02160 }
02161 
02162 
02163 
02164 
02165 
02166 SUMA_Boolean SUMA_GetOverlaysFromParent(SUMA_SurfaceObject *SO_nxt, SUMA_SurfaceObject *SO_prec) 
02167 {
02168    static char FuncName[]={"SUMA_GetOverlaysFromParent"};
02169    int j, OverInd=-1;
02170    SUMA_Boolean LocalHead = NOPE;
02171 
02172    SUMA_ENTRY;
02173 
02174    if (!SO_nxt || !SO_prec) {
02175       SUMA_SL_Err("Null input");
02176       SUMA_RETURN(NOPE);
02177    }
02178    if (!SUMA_isRelated(SO_prec, SO_nxt, 1)) {
02179       SUMA_SL_Err("Surfaces are not level 1 related");
02180       SUMA_RETURN(NOPE);
02181    }
02182 
02183    
02184    for (j=0; j < SO_prec->N_Overlays; ++j) {
02185       if (!SUMA_Fetch_OverlayPointer (SO_nxt->Overlays, SO_nxt->N_Overlays, SO_prec->Overlays[j]->Name, &OverInd)) {
02186          
02187          if (LocalHead) fprintf (SUMA_STDERR,"Local Debug %s: Overlay plane %s not found, creating the link.\n", FuncName, SO_prec->Overlays[j]->Name);
02188          SO_nxt->Overlays[SO_nxt->N_Overlays] = (SUMA_OVERLAYS *)SUMA_LinkToPointer((void*)SO_prec->Overlays[j]);
02189          
02190 
02191          if (SO_nxt->Overlays[SO_nxt->N_Overlays]->OptScl) {
02192             if (SO_nxt->Overlays[SO_nxt->N_Overlays]->OptScl->BiasVect) {
02193                SUMA_LH("Adding coordbias");
02194                SUMA_ADD_COORD_BIAS_VECT(  SO_nxt,
02195                                           SO_nxt->Overlays[SO_nxt->N_Overlays], 
02196                                           SO_nxt->Overlays[SO_nxt->N_Overlays]->OptScl->DoBias, 
02197                                           SO_nxt->Overlays[SO_nxt->N_Overlays]->OptScl->BiasVect);
02198                
02199                SUMA_NewSurfaceGeometry(SO_nxt);
02200             }
02201          }
02202          
02203          ++SO_nxt->N_Overlays;
02204       } else {
02205          
02206          if (LocalHead) fprintf (SUMA_STDERR,"Local Debug %s: Overlay plane %s found. Index#%d\n.", FuncName, SO_prec->Overlays[j]->Name, OverInd);
02207       }
02208    }   
02209 
02210    SUMA_RETURN(YUP);
02211 }
02212 
02213 
02214 
02215 
02216 
02217 
02218 
02219 SUMA_Boolean SUMA_SwitchState (SUMA_DO *dov, int N_dov, SUMA_SurfaceViewer *sv, int nxtstateID, char *nxtgroup)
02220 {
02221    static char FuncName[]={"SUMA_SwitchState"};
02222    SUMA_Axis *EyeAxis;
02223    int EyeAxis_ID, I_C, ND, id;
02224    char CommString[100];
02225    SUMA_EngineData ED;
02226    int curstateID, i, j, jmax, prec_ID;
02227    SUMA_SurfaceObject *SO_nxt, *SO_prec;
02228    float *XYZ, *XYZmap;
02229    DList *list = NULL;
02230    SUMA_Boolean LocalHead = NOPE;
02231    
02232    SUMA_ENTRY;
02233 
02234    XYZ = NULL;
02235    XYZmap = NULL;
02236    
02237    curstateID = SUMA_WhichState(sv->State, sv, sv->CurGroupName);
02238    
02239    
02240    if (LocalHead) fprintf(SUMA_STDERR,"%s: Unregistering state %d\n", FuncName, curstateID);
02241    for (i=0; i<sv->VSv[curstateID].N_MembSOs; ++i) {
02242       if (!SUMA_UnRegisterDO(sv->VSv[curstateID].MembSOs[i], sv)) {
02243          fprintf(SUMA_STDERR,"Error %s: Failed to UnRegisterDO.\n", FuncName);
02244          SUMA_RETURN (NOPE);
02245       }
02246    }
02247    
02248    
02249    if (strcmp(sv->CurGroupName, nxtgroup)) { 
02250       SUMA_LH("Changing group...");
02251       if (!SUMA_AdoptGroup(sv, nxtgroup)) {
02252          SUMA_SLP_Err("Failed to adopt new group");
02253          SUMA_RETURN(NOPE);
02254       }
02255    } else {
02256       SUMA_LH("No group change...");
02257    }
02258    
02259    
02260    if (LocalHead) fprintf(SUMA_STDERR,"%s: Registering DOv of state %d...\n", FuncName, nxtstateID);
02261    for (i=0; i<sv->VSv[nxtstateID].N_MembSOs; ++i) {
02262       if (!SUMA_RegisterDO(sv->VSv[nxtstateID].MembSOs[i], sv)) {
02263          fprintf(SUMA_STDERR,"Error %s: Failed to RegisterDO.\n", FuncName);
02264          SUMA_RETURN (NOPE);
02265       }
02266    }
02267       
02268    #if 0
02269    {
02270       
02271 
02272 
02273 
02274 
02275 
02276       int RegSO[SUMA_MAX_DISPLAYABLE_OBJECTS], N_RegSO, im;
02277       float Ep1, Ep2, d1, d2, dc, dd, xShift1=0.0, xShift2=0.0;
02278       SUMA_SurfaceObject *SO1, *SO2;
02279       
02280       N_RegSO = SUMA_RegisteredSOs (sv, dov, RegSO);
02281       if (N_RegSO > 2) {
02282          SUMA_SLP_Note( "Will not attempt\n"
02283                         "to separate more than\n"
02284                         "2 surfaces.\n");
02285       }
02286       if (N_RegSO == 2) {
02287          SO1 = (SUMA_SurfaceObject *)dov[RegSO[0]].OP;
02288          SO2 = (SUMA_SurfaceObject *)dov[RegSO[1]].OP;
02289          
02290          
02291          
02292          
02293          
02294          if ( ((SO1->MaxDims[0] - SO1->Center[0]) * (SO1->MaxDims[0] - SO2->Center[0]) ) < 0 ) {
02295             Ep1 = SO1->MaxDims[0];
02296          }else {
02297             Ep1 = SO1->MinDims[0];
02298          }
02299          
02300          if ( ((SO2->MaxDims[0] - SO2->Center[0]) * (SO2->MaxDims[0] - SO1->Center[0]) ) < 0 ) {
02301             Ep2 = SO2->MaxDims[0];
02302          }else {
02303             Ep2 = SO2->MinDims[0];
02304          }
02305          
02306          
02307          d1 = (float)fabs(Ep1 - SO1->Center[0]);
02308          d2 = (float)fabs(Ep2 - SO2->Center[0]);
02309          dc = (float)fabs(SO1->Center[0] -SO2->Center[0]);
02310          dd = d1 + d2 - dc;
02311          if (dd > 0) {
02312             if (SO1->Center[0] > SO2->Center[0]) {
02313                xShift1 = 1.1 * dd / 2.0;
02314                xShift2 = 1.1 * -dd / 2.0;
02315             }else {
02316                xShift1 = 1.1 * -dd / 2.0;
02317                xShift2 = 1.1 * +dd / 2.0;
02318             }
02319          } 
02320          
02321          if (xShift1) {
02322             if (LocalHead) fprintf (SUMA_STDERR,"%s: Shifting by +- %f\n", FuncName, xShift1);
02323             
02324             for (im=0; im< SO1->N_Node; ++im) SO1->NodeList[3*im] += xShift1;
02325             SO1->Center[0] += xShift1;
02326             SO1->MaxDims[0] += xShift1;
02327             SO1->MinDims[0] += xShift1;
02328             for (im=0; im< SO2->N_Node; ++im) SO2->NodeList[3*im] += xShift2;
02329             SO2->Center[0] += xShift2;
02330             SO2->MaxDims[0] += xShift2;
02331             SO2->MinDims[0] += xShift2;
02332          } else {
02333             SUMA_LH("No shift necessary");
02334          }
02335       } 
02336    }
02337    #endif
02338    
02339    
02340    if (!SUMA_SetShownLocalRemixFlag (sv)) {
02341       fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SetShownLocalRemixFlag.\n", FuncName);
02342       SUMA_RETURN (NOPE);
02343    }
02344 
02345    
02346    
02347    for (i=0; i<sv->VSv[nxtstateID].N_MembSOs; ++i) {
02348       
02349       SO_nxt = (SUMA_SurfaceObject *)(dov[sv->VSv[nxtstateID].MembSOs[i]].OP);
02350 
02351       
02352       if (!SO_nxt->LocalDomainParentID) {
02353          prec_ID = -1;
02354       }else {
02355          prec_ID = SUMA_findSO_inDOv(SO_nxt->LocalDomainParentID, SUMAg_DOv, SUMAg_N_DOv);
02356       }
02357       if (prec_ID < 0) {
02358          
02359          fprintf(SUMA_STDERR, "\n\aWarning %s: No precursors found for surface %d.\nColors, selected nodes and facesets will not be reflect those in previous state.\n.",\
02360           FuncName, sv->VSv[nxtstateID].MembSOs[i]);
02361          continue;
02362       }
02363 
02364       SO_prec = (SUMA_SurfaceObject *)(dov[prec_ID].OP);
02365 
02366       
02367 
02368       if (SO_prec->N_Node >= SO_nxt->N_Node ) {
02369          
02370          if (!SUMA_GetOverlaysFromParent(SO_nxt,SO_prec)) {
02371             SUMA_SL_Err("Failed to get overlays from parents");
02372             SUMA_RETURN(NOPE);
02373          }
02374 
02375          if (SO_prec->N_Node > SO_nxt->N_Node) {
02376             
02377             fprintf(SUMA_STDERR, "Warning %s: More nodes (%d) in precursor surface. \n Assuming upcoming surface is a subset of precursor.\n", FuncName, SO_prec->N_Node - SO_nxt->N_Node);
02378          } 
02379 
02380          
02381          
02382          
02383          if (SO_prec->N_Node == SO_nxt->N_Node) {
02384             SO_nxt->SelectedNode = SO_prec->SelectedNode;
02385             } else { 
02386             if (SO_prec->SelectedNode < SO_nxt->N_Node) {
02387                SO_nxt->SelectedNode = SO_prec->SelectedNode;
02388                } else { 
02389                fprintf(SUMA_STDERR, "\n\aWarning %s: Slected node in precursor state does not exist in current state.\n Selected Node is left at previous setting in this view state.\n", FuncName);
02390                }
02391             }
02392 
02393          }  else { 
02394             fprintf(SUMA_STDERR, "\n\aWarning %s: More nodes (%d) in upcoming surface. Colors, selected nodes and facesets are not carried through from precursor.\n", FuncName, SO_nxt->N_Node - SO_prec->N_Node);
02395          }
02396 
02397          #if 0
02398          
02399          
02400          if (!SUMA_Overlays_2_GLCOLAR4(SO_nxt->Overlays, SO_nxt->N_Overlays, SUMA_GetColorList (sv, SO_nxt->idcode_str), SO_nxt->N_Node,\
02401              sv->Back_Modfact, sv->ShowBackground, sv->ShowForeground)) {
02402             fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Overlays_2_GLCOLAR4.\n", FuncName);
02403             SUMA_RETURN (NOPE);
02404          }
02405          #endif
02406          
02407       }
02408    
02409    
02410    if (sv->Ch->SurfaceID >= 0) {      
02411       if (LocalHead) fprintf(SUMA_STDERR, "Local Debug %s: Linking Cross Hair via SurfaceID...\n", FuncName);
02412       j = SUMA_MapRefRelative (sv->Ch->SurfaceID, sv->VSv[nxtstateID].MembSOs, sv->VSv[nxtstateID].N_MembSOs, dov);
02413       if (LocalHead) fprintf(SUMA_STDERR, "Local Debug %s: Cross Hair's  New SurfaceID = %d\n", FuncName, j );
02414       
02415       
02416       if (j >= 0) {
02417          SO_nxt = (SUMA_SurfaceObject *)(dov[j].OP);
02418          ND = SO_nxt->NodeDim;
02419          id = ND * sv->Ch->NodeID;
02420          if (sv->Ch->NodeID >= 0) {
02421             if (LocalHead) fprintf(SUMA_STDERR, "Local Debug %s: Using NodeID for link.\n", FuncName);
02422             sv->Ch->c[0] = SO_nxt->NodeList[id];
02423             sv->Ch->c[1] = SO_nxt->NodeList[id+1];
02424             sv->Ch->c[2] = SO_nxt->NodeList[id+2];
02425          } else {
02426             
02427             if (LocalHead) fprintf(SUMA_STDERR, "Local Debug %s: Using XYZ for link.\n", FuncName);
02428             SO_prec = (SUMA_SurfaceObject *)(dov[sv->Ch->SurfaceID].OP);
02429             
02430             I_C = -1;
02431             XYZmap = SUMA_XYZ_XYZmap (sv->Ch->c, SO_prec, dov, N_dov, &I_C);
02432             if (XYZmap == NULL) {
02433                fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_XYZ_XYZmap\n", FuncName); 
02434             }else {
02435                XYZ = SUMA_XYZmap_XYZ (XYZmap, SO_nxt, dov, N_dov, &I_C);
02436                if (XYZ == NULL) {
02437                   fprintf(SUMA_STDERR, "Error %s: Failed in SUMA_XYZmap_XYZ\n", FuncName); 
02438                } else {
02439                   sv->Ch->c[0] = XYZ[0];
02440                   sv->Ch->c[1] = XYZ[1];
02441                   sv->Ch->c[2] = XYZ[2];
02442                }
02443                
02444             }
02445             if (XYZ) SUMA_free(XYZ);
02446             if (XYZmap) SUMA_free(XYZmap);
02447          }
02448          
02449          
02450          if (SO_nxt->SurfCont->TopLevelShell)   { 
02451             SUMA_Init_SurfCont_SurfParam(SO_nxt);
02452          }
02453 
02454       } else {
02455          fprintf(SUMA_STDERR, "%s: No relatives between states. CrossHair location will not correspond between states\n", FuncName); 
02456       }
02457        sv->Ch->SurfaceID = j;
02458       if (LocalHead) fprintf(SUMA_STDERR, "Local Debug %s: Linking Cross Hair Via NodeID Done.\n", FuncName);
02459    }
02460    
02461 
02462 
02463    
02464    sv->State =  sv->VSv[nxtstateID].Name;
02465    sv->iState = nxtstateID;
02466    
02467    
02468    sv->Focus_SO_ID = sv->VSv[nxtstateID].MembSOs[0];
02469    
02470    
02471    if (sv->Ch->SurfaceID >= 0)   { 
02472       SUMA_SurfaceObject *SOtmp=(SUMA_SurfaceObject *)(dov[sv->Focus_SO_ID].OP);
02473       if (SOtmp->SurfCont->TopLevelShell) {
02474          SUMA_Init_SurfCont_CrossHair(SOtmp);
02475       }
02476    }
02477 
02478    if (LocalHead) {
02479       SUMA_SurfaceObject *SOtmp=(SUMA_SurfaceObject *)(dov[sv->Focus_SO_ID].OP);
02480       fprintf(SUMA_STDERR,"%s: Setting new Focus ID to surface %s\n", FuncName, SOtmp->Label);
02481    }
02482    
02483    
02484    sv->StdView = SUMA_BestStandardView (sv,dov, N_dov);
02485    if (LocalHead) fprintf(SUMA_STDOUT,"%s: Standard View Now %d\n", FuncName, sv->StdView);
02486    if (sv->StdView == SUMA_Dunno) {
02487       fprintf(SUMA_STDERR,"Error %s: Could not determine the best standard view. Choosing default SUMA_3D\n", FuncName);
02488       sv->StdView = SUMA_3D;
02489    }
02490 
02491    
02492    if (!SUMA_UpdateRotaCenter(sv, dov, N_dov)) {
02493       fprintf (SUMA_STDERR,"Error %s: Failed to update center of rotation", FuncName);
02494       SUMA_RETURN (NOPE);
02495    }
02496    
02497    
02498    if (!SUMA_UpdateViewPoint(sv, dov, N_dov)) {
02499       fprintf (SUMA_STDERR,"Error %s: Failed to update view point", FuncName);
02500       SUMA_RETURN (NOPE);
02501    }
02502    
02503    
02504    EyeAxis_ID = SUMA_GetEyeAxis (sv, dov);
02505 
02506    if (EyeAxis_ID < 0) {
02507       fprintf(SUMA_STDERR,"Error %s: No Eye Axis. %d\n", FuncName, EyeAxis_ID);
02508    } else {
02509       EyeAxis = (SUMA_Axis *)(dov[EyeAxis_ID].OP);
02510       SUMA_EyeAxisStandard (EyeAxis, sv);
02511    }
02512 
02513    
02514    SUMA_WorldAxisStandard (sv->WAx, sv);
02515     
02516    
02517    if (!list) list = SUMA_CreateList();
02518    SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Home, SES_Suma, sv);
02519    if (!SUMA_Engine (&list)) {
02520       fprintf(stderr, "Error SUMA_input: SUMA_Engine call failed.\n");
02521    }
02522 
02523    SUMA_RETURN (YUP);
02524 }
02525 
02526 
02527 
02528 
02529 
02530 
02531 
02532 SUMA_Boolean SUMA_NewGeometryInViewer (SUMA_DO *dov, int N_dov, SUMA_SurfaceViewer *sv)
02533 {
02534    static char FuncName[]={"SUMA_NewGeometryInViewer"};
02535    SUMA_Axis *EyeAxis;
02536    int EyeAxis_ID, I_C, OverInd, ND, id;
02537    char CommString[100];
02538    SUMA_EngineData ED;
02539    int  i, j, jmax, prec_ID;
02540    SUMA_SurfaceObject *SO_nxt, *SO_prec;
02541    SUMA_Boolean LocalHead = NOPE;
02542    
02543    SUMA_ENTRY;   
02544    
02545    
02546    sv->StdView = SUMA_BestStandardView (sv,dov, N_dov);
02547    if (LocalHead) fprintf(SUMA_STDOUT,"%s: Standard View Now %d\n", FuncName, sv->StdView);
02548    if (sv->StdView == SUMA_Dunno) {
02549       fprintf(SUMA_STDERR,"Error %s: Could not determine the best standard view. Choosing default SUMA_3D\n", FuncName);
02550       sv->StdView = SUMA_3D;
02551    }
02552    
02553    
02554    if (!SUMA_UpdateRotaCenter(sv, dov, N_dov)) {
02555       fprintf (SUMA_STDERR,"Error %s: Failed to update center of rotation", FuncName);
02556       SUMA_RETURN (NOPE);
02557    }
02558    
02559    
02560    if (!SUMA_UpdateViewPoint(sv, dov, N_dov)) {
02561       fprintf (SUMA_STDERR,"Error %s: Failed to update view point", FuncName);
02562       SUMA_RETURN (NOPE);
02563    }
02564    
02565    
02566    
02567    EyeAxis_ID = SUMA_GetEyeAxis (sv, dov);
02568 
02569    if (EyeAxis_ID < 0) {
02570       fprintf(SUMA_STDERR,"Error %s: No Eye Axis. %d\n", FuncName, EyeAxis_ID);
02571    } else {
02572       EyeAxis = (SUMA_Axis *)(dov[EyeAxis_ID].OP);
02573       SUMA_EyeAxisStandard (EyeAxis, sv);
02574    }
02575    
02576    
02577    glMatrixMode(GL_MODELVIEW);
02578    glLoadIdentity();
02579    gluLookAt ( sv->GVS[sv->StdView].ViewFrom[0], sv->GVS[sv->StdView].ViewFrom[1], 
02580                sv->GVS[sv->StdView].ViewFrom[2], sv->GVS[sv->StdView].ViewCenter[0], 
02581                sv->GVS[sv->StdView].ViewCenter[1], sv->GVS[sv->StdView].ViewCenter[2], 
02582                sv->GVS[sv->StdView].ViewCamUp[0], sv->GVS[sv->StdView].ViewCamUp[1], 
02583                sv->GVS[sv->StdView].ViewCamUp[2]);
02584    
02585    
02586    SUMA_WorldAxisStandard (sv->WAx, sv);
02587 
02588     
02589 
02590    SUMA_RETURN (YUP);
02591 }
02592 
02593 
02594 
02595 
02596 
02597 
02598 
02599 
02600 
02601 
02602 
02603 
02604 
02605 
02606 
02607 
02608 
02609 
02610 
02611 SUMA_Boolean SUMA_OpenGLStateReset (SUMA_DO *dov, int N_dov, SUMA_SurfaceViewer *sv)
02612 {
02613    static char FuncName[]={"SUMA_OpenGLStateReset"};
02614    SUMA_Axis *EyeAxis;
02615    int EyeAxis_ID, I_C, OverInd, ND, id;
02616    char CommString[100];
02617    SUMA_EngineData ED;
02618    int  i, j, jmax, prec_ID;
02619    SUMA_SurfaceObject *SO_nxt, *SO_prec;
02620    SUMA_Boolean LocalHead = NOPE;
02621    
02622    SUMA_ENTRY;   
02623    
02624    #if 0
02625    
02626    if (!SUMA_UpdateRotaCenter(sv, dov, N_dov)) {
02627       fprintf (SUMA_STDERR,"Error %s: Failed to update center of rotation", FuncName);
02628       SUMA_RETURN (NOPE);
02629    }
02630    
02631    
02632    if (!SUMA_UpdateViewPoint(sv, dov, N_dov)) {
02633       fprintf (SUMA_STDERR,"Error %s: Failed to update view point", FuncName);
02634       SUMA_RETURN (NOPE);
02635    }
02636    #endif
02637    
02638    
02639    
02640    
02641    EyeAxis_ID = SUMA_GetEyeAxis (sv, dov);
02642 
02643    if (EyeAxis_ID < 0) {
02644       fprintf(SUMA_STDERR,"Error %s: No Eye Axis. %d\n", FuncName, EyeAxis_ID);
02645    } else {
02646       EyeAxis = (SUMA_Axis *)(dov[EyeAxis_ID].OP);
02647       SUMA_EyeAxisStandard (EyeAxis, sv);
02648    }
02649    
02650 
02651    #if 0
02652    
02653    SUMA_SET_GL_PROJECTION(sv);   
02654    #endif
02655    
02656     
02657 
02658    SUMA_RETURN (YUP);
02659 }
02660 
02661 
02662 
02663 
02664 
02665 
02666 
02667 
02668 
02669 
02670 int SUMA_GetEyeAxis (SUMA_SurfaceViewer *sv, SUMA_DO *dov)
02671 {
02672    static char FuncName[]={"SUMA_GetEyeAxis"};
02673    int i, k = -1, cnt = 0;
02674    SUMA_Axis *AO;
02675    
02676    SUMA_ENTRY;
02677 
02678    for (i=0; i< sv->N_DO; ++i) {
02679       if (dov[sv->RegisteredDO[i]].ObjectType == AO_type) {
02680          AO = (SUMA_Axis *)(dov[sv->RegisteredDO[i]].OP);
02681          if (strcmp(AO->Name, "Eye Axis") == 0) {
02682             k = sv->RegisteredDO[i];
02683             ++cnt;
02684          }
02685       }
02686    }
02687    if (cnt > 1) {
02688       fprintf (SUMA_STDERR,"Error %s: Found more than one Eye Axis. \n", FuncName);
02689       SUMA_RETURN (-1);
02690    }
02691    
02692    SUMA_RETURN (k);
02693 }
02694 
02695 
02696 
02697 
02698 
02699 
02700 
02701 
02702 
02703 
02704 
02705 
02706 
02707 
02708 
02709 
02710 
02711 
02712 
02713 
02714 
02715 float * SUMA_XYZ_XYZmap (float *XYZ, SUMA_SurfaceObject *SO, SUMA_DO* dov, int N_dov, int *I_C)
02716 {
02717    static char FuncName[]={"SUMA_XYZ_XYZmap"};
02718    float *XYZmap;
02719    int iclosest, id, ND;
02720    SUMA_SurfaceObject *SOmap;
02721    int SOmapID;
02722    SUMA_Boolean LocalHead = NOPE;
02723    
02724    SUMA_ENTRY;
02725 
02726    
02727    XYZmap = (float *)SUMA_calloc (3, sizeof(float));
02728    if (XYZmap == NULL) {
02729       fprintf(SUMA_STDERR,"Error %s: Could not allocate for XYZmap.\n", FuncName);
02730       SUMA_RETURN (NULL);
02731    } 
02732    
02733    
02734    if (SUMA_isLocalDomainParent(SO)){
02735       
02736       SUMA_COPY_VEC (XYZ, XYZmap, 3, float, float);
02737       SUMA_RETURN (XYZmap);   
02738    }
02739    
02740    if (!SUMA_ismappable(SO)){
02741       fprintf(SUMA_STDERR,"%s: Surface is NOT mappable, returning NULL.\n", FuncName);
02742       SUMA_free(XYZmap);
02743       SUMA_RETURN (NULL);
02744    }
02745 
02746    
02747 
02748    
02749    if (*I_C < 0) { 
02750       
02751          {
02752             SUMA_ISINBOX IB;
02753             float Bd[3], distance;
02754             int ii;
02755             
02756             
02757             Bd[0] = Bd[1] = Bd[2] = SUMA_XYZ_XFORM_BOXDIM_MM;
02758             IB = SUMA_isinbox (SO->NodeList, SO->N_Node, XYZ, Bd,  YUP);
02759             fprintf (SUMA_STDOUT,"%s: %d nodes (out of %d) found in box\n",FuncName, IB.nIsIn, SO->N_Node);
02760 
02761             if (IB.nIsIn) { 
02762                
02763                
02764 
02765 
02766                SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, distance, iclosest);
02767                iclosest = IB.IsIn[iclosest];
02768                
02769                if (!SUMA_Free_IsInBox (&IB)) {
02770                   fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName);
02771                }
02772 
02773             } else { 
02774                fprintf (SUMA_STDERR,"%s: No node was close enough to XYZ, no linkage possible\n", FuncName);
02775                SUMA_free(XYZmap);
02776                SUMA_RETURN (NULL);
02777             }
02778             
02779             *I_C = iclosest;
02780          }
02781    } else { 
02782       iclosest = *I_C;
02783    }
02784    
02785    if (LocalHead) fprintf (SUMA_STDERR,"%s: Node identified for linking purposes is %d\n", FuncName, *I_C);
02786    
02787    SOmapID = SUMA_findSO_inDOv(SO->LocalDomainParentID, dov, N_dov);
02788    if (SOmapID < 0) {
02789       fprintf (SUMA_STDERR,"%s: Failed in SUMA_findSO_inDOv This should not happen.\n", FuncName);
02790       SUMA_free(XYZmap);
02791       SUMA_RETURN (NULL);
02792    }
02793 
02794    SOmap = (SUMA_SurfaceObject *)(dov[SOmapID].OP);
02795    ND = SOmap->NodeDim;
02796    id = ND * iclosest;
02797    XYZmap[0]=SOmap->NodeList[id];
02798    XYZmap[1]=SOmap->NodeList[id+1];
02799    XYZmap[2]=SOmap->NodeList[id+2];
02800 
02801    
02802 
02803    SUMA_RETURN (XYZmap);
02804 }
02805 
02806 
02807 
02808 
02809 
02810 
02811 
02812 
02813 
02814 
02815 
02816 
02817 
02818 
02819 
02820 
02821 
02822 
02823 
02824 
02825 
02826 float * SUMA_XYZmap_XYZ (float *XYZmap, SUMA_SurfaceObject *SO, SUMA_DO* dov, int N_dov, int *I_C)
02827 {
02828    static char FuncName[]={"SUMA_XYZmap_XYZ"};
02829    float *XYZ;
02830    int iclosest, id, ND;
02831    SUMA_SurfaceObject *SOmap;
02832    int SOmapID;
02833    SUMA_Boolean LocalHead = NOPE;
02834    
02835    SUMA_ENTRY;
02836 
02837    
02838    XYZ = (float *)SUMA_calloc (3, sizeof(float));
02839    if (XYZ == NULL) {
02840       fprintf(SUMA_STDERR,"Error %s: Could not allocate for XYZ.\n", FuncName);
02841       SUMA_RETURN (NULL);
02842    } 
02843    
02844    
02845    if (!SUMA_ismappable(SO)){
02846       fprintf(SUMA_STDERR,"%s: Surface is NOT mappable, returning NULL.\n", FuncName);
02847       SUMA_free(XYZ);
02848       SUMA_RETURN (NULL);
02849    }
02850 
02851    
02852    if (SUMA_isLocalDomainParent(SO)){
02853       if (LocalHead) fprintf(SUMA_STDERR,"%s: Surface is a local domain parent. XYZ = XYZmap.\n", FuncName);
02854       SUMA_COPY_VEC (XYZmap, XYZ, 3, float, float);
02855       SOmap = SO;
02856       
02857    } else {
02858       
02859       
02860       SOmapID = SUMA_findSO_inDOv(SO->LocalDomainParentID, dov, N_dov);
02861       if (SOmapID < 0) {
02862          fprintf (SUMA_STDERR,"%s: Failed in SUMA_findSO_inDOv This should not happen.\n", FuncName);
02863          SUMA_free(XYZ);
02864          SUMA_RETURN (NULL);
02865       }
02866       SOmap = (SUMA_SurfaceObject *)(dov[SOmapID].OP);
02867    }
02868    
02869    if (*I_C < 0) { 
02870       
02871          {
02872             SUMA_ISINBOX IB;
02873             float Bd[3], distance;
02874             int ii;
02875             
02876             
02877             Bd[0] = Bd[1] = Bd[2] = SUMA_XYZ_XFORM_BOXDIM_MM;
02878             IB = SUMA_isinbox (SOmap->NodeList, SOmap->N_Node, XYZmap, Bd,  YUP);
02879             if (LocalHead) fprintf (SUMA_STDERR,"%s: %d nodes (out of %d) found in box\n",FuncName, IB.nIsIn, SOmap->N_Node);
02880 
02881             if (IB.nIsIn) { 
02882                
02883                
02884 
02885 
02886                SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, distance, iclosest);
02887                iclosest = IB.IsIn[iclosest];
02888                
02889                if (!SUMA_Free_IsInBox (&IB)) {
02890                   fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName);
02891                }
02892 
02893             } else { 
02894                if (SO != SOmap) {
02895                   SUMA_SL_Warn(  "No node was close enough\n"
02896                                  "to XYZmap, no linkage possible."   );
02897                   SUMA_free(XYZ);
02898                   SUMA_RETURN (NULL);
02899                } else {
02900                   
02901                   SUMA_SL_Warn(  "No node was close enough\n"
02902                                  "to XYZmap, linking by coordinate."   );
02903                   SUMA_RETURN (XYZ);
02904                }
02905             }
02906             
02907             *I_C = iclosest;
02908          }
02909    } else { 
02910       iclosest = *I_C;
02911    }
02912    if (LocalHead) fprintf (SUMA_STDERR,"%s: Node identified for linking purposes is %d\n", FuncName, *I_C);
02913    ND = SO->NodeDim;
02914    id = ND * iclosest;
02915    XYZ[0]=SO->NodeList[id];
02916    XYZ[1]=SO->NodeList[id+1];
02917    XYZ[2]=SO->NodeList[id+2];
02918 
02919    
02920    SUMA_RETURN (XYZ);
02921 }
02922 
02923 
02924 
02925 
02926 
02927 
02928 
02929 
02930 
02931 
02932 
02933 
02934 
02935 
02936 int SUMA_MapRefRelative (int cur_id, int *prec_list, int N_prec_list, SUMA_DO *dov) 
02937 {
02938    int i, rel_id = -1;
02939    static char FuncName[]={"SUMA_MapRefRelative"};
02940    SUMA_SurfaceObject *SOcur, *SO_prec;
02941 
02942    SUMA_ENTRY;
02943 
02944    SOcur = (SUMA_SurfaceObject *)(dov[cur_id].OP);
02945    
02946    if (!SUMA_ismappable(SOcur)) {
02947       SUMA_RETURN (-1);
02948    }
02949    
02950     
02951    for (i=0; i<N_prec_list; ++i) {
02952       SO_prec = (SUMA_SurfaceObject *)(dov[prec_list[i]].OP);
02953       
02954       if (  SO_prec == SOcur ||
02955             strcmp(SOcur->idcode_str, SO_prec->idcode_str) == 0 ) {
02956          if (N_prec_list == 1) {
02957             
02958          } else {
02959             fprintf(SUMA_STDERR,"Error %s: Flow problem. Did not expect identical surfaces in this condition (N_prec_list = %d)\n", FuncName, N_prec_list);
02960             SUMA_BEEP; 
02961          }
02962          
02963 
02964 
02965 
02966 
02967 
02968 
02969 
02970 
02971 
02972          
02973       }
02974       
02975       if (  SUMA_isRelated(SOcur, SO_prec, 1) ) { 
02976          
02977          if (rel_id < 0) {
02978             rel_id = prec_list[i];
02979          } else {
02980             fprintf (SUMA_STDERR,"Error %s: I did not think that would occur! Ignoring other relatives for now.\n", FuncName); 
02981          }
02982 
02983       }
02984    }
02985 
02986    SUMA_RETURN (rel_id);
02987 
02988 }
02989 
02990 
02991 
02992 
02993 int *SUMA_FormSOListToSendToAFNI(SUMA_DO *dov, int N_dov, int *N_Send) 
02994 {
02995    static char FuncName[]={"SUMA_FormSOListToSendToAFNI"};
02996    int *SendList = NULL, ii, j, s, *is_listed=NULL;
02997    SUMA_SurfaceObject *SO=NULL;
02998    SUMA_SO_SIDE side=SUMA_NO_SIDE;
02999    SUMA_Boolean LocalHead = NOPE;
03000    
03001    SUMA_ENTRY;
03002 
03003    *N_Send = 0;
03004    SendList = (int *)SUMA_malloc(N_dov * sizeof(int));
03005    is_listed = (int *)SUMA_calloc(N_dov,  sizeof(int));
03006    if (!SendList || !is_listed) {
03007       SUMA_SL_Crit("Failed to allocate");
03008       SUMA_RETURN(SendList);
03009    }
03010    
03011    
03012    for (s=0;s<5; ++s) {
03013       for (ii=0; ii<N_dov; ++ii) {
03014          if (SUMA_isSO(dov[ii])) {
03015             SO = (SUMA_SurfaceObject *)(dov[ii].OP);      
03016             if (SO->AnatCorrect && !SO->SentToAfni && SO->VolPar) {
03017                switch (s) {
03018                   case 0:
03019                      if (SO->Side == SUMA_LEFT && SUMA_isTypicalSOforVolSurf(SO) ==  -1) { SendList[*N_Send] = ii; *N_Send = *N_Send + 1; is_listed[ii] = 1;}
03020                      break;
03021                   case 1:
03022                      if (SO->Side == SUMA_LEFT && SUMA_isTypicalSOforVolSurf(SO) ==   1) { SendList[*N_Send] = ii; *N_Send = *N_Send + 1; is_listed[ii] = 1;}
03023                      break;
03024                   case 2:
03025                      if (SO->Side == SUMA_RIGHT && SUMA_isTypicalSOforVolSurf(SO) == -1) { SendList[*N_Send] = ii; *N_Send = *N_Send + 1; is_listed[ii] = 1;}
03026                      break;
03027                   case 3:
03028                      if (SO->Side == SUMA_RIGHT && SUMA_isTypicalSOforVolSurf(SO) ==  1) { SendList[*N_Send] = ii; *N_Send = *N_Send + 1; is_listed[ii] = 1;}
03029                      break;
03030                   default:
03031                      if (!is_listed[ii]) { SendList[*N_Send] = ii; *N_Send = *N_Send + 1; is_listed[ii] = 1;}
03032                      break;
03033                }
03034             }
03035          }
03036       }
03037    }
03038    
03039    #if 0
03040    for (s=0; s<3; ++s) {
03041       if (s==0) side = SUMA_LEFT;
03042       else if (s == 1) side = SUMA_RIGHT;
03043       else side = SUMA_NO_SIDE;
03044       for (j=0; j<3; ++j) {
03045          for (ii=0; ii<N_dov; ++ii) {
03046             if (SUMA_isSO(dov[ii])) {
03047                SO = (SUMA_SurfaceObject *)(dov[ii].OP);
03048                if (s==0) {
03049                   if (SO->Side != side) { continue;}
03050                } else if (s == 1){
03051                   if (SO->Side != side) { continue;}
03052                } else {
03053                   
03054                }
03055                #if 1 
03056                
03057 
03058 
03059 
03060 
03061                if (!SO->AnatCorrect) {
03062                   continue;
03063                }
03064                #else 
03065                
03066 
03067 
03068 
03069                if (!SUMA_isLocalDomainParent(SO)) {
03070                   continue;
03071                }
03072                #endif
03073                if (j==0) { 
03074                   if (SUMA_isTypicalSOforVolSurf(SO) != -1 ) {
03075                      continue;
03076                   }
03077                }else if (j==1) { 
03078                   if (SUMA_isTypicalSOforVolSurf(SO)  != 1 ) {
03079                      continue;
03080                   }
03081                }else if (j==2) { 
03082                   if (SUMA_isTypicalSOforVolSurf(SO)  != 0 ) {
03083                      continue;
03084                   }
03085                }
03086                
03087                if (SO->SentToAfni) {
03088                   if (LocalHead) fprintf(SUMA_STDERR, "Warning %s: Surface %s has been sent to AFNI before.\n", \
03089                      FuncName, SO->idcode_str);
03090                   continue;
03091                }else {
03092                   if (LocalHead) fprintf(SUMA_STDERR, "Warning %s: Surface %s Will be sent to AFNI.\n", \
03093                      FuncName, SO->idcode_str);
03094                }
03095                SendList[*N_Send] = ii; *N_Send = *N_Send + 1;
03096             }
03097          }
03098       }
03099    }
03100    #endif
03101    SUMA_RETURN(SendList);
03102 
03103 }
03104