Doxygen Source Code Documentation
SUMA_Engine.h File Reference
Go to the source code of this file.
Functions | |
SUMA_Boolean | SUMA_Engine (DList **listp) |
This is the function that runs the viewers. success = SUMA_Engine (listp);. | |
SUMA_Boolean | SUMA_process_NIML_data (void *nini, SUMA_SurfaceViewer *sv) |
int | SUMA_RegisteredSOs (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int *SO_IDs) |
int | SUMA_VisibleSOs (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int *SO_IDs) |
int | SUMA_NextSO (SUMA_DO *dov, int n_dov, char *idcode, SUMA_SurfaceObject *SOnxt) |
int | SUMA_NextState (SUMA_SurfaceViewer *sv) |
int | SUMA_PrevState (SUMA_SurfaceViewer *sv) |
SUMA_Boolean | SUMA_GetOverlaysFromParent (SUMA_SurfaceObject *SO_nxt, SUMA_SurfaceObject *SO_prec) |
gets overlays from parent surface SO_prec to child surface SO_nxt | |
SUMA_Boolean | SUMA_SwitchState (SUMA_DO *dov, int N_dov, SUMA_SurfaceViewer *sv, int nxtstateID, char *nxtgroup) |
SUMA_Boolean | SUMA_OpenGLStateReset (SUMA_DO *dov, int N_dov, SUMA_SurfaceViewer *sv) |
ans = SUMA_OpenGLStateReset (dov, N_dov, sv); Used when going from one surface viewer to another. The OpenGL state variables need to be reset when moving from one viewer to the next. Otherwise you risk having unpredictable results the first time you do something in one viewer after you'd been in another. This function is a stripped down version of SUMA_SwitchState and should be followed by a call to SUMA_postRedisplay for all the changes to take effect. Do not try executing all the commands in SUMA_display that affect the modelview matrix and the projection matrix without calling for a display the changes will not take effect. | |
SUMA_Boolean | SUMA_SwitchSO (SUMA_DO *dov, int N_dov, int SOcurID, int SOnxtID, SUMA_SurfaceViewer *sv) |
int | SUMA_GetEyeAxis (SUMA_SurfaceViewer *sv, SUMA_DO *dov) |
float * | SUMA_XYZ_XYZmap (float *XYZ, SUMA_SurfaceObject *SO, SUMA_DO *dov, int N_dov, int *I_C) |
float * | SUMA_XYZmap_XYZ (float *XYZmap, SUMA_SurfaceObject *SO, SUMA_DO *dov, int N_dov, int *I_C) |
int | SUMA_MapRefRelative (int cur_id, int *prec_list, int N_prec_list, SUMA_DO *dov) |
SUMA_Boolean | SUMA_NewGeometryInViewer (SUMA_DO *dov, int N_dov, SUMA_SurfaceViewer *sv) |
SUMA_Boolean | SUMA_isVisibleSO (SUMA_SurfaceViewer *sv, SUMA_DO *dov, SUMA_SurfaceObject *curSO) |
YUP if surface is visible in a viewer. | |
int * | SUMA_FormSOListToSendToAFNI (SUMA_DO *dov, int N_dov, int *N_Send) |
creates a list of surfaces that are to be sent to AFNI |
Function Documentation
|
This is the function that runs the viewers. success = SUMA_Engine (listp);.
Definition at line 34 of file SUMA_Engine.c. References SUMA_SurfaceObject::AnatCorrect, SUMA_CrossHair::c, SUMA_SurfaceViewer::Ch, cmap, SUMA_EngineData::CommandCode, SUMA_CommonFields::Connected_v, SUMA_EngineData::cp, SUMA_EngineData::cp_Dest, SUMA_CREATE_TEXT_SHELL_STRUCT::CursorAtBottom, SUMA_ISINBOX::d, DListElmt_::data, dlist_head, SUMA_X_AllView::DPY_controller1, SUMA_CommonFields::DsetList, SUMA_EngineData::f, SUMA_EngineData::f_Dest, SUMA_SurfaceObject::FaceNormList, SUMA_SurfaceObject::FaceSetDim, SUMA_SurfaceObject::FaceSetList, SUMA_SurfaceObject::FaceSetMarker, SUMA_X_AllView::FileSelectDlg, SUMA_EngineData::fm, SUMA_EngineData::fm_Dest, SUMA_SurfaceViewer::Focus_SO_ID, SUMA_SurfaceViewer::FOV, FOV_INITIAL, ft, SUMA_EngineData::fv15, SUMA_EngineData::fv15_Dest, SUMA_EngineData::fv3, SUMA_EngineData::fv3_Dest, SUMA_X::GLXAREA, SUMA_SurfaceViewer::GVS, SUMA_X_AllView::Help_Cmap_TextShell, SUMA_X_AllView::Help_TextShell, SUMA_EngineData::i, i, SUMA_EngineData::i_Dest, SUMA_SurfaceObject::idcode_str, SUMA_EngineData::ip, SUMA_EngineData::ip_Dest, SUMA_ISINBOX::IsIn, SUMA_SurfaceViewer::isShaded, SUMA_SurfaceViewer::iState, SUMA_EngineData::iv15, SUMA_EngineData::iv15_Dest, SUMA_EngineData::iv3, SUMA_EngineData::iv3_Dest, SUMA_EngineData::ivec, SUMA_EngineData::ivec_Dest, SUMA_SurfaceObject::Label, SUMA_SurfaceViewer::light0_position, SUMA_CommonFields::Listening, LocalHead, SUMA_X_SumaCont::Lock_rbg, SUMA_X_SumaCont::LockAllView_tb, SUMA_CommonFields::Locked, SUMA_X_SumaCont::LockView_tbg, SUMA_X_AllView::Log_TextShell, SUMA_COLOR_MAP::M, SUMA_CommonFields::MessageList, SUMA_IVEC::n, SUMA_FaceSetMarker::n0, SUMA_FaceSetMarker::n1, SUMA_FaceSetMarker::n2, SUMA_COLOR_MAP::N_Col, SUMA_EngineData::N_cols, SUMA_SurfaceViewer::N_DO, SUMA_SurfaceObject::N_FaceSet, SUMA_SurfSpecFile::N_Groups, SUMA_SurfaceObject::N_Node, SUMA_EngineData::N_rows, SUMA_COLOR_MAP::Name, NI_BINARY_MODE, NI_free_element(), NI_new_data_element(), NI_set_attribute(), NI_stream_close(), NI_stream_goodcheck(), NI_stream_open(), NI_TEXT_MODE, NI_write_element(), SUMA_CommonFields::niml_work_on, SUMA_ISINBOX::nIsIn, SUMA_SurfaceObject::NodeDim, SUMA_CrossHair::NodeID, SUMA_SurfaceObject::NodeList, SUMA_SurfaceObject::NodeNormList, SUMA_FaceSetMarker::NormVect, SUMA_CommonFields::ns_flags_v, SUMA_CommonFields::ns_v, SUMA_DO::OP, SUMA_SurfaceObject::PolyMode, SUMA_SurfaceViewer::RegisteredDO, SUMA_SurfaceViewer::ResetGLStateVariables, SUMA_EngineData::s, SUMA_EngineData::s_Dest, SE_BadCode, SE_BindCrossHair, SE_CloseStream4All, SE_FlipLight0Pos, SE_FOVreset, SE_GetNearestNode, SE_Help, SE_Help_Cmap, SE_HighlightNodes, SE_Home, SE_Home_AllVisible, SE_Load_Group, SE_LoadSegDO, SE_LoadViewFileSelection, SE_LockCrossHair, SE_Log, SE_OpenCmapFileSelection, SE_OpenColFileSelection, SE_OpenDrawnROIFileSelection, SE_OpenDrawROI, SE_OpenDsetFileSelection, SE_Redisplay, SE_Redisplay_AllVisible, SE_RedisplayNow, SE_RedisplayNow_AllOtherVisible, SE_RedisplayNow_AllVisible, SE_ResetOpenGLState, SE_SaveDrawnROIFileSelection, SE_SaveSOFileSelection, SE_SaveViewFileSelection, SE_SendColorMapToAfni, SE_SetAfniCrossHair, SE_SetAfniSurf, SE_SetAfniSurfList, SE_SetAfniThisSurf, SE_SetCrossHair, SE_SetForceAfniSurf, SE_SetLight0Pos, SE_SetLockAllCrossHair, SE_SetLookAt, SE_SetLookAtNode, SE_SetLookFrom, SE_SetNodeColor, SE_SetRenderMode, SE_SetRotMatrix, SE_SetSelectedFaceSet, SE_SetSelectedNode, SE_SetSOinFocus, SE_StartListening, SE_ToggleBackground, SE_ToggleConnected, SE_ToggleCrossHair, SE_ToggleForeground, SE_ToggleLockAllCrossHair, SE_ToggleLockAllViews, SE_ToggleLockView, SE_ToggleShowSelectedFaceSet, SE_ToggleShowSelectedNode, SE_UpdateLog, SEF_Empty, SEF_fm, SEF_fv15, SEF_i, SEF_ivec, SEF_s, SEI_After, SEI_Head, SEI_In, SEI_Tail, SUMA_SurfaceObject::SelectedFaceSet, SUMA_SurfaceObject::SelectedNode, SUMA_SurfaceObject::SentToAfni, SES_Afni, SES_Suma, SES_SumaFromAfni, SES_SumaFromAny, SES_SumaWidget, SUMA_SurfaceViewer::ShowBackground, SUMA_SurfaceViewer::ShowCrossHair, SUMA_SurfaceViewer::ShowForeground, SUMA_SurfaceObject::ShowSelectedFaceSet, SUMA_SurfaceObject::ShowSelectedNode, DList_::size, SMA_LogAndPopup, SMT_Error, SUMA_SAVESO_STRUCT::SO, SUMA_EngineData::Src, SUMA_EngineData::Srcp, SUMA_SurfaceViewer::StdView, SUMA_AFNI_STREAM_INDEX, SUMA_allocate2D(), SUMA_append_replace_string(), SUMA_append_string(), SUMA_Boolean, SUMA_BuildMessageLog(), SUMA_CanTalkToAfni(), SUMA_CommandString(), SUMA_CreateFileSelectionDialog(), SUMA_CreateFileSelectionDialogStruct(), SUMA_CreateTextShell(), SUMA_CreateTextShellStruct(), SUMA_DestroyList(), SUMA_ENTRY, SUMA_etime(), SUMA_FetchROI_InCreation(), SUMA_FILE_OPEN, SUMA_FILE_SAVE, SUMA_findSO_inDOv(), SUMA_FormSOListToSendToAFNI(), SUMA_free, SUMA_free2D(), SUMA_Free_ColorMap(), SUMA_Free_IsInBox(), SUMA_FromToRotation(), SUMA_GetColorList(), SUMA_GetStandardMap(), SUMA_handleRedisplay(), SUMA_help_Cmap_message_Info(), SUMA_help_message_Info(), SUMA_I_Lock, SUMA_InitializeEngineListData(), SUMA_isinbox(), SUMA_isRelated(), SUMA_isSO(), SUMA_iswordin(), SUMA_LH, SUMA_LoadSpec_eng(), SUMA_LockEnum_LockType(), SUMA_makeNI_CrossHair(), SUMA_makeNI_SurfIJK(), SUMA_makeNI_SurfINORM(), SUMA_makeNI_SurfIXYZ(), SUMA_malloc, SUMA_mattoquat(), SUMA_MAX_COMMAND_LENGTH, SUMA_MAX_DISPLAYABLE_OBJECTS, SUMA_MAX_STREAMS, SUMA_MAX_SURF_VIEWERS, SUMA_MIN_LOC_VEC, SUMA_N_Lock_Types, SUMA_niml_call(), SUMA_No_Lock, SUMA_OpenDrawROIWindow(), SUMA_POINT_AT_DISTANCE, SUMA_postRedisplay(), SUMA_Read_SpecFile(), SUMA_REGISTER_HEAD_COMMAND_NO_DATA, SUMA_register_workproc(), SUMA_RegisteredSOs(), SUMA_RegisterEngineListCommand(), SUMA_RegisterGroup(), SUMA_RegisterMessage(), SUMA_ReleaseEngineListElement(), SUMA_RETURN, SUMA_set_Lock_arb(), SUMA_set_Lock_rb(), SUMA_set_LockView_atb(), SUMA_SetShownLocalRemixFlag(), SUMA_SetupSVforDOs(), SUMA_SL_Err, SUMA_SL_Warn, SUMA_SLP_Err, SUMA_UpdateNodeField(), SUMA_UpdateTriField(), SUMA_UpdateViewerTitle(), SUMA_UpdateXhairField(), SUMA_WhichSV(), SUMA_XYZ_Lock, SUMA_X_AllView::SumaCont, SUMAg_N_DOv, SUMAg_N_SVv, SUMA_CrossHair::SurfaceID, SUMA_SAVESO_STRUCT::sv, SW_ViewCrossHair, SW_ViewNodeInFocus, SW_ViewSelectedFaceset, SUMA_CREATE_TEXT_SHELL_STRUCT::toplevel, SUMA_X::TOPLEVEL, SUMA_CommonFields::TrackingId_v, tt, SUMA_IVEC::v, SUMA_CommonFields::ViewLocked, SUMA_X::ViewMenu, SUMA_EngineData::vp, SUMA_EngineData::vp_Dest, SUMA_SurfaceViewer::X, and SUMA_CommonFields::X. Referenced by main(), SUMA_cb_AfniLink_toggled(), SUMA_cb_Cmap_Load(), SUMA_cb_ColPlane_Load(), SUMA_cb_DrawROI_Delete(), SUMA_cb_DrawROI_Finish(), SUMA_cb_DrawROI_Join(), SUMA_cb_DrawROI_Load(), SUMA_cb_DrawROI_Redo(), SUMA_cb_DrawROI_Save(), SUMA_cb_DrawROI_Undo(), SUMA_cb_Dset_Load(), SUMA_cb_FileLoadView(), SUMA_cb_FileSaveView(), SUMA_cb_SetRenderMode(), SUMA_cb_toggle_crosshair(), SUMA_cb_toggle_node_in_focus(), SUMA_cb_toggle_selected_faceset(), SUMA_cb_ToolsDrawROI(), SUMA_cb_XHalock_toggled(), SUMA_cb_XHaviewlock_toggled(), SUMA_cb_XHviewlock_toggled(), SUMA_cmap_wid_input(), SUMA_DrawROI_NewValue(), SUMA_HighlightBox(), SUMA_input(), SUMA_JumpFocusFace(), SUMA_JumpFocusNode(), SUMA_JumpIndex(), SUMA_JumpXYZ(), SUMA_LookAtCoordinates(), SUMA_MarkLineSurfaceIntersect(), SUMA_niml_workproc(), SUMA_OpenDrawnROI(), SUMA_Paint_SO_ROIplanes(), SUMA_process_NIML_data(), SUMA_RedisplayAllShowing(), SUMA_RegisterMessage(), SUMA_RemixRedisplay(), SUMA_SetLight0(), SUMA_SetNumForeSmoothing(), SUMA_SwitchGroups(), SUMA_SwitchSO(), and SUMA_SwitchState().
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; /* EngineData is what get passed from a list element, 00052 ED is what gets added to the list inside SUMA_Engine */ 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 /*int iv3[3], iv15[15], **im; 00059 float fv3[3]; 00060 char s[SUMA_MAX_STRING_LENGTH];*/ /* keep standard unused variables undeclared, else compiler complains*/ 00061 00062 00063 SUMA_ENTRY; 00064 00065 list = *listp; /* listp is now passed instead of list so that I can set list to NULL from within this function */ 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) {/* cycle through NextComs */ 00074 if (LocalHead) fprintf (SUMA_STDERR,"%s: Fetching next element\n", FuncName); 00075 /* get the next command from the head of the list */ 00076 NextElem_CANT_TOUCH_THIS = dlist_head(list); 00077 EngineData = (SUMA_EngineData *)NextElem_CANT_TOUCH_THIS->data; 00078 00079 /* decide on what Srcp might be. Currently only sv is passed when the source is Suma*/ 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) {/* switch NextComCode */ 00101 case SE_SendColorMapToAfni: 00102 /* expects in i the code of one of SUMA's standard colormaps */ 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 /* get the CMAP */ 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 /* send AFNI the color map */ 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 /* SEND COLORMAP In REVERSE ORDER TO AFNI, 00134 C'est la vie */ 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 /* SUMA_ShowNel(nel); */ 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 /* Now set the colormap in AFNI */ 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 /* SUMA_ShowNel(nel); */ 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 /* set the autorange off */ 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 /* set the range of the colorbar */ 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 /* opens the open ROI file selection window. 00211 Expects NULL in vp (to be used later and a position reference widget typecast to ip, the latter can be null.*/ 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 /* open the ROI file */ 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 /* opens the save roi file selection window. 00237 Expects NULL in vp (to be used later and a position reference widget typecast to ip, the latter can be null.*/ 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 /* save ROI to file */ 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 /* saves a surface and its node colors to ascii files */ 00266 /* expects SO in vp and a position reference widget typecast to ip, the latter can be null.*/ 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)); /* DO NOT FREE THIS POINTER, 00278 It is freed by the function 00279 SUMA_SaveSOascii */ 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 /* opens the view file selection window. 00326 Expects a position reference widget typecast to ip, the latter can be null.*/ 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 /* opens the view file selection window. 00352 Expects a position reference widget typecast to ip, the latter can be null.*/ 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 /* opens the dataset file selection window. 00378 Expects SO in vp and a position reference widget typecast to ip, the latter can be null.*/ 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 /*Load data from file */ 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 /* opens the Cmap file selection window. 00408 Expects SO in vp and a position reference widget typecast to ip, the latter can be null.*/ 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 /*Load colors from file */ 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 /* opens the color file selection window. 00437 Expects SO in vp and a position reference widget typecast to ip, the latter can be null.*/ 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 /*Load colors from file */ 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 /* opens the DrawROI window, expects a surface viewer pointer in EngineData->Srcp*/ 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 /* determine if there are ROIs being drawn on surfaces displayed here */ 00477 DrawnROI = NULL; 00478 /* start with the Focus_SO */ 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) { /* none found on focus surface, check other surfaces in this viewer */ 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 /* call function to create ROI window */ 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 { /* sets the rendering mode of a surface, expects SO in vp and rendering mode in i*/ 00505 SO = (SUMA_SurfaceObject *)EngineData->vp; 00506 SO->PolyMode = EngineData->i; 00507 } 00508 break; 00509 00510 case SE_UpdateLog: 00511 /* Updates the Log window if it is open */ 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 /* opens log window, needs nothing for the moment*/ 00526 { 00527 char *s = NULL; 00528 if (SUMAg_CF->X->Log_TextShell) { /* just raise it */ 00529 XRaiseWindow(SUMAg_CF->X->DPY_controller1, XtWindow(SUMAg_CF->X->Log_TextShell->toplevel)); 00530 break; 00531 }else { /* create it */ 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 /* opens help window, needs nothing for the moment*/ 00548 { 00549 char *s = NULL; 00550 if (SUMAg_CF->X->Help_TextShell) { /* just raise it */ 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 /* opens Cmap help window, needs Cmap in vp*/ 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) { /* just raise it */ 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 /* Does not need a sv 00605 expects a pointer to .spec filename in cp, 00606 if cp is NULL then it will look for a spec structure pointer in ip (sorry, ran out of places...) 00607 it will also determine if surfaces in a spec structure pointer have already been loaded from f (really, ran out of places...) 00608 a VolumeParent name in vp, 00609 the indices of the viewers to register the surfaces with in iv15. 00610 and the number of viewers specified in iv15 in i. 00611 Surfaces are registered with all i viewers in iv15*/ 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 /* Load The spec file */ 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 /* make sure only one group was read in */ 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 /* load the surfaces specified in the specs file, one by one*/ 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 /* register the new group with SUMA */ 00659 if (!SUMA_RegisterGroup(SUMAg_CF, &Spec)) { 00660 SUMA_SL_Err("Failed to register group"); 00661 break; 00662 } 00663 00664 /* Register the surfaces in Spec file with the surface viewer and perform setups */ 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 /* add a call to Home and a redisplay */ 00676 if (!list) { 00677 fprintf (SUMA_STDERR, "Error %s: Should not be inside SUMA_Engine: ZSS Feb 02 05.\n", FuncName); 00678 /* list = SUMA_CreateList();*/ 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 /* expects a center XYZ in EngineData->fv3[0 .. 2] */ 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 /* calculate the transform required to bring the new look at location to the current one */ 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 /* add a SetRotMatrix to list*/ 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 /* add a redisplay call */ 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 /* fm was copied into engine data, free it */ 00767 SUMA_free2D((char **)fm, 4); 00768 } 00769 break; 00770 00771 case SE_StartListening: 00772 /* expects nothing in EngineData */ 00773 if (!SUMAg_CF->Listening) { 00774 SUMAg_CF->Listening = !SUMAg_CF->Listening; 00775 fprintf(SUMA_STDERR,"%s: Starting to listen ...\n", FuncName); 00776 /* start the listening WorkProcess */ 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 /* if already on, just close streams */ 00785 /* closing the streams */ 00786 fprintf(SUMA_STDERR,"%s: Closing streams, but still listening ...\n", FuncName); 00787 /* kill the streams */ 00788 for (ii=0; ii< SUMA_MAX_STREAMS; ++ii) { 00789 if (ii != SUMA_AFNI_STREAM_INDEX) { /* leave AFNI connection separate */ 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 /* expects nothing in EngineData */ 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 /* conection flag is reset in SUMA_niml_call */ 00810 break; 00811 } 00812 00813 /* start the listening WorkProcess */ 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 /* register a call for sending the surface to afni (SetAfniSurf)*/ 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 /* It looks like the stream was closed, do the clean up */ 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 /* Close the stream if nobody else wants it. 00847 This is not a great condition, one should be able to leave the stream open 00848 even if no viewer, for the moment, does not want to talk to AFNI. 00849 Perhaps in the future. */ 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 /* expects the stream index in i in EngineData */ 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 /* odds are communicating program died or closed stream, mark all surfaces as unsent */ 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 /* same for parent fields */ 00877 /* check first if stream in SUMAg_CF still good by any chance */ 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 /* clean up and get out of here*/ 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 /* expects nothing in EngineData */ 00894 /* send to afni surfaces that can be sent even if they have been sent already */ 00895 #if 0 /* pre Oct 26 */ 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 /* send all geometrically correct surfaces */ 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 /* proceed to SE_SetAfniSurf: */ 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 /* expects ivec in EngineData and a string in s saying what is to be sent, a flag in i 1=report transmission, 0 = be quiet*/ 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 /* send to afni the list of surfaces in SendList*/ 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 /* send surface nel */ 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 /* send node normals ZSS Oct 05 04 */ 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 /* send surface nel */ 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 /* send triangles */ 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 /* send surface nel */ 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 /* mark surface as sent to afni */ 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 /* expects nothing in EngineData */ 01014 { int N_Send, *SendList, ti=1; 01015 SUMA_IVEC ivec; 01016 /* send to afni the list of anatomically correct surfaces and with a surface volume*/ 01017 /* No surfaces are sent twice because there should not be duplicate 01018 local domain parent surfaces in SUMAg_DOv */ 01019 /* prior to Wed Nov 6 17:47:20 EST 2002, only mappable surfaces that are related to the ones shown in the viewer 01020 were being sent to AFNI. Now all mappable surfaces loaded are sent regardless of what is shown */ 01021 /* Jan. 08 04: All anatomically correct surfaces are now sent to AFNI */ 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 /* expects an idcode_str in EngineData->cp and what needs to be sent in EngineData->s for surface to be sent to AFNI */ 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 /* expects nothing in EngineData */ 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 /* expects a node index in i */ 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 /* ignore -1, used in initializations */ 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 /* expects nothing ! */ 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) { /* first surface, set the common state */ 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 /* expects the index for the selected FaceSet */ 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) { /* ignore -1, used in initialization */ 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 /* expects nothing in EngineData */ 01198 sv->ShowCrossHair = !sv->ShowCrossHair; 01199 XmToggleButtonSetState (sv->X->ViewMenu[SW_ViewCrossHair], 01200 sv->ShowCrossHair, NOPE); 01201 break; 01202 01203 case SE_SetCrossHair: 01204 /* Expects Cross Hair coordinates in fv3 */ 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 /* Attempt to update crosshair corrdinates in open surface controllers */ 01212 SUMA_UpdateXhairField(sv); 01213 break; 01214 01215 case SE_BindCrossHair: 01216 /* expects SurfaceID to bind cross hair to*/ 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 /* expects surface ID in i */ 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 /* a new one, update */ 01234 sv->Focus_SO_ID = EngineData->i; 01235 SUMA_UpdateViewerTitle(sv); 01236 } 01237 break; 01238 01239 case SE_ToggleLockView: 01240 /* expects index of viewer in i to toggle its lock view */ 01241 /* toggles the lock view button */ 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 /* update button if needed*/ 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 /* call function to update the AllLock button */ 01253 SUMA_set_LockView_atb (); 01254 01255 break; 01256 01257 case SE_ToggleLockAllViews: 01258 /* expects nothing, toggles all locked view buttons */ 01259 01260 /* get the current value of the button */ 01261 { 01262 SUMA_Boolean CurState; 01263 CurState = XmToggleButtonGetState (SUMAg_CF->X->SumaCont->LockAllView_tb); 01264 for (ii=0; ii< SUMA_MAX_SURF_VIEWERS; ++ii) { /* set all buttons accrodingly */ 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 /* expects nothing, toggles cross hair lock for all viewers */ 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 /* change the locking type of viewer 0 */ 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 /* update the widget*/ 01282 SUMA_set_Lock_rb (SUMAg_CF->X->SumaCont->Lock_rbg, 0, SUMAg_CF->Locked[0]); 01283 /* Change the locking type of all remaining viewers, including unopen ones */ 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 /* now update the all lock keys */ 01290 SUMA_set_Lock_arb (SUMAg_CF->X->SumaCont->Lock_rbg); 01291 01292 } 01293 break; 01294 01295 case SE_SetLockAllCrossHair: 01296 /* expects a Lock value in i , sets the lock of all viewers */ 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 /* Change the locking type of all remaining viewers, including unopen ones */ 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 /* now update the all lock keys */ 01310 SUMA_set_Lock_arb (SUMAg_CF->X->SumaCont->Lock_rbg); 01311 } 01312 break; 01313 01314 case SE_LockCrossHair: 01315 /* expects nothing in EngineData */ 01316 01317 /* calls other viewers and determine if the cross hair needs to be locked to the calling sv */ 01318 01319 /* check to see if other viewers need to share the fate */ 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]) { /* This one's locked, find out which other viewers are locked to this one */ 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 /* just set the XYZ, and free the binding to the surfaces */ 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 /* FORCE a redisplay */ 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 /* determine the list of shown surfaces */ 01352 N_SOlist = SUMA_RegisteredSOs(svi, SUMAg_DOv, SOlist); 01353 01354 /* first find the surface that the cross hair is bound to */ 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)) { /* high level relationship is allowed */ 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 /* set the XYZ */ 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 /* FORCE a redisplay */ 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 /* not locked to anything */ 01406 } 01407 break; 01408 01409 case SE_SetAfniCrossHair: 01410 /* expects nothing in EngineData */ 01411 /* sends the current cross hair to afni */ 01412 /* form nel */ 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 /*send it to afni */ 01419 /*fprintf(SUMA_STDERR,"Sending cross hair nel ") ;*/ 01420 nn = NI_write_element( SUMAg_CF->ns_v[SUMA_AFNI_STREAM_INDEX] , nel , NI_TEXT_MODE ) ; 01421 /*SUMA_nel_stdout (nel);*/ 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 /* expects a center XYZ in EngineData->fv15[0 .. 2] 01433 expects a normal vector in EngineData->fv15[3 .. 5] */ 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 /* modify the ViewFrom Value such that the viewing distance remains the same */ 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 /* set the ViewCenter Value to that of the node's XYZ*/ 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 /* obtain the LookFrom point based on CurrentDistance and the normal vector */ 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 /* expects a center XYZ in EngineData->fv3[0 .. 2] */ 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 /* set the LookFrom option */ 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 /* expects nothing in EngineData */ 01483 /* post a redisplay to all visible viewers */ 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 /* you must check for both conditions because by default 01488 all viewers are initialized to isShaded = NOPE, even before they are ever opened */ 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 /* expects nothing in EngineData */ 01499 /*post a redisplay to one specific viewer*/ 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 /* expects nothing in EngineData */ 01507 /*call handle redisplay immediately to one specific viewer*/ 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 /* expects nothing in EngineData */ 01516 /* causes an immediate redisplay to all visible viewers */ 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 /* you must check for both conditions because by default 01521 all viewers are initialized to isShaded = NOPE, even before they are ever opened */ 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 /* expects nothing in EngineData, expects sv in srcp*/ 01531 /* causes an immediate redisplay to all visible viewers other than sv*/ 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 /* you must check for both conditions because by default 01536 all viewers are initialized to isShaded = NOPE, even before they are ever opened */ 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 /* reset OPEN GL's state variables */ 01546 /* expects the surface viewer pointer in vp */ 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 /* No need to call SUMA_OpenGLStateReset, that is now done in SUMA_display */ 01554 svi = (SUMA_SurfaceViewer *)EngineData->vp; 01555 svi->ResetGLStateVariables = YUP; 01556 break; 01557 01558 case SE_ToggleForeground: 01559 /* expects nothing in EngineData */ 01560 /* Show/hide the foreground */ 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 /* set the color remix flag */ 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 /* expects nothing in EngineData */ 01576 /* Show/hide the background */ 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 /* set the color remix flag */ 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 /* expects nothing in EngineData, needs sv */ 01592 sv->GVS[sv->StdView].translateVec[0]=0; sv->GVS[sv->StdView].translateVec[1]=0; 01593 glMatrixMode(GL_PROJECTION); 01594 /* sv->FOV[sv->iState] = FOV_INITIAL; *//* Now done in SE_FOVreset *//* reset the zooming */ 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 /* expects nothing in EngineData, needs no sv */ 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 /* you must check for both conditions because by default 01614 all viewers are initialized to isShaded = NOPE, even before they are ever opened */ 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 /* list = SUMA_CreateList();*/ 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 /* expects nothing in EngineData */ 01629 sv->FOV[sv->iState] = FOV_INITIAL; /* reset the zooming */ 01630 break; 01631 01632 case SE_SetNodeColor: 01633 /* expects a four-columned fm in EngineData->fm[0 .. N][0..3] 01634 [Node Index] [R] [G] [B] RGB between 0 and 1*/ 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 /* expects nothing in EngineData */ 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 /* expects light XYZ position in fv[3] */ 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 /* highlight nodes inside the search box */ 01679 /* expects Node XYZ in EngineData->fv15[0..2] 01680 Box dimensions in EngineData->fv15[3..5] */ 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) { /* found some, find the closest node */ 01698 /* locate the closest node and store it's id in EngineData*/ 01699 SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, ft, it); 01700 01701 /* XYZ and normal of the closest to the center */ 01702 #ifdef STUFF 01703 /* This is not being used and if it is to be used, EngineData should 01704 not be set manually */ 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 /* Color the nodes*/ 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 /* id = ND * IB.IsIn[i]; */ 01721 /*fprintf (SUMA_STDOUT,"\t[%d] %f %f %f\n", IB.IsIn[i] ,\ 01722 SO->NodeList[id], SO->NodeList[id+1], SO->NodeList[id+2]);*/ 01723 /* color those nodes in yellow, just for kicks */ 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 /* Place a call to Redisplay and SetNodeColor */ 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 /* free fm since it was copied to EngineData*/ 01748 if (fm) SUMA_free2D ((char **)fm, IB.nIsIn); 01749 01750 /* get ridd of IB's vectors */ 01751 if (!SUMA_Free_IsInBox (&IB)) { 01752 fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName); 01753 } 01754 } else { /* no node is close enough */ 01755 /* Do nothing yet */ 01756 fprintf (SUMA_STDOUT,"\nNo nodes found inside the specified box.\n"); 01757 } 01758 } 01759 break; 01760 01761 case SE_GetNearestNode: 01762 /* lookfor nodes inside the search box */ 01763 /* expects Node XYZ in EngineData->fv15[0..2] 01764 Box dimensions in EngineData->fv15[3..5] */ 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) { /* found some, find the closest node */ 01781 /* locate the closest node and store it's id in EngineData*/ 01782 SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, ft, it); 01783 01784 /* get the XYZ and normal of that node */ 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 /* get ridd of IB's vectors */ 01803 if (!SUMA_Free_IsInBox (&IB)) { 01804 fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName); 01805 } 01806 } else { /* no node is close enough */ 01807 /* Do nothing yet */ 01808 } 01809 } 01810 break; 01811 01812 case SE_SetRotMatrix: 01813 /* expects a rotation matrix in fm, 4x4 */ 01814 /* takes the rotation matrix 3x3 with 0 in 4th row and column and 1.0 at 4,4 01815 makes a quaternion from it and sets csv->currentQuat and posts redisplay */ 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 /*case SE_Something: 01832 break;*/ 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 } /* switch NextComCode */ 01839 01840 /* release used Element */ 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 } /* cycle through NextCom */ 01847 01848 if (LocalHead) fprintf (SUMA_STDERR, "\n%s: Destroying List.\n", FuncName); 01849 /* If you get here, all is well, destroy the list since it is empty*/ 01850 list = SUMA_DestroyList (list); 01851 *listp = NULL; 01852 01853 SUMA_RETURN (YUP); 01854 } |
|
creates a list of surfaces that are to be sent to AFNI
Definition at line 2993 of file SUMA_Engine.c. References SUMA_SurfaceObject::AnatCorrect, SUMA_SurfaceObject::idcode_str, LocalHead, SUMA_DO::OP, SUMA_SurfaceObject::SentToAfni, SUMA_SurfaceObject::Side, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_isLocalDomainParent(), SUMA_isSO(), SUMA_isTypicalSOforVolSurf(), SUMA_LEFT, SUMA_malloc, SUMA_NO_SIDE, SUMA_RETURN, SUMA_RIGHT, SUMA_SL_Crit, SUMA_SO_SIDE, and SUMA_SurfaceObject::VolPar. Referenced by SUMA_Engine().
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 /* let it proceed */ 03054 } 03055 #if 1 03056 /* Jan. 08 04 this is the right thing to do but 03057 AFNI is not ready to deal with this 03058 and things can get confusing. See 03059 confusing fat point in Readme_Modify.log, 03060 date: Thu Jan 8 13:55:33 EST 2004 */ 03061 if (!SO->AnatCorrect) { 03062 continue; 03063 } 03064 #else 03065 /* Jan. 08 04 the old and not confusing way. 03066 Turn it off as soon as AFNI is ready 03067 for the option above. 03068 See labbook NIH-3 page 146 */ 03069 if (!SUMA_isLocalDomainParent(SO)) { 03070 continue; 03071 } 03072 #endif 03073 if (j==0) { /* inner surfaces */ 03074 if (SUMA_isTypicalSOforVolSurf(SO) != -1 ) { 03075 continue; 03076 } 03077 }else if (j==1) { /* outer surfaces */ 03078 if (SUMA_isTypicalSOforVolSurf(SO) != 1 ) { 03079 continue; 03080 } 03081 }else if (j==2) { /* other */ 03082 if (SUMA_isTypicalSOforVolSurf(SO) != 0 ) { 03083 continue; 03084 } 03085 } 03086 /* if this surface has been sent to AFNI before, bypass it */ 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 } |
|
EyeAxisID = SUMA_GetEyeAxis (sv, dov); gets the ID (indices into dov) of the Eye Axis in sv
Definition at line 2670 of file SUMA_Engine.c. References AO_type, i, SUMA_SurfaceViewer::N_DO, SUMA_Axis::Name, SUMA_SurfaceViewer::RegisteredDO, SUMA_ENTRY, and SUMA_RETURN. Referenced by SUMA_NewGeometryInViewer(), SUMA_OpenGLStateReset(), SUMA_SetupSVforDOs(), SUMA_SwitchSO(), and SUMA_SwitchState().
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 } |
|
gets overlays from parent surface SO_prec to child surface SO_nxt
Definition at line 2166 of file SUMA_Engine.c. References LocalHead, SUMA_SurfaceObject::N_Overlays, SUMA_OVERLAYS::Name, SUMA_SurfaceObject::Overlays, SUMA_ADD_COORD_BIAS_VECT, SUMA_Boolean, SUMA_ENTRY, SUMA_Fetch_OverlayPointer(), SUMA_isRelated(), SUMA_LH, SUMA_LinkToPointer(), SUMA_NewSurfaceGeometry(), SUMA_RETURN, and SUMA_SL_Err. Referenced by SUMA_cb_createSurfaceCont(), and SUMA_SwitchState().
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 /* Create a link to each overlay plane in the precursor unless such a plane exists already */ 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 /* plane not found, create a link to it */ 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 /* it happens at times, that an overlay carries coordinate bias with it. 02190 When that happens, the bias should be added immediately */ 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 /* Update surface geometry properties */ 02199 SUMA_NewSurfaceGeometry(SO_nxt); 02200 } 02201 } 02202 /*increment the number of overlay planes */ 02203 ++SO_nxt->N_Overlays; 02204 } else { 02205 /* plane found, do nothing */ 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 } |
|
|
Prec_ID = SUMA_MapRefRelative (Cur_ID, Prec_List, N_Prec_List, dov); Returns the ID (index into dov) of the surface object in Prec_List that is related (via MapRef) to the surface object Cur_ID. This means that SOcur.LocalDomainParentID = SOprec.MapRef_icode_str or SOprec.idcode_str
Definition at line 2936 of file SUMA_Engine.c. References i, SUMA_SurfaceObject::idcode_str, SUMA_DO::OP, SUMA_BEEP, SUMA_ENTRY, SUMA_ismappable(), SUMA_isRelated(), and SUMA_RETURN. Referenced by SUMA_SwitchState().
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 /* if surface has no MapRef then it cannot receive colors from precursors */ 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 /* if all you have is one surface in one state in SUMA then you need not worry about the rest */ 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 I changed the next condition: 02964 if ( strcmp(SOcur->LocalDomainParentID, SO_prec->LocalDomainParentID) == 0 || 02965 strcmp(SOcur->LocalDomainParentID, SO_prec->idcode_str) == 0 ) 02966 to 02967 if ( SUMA_isRelated(SOcur, SO_prec, 1) ) 02968 The two are the same except for the condition when the two surfaces are identical. 02969 So I put in a error message when that would happen and I'll deal with it then. 02970 ZSS Jan 08 04 02971 */ 02972 02973 } 02974 02975 if ( SUMA_isRelated(SOcur, SO_prec, 1) ) { /* Change made Jan 08 04, see note above */ 02976 /* there's some relationship here, save it for return */ 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 } |
|
Call this function whenever you have new geometry in the viewer This happens when you switch states or when you modify the coordinates of a surface The succession of function calls is replicated in parts elsewhere in the code like in the SwitchState function Definition at line 2532 of file SUMA_Engine.c. References SUMA_SurfaceViewer::GVS, i, LocalHead, SUMA_DO::OP, SUMA_SurfaceViewer::StdView, SUMA_3D, SUMA_BestStandardView(), SUMA_Boolean, SUMA_Dunno, SUMA_ENTRY, SUMA_EyeAxisStandard(), SUMA_GetEyeAxis(), SUMA_RETURN, SUMA_UpdateRotaCenter(), SUMA_UpdateViewPoint(), SUMA_WorldAxisStandard(), and SUMA_SurfaceViewer::WAx. Referenced by SUMA_display().
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 /* decide what the best std view is */ 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 /* modify the rotation center */ 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 /* set the viewing points */ 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 /* Change the defaults of the eye axis to fit standard EyeAxis */ 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 /* Need to update where you're looking at*/ 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 /* do the axis setup */ 02586 SUMA_WorldAxisStandard (sv->WAx, sv); 02587 02588 /* You still need to call SUMA_display via SUMA_postRedisplay but that is done after this function returns */ 02589 02590 SUMA_RETURN (YUP); 02591 } |
|
SOnxtID = SUMA_NextSO (dov, n_dov, CurrentIDcode, SOnxt); Get the next Surface Object in DOv
Definition at line 2051 of file SUMA_Engine.c. References SUMA_DO::OP, SUMA_ENTRY, SUMA_findSO_inDOv(), SUMA_isSO(), and SUMA_RETURN.
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 /*fprintf(SUMA_STDERR,"%s: Checking %d\n", FuncName, icheck);*/ 02077 if (SUMA_isSO(dov[icheck])) { 02078 /*fprintf(SUMA_STDERR,"%s: Settling on %d\n", FuncName, icheck);*/ 02079 SOnxt = (SUMA_SurfaceObject *)dov[icheck].OP; 02080 SUMA_RETURN (icheck); 02081 } 02082 ++ncheck; 02083 } 02084 /* should not get here */ 02085 SUMA_RETURN (-1); 02086 } |
|
nxtState = SUMA_NextState(sv); get the next Viewing State available in sv
Definition at line 1970 of file SUMA_Engine.c. References SUMA_SurfaceViewer::CurGroupName, SUMA_ViewState::Group, LocalHead, SUMA_SurfaceViewer::N_VSv, SUMA_SurfaceViewer::State, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, SUMA_SL_Err, SUMA_WhichState(), and SUMA_SurfaceViewer::VSv. Referenced by SUMA_input().
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 /* Now see if the upcoming one is of the same group */ 01986 if (inxt == icur) { 01987 /* back where we started */ 01988 SUMA_RETURN(inxt); 01989 } else { 01990 if (!strcmp(sv->VSv[inxt].Group, sv->CurGroupName)) { /* group match, good, go back */ 01991 SUMA_RETURN(inxt); 01992 } 01993 } 01994 inxt = (inxt + 1) % sv->N_VSv; 01995 } while (1); 01996 } 01997 01998 /* should not get here */ 01999 SUMA_SL_Err("Flow error"); 02000 SUMA_RETURN (-1); 02001 } |
|
ans = SUMA_OpenGLStateReset (dov, N_dov, sv); Used when going from one surface viewer to another. The OpenGL state variables need to be reset when moving from one viewer to the next. Otherwise you risk having unpredictable results the first time you do something in one viewer after you'd been in another. This function is a stripped down version of SUMA_SwitchState and should be followed by a call to SUMA_postRedisplay for all the changes to take effect. Do not try executing all the commands in SUMA_display that affect the modelview matrix and the projection matrix without calling for a display the changes will not take effect.
Definition at line 2611 of file SUMA_Engine.c. References i, LocalHead, SUMA_DO::OP, SUMA_Boolean, SUMA_ENTRY, SUMA_EyeAxisStandard(), SUMA_GetEyeAxis(), SUMA_RETURN, SUMA_SET_GL_PROJECTION, SUMA_UpdateRotaCenter(), and SUMA_UpdateViewPoint(). Referenced by SUMA_display().
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 /* modify the rotation center */ 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 /* set the viewing points */ 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 /* This is all that is needed, the others above do not need to be updated at this stage*/ 02639 02640 /* Change the defaults of the eye axis to fit standard EyeAxis */ 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 /* force an axis drawing to set the projection matrix correctly */ 02653 SUMA_SET_GL_PROJECTION(sv); 02654 #endif 02655 02656 /* You still need to call SUMA_display via SUMA_postRedisplay but that is done after this function returns */ 02657 02658 SUMA_RETURN (YUP); 02659 } |
|
precState = SUMA_PreviState (sv); get the previous Viewing State available in sv
Definition at line 2008 of file SUMA_Engine.c. References SUMA_SurfaceViewer::CurGroupName, SUMA_ViewState::Group, LocalHead, SUMA_SurfaceViewer::N_VSv, SUMA_SurfaceViewer::State, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, SUMA_WhichState(), and SUMA_SurfaceViewer::VSv. Referenced by SUMA_input().
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 /* Now see if the upcoming one is of the same group */ 02024 if (inxt == icur) { 02025 /* back where we started */ 02026 SUMA_RETURN(inxt); 02027 } else { 02028 if (!strcmp(sv->VSv[inxt].Group, sv->CurGroupName)) { /* group match, good, go back */ 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 } |
|
Process NIML data. ------------------------------------------------------------------------ Definition at line 379 of file SUMA_niml.c. References SUMA_OVERLAY_PLANE_DATA::a, SUMA_SurfaceObject::AnatCorrect, SUMA_OVERLAY_PLANE_DATA::b, SUMA_CommonFields::Connected_v, SUMA_SurfaceViewer::CurGroupName, SUMA_OVERLAY_PLANE_DATA::DimFact, SUMA_NEW_SO_OPT::DoCenter, SUMA_NEW_SO_OPT::DoMetrics, SUMA_NEW_SO_OPT::DoNormals, SUMA_CommonFields::DsetList, SUMA_SurfaceObject::EmbedDim, SUMA_SurfaceObject::FaceSetDim, SUMA_SurfaceObject::FaceSetList, SUMA_SurfaceViewer::Focus_SO_ID, SUMA_OVERLAY_PLANE_DATA::g, SUMA_OVERLAY_PLANE_DATA::GlobalOpacity, SUMA_SurfaceObject::Group, i, SUMA_OVERLAY_PLANE_DATA::i, SUMA_NEW_SO_OPT::idcode_str, SUMA_SurfaceObject::idcode_str, IJK, SUMA_OVERLAY_PLANE_DATA::isBackGrnd, SUMA_SurfaceObject::Label, SUMA_SurfaceViewer::LinkAfniCrossHair, SUMA_SurfaceObject::LocalDomainParentID, LocalHead, SUMA_OVERLAY_PLANE_DATA::N, SUMA_SurfaceObject::N_FaceSet, SUMA_SurfaceObject::N_Node, NI_element::name, NI_group::name, NI_BYTE, NI_element_type(), NI_ELEMENT_TYPE, NI_FLOAT, NI_get_attribute(), NI_GROUP_TYPE, NI_INT, NI_sleep(), SUMA_SurfaceObject::NodeDim, SUMA_SurfaceObject::NodeList, SUMA_DO::OP, r, SUMA_OVERLAY_PLANE_DATA::r, SUMA_SurfaceViewer::ResetGLStateVariables, SE_BindCrossHair, SE_Redisplay, SE_Redisplay_AllVisible, SE_SetAfniThisSurf, SE_SetCrossHair, SE_SetSOinFocus, SE_ToggleConnected, SEF_cp, SEF_fv3, SEF_i, SEF_iv3, SEF_s, SEI_Head, SEI_In, SEI_Tail, SES_Afni, SES_Suma, SES_SumaFromAfni, SES_SumaFromAny, SUMA_OVERLAY_PLANE_DATA::Show, SO_type, SOPT_ibbb, SUMA_OVERLAY_PLANE_DATA::Source, SUMA_SurfaceObject::State, strtod(), SUMA_AddDO(), SUMA_AFNI_COLORPLANE_OPACITY, SUMA_AFNI_STREAM_INDEX, SUMA_Boolean, SUMA_copy_string(), SUMA_CreateList(), SUMA_DIM_AFNI_COLOR_FACTOR, SUMA_Engine(), SUMA_ENTRY, SUMA_findSO_inDOv(), SUMA_findSOp_inDOv(), SUMA_free, SUMA_Free_Surface_Object(), SUMA_Free_VolPar(), SUMA_FreeNewSOOpt(), SUMA_InitializeEngineListData(), SUMA_iRGB_to_OverlayPointer(), SUMA_IS_EMPTY_STR_ATTR, SUMA_LH, SUMA_LOCAL, SUMA_malloc, SUMA_MAX_COMMAND_LENGTH, SUMA_MAX_DISPLAYABLE_OBJECTS, SUMA_MAX_STRING_LENGTH, SUMA_MAX_SURF_VIEWERS, SUMA_nel_stdout(), SUMA_NewNewSOOpt(), SUMA_NewSO(), SUMA_niml_hangup(), SUMA_nimlSO2SO(), SUMA_PrepAddmappableSO(), SUMA_PrepSO_GeomProp_GL(), SUMA_RECOMPUTE_NORMALS, SUMA_REGISTER_HEAD_COMMAND_NO_DATA, SUMA_REGISTER_TAIL_COMMAND_NO_DATA, SUMA_RegisteredSOs(), SUMA_RegisterEngineListCommand(), SUMA_RegisterGroup(), SUMA_RETURN, SUMA_S_Err, SUMA_SetRemixFlag(), SUMA_SetupSVforDOs(), SUMA_SL_Crit, SUMA_SL_Err, SUMA_SL_Note, SUMA_SL_Warn, SUMA_SLP_Err, SUMA_SLP_Warn, SUMA_SOGroup_2_Spec(), SUMA_SwitchGroups(), SUMA_SwitchState(), SUMA_SurfaceObject::SUMA_VolPar_Aligned, SUMA_VolPar_Attr(), SUMA_which_stream_index(), SUMA_WhichState(), SUMA_XYZmap_XYZ(), SUMAg_N_DOv, SUMAg_N_SVv, SUMA_X::TOPLEVEL, SUMA_CommonFields::TrackingId_v, tt, SUMA_OVERLAY_PLANE_DATA::Type, NI_element::vec, NI_element::vec_filled, NI_element::vec_len, NI_element::vec_num, NI_element::vec_typ, SUMA_SurfaceObject::VolPar, and SUMA_SurfaceViewer::X. Referenced by SUMA_niml_workproc().
00380 { 00381 static char FuncName[]={"SUMA_process_NIML_data"}; 00382 int tt = NI_element_type(nini) ; 00383 int OverInd, loc_ID, iview, *IJK=NULL, N_Node, *FaceSetList=NULL, N_FaceSet; 00384 int i, I_C = -1, nodeid = -1, iv3[3], dest_SO_ID = -1, 00385 N_SOlist, SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS]; 00386 NI_element *nel = NULL ; 00387 NI_group *ngr = NULL; 00388 SUMA_EngineData *ED = NULL; 00389 DList *list = NULL; 00390 DListElmt *Elm = NULL; 00391 char CommString[SUMA_MAX_COMMAND_LENGTH], *nel_surfidcode = NULL, *nel_nodeid = NULL; 00392 char s[SUMA_MAX_STRING_LENGTH], sfield[100], sdestination[100], ssource[100]; 00393 float **fm, dimfact, *XYZ=NULL, *NodeList=NULL; 00394 byte *r, *g, *b; 00395 byte BrandNew = YUP; 00396 SUMA_NEW_SO_OPT *nsoopt=NULL; 00397 SUMA_Boolean Empty_irgba = NOPE, Found = NOPE; 00398 SUMA_SurfaceObject *SO = NULL; 00399 SUMA_SurfaceViewer *svi = NULL; 00400 SUMA_OVERLAYS * tmpptr; 00401 GLfloat *glar_ColorList = NULL; 00402 SUMA_OVERLAY_PLANE_DATA sopd; 00403 SUMA_SurfSpecFile *Spec=NULL; 00404 SUMA_Boolean iselement = YUP; 00405 SUMA_Boolean LocalHead = NOPE; 00406 00407 /*int it; 00408 float fv3[3], fv15[15];*/ 00409 /*float ft; 00410 int **im, iv15[15];*/ /* keep unused variables undeclared to quite compiler */ 00411 00412 SUMA_ENTRY; 00413 00414 if( tt < 0 ) {/* should never happen */ 00415 fprintf(SUMA_STDERR,"Error %s: Should never have happened.\n", FuncName); 00416 SUMA_RETURN(NOPE); 00417 } 00418 00419 00420 SUMA_LH("Checking on nini type"); 00421 /* check if group or element */ 00422 if(tt == NI_GROUP_TYPE) { 00423 iselement = NOPE; 00424 SUMA_LH("Dealing with group"); 00425 } else if (tt == NI_ELEMENT_TYPE) { 00426 iselement = YUP; 00427 SUMA_LH("Dealing with element"); 00428 } else { 00429 fprintf(SUMA_STDERR,"Error %s: Not an element, nor a group. What the hell are you doing?\n", FuncName); 00430 SUMA_RETURN(NOPE); 00431 } 00432 00433 00434 if (iselement) { 00435 /* if here, have a single data element; 00436 process the data based on the element name */ 00437 00438 nel = (NI_element *) nini ; 00439 00440 if (LocalHead) { 00441 fprintf(SUMA_STDERR,"%s: name=%s vec_len=%d vec_filled=%d, vec_num=%d\n", FuncName,\ 00442 nel->name, nel->vec_len, nel->vec_filled, nel->vec_num ); 00443 } 00444 00445 /*--- stream closer ---*/ 00446 if( strcmp(nel->name,"CloseKillStream") == 0) { /* CloseKillStream */ 00447 if (LocalHead) fprintf (SUMA_STDERR,"%s:\nClosing then killing stream %s ...\n", 00448 FuncName, NI_get_attribute(nel, "ni_stream_name")); 00449 if (!SUMA_niml_hangup (SUMAg_CF, NI_get_attribute(nel, "ni_stream_name"), NOPE, YUP)) { 00450 SUMA_SL_Err("Failed in SUMA_niml_hangup.\n"); 00451 SUMA_RETURN(NOPE); 00452 } 00453 SUMA_RETURN(YUP); 00454 } /* CloseStreamKill */ 00455 00456 /*--- stream tracking ON ---*/ 00457 if( strcmp(nel->name,"StartTracking") == 0) { /* Start tracking */ 00458 if (LocalHead) fprintf (SUMA_STDERR,"%s:\n Starting NI element tracking for %s ...\n", 00459 FuncName, NI_get_attribute(nel, "ni_stream_name")); 00460 i = SUMA_which_stream_index(SUMAg_CF, NI_get_attribute(nel, "ni_stream_name")); 00461 if ( i < 0) { 00462 SUMA_SL_Err("Failed to find stream!\n"); 00463 SUMA_RETURN(NOPE); 00464 } 00465 if (NI_get_attribute(nel, "Tracking_ID")) { 00466 if (atoi(NI_get_attribute(nel, "Tracking_ID")) != 1) { 00467 SUMA_SL_Err("First tracking element is not 1.\nTracking ignored.\n"); 00468 SUMA_RETURN(YUP); 00469 } 00470 } 00471 SUMA_LH("Tracking on ..."); 00472 SUMAg_CF->TrackingId_v[i] = 1; /* this is to be the first element ! */ 00473 SUMA_RETURN(YUP); 00474 } /* Start tracking */ 00475 00476 /*--- stream tracking OFF ---*/ 00477 if( strcmp(nel->name,"StopTracking") == 0) { /* Stop tracking */ 00478 if (LocalHead) fprintf (SUMA_STDERR,"%s:\n Stopping NI element tracking for %s ...\n", 00479 FuncName, NI_get_attribute(nel, "ni_stream_name")); 00480 i = SUMA_which_stream_index(SUMAg_CF, NI_get_attribute(nel, "ni_stream_name")); 00481 if ( i < 0) { 00482 SUMA_SL_Err("Failed to find stream!\n"); 00483 SUMA_RETURN(NOPE); 00484 } 00485 SUMA_LH("Tracking Off ..."); 00486 SUMAg_CF->TrackingId_v[i] = 0; /* this is to be the first element ! */ 00487 SUMA_RETURN(YUP); 00488 } /* Stop tracking */ 00489 00490 /*--- CrossHair XYZ --- */ 00491 if( strcmp(nel->name,"SUMA_crosshair_xyz") == 0) {/* SUMA_crosshair_xyz */ 00492 /* Do it for all viewers */ 00493 for (iview = 0; iview < SUMAg_N_SVv; ++iview) { 00494 svi = &(SUMAg_SVv[iview]); 00495 if (svi->LinkAfniCrossHair) {/* link cross hair */ 00496 /* look for the surface idcode */ 00497 nel_surfidcode = NI_get_attribute(nel, "surface_idcode"); 00498 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) nel_surfidcode = NI_get_attribute(nel, "Parent_ID"); 00499 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) { 00500 if (LocalHead) fprintf(SUMA_STDERR,"%s: surface_idcode missing in nel (%s), using svi->Focus_SO_ID.\n", FuncName, nel->name); 00501 dest_SO_ID = svi->Focus_SO_ID; /* default */ 00502 } else { 00503 /* first try to find out if one of the displayed surfaces has a parent equal to nel_surfidcode */ 00504 if (LocalHead) fprintf (SUMA_STDERR,"%s: Searching displayed surfaces.\n", FuncName); 00505 Found = NOPE; 00506 i = 0; 00507 N_SOlist = SUMA_RegisteredSOs(svi, SUMAg_DOv, SOlist); 00508 while (i < N_SOlist && !Found) { 00509 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP); 00510 if (strcmp(nel_surfidcode, SO->LocalDomainParentID) == 0) { 00511 Found = YUP; 00512 dest_SO_ID = SOlist[i]; 00513 } 00514 ++i; 00515 } 00516 /* if not found, look for any DO */ 00517 if (!Found) { 00518 if (LocalHead) fprintf (SUMA_STDERR,"%s: None of the displayed surfaces (or their parents) match nel_surfidcode. Trying all of DOv...\n", FuncName); 00519 dest_SO_ID = SUMA_findSO_inDOv (nel_surfidcode, SUMAg_DOv, SUMAg_N_DOv); 00520 if (dest_SO_ID < 0) { 00521 if (LocalHead) fprintf(SUMA_STDERR,"%s:%s: nel idcode is not found in DOv.\n", FuncName, nel->name); 00522 dest_SO_ID = svi->Focus_SO_ID; 00523 } else { /* good, set SO accordingly */ 00524 if (LocalHead) fprintf(SUMA_STDOUT,"%s: DOv[%d] Matched idcode\n", FuncName, dest_SO_ID); 00525 } 00526 } 00527 } 00528 00529 SO = (SUMA_SurfaceObject *)(SUMAg_DOv[dest_SO_ID].OP); 00530 00531 if (LocalHead) SUMA_nel_stdout (nel); 00532 00533 /* check for node id */ 00534 nel_nodeid = NI_get_attribute (nel, "surface_nodeid"); 00535 if (!nel_nodeid) nodeid = -1; 00536 else { 00537 if (strlen(nel_nodeid)) nodeid = (int)strtod(nel_nodeid, NULL); 00538 else nodeid = -1; 00539 } 00540 00541 /*-- check element for suitability --*/ 00542 if( nel->vec_len < 1 || nel->vec_filled < 1) { /* empty element? */ 00543 SUMA_SLP_Warn ("Empty crosshair xyz.\n"); 00544 SUMA_RETURN(YUP); 00545 } 00546 00547 if( nel->vec_len != 3 || nel->vec_num != 1 || nel->vec_typ[0] != NI_FLOAT) { 00548 SUMA_SLP_Err( "SUMA_crosshair_xyz requires\n" 00549 "3 floats in one vector.\n"); 00550 SUMA_RETURN(NOPE); 00551 } 00552 00553 00554 /* nodeid is supplied, even if the distance from the cross hair to the node is large, 00555 set a limit */ 00556 if (nodeid >= 0) { 00557 SUMA_LH("Node index courtesy of AFNI"); 00558 /* get the XYZ on the mapping reference */ 00559 I_C = -1; 00560 XYZ = SUMA_XYZmap_XYZ (nel->vec[0], SO, SUMAg_DOv, SUMAg_N_DOv, &I_C); 00561 if (!XYZ) { 00562 SUMA_SL_Warn("AFNI cross hair too\n" 00563 "far from surface.\n" 00564 "No action taken."); 00565 XBell (XtDisplay (sv->X->TOPLEVEL), 50); 00566 SUMA_RETURN(YUP); 00567 } 00568 I_C = nodeid; /* node index is set by AFNI */ 00569 } else { 00570 SUMA_LH("Searching for node index."); 00571 /* set the cross hair XYZ for now and let SUMA_XYZmap_XYZ set the node index*/ 00572 I_C = -1; 00573 XYZ = SUMA_XYZmap_XYZ (nel->vec[0], SO, SUMAg_DOv, SUMAg_N_DOv, &I_C); 00574 00575 if (XYZ == NULL || I_C < 0) { 00576 SUMA_SL_Warn("AFNI cross hair too\n" 00577 "far from surface.\n" 00578 "No action taken."); 00579 XBell (XtDisplay (sv->X->TOPLEVEL), 50); 00580 SUMA_RETURN(YUP); 00581 } 00582 } 00583 00584 /* attach the cross hair to the selected surface */ 00585 #if 0 00586 if (nel_surfidcode == NULL) { 00587 fprintf(SUMA_STDERR,"Error %s: surface_idcode missing in nel (%s).\nLoose Crosshair\n", FuncName, nel->name); 00588 iv3[0] = -1; 00589 } else { 00590 iv3[0] = dest_SO_ID; 00591 } 00592 #else 00593 iv3[0] = dest_SO_ID; /* nel_surfidcode == NULL is handled above, May 15 03*/ 00594 #endif 00595 00596 iv3[1] = I_C; /* use the closest node for a link otherwise when you switch states, you'll get a wandering cross hair */ 00597 if (!list) list = SUMA_CreateList(); 00598 ED = SUMA_InitializeEngineListData (SE_BindCrossHair); 00599 if (!SUMA_RegisterEngineListCommand ( list, ED, 00600 SEF_iv3, (void*)iv3, 00601 SES_SumaFromAfni, (void *)svi, NOPE, 00602 SEI_Head, NULL)) { 00603 fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName); 00604 SUMA_RETURN (NOPE); 00605 } 00606 00607 /* send cross hair coordinates */ 00608 ED = SUMA_InitializeEngineListData (SE_SetCrossHair); 00609 if (!SUMA_RegisterEngineListCommand ( list, ED, 00610 SEF_fv3, (void*)XYZ, 00611 SES_SumaFromAfni, svi, NOPE, 00612 SEI_Tail, NULL)) { 00613 fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName); 00614 SUMA_RETURN (NOPE); 00615 } 00616 00617 svi->ResetGLStateVariables = YUP; 00618 00619 #if 0 00620 /* logic for that not too clear yet */ 00621 /* set the SO in Focus */ 00622 ED = SUMA_InitializeEngineListData (SE_SetSOinFocus); 00623 if (!SUMA_RegisterEngineListCommand ( list, ED, 00624 SEF_i, (void*)&dest_SO_ID, 00625 SES_SumaFromAfni, (void *)svi, NOPE, 00626 SEI_Tail, NULL)) { 00627 fprintf(SUMA_STDERR,"Error %s: Failed to register element\n", FuncName); 00628 SUMA_RETURN (NOPE); 00629 } 00630 #endif 00631 00632 SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay, SES_SumaFromAfni, svi); 00633 if (!SUMA_Engine (&list)) { 00634 fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName); 00635 } 00636 00637 } /* link cross hair */ 00638 } /* iview ... for all viewers */ 00639 /* don't free nel, it's freed later on 00640 dont't free attributes obtained in NI_get_attribute, they are copies of pointers in nel */ 00641 SUMA_RETURN(YUP) ; 00642 }/* SUMA_crosshair_xyz */ 00643 00644 /* New surface mesh_IJK, This one is now obsolete, along with NewNode_XYZ, they were used to send a surface in chunks, now 00645 I can send an entire surface. Look at commented out section in SUMA_Mesh_IJK2Mesh_IJK_nel if you want to reuse this chunk*/ 00646 if (strcmp(nel->name,"NewMesh_IJK") == 0) { /* NewMesh_IJK */ 00647 SUMA_SL_Err("Element obsolete. Please use SUMA_SurfaceObject"); 00648 SUMA_RETURN(NOPE) ; 00649 if( nel->vec_len < 1 || nel->vec_filled < 1) { /* empty element? */ 00650 fprintf(SUMA_STDERR,"%s: Empty NewMesh_IJK\n", FuncName); 00651 SUMA_RETURN(NOPE); 00652 }else { 00653 if( nel->vec_num != 1 || nel->vec_typ[0] != NI_INT) { 00654 fprintf(SUMA_STDERR,"%s: NewMesh_IJK Bad format\n", FuncName); 00655 SUMA_RETURN(NOPE); 00656 } 00657 } 00658 /* show me nel */ 00659 /* if (LocalHead) SUMA_nel_stdout (nel); */ 00660 /* look for the surface idcode */ 00661 nel_surfidcode = NI_get_attribute(nel, "surface_idcode"); 00662 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) nel_surfidcode = NI_get_attribute(nel, "Parent_ID"); 00663 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) { 00664 fprintf(SUMA_STDERR,"Error %s: surface_idcode missing in nel (%s).\n", FuncName, nel->name); 00665 SUMA_RETURN(NOPE); 00666 } 00667 00668 SUMA_LH("Checking for new surface..."); 00669 SO = SUMA_findSOp_inDOv (nel_surfidcode, SUMAg_DOv, SUMAg_N_DOv); 00670 if (SO) { 00671 fprintf(SUMA_STDERR,"Warning %s: nel idcode was found in DOv.\nChecking for mesh compatibility\n", FuncName); 00672 if (SO->N_FaceSet * SO->FaceSetDim == nel->vec_len) { 00673 fprintf(SUMA_STDERR,"Note %s: Mesh dimensions match. New mesh will be adopted.\n", FuncName); 00674 } else { 00675 fprintf(SUMA_STDERR,"Error %s: Mesh dimensions mismatch.\n", FuncName); 00676 SUMA_RETURN(NOPE); 00677 } 00678 } 00679 00680 /* get the number of nodes */ 00681 if (!NI_get_attribute(nel, "N_Node")) { 00682 fprintf(SUMA_STDERR,"Error %s: NULL or non existent N_Node field.\n", FuncName); 00683 SUMA_RETURN(NOPE); 00684 } 00685 00686 if (LocalHead) fprintf(SUMA_STDERR,"Number of nodes:%s...\n", NI_get_attribute(nel, "N_Node")); 00687 N_Node = atoi(NI_get_attribute(nel, "N_Node")); 00688 if (N_Node <= 0 || N_Node > 1000000) { 00689 fprintf(SUMA_STDERR,"Error %s: Bad number of nodes %d (limit of 1000000 nodes.)\n", FuncName, N_Node); 00690 SUMA_RETURN(NOPE); 00691 } 00692 00693 if (!SO) { 00694 SUMA_LH("A brand new surface."); 00695 BrandNew = YUP; 00696 NodeList = (float *)SUMA_malloc(3 * N_Node * sizeof(float)); /* do not use calloc so that you can see something ... */ 00697 FaceSetList = (int *)SUMA_malloc(nel->vec_len * sizeof(int)); 00698 if (!NodeList || !FaceSetList) { 00699 SUMA_SL_Crit("Failed to allocate for NodeList || FaceSetList"); 00700 SUMA_RETURN(NOPE); 00701 } 00702 IJK = (int *)nel->vec[0]; 00703 N_FaceSet = nel->vec_len / 3; 00704 if (nel->vec_len % 3) { 00705 fprintf(SUMA_STDERR,"Error %s: Bad number of elements in IJK vector not divisible by 3! %d\n", FuncName, nel->vec_len); 00706 SUMA_RETURN(NOPE); 00707 } 00708 SUMA_LH("Copying new mesh"); 00709 for (i=0; i < nel->vec_len; ++i) FaceSetList[i] = IJK[i]; 00710 /* Now form the new surface */ 00711 SUMA_LH("Now forming new surface"); 00712 nsoopt = SUMA_NewNewSOOpt(); 00713 nsoopt->DoNormals = NOPE; nsoopt->DoMetrics = NOPE; nsoopt->DoCenter = NOPE; 00714 nsoopt->idcode_str = SUMA_copy_string(nel_surfidcode); 00715 SO = SUMA_NewSO(&NodeList, N_Node, &FaceSetList, N_FaceSet, nsoopt); 00716 nsoopt=SUMA_FreeNewSOOpt(nsoopt); 00717 } else { 00718 SUMA_LH("A refit of an existing surface."); 00719 BrandNew = NOPE; 00720 if (N_Node != SO->N_Node) { 00721 fprintf(SUMA_STDERR,"Error %s: Mismatch in number of nodes between new mesh and pre-existing one (%d vs %d)\n", FuncName, N_Node, SO->N_Node); 00722 SUMA_RETURN(NOPE); 00723 } 00724 IJK = (int *)nel->vec[0]; 00725 for (i=0; i < nel->vec_len; ++i) SO->FaceSetList[i] = IJK[i]; 00726 } 00727 00728 /* work the mesh a little and add it to DOv NO LONGER DONE HERE...*/ 00729 SO->Group = SUMA_copy_string(NI_get_attribute(nel, "Group")); 00730 if (!SO->Group) SO->Group = SUMA_copy_string(NI_get_attribute(nel, "Subject_Label")); 00731 SO->State = SUMA_copy_string(NI_get_attribute(nel, "State")); 00732 if (!SO->State) SO->State = SUMA_copy_string(NI_get_attribute(nel, "Layer_Name")); 00733 SO->Label = SUMA_copy_string(NI_get_attribute(nel, "Label")); 00734 if (!SO->Label) SO->Label = SUMA_copy_string(NI_get_attribute(nel, "Object_Label")); 00735 SO->EmbedDim = atoi(NI_get_attribute(nel, "EmbedDim")); 00736 if (!SO->EmbedDim) SO->EmbedDim = atoi(NI_get_attribute(nel, "Embedding_Dimension")); 00737 SO->AnatCorrect = atoi(NI_get_attribute(nel, "AnatCorrect")); 00738 if (!SO->AnatCorrect) { 00739 char *tmp = NI_get_attribute(nel, "Anatomically_Correct"); 00740 if (tmp) { 00741 if (strstr(tmp,"yes")) SO->AnatCorrect = 1; 00742 else if (strstr(tmp,"no")) SO->AnatCorrect = 0; 00743 } 00744 } 00745 /* add this surface to DOv */ 00746 if (BrandNew) { 00747 if (!SUMA_AddDO(SUMAg_DOv, &(SUMAg_N_DOv), (void *)SO, SO_type, SUMA_LOCAL)) { 00748 fprintf(SUMA_STDERR,"Error %s: Error Adding DO\n", FuncName); 00749 SUMA_RETURN(NOPE); 00750 } 00751 } 00752 00753 /* don't free nel, it's freed later on */ 00754 SUMA_RETURN(YUP) ; 00755 }/* NewMesh_IJK */ 00756 00757 if (strcmp(nel->name,"PrepNewSurface") == 0) { /* PrepNewSurface */ 00758 /* show me nel */ 00759 /* if (LocalHead) SUMA_nel_stdout (nel); */ 00760 /* look for the surface idcode */ 00761 nel_surfidcode = NI_get_attribute(nel, "surface_idcode"); 00762 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) nel_surfidcode = NI_get_attribute(nel, "Parent_ID"); 00763 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) { 00764 fprintf(SUMA_STDERR,"Error %s: surface_idcode missing in nel (%s).\n", FuncName, nel->name); 00765 SUMA_RETURN(NOPE); 00766 } 00767 SUMA_LH("Looking for surface..."); 00768 SO = SUMA_findSOp_inDOv (nel_surfidcode, SUMAg_DOv, SUMAg_N_DOv); 00769 if (!SO) { 00770 fprintf(SUMA_STDERR,"Error %s: nel idcode was not found in DOv.\n", FuncName); 00771 SUMA_RETURN(NOPE); 00772 } 00773 00774 if (LocalHead) fprintf(SUMA_STDERR,"%s: Surface SO about to be prepped: Label %s, State %s, Group %s\n", FuncName, SO->Label, SO->State, SO->Group); 00775 00776 #if 0 00777 if (NI_get_attribute(nel, "VolParFilecode")) { 00778 SO->VolPar = SUMA_VolPar_Attr (NI_get_attribute(nel, "VolParFilecode")); 00779 if (!SO->VolPar) { 00780 SUMA_S_Err("Failed in SUMA_VolPar_Attr"); 00781 SUMA_RETURN(NOPE); 00782 } 00783 SO->SUMA_VolPar_Aligned = YUP; /* Surface should already be in alignment with volume, should not call SUMA_Align_to_VolPar ... */ 00784 } 00785 #else 00786 /* VolPar should have been dealt with by now */ 00787 if (!SO->VolPar) SO->SUMA_VolPar_Aligned = NOPE; 00788 else SO->SUMA_VolPar_Aligned = YUP; /* Surface should already be in alignment with volume, should not call SUMA_Align_to_VolPar ... */ 00789 #endif 00790 00791 /* make this surface friendly for suma */ 00792 if (!SUMA_PrepSO_GeomProp_GL(SO)) { 00793 SUMA_S_Err("Failed in SUMA_PrepSO_GeomProp_GL"); 00794 SUMA_RETURN(NOPE); 00795 } 00796 /* Add this surface to SUMA's displayable objects */ 00797 if (!SUMA_PrepAddmappableSO(SO, SUMAg_DOv, &(SUMAg_N_DOv), 0, SUMAg_CF->DsetList)) { 00798 SUMA_S_Err("Failed to add mappable SOs "); 00799 SUMA_RETURN(NOPE); 00800 } 00801 /* create a fake spec, be damned gates of spec! */ 00802 Spec = SUMA_SOGroup_2_Spec (&SO, 1); 00803 00804 /* register the new group with SUMA */ 00805 if (!SUMA_RegisterGroup(SUMAg_CF, Spec)) { 00806 SUMA_SL_Err("Failed to register group"); 00807 SUMA_RETURN(NOPE); 00808 } 00809 00810 /* Register the surfaces in Spec file with the surface viewer and perform setups */ 00811 if (LocalHead) fprintf (SUMA_STDERR, "%s: Registering surfaces with surface viewers ...\n", FuncName); 00812 00813 for (i = 0; i< SUMA_MAX_SURF_VIEWERS; ++i) { 00814 if (!SUMA_SetupSVforDOs (*Spec, SUMAg_DOv, SUMAg_N_DOv, &(SUMAg_SVv[i]))) { 00815 fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_SetupSVforDOs function.\n", FuncName); 00816 SUMA_RETURN(NOPE); 00817 } 00818 } 00819 00820 /* do not switch or redisplay yet, all you have is garbage for geometry ... */ 00821 SUMA_free(Spec); Spec = NULL; 00822 00823 /* switch viewer 0 to the group in question */ 00824 if (!sv) sv = &(SUMAg_SVv[0]); 00825 if (!SUMA_SwitchGroups (sv, SO->Group)) { 00826 SUMA_SL_Err("Failed to switch groups!"); 00827 SUMA_RETURN(NOPE); 00828 } 00829 if ((i = SUMA_WhichState(SO->State, sv, sv->CurGroupName)) < 0) { 00830 SUMA_SL_Err("Failed to find state!"); 00831 SUMA_RETURN(NOPE); 00832 } else { 00833 if (!SUMA_SwitchState(SUMAg_DOv, SUMAg_N_DOv, sv, i, sv->CurGroupName)) { 00834 SUMA_SL_Err("Failed to switch states!"); 00835 SUMA_RETURN(NOPE); 00836 } 00837 } 00838 00839 /* do we need to notify AFNI ? */ 00840 if (NI_get_attribute(nel, "Send2Afni")) { 00841 SUMA_LH("Attempting to talk to AFNI"); 00842 if (!SO->VolPar) { 00843 SUMA_SL_Err("Have no VolPar, cannot send to AFNI!\nCommand ignored."); 00844 } else { 00845 if (!SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX]) { /* need to send a toggle request */ 00846 if (LocalHead) fprintf(SUMA_STDERR, "%s: Sending talk request...\n", FuncName); 00847 if (!list) list = SUMA_CreateList(); 00848 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_ToggleConnected, SES_SumaFromAny, sv); 00849 if (!SUMA_Engine (&list)) { 00850 fprintf(SUMA_STDERR, "Warning %s: SUMA_Engine call failed.\nContinuing...", FuncName); 00851 } 00852 } else { 00853 SUMA_LH("Looks like they're talking already"); 00854 } 00855 /* now send the surface */ 00856 SUMA_LH("Now trying to send surface"); 00857 if (!SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX]) { 00858 fprintf(SUMA_STDERR, "Warning %s: Failed to open connection.\nContinuing...", FuncName); 00859 } else { 00860 SUMA_LH("Making Call"); 00861 if (!list) list = SUMA_CreateList(); 00862 ED = SUMA_InitializeEngineListData (SE_SetAfniThisSurf); 00863 if (!( Elm = SUMA_RegisterEngineListCommand ( list, ED, 00864 SEF_cp, (void *)SO->idcode_str, 00865 SES_Suma, NULL, NOPE, 00866 SEI_Tail, NULL ))) { 00867 fprintf(SUMA_STDERR,"Error %s: Failed to register command\nIgnoring ...", FuncName); 00868 }else { 00869 int ti= 0; 00870 SUMA_RegisterEngineListCommand ( list, ED, 00871 SEF_s, (void *)("NodeList, FaceSetList, NodeNormList"), 00872 SES_Suma, NULL, NOPE, 00873 SEI_In, Elm ); 00874 SUMA_RegisterEngineListCommand ( list, ED, 00875 SEF_i, (void *)&ti, /* 0, be quiet about it */ 00876 SES_Suma, NULL, NOPE, 00877 SEI_In, Elm ); 00878 if (!SUMA_Engine (&list)) { 00879 fprintf(SUMA_STDERR, "Warning %s: SUMA_Engine call failed.\nContinuing...", FuncName); 00880 } 00881 } 00882 } 00883 } 00884 } else { 00885 SUMA_LH("No talking to AFNI requested."); 00886 } 00887 /* don't free nel, it's freed later on */ 00888 SUMA_RETURN(YUP) ; 00889 } /* PrepNewSurface */ 00890 00891 /* NewNode_XYZ NOW OBSOLETE, see comment for NewMesh_IJK*/ 00892 if( strcmp(nel->name,"NewNode_XYZ") == 0) {/* NewNode_XYZ */ 00893 SUMA_SL_Err("Obsolete element, please use SUMA_SurfaceObject element instead"); 00894 SUMA_RETURN(NOPE); 00895 if( nel->vec_len < 1 || nel->vec_filled < 1) { /* empty element? */ 00896 fprintf(SUMA_STDERR,"%s: Empty NewNode_XYZ\n", FuncName); 00897 SUMA_RETURN(NOPE); 00898 }else { 00899 if( nel->vec_num != 1 || nel->vec_typ[0] != NI_FLOAT) { 00900 fprintf(SUMA_STDERR,"%s: NewNode_XYZ Bad format\n", FuncName); 00901 SUMA_RETURN(NOPE); 00902 } 00903 } 00904 /* show me nel */ 00905 /* if (LocalHead) SUMA_nel_stdout (nel); */ 00906 00907 /* look for the surface idcode */ 00908 nel_surfidcode = NI_get_attribute(nel, "surface_idcode"); 00909 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) nel_surfidcode = NI_get_attribute(nel, "Parent_ID"); 00910 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) { 00911 fprintf(SUMA_STDERR,"Error %s: surface_idcode missing in nel (%s).\n", FuncName, nel->name); 00912 SUMA_RETURN(NOPE); 00913 } 00914 00915 SO = SUMA_findSOp_inDOv (nel_surfidcode, SUMAg_DOv, SUMAg_N_DOv); 00916 if (!SO) { 00917 fprintf(SUMA_STDERR,"Error %s:%s: nel idcode is not found in DOv.\n", FuncName, nel->name); 00918 SUMA_RETURN(NOPE); 00919 } 00920 00921 /* now copy the new node coordinates over the old ones */ 00922 if (nel->vec_len != SO->N_Node * 3) { 00923 fprintf(SUMA_STDERR,"Error %s:\nExpected %d * 3 = %d values, found %d\n", 00924 FuncName, SO->N_Node, SO->N_Node * 3, nel->vec_len); 00925 SUMA_RETURN(NOPE); 00926 } 00927 00928 XYZ = (float *)nel->vec[0]; 00929 for (i=0; i < nel->vec_len; ++i) SO->NodeList[i] = XYZ[i]; 00930 00931 /* don't free nel, it's freed later on */ 00932 SUMA_RETURN(YUP) ; 00933 } /* NewNode_XYZ */ 00934 00935 /* Node_XYZ */ 00936 if( strcmp(nel->name,"Node_XYZ") == 0) {/* Node_XYZ */ 00937 if( nel->vec_len < 1 || nel->vec_filled < 1) { /* empty element? */ 00938 fprintf(SUMA_STDERR,"%s: Empty Node_XYZ\n", FuncName); 00939 SUMA_RETURN(NOPE); 00940 }else { 00941 if( nel->vec_num != 1 || nel->vec_typ[0] != NI_FLOAT) { 00942 fprintf(SUMA_STDERR,"%s: Node_XYZ Bad format\n", FuncName); 00943 SUMA_RETURN(NOPE); 00944 } 00945 } 00946 /* show me nel */ 00947 /* if (LocalHead) SUMA_nel_stdout (nel); */ 00948 00949 /* look for the surface idcode */ 00950 nel_surfidcode = NI_get_attribute(nel, "surface_idcode"); 00951 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) nel_surfidcode = NI_get_attribute(nel, "Parent_ID"); 00952 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) { 00953 fprintf(SUMA_STDERR,"Error %s: surface_idcode missing in nel (%s).\n", FuncName, nel->name); 00954 SUMA_RETURN(NOPE); 00955 } 00956 00957 SO = SUMA_findSOp_inDOv (nel_surfidcode, SUMAg_DOv, SUMAg_N_DOv); 00958 if (!SO) { 00959 fprintf(SUMA_STDERR,"Error %s:%s: nel idcode is not found in DOv.\n", FuncName, nel->name); 00960 SUMA_RETURN(NOPE); 00961 } 00962 00963 /* now copy the new node coordinates over the old ones */ 00964 if (nel->vec_len != SO->N_Node * 3) { 00965 fprintf(SUMA_STDERR,"Error %s:\nExpected %d * 3 = %d values, found %d\n", 00966 FuncName, SO->N_Node, SO->N_Node * 3, nel->vec_len); 00967 SUMA_RETURN(NOPE); 00968 } 00969 00970 XYZ = (float *)nel->vec[0]; 00971 for (i=0; i < nel->vec_len; ++i) SO->NodeList[i] = XYZ[i]; 00972 00973 /* must recompute normals */ 00974 SUMA_RECOMPUTE_NORMALS(SO); 00975 00976 /* file a redisplay request */ 00977 if (LocalHead) fprintf(SUMA_STDERR, "%s: Redisplaying all visible...\n", FuncName); 00978 if (!list) list = SUMA_CreateList(); 00979 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible, SES_SumaFromAny, sv); 00980 if (NI_get_attribute(nel, "Send2Afni")) { 00981 if (SUMAg_CF->Connected_v[SUMA_AFNI_STREAM_INDEX]) { 00982 SUMA_LH("Putting request for sending to afni ..."); 00983 ED = SUMA_InitializeEngineListData (SE_SetAfniThisSurf); 00984 if (!( Elm = SUMA_RegisterEngineListCommand ( list, ED, 00985 SEF_cp, (void *)SO->idcode_str, 00986 SES_Suma, NULL, NOPE, 00987 SEI_Tail, NULL ))) { 00988 fprintf(SUMA_STDERR,"Error %s: Failed to register command\n", FuncName); 00989 SUMA_RETURN(NOPE); 00990 } 00991 00992 /* You could save time and not send the NodeNormList but that means AFNI 00993 will end up with a bad set of normals for the final version of the surface 00994 not a good idea... */ 00995 SUMA_RegisterEngineListCommand ( list, ED, 00996 SEF_s, (void *)("NodeList, NodeNormList"), 00997 SES_Suma, NULL, NOPE, 00998 SEI_In, Elm ); 00999 { int ti = 0; /* keep it quiet */ 01000 SUMA_RegisterEngineListCommand ( list, ED, 01001 SEF_i, (void *)&ti, 01002 SES_Suma, NULL, NOPE, 01003 SEI_In, Elm ); 01004 } 01005 } else { 01006 if (LocalHead) { 01007 SUMA_SL_Note("Cannot send surface to afni, no connection established"); 01008 } 01009 } 01010 } 01011 01012 if (!SUMA_Engine (&list)) { 01013 fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName); 01014 SUMA_RETURN(NOPE); 01015 } 01016 01017 /* don't free nel, it's freed later on */ 01018 SUMA_RETURN(YUP) ; 01019 01020 01021 }/* Node_XYZ */ 01022 01023 /* SUMA_irgba Node colors */ 01024 if( strcmp(nel->name,"SUMA_irgba") == 0 || strcmp(nel->name,"Node_RGBAb") == 0) {/* SUMA_irgba */ 01025 if( nel->vec_len < 1 || nel->vec_filled < 1) { /* empty element? */ 01026 fprintf(SUMA_STDERR,"%s: Empty SUMA_irgba.\n", FuncName); 01027 Empty_irgba = YUP; 01028 }else { 01029 if( nel->vec_num != 5 || nel->vec_typ[0] != NI_INT || nel->vec_typ[1] != NI_BYTE || nel->vec_typ[2] != NI_BYTE || nel->vec_typ[3] != NI_BYTE) { 01030 fprintf(SUMA_STDERR,"%s: SUMA_irgba Bad format\n", FuncName); 01031 SUMA_RETURN(NOPE); 01032 } 01033 } 01034 #if SUMA_SUMA_NIML_DEBUG 01035 fprintf(SUMA_STDERR,"Warning %s:\nSleeping ONLY ...\n", FuncName); 01036 NI_sleep(200); 01037 SUMA_RETURN(YUP); 01038 01039 01040 if (0) { /* At times, I found the value in nel->vec[0] to be corrupted, use this to check on it */ 01041 int *ibad; 01042 ibad = (int *)nel->vec[0]; 01043 fprintf (SUMA_STDERR,"ibad[0] = %d\n", ibad[0]); 01044 } 01045 #endif 01046 01047 /* show me nel */ 01048 /* if (LocalHead) SUMA_nel_stdout (nel); */ 01049 01050 /* look for the surface idcode */ 01051 nel_surfidcode = NI_get_attribute(nel, "surface_idcode"); 01052 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) nel_surfidcode = NI_get_attribute(nel, "Parent_ID"); 01053 if (SUMA_IS_EMPTY_STR_ATTR(nel_surfidcode)) { 01054 fprintf(SUMA_STDERR,"Error %s: surface_idcode missing in nel (%s).\n", FuncName, nel->name); 01055 SUMA_RETURN(NOPE); 01056 } 01057 01058 SO = SUMA_findSOp_inDOv (nel_surfidcode, SUMAg_DOv, SUMAg_N_DOv); 01059 if (!SO) { 01060 fprintf(SUMA_STDERR,"Error %s:%s: nel idcode is not found in DOv.\n", FuncName, nel->name); 01061 SUMA_RETURN(NOPE); 01062 } 01063 01064 /* store the node colors */ 01065 /* create a color overlay plane */ 01066 /* you could create an overlay plane with partial node coverage but you'd have to clean up and SUMA_reallocate 01067 with each new data sent since the number of colored nodes will change. So I'll allocate for the entire node list 01068 for the FuncAfni_0 color plane although only some values will be used*/ 01069 01070 sopd.Type = SOPT_ibbb; 01071 sopd.Source = SES_Afni; 01072 sopd.GlobalOpacity = SUMA_AFNI_COLORPLANE_OPACITY; 01073 sopd.isBackGrnd = NOPE; 01074 sopd.Show = YUP; 01075 /* dim colors from maximum intensity to preserve surface shape highlights, 01076 division by is no longer necessary. 01077 */ 01078 sopd.DimFact = SUMA_DIM_AFNI_COLOR_FACTOR; 01079 if (!Empty_irgba) { 01080 sopd.i = (void *)nel->vec[0]; 01081 sopd.r = (void *)nel->vec[1]; 01082 sopd.g = (void *)nel->vec[2]; 01083 sopd.b = (void *)nel->vec[3]; 01084 sopd.a = NULL; 01085 sopd.N = nel->vec_len; 01086 } else { 01087 sopd.i = sopd.r = sopd.g = sopd.b = sopd.a = NULL; 01088 sopd.N = 0; 01089 } 01090 01091 if (!SUMA_iRGB_to_OverlayPointer (SO, "FuncAfni_0", &sopd, &OverInd, SUMAg_DOv, SUMAg_N_DOv, SUMAg_CF->DsetList)) { 01092 SUMA_SLP_Err("Failed to fetch or create overlay pointer."); 01093 SUMA_RETURN(NOPE); 01094 } 01095 01096 01097 /* register a color remix request */ 01098 if (LocalHead) fprintf(SUMA_STDERR, "%s: Setting Remix Flag for all related surfaces. ...\n", FuncName); 01099 if(!SUMA_SetRemixFlag (SO->idcode_str, SUMAg_SVv, SUMAg_N_SVv)) { 01100 fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SetRemixFlag.\n", FuncName); 01101 SUMA_RETURN(NOPE); 01102 } 01103 01104 /* file a redisplay request */ 01105 if (LocalHead) fprintf(SUMA_STDERR, "%s: Redisplaying all visible...\n", FuncName); 01106 if (!list) list = SUMA_CreateList(); 01107 if (strcmp(nel->name,"SUMA_irgba") == 0) { 01108 /* call from AFNI */ 01109 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible, SES_SumaFromAfni, sv); 01110 } else { 01111 SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible, SES_SumaFromAny, sv); 01112 } 01113 01114 if (!SUMA_Engine (&list)) { 01115 fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName); 01116 SUMA_RETURN(NOPE); 01117 } 01118 01119 /* don't free nel, it's freed later on */ 01120 SUMA_RETURN(YUP) ; 01121 01122 01123 }/* SUMA_irgba */ 01124 01125 /*** If here, then name of element didn't match anything ***/ 01126 01127 fprintf(SUMA_STDERR,"Error %s: Unknown NIML input: %s\n", FuncName ,nel->name) ; 01128 SUMA_RETURN(NOPE) ; 01129 } /* end parse nels */ else { /* is group */ 01130 ngr = (NI_group *) nini ; 01131 01132 if (strcmp(ngr->name,"SurfaceObject") == 0) { /* New Surface Object */ 01133 SUMA_SurfaceObject *SOn=NULL; 01134 01135 SOn = SUMA_nimlSO2SO(ngr); 01136 if (!SOn) { 01137 SUMA_SL_Err("Failed to interpret SO"); 01138 SUMA_RETURN(NOPE) ; 01139 } 01140 01141 SUMA_LH("Checking for new surface..."); 01142 SO = SUMA_findSOp_inDOv (SOn->idcode_str, SUMAg_DOv, SUMAg_N_DOv); 01143 if (SO) { 01144 fprintf(SUMA_STDERR,"Warning %s: nel idcode was found in DOv.\nChecking for mesh compatibility\n", FuncName); 01145 if (SO->N_FaceSet * SO->FaceSetDim == SOn->N_FaceSet * SOn->FaceSetDim) { 01146 fprintf(SUMA_STDERR,"Note %s: Mesh dimensions match. New mesh will be adopted.\n", FuncName); 01147 } else { 01148 fprintf(SUMA_STDERR,"Error %s: Mesh dimensions mismatch.\n", FuncName); 01149 SUMA_RETURN(NOPE); 01150 } 01151 } 01152 01153 if (!SO) { 01154 SUMA_LH("A brand new surface."); 01155 BrandNew = YUP; 01156 } else { 01157 SUMA_LH("A refit of an existing surface."); 01158 BrandNew = NOPE; 01159 if (SOn->N_Node != SO->N_Node) { 01160 fprintf(SUMA_STDERR,"Error %s: Mismatch in number of nodes between new mesh and pre-existing one (%d vs %d)\n", FuncName, SO->N_Node, SO->N_Node); 01161 SUMA_RETURN(NOPE); 01162 } 01163 memcpy((void*)SO->FaceSetList, (void *)SOn->FaceSetList, SOn->N_FaceSet * SOn->FaceSetDim * sizeof(int)); /* this one's likely to be completely useless! */ 01164 memcpy((void*)SO->NodeList, (void *)SOn->NodeList, SOn->N_Node * SOn->NodeDim * sizeof(float)); 01165 /* swap VolPar */ 01166 if (SOn->VolPar) { 01167 if (SO->VolPar) SUMA_Free_VolPar(SO->VolPar); 01168 SO->VolPar = SOn->VolPar; 01169 SOn->VolPar = NULL; 01170 } 01171 SUMA_Free_Surface_Object(SOn); SOn = NULL; /* alas, not needed no more. 01172 Perhaps you should consider eliminating SO's EdgeLists, area vectors and the like, 01173 You should also perhaps update VolPar with SOn's... */ 01174 } 01175 01176 /* add this surface to DOv */ 01177 if (BrandNew) { 01178 if (!SUMA_AddDO(SUMAg_DOv, &(SUMAg_N_DOv), (void *)SOn, SO_type, SUMA_LOCAL)) { 01179 fprintf(SUMA_STDERR,"Error %s: Error Adding DO\n", FuncName); 01180 SUMA_RETURN(NOPE); 01181 } 01182 } 01183 01184 /* don't free nel, it's freed later on */ 01185 SUMA_RETURN(YUP) ; 01186 } 01187 01188 /*** If here, then name of group didn't match anything ***/ 01189 01190 fprintf(SUMA_STDERR,"Error %s: Unknown NIML input: %s\n", FuncName ,ngr->name) ; 01191 SUMA_RETURN(NOPE) ; 01192 } 01193 } |
|
ans = SUMA_RegisteredSOs (sv, dov, SO_IDs); gets the IDs (indices into dov) and number of the Surface Objects shown in sv
Definition at line 1866 of file SUMA_Engine.c. References SUMA_SurfaceViewer::CurGroupName, i, SUMA_SurfaceViewer::N_DO, SUMA_SurfaceViewer::RegisteredDO, SUMA_ENTRY, SUMA_isSO_G(), and SUMA_RETURN. Referenced by SUMA_Engine(), SUMA_input(), SUMA_process_NIML_data(), SUMA_SwitchState(), SUMA_UpdateViewerTitle(), and SUMA_UpdateViewerTitle_old().
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 } |
|
Replaces one surface in RegisteredDO with another Definition at line 2092 of file SUMA_Engine.c. References SUMA_SurfaceViewer::Focus_SO_ID, SUMA_DO::OP, SE_Home, SES_Suma, SUMA_Boolean, SUMA_CreateList(), SUMA_Engine(), SUMA_ENTRY, SUMA_EyeAxisStandard(), SUMA_GetEyeAxis(), SUMA_REGISTER_HEAD_COMMAND_NO_DATA, SUMA_RegisterDO(), SUMA_RETURN, SUMA_UnRegisterDO(), SUMA_UpdateRotaCenter(), SUMA_UpdateViewPoint(), SUMA_WorldAxisStandard(), and SUMA_SurfaceViewer::WAx.
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 /* unregister the current surface from RegisteredDO */ 02104 /*fprintf(SUMA_STDERR,"%s: Unregistering DOv[%d]...\n", FuncName, SOcurID);*/ 02105 if (!SUMA_UnRegisterDO(SOcurID, sv)) { 02106 fprintf(SUMA_STDERR,"Error %s: Failed to UnRegisterDO.\n", FuncName); 02107 SUMA_RETURN (NOPE); 02108 } 02109 02110 /* set the focus ID to the current surface */ 02111 sv->Focus_SO_ID = SOnxtID; 02112 02113 /* register the new surface in RegisteredDO */ 02114 /*fprintf(SUMA_STDERR,"%s: Registering DOv[%d]...\n", FuncName, sv->Focus_SO_ID); */ 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 /* modify the rotation center */ 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 /* set the viewing points */ 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 /* Change the defaults of the eye axis to fit standard EyeAxis */ 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 /* do the axis setup */ 02143 SUMA_WorldAxisStandard (sv->WAx, sv); 02144 02145 02146 /* Home call baby */ 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 /* take care of the cross hair's XYZ */ 02156 02157 /* to do elsewhere */ 02158 /* when a cross hair needs to be communicated, you must use the LocalDomainParentID surface and not the Focus_Surface */ 02159 SUMA_RETURN (YUP); 02160 } |
|
ans = SUMA_SwitchState (dov, N_dov, sv, nxtstateID, nxtgroup); Replaces one viewing state with another Definition at line 2219 of file SUMA_Engine.c. References SUMA_SurfaceViewer::Back_Modfact, SUMA_CrossHair::c, SUMA_SurfaceObject::Center, SUMA_SurfaceViewer::Ch, SUMA_SurfaceViewer::CurGroupName, SUMA_SurfaceViewer::Focus_SO_ID, i, SUMA_SurfaceObject::idcode_str, SUMA_SurfaceViewer::iState, SUMA_SurfaceObject::Label, SUMA_SurfaceObject::LocalDomainParentID, LocalHead, SUMA_SurfaceObject::MaxDims, SUMA_ViewState::MembSOs, SUMA_SurfaceObject::MinDims, SUMA_ViewState::N_MembSOs, SUMA_SurfaceObject::N_Node, SUMA_SurfaceObject::N_Overlays, SUMA_ViewState::Name, SUMA_SurfaceObject::NodeDim, SUMA_CrossHair::NodeID, SUMA_SurfaceObject::NodeList, SUMA_DO::OP, SUMA_SurfaceObject::Overlays, SE_Home, SUMA_SurfaceObject::SelectedNode, SES_Suma, SUMA_SurfaceViewer::ShowBackground, SUMA_SurfaceViewer::ShowForeground, SUMA_SurfaceViewer::State, SUMA_SurfaceViewer::StdView, SUMA_3D, SUMA_AdoptGroup(), SUMA_BestStandardView(), SUMA_Boolean, SUMA_CreateList(), SUMA_Dunno, SUMA_Engine(), SUMA_ENTRY, SUMA_EyeAxisStandard(), SUMA_findSO_inDOv(), SUMA_free, SUMA_GetEyeAxis(), SUMA_GetOverlaysFromParent(), SUMA_Init_SurfCont_CrossHair(), SUMA_Init_SurfCont_SurfParam(), SUMA_LH, SUMA_MapRefRelative(), SUMA_MAX_DISPLAYABLE_OBJECTS, SUMA_Overlays_2_GLCOLAR4(), SUMA_REGISTER_HEAD_COMMAND_NO_DATA, SUMA_RegisterDO(), SUMA_RegisteredSOs(), SUMA_RETURN, SUMA_SetShownLocalRemixFlag(), SUMA_SL_Err, SUMA_SLP_Err, SUMA_SLP_Note, SUMA_UnRegisterDO(), SUMA_UpdateRotaCenter(), SUMA_UpdateViewPoint(), SUMA_WhichState(), SUMA_WorldAxisStandard(), SUMA_XYZ_XYZmap(), SUMA_XYZmap_XYZ(), SUMAg_N_DOv, SUMA_CrossHair::SurfaceID, SUMA_SurfaceObject::SurfCont, SUMA_X_SurfCont::TopLevelShell, SUMA_SurfaceViewer::VSv, and SUMA_SurfaceViewer::WAx. Referenced by SUMA_input(), SUMA_process_NIML_data(), and SUMA_SwitchGroups().
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 /* unregister all the surfaces for the current view */ 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 /* adopt the new group */ 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 /* register all the surfaces from the next view */ 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 {/* trying to keep two surfaces from riding on top of each other - An initial pass*/ 02270 /* This method works OK but you should not be applying it to 02271 geometrically correct surfaces (like the pial surfaces whose containing 02272 boxes intersect although slightly). Since you're modifying the coordinates 02273 here, you will be throwing them out of alignment with the volume. 02274 Since I have not such field yet, this method will be put on hold for a while 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 /* find out how many SOs are registered in the current view */ 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 /* THIS IS AN EXTREMELY CRUDE TEST */ 02291 /* check if bounding boxes overlap */ 02292 /* Usually, problem is in the x direction*/ 02293 /* what extreme points fall within the two centroids ? */ 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 /* Do the surfaces intersect each other in that direction ? */ 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 /* modify the coordinates */ 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 /*set the Color Remix flag */ 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 /* if no coloroverlay exists, link to MapReference surface, if possible */ 02347 for (i=0; i<sv->VSv[nxtstateID].N_MembSOs; ++i) { 02348 /* next surface being checked */ 02349 SO_nxt = (SUMA_SurfaceObject *)(dov[sv->VSv[nxtstateID].MembSOs[i]].OP); 02350 02351 /* Get the Mapping Reference surface, that's the precursor*/ 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 /* no precursors found, notify user */ 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 /* check for risk of node inconsistencies */ 02367 02368 if (SO_prec->N_Node >= SO_nxt->N_Node ) {/* > or equal number of nodes*/ 02369 /* matching number of nodes */ 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) {/* More in prec */ 02376 /* just warn */ 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 }/* More in prec */ 02379 02380 /* link the selected nodes and facesets, if possible */ 02381 /*fprintf(SUMA_STDERR, "%s: Linking selected nodes ...\n", FuncName);*/ 02382 /* check for risk of node inconsistencies */ 02383 if (SO_prec->N_Node == SO_nxt->N_Node) { 02384 SO_nxt->SelectedNode = SO_prec->SelectedNode; 02385 } else { /* more nodes in precursor, make sure selected node is OK */ 02386 if (SO_prec->SelectedNode < SO_nxt->N_Node) { 02387 SO_nxt->SelectedNode = SO_prec->SelectedNode; 02388 } else { /* this node does not exist in the upcoming thing */ 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 } /* > or equal number of nodes */ else { /* less in prec */ 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 /* You do not want to mix colors yet, the flag for doing that has already been set*/ 02399 /* Here you need to remix the colors */ 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 /* Bind the cross hair to a reasonable surface, if possible */ 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 /* set the XYZ of the cross hair based on the coordinates of the upcoming surface, if possible */ 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 /* no node associated with cross hair, use XYZ */ 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 /* go from XYZ to XYZmap on current surface then from XYZmap to XYZ on new surface */ 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 /* if the surface controller is open, update it */ 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 /* switch the state accordingly */ 02464 sv->State = sv->VSv[nxtstateID].Name; 02465 sv->iState = nxtstateID; 02466 02467 /* set the focus ID to the first surface in the next view */ 02468 sv->Focus_SO_ID = sv->VSv[nxtstateID].MembSOs[0]; 02469 02470 /* Now update the cross hair info if needed for the surface in focus */ 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 /* decide what the best state is */ 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 /* modify the rotation center */ 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 /* set the viewing points */ 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 /* Change the defaults of the eye axis to fit standard EyeAxis */ 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 /* do the axis setup */ 02514 SUMA_WorldAxisStandard (sv->WAx, sv); 02515 02516 /* Home call baby */ 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 } |
|
ans = SUMA_VisibleSOs (sv, dov, SO_IDs); gets the IDs (indices into dov) and number of the Surface Objects registered with sv and with the SO->Side matching sv->ShowRight/ sv->ShowLeft and with SO->Show set to YUP
Definition at line 1896 of file SUMA_Engine.c. References SUMA_SurfaceViewer::CurGroupName, i, SUMA_SurfaceViewer::N_DO, SUMA_SurfaceViewer::RegisteredDO, SUMA_SurfaceObject::Show, SUMA_SurfaceViewer::ShowLeft, SUMA_SurfaceViewer::ShowRight, SUMA_SurfaceObject::Side, SUMA_ENTRY, SUMA_isSO_G(), SUMA_LEFT, SUMA_NO_SIDE, SUMA_RETURN, SUMA_RIGHT, and SUMA_SIDE_ERROR. Referenced by SUMA_input(), SUMA_MarkLineSurfaceIntersect(), SUMA_UpdateXhairField(), and SUMA_WorldAxisStandard().
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 } |
|
transform current XYZ to XYZmap The XYZ on an auxilliary surface are of no relevance to the volume. They must be transformed to mappable XYZ (in mm, RAI, in alignment with the Parent Volume) XYZmap = SUMA_XYZ_XYZmap (XYZ, SO, dov, N_dov, I_C);
Definition at line 2715 of file SUMA_Engine.c. References SUMA_ISINBOX::d, distance(), SUMA_ISINBOX::IsIn, SUMA_SurfaceObject::LocalDomainParentID, LocalHead, SUMA_SurfaceObject::N_Node, SUMA_ISINBOX::nIsIn, SUMA_SurfaceObject::NodeDim, SUMA_SurfaceObject::NodeList, SUMA_DO::OP, SUMA_Boolean, SUMA_calloc, SUMA_COPY_VEC, SUMA_ENTRY, SUMA_findSO_inDOv(), SUMA_free, SUMA_Free_IsInBox(), SUMA_isinbox(), SUMA_isLocalDomainParent(), SUMA_ismappable(), SUMA_MIN_LOC_VEC, SUMA_RETURN, and SUMA_XYZ_XFORM_BOXDIM_MM. Referenced by SUMA_makeNI_CrossHair(), and SUMA_SwitchState().
02716 {/* SUMA_XYZ_XYZmap */ 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 /* allocate for return */ 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 /* if surface is a local domain parent, do the obivious */ 02734 if (SUMA_isLocalDomainParent(SO)){ 02735 /*fprintf(SUMA_STDERR,"%s: Surface is a local domain parent. XYZmap = XYZ.\n", FuncName); */ 02736 SUMA_COPY_VEC (XYZ, XYZmap, 3, float, float); 02737 SUMA_RETURN (XYZmap); 02738 } 02739 /* if surface is not a local domain parent , do the deed */ 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 /* surface is mappable, things will get more complicated */ 02747 02748 /* find the closest node in SO */ 02749 if (*I_C < 0) { /* user has not specified closest node ID*/ 02750 /* must find closest node on my own */ 02751 { 02752 SUMA_ISINBOX IB; 02753 float Bd[3], distance; 02754 int ii; 02755 02756 /* set the search box dimensions */ 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) { /* found some, find the closest node */ 02762 /* locate the closest node and store it's id in EngineData*/ 02763 /*for (ii=0; ii<IB.nIsIn; ++ii) { 02764 fprintf (SUMA_STDERR,"%d\t%.3f\t\t", IB.IsIn[ii], IB.d[ii]); 02765 }*/ 02766 SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, distance, iclosest); 02767 iclosest = IB.IsIn[iclosest]; 02768 /* get ridd of IB's vectors */ 02769 if (!SUMA_Free_IsInBox (&IB)) { 02770 fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName); 02771 } 02772 02773 } else { /* no node is close enough */ 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 /* store iclosest for lazy user */ 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 /* find the SO that is the Mappable cahuna */ 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 /* all is done */ 02802 02803 SUMA_RETURN (XYZmap); 02804 }/* SUMA_XYZ_XYZmap */ |
|
transform XYZmap to XYZ on current surface XYZ = SUMA_XYZmap_XYZ (XYZmap, SO, dov, N_dov, I_C);
Definition at line 2826 of file SUMA_Engine.c. References SUMA_ISINBOX::d, distance(), SUMA_ISINBOX::IsIn, SUMA_SurfaceObject::LocalDomainParentID, LocalHead, SUMA_SurfaceObject::N_Node, SUMA_ISINBOX::nIsIn, SUMA_SurfaceObject::NodeDim, SUMA_SurfaceObject::NodeList, SUMA_DO::OP, SUMA_Boolean, SUMA_calloc, SUMA_COPY_VEC, SUMA_ENTRY, SUMA_findSO_inDOv(), SUMA_free, SUMA_Free_IsInBox(), SUMA_isinbox(), SUMA_isLocalDomainParent(), SUMA_ismappable(), SUMA_MIN_LOC_VEC, SUMA_RETURN, SUMA_SL_Warn, and SUMA_XYZ_XFORM_BOXDIM_MM. Referenced by SUMA_process_NIML_data(), and SUMA_SwitchState().
02827 {/* SUMA_XYZmap_XYZ */ 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 /* allocate for return */ 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 /* if surface is not mappable, do the deed */ 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 /* if surface is a local domain parent, do the obivious */ 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 /* do not return yet, must fix the node id too */ 02857 } else { 02858 /* surface is mappable, things will get more complicated */ 02859 /* find the SO that is the Mappable cahuna */ 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 /* find the closest node in SO */ 02869 if (*I_C < 0) { /* user has not specified closest node ID*/ 02870 /* must find closest node on my own */ 02871 { 02872 SUMA_ISINBOX IB; 02873 float Bd[3], distance; 02874 int ii; 02875 02876 /* set the search box dimensions */ 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) { /* found some, find the closest node */ 02882 /* locate the closest node and store it's id in EngineData*/ 02883 /*for (ii=0; ii<IB.nIsIn; ++ii) { 02884 fprintf (SUMA_STDERR,"%d\t%.3f\t\t", IB.IsIn[ii], IB.d[ii]); 02885 }*/ 02886 SUMA_MIN_LOC_VEC (IB.d, IB.nIsIn, distance, iclosest); 02887 iclosest = IB.IsIn[iclosest]; 02888 /* get ridd of IB's vectors */ 02889 if (!SUMA_Free_IsInBox (&IB)) { 02890 fprintf(SUMA_STDERR,"Error %s: Failed to free IB\n", FuncName); 02891 } 02892 02893 } else { /* no node is close enough */ 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 /* comes from inherrently mappable stuff, makes sense to leave XYZ */ 02901 SUMA_SL_Warn( "No node was close enough\n" 02902 "to XYZmap, linking by coordinate." ); 02903 SUMA_RETURN (XYZ); 02904 } 02905 } 02906 /* store iclosest for lazy user */ 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 /* all is done */ 02920 SUMA_RETURN (XYZ); 02921 }/* SUMA_XYZmap_XYZ */ |