Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

SUMA_MiscFunc.h File Reference

Go to the source code of this file.

Defines

#define SUMA_free(p)   SUMA_free_fn( FuncName, p )
#define SUMA_calloc(nmemb,size)   SUMA_calloc_fn( FuncName, nmemb, size)
#define SUMA_malloc(size)   SUMA_malloc_fn( FuncName, size)
#define SUMA_realloc(ptr, size)   SUMA_realloc_fn( FuncName, ptr, size)

Functions

void * SUMA_free_fn (const char *CallingFunc, void *ptr)
void * SUMA_calloc_fn (const char *CallingFunc, size_t nmemb, size_t size)
void * SUMA_malloc_fn (const char *CallingFunc, size_t size)
void * SUMA_realloc_fn (const char *CallingFunc, void *ptr, size_t size)
SUMA_MEMTRACE_STRUCTSUMA_Create_MemTrace (void)
void SUMA_ShowMemTrace (SUMA_MEMTRACE_STRUCT *Mem, FILE *Out)
SUMA_Boolean SUMA_Free_MemTrace (SUMA_MEMTRACE_STRUCT *Mem)
int SUMA_filexists (char *f_name)
void SUMA_alloc_problem (char *s1)
char ** SUMA_allocate2D (int rows, int cols, int element_size)
void SUMA_free2D (char **a, int rows)
void SUMA_error_message (char *s1, char *s2, int ext)
int SUMA_iswordin (const char *sbig, const char *ssub)
SUMA_FileName SUMA_StripPath (char *FileName)
SUMA_PARSED_NAMESUMA_ParseFname (char *FileName)
 ans = SUMA_ParseFname (FileName); parses a file name into its elements. More...

char * SUMA_Extension (char *filename, char *ext, SUMA_Boolean Remove)
 ans = SUMA_Extension(filename, ext, Remove); removes or enforces an arbitrary extension from/to a filename. More...

SUMA_Boolean SUMA_isExtension (char *filename, char *ext)
 ans = SUMA_isExtension(filename, ext); YUP if filename has the extension ext. More...

void * SUMA_Free_Parsed_Name (SUMA_PARSED_NAME *Test)
float SUMA_etime (struct timeval *t, int Report)
SUMA_ISINBOX SUMA_isinbox (float *NodeList, int nr, float *S_cent, float *S_dim, int BoundIn)
SUMA_Boolean SUMA_Free_IsInBox (SUMA_ISINBOX *IB)
SUMA_ISINSPHERE SUMA_isinsphere (float *NodeList, int nr, float *S_cent, float S_rad, int BoundIn)
float ** SUMA_Point_At_Distance (float *U, float *P1, float d)
SUMA_Boolean SUMA_Point_To_Line_Distance (float *NodeList, int N_points, float *P1, float *P2, float *d2, float *d2min, int *i2min)
SUMA_Boolean SUMA_Point_To_Point_Distance (float *NodeList, int N_points, float *P1, float *d2, float *d2min, int *i2min)
int * SUMA_z_dqsort (int *x, int nx)
int * SUMA_z_dqsort_nsc (int *x, int nx)
int * SUMA_z_qsort (float *x, int nx)
int SUMA_compare_int (int *a, int *b)
void SUMA_disp_dmat (int **v, int nr, int nc, int SpcOpt)
void SUMA_disp_mat (float **v, int nr, int nc, int SpcOpt)
void SUMA_disp_vecmat (float *v, int nr, int nc, int SpcOpt)
void SUMA_disp_vecdmat (int *v, int nr, int nc, int SpcOpt)
void SUMA_disp_dvect (int *v, int l)
void SUMA_disp_vect (float *v, int l)
SUMA_Boolean SUMA_MT_isIntersect_Triangle (float *P0, float *P1, float *vert0, float *vert1, float *vert2, float *iP, float *d, int *closest_vert)
SUMA_MT_INTERSECT_TRIANGLESUMA_MT_intersect_triangle (float *P0, float *P1, float *NodeList, int N_Node, int *FaceSetList, int N_FaceSet, SUMA_MT_INTERSECT_TRIANGLE *PrevMTI)
void * SUMA_Free_MT_intersect_triangle (SUMA_MT_INTERSECT_TRIANGLE *MTI)
 free structure SUMA_MT_INTERSECT_TRIANGLE, returns NULL so you should use it as such: MTI = SUMA_Free_MT_intersect_triangle (MTI);. More...

SUMA_Boolean SUMA_Show_MT_intersect_triangle (SUMA_MT_INTERSECT_TRIANGLE *MTI, FILE *Out)
SUMA_Boolean SUMA_mattoquat (float **mat, float *q)
SUMA_Boolean SUMA_FromToRotation (float *v0, float *v1, float **mtx)
int * SUMA_fqsortrow (float **X, int nr, int nc)
int * SUMA_dqsortrow (int **X, int nr, int nc)
int SUMA_float_file_size (char *f_name)
int SUMA_Read_2Dfile (char *f_name, float **x, int n_rows, int n_cols)
int SUMA_Read_2Ddfile (char *f_name, int **x, int n_rows, int n_cols)
SUMA_Boolean SUMA_MakeConsistent (int *FaceSetList, int N_FaceSet, SUMA_EDGE_LIST *SEL)
SUMA_EDGE_LISTSUMA_Make_Edge_List (int *FaceSetList, int N_FaceSet, int N_Node, float *NodeList)
void SUMA_free_Edge_List (SUMA_EDGE_LIST *SEL)
int SUMA_isConsistent (int *T, int *t)
int SUMA_isTriLinked (int *T, int *t, int *cn)
 This function determines how many nodes two triangles share. N_cn = SUMA_isTriLinked (T, t, cn);. More...

SUMA_FACESET_FIRST_EDGE_NEIGHBSUMA_allocate_FaceSet_Edge_Neighb (int N_FaceSet)
SUMA_FACESET_FIRST_EDGE_NEIGHBSUMA_FaceSet_Edge_Neighb (int **EL, int **ELps, int N_EL)
float * SUMA_SmoothAttr_Neighb (float *attr, int N_attr, float *attr_sm, SUMA_NODE_FIRST_NEIGHB *fn)
SUMA_NODE_FIRST_NEIGHBSUMA_Build_FirstNeighb (SUMA_EDGE_LIST *el, int N_Node)
SUMA_Boolean SUMA_Free_FirstNeighb (SUMA_NODE_FIRST_NEIGHB *FN)
float * SUMA_PolySurf3 (float *NodeList, int N_Node, int *FaceSetList, int N_FaceSet, int PolyDim, float *FaceNormList, SUMA_Boolean SignedArea)
float SUMA_TriSurf3 (float *n0, float *n1, float *n2)
float * SUMA_TriSurf3v (float *NodeList, int *FaceSets, int N_FaceSet)
SUMA_Boolean SUMA_TriNorm (float *n0, float *n1, float *n2, float *norm)
SUMA_SURFACE_CURVATURESUMA_Surface_Curvature (float *NodeList, int N_Node, float *NodeNormList, float *Face_A, int N_FaceSet, SUMA_NODE_FIRST_NEIGHB *FN, SUMA_EDGE_LIST *el)
SUMA_Boolean SUMA_Householder (float *Ni, float **Q)
void SUMA_Free_SURFACE_CURVATURE (SUMA_SURFACE_CURVATURE *SC)
float * SUMA_Convexity (float *NodeList, int N_Node, float *NodeNormList, SUMA_NODE_FIRST_NEIGHB *FN)
int SUMA_Read_file (float *x, char *f_name, int n_points)
int SUMA_Read_dfile (int *x, char *f_name, int n_points)
char * SUMA_pad_str (char *str, char pad_val, int pad_ln, int opt)
int SUMA_ReadNumStdin (float *fv, int nv)
SUMA_Boolean SUMA_isNumString (char *s, void *p)
 function that tests whether a string contains N numbers. More...

int SUMA_StringToNum (char *s, float *fv, int N)
 function that parses a string of numbers into a float vector. More...

int * SUMA_Find_inIntVect (int *x, int xsz, int val, int *nValLocation)
int * SUMA_UniqueInt (int *y, int xsz, int *kunq, int Sorted)
void SUMA_Show_Edge_List (SUMA_EDGE_LIST *SEL, FILE *Out)
int SUMA_FindEdge (SUMA_EDGE_LIST *EL, int n1, int n2)
 finds the first occurence in EL of an edge formed by nodes n1 n2 eloc = SUMA_FindEdge (EL, int n1, int n2);. More...

int SUMA_FindEdgeInTri (SUMA_EDGE_LIST *EL, int n1, int n2, int Tri)
 finds the index of an edge in EL of an edge formed by nodes n1 n2 and belonging to triangle Tri eloc = SUMA_FindEdgeInTri (EL, int n1, int n2, int Tri);. More...

int SUMA_whichTri (SUMA_EDGE_LIST *EL, int n1, int n2, int n3)
 This function determines which triangle, if any is formed by the specified nodes Tri = SUMA_wichTri (EL, n1, n2, n3);. More...

SUMA_Boolean SUMA_Get_Incident (int n1, int n2, SUMA_EDGE_LIST *SEL, int *Incident, int *N_Incident)
 finds triangles incident to an edge ans = SUMA_Get_Incident( n1, n2, SEL, Incident, N_Incident);. More...

SUMA_STRINGSUMA_StringAppend (SUMA_STRING *SS, char *newstring)
 Appends newstring to string in SS->s while taking care of resizing space allocated for s. More...

SUMA_Boolean SUMA_Get_NodeIncident (int n1, SUMA_SurfaceObject *SO, int *Incident, int *N_Incident)
 finds triangles incident to a node ans = SUMA_Get_NodeIncident(n1, SEL, Incident, N_Incident);. More...

SUMA_IRGBSUMA_Free_IRGB (SUMA_IRGB *irgb)
 function to free SUMA_IRGB *. More...

SUMA_IRGBSUMA_Read_IRGB_file (char *f_name, int n_rows)
 Function to read a node color file formatted as: i r g b (int float float float). More...

SUMA_IRGBSUMA_Create_IRGB (int n_el)
 Allocate for irgb structure containing n_el elements in each vector. More...


Define Documentation

#define SUMA_calloc nmemb,
size       SUMA_calloc_fn( FuncName, nmemb, size)
 

Definition at line 6 of file SUMA_MiscFunc.h.

Referenced by SUMA_Alloc_Axis(), SUMA_Alloc_SegmentDO(), SUMA_Alloc_SurfaceViewer_Struct(), SUMA_allocate_FaceSet_Edge_Neighb(), SUMA_Allocate_SPI(), SUMA_AllocateDrawnROI(), SUMA_AllocateROI(), SUMA_AllocateScrolledList(), SUMA_append_string(), SUMA_AppendToROIdatum(), SUMA_AssembleAllROIList(), SUMA_AssembleColorPlaneList(), SUMA_AssignTriBranch(), SUMA_BrushStrokeToNodeStroke(), SUMA_Build_FirstNeighb(), SUMA_Build_Mask_AllROI(), SUMA_Convexity(), SUMA_copy_string(), SUMA_Create_ColorScaledVect(), SUMA_Create_IRGB(), SUMA_CreateIcosahedron(), SUMA_CreateOverlayPointer(), SUMA_CreatePromptDialogStruct(), SUMA_detWeight(), SUMA_Dijkstra(), SUMA_divEdge(), SUMA_dqsortrow(), SUMA_DrawnROI_to_1DDrawROI(), SUMA_FileSelection_file_select_cb(), SUMA_FillColorList(), SUMA_FillToMask(), SUMA_Find_inIntVect(), SUMA_FormatMessage(), SUMA_fqsortrow(), SUMA_FreeSurfer_Read(), SUMA_GetContour(), SUMA_GetDO_Type(), SUMA_getPatch(), SUMA_GetStandardMap(), SUMA_input(), SUMA_IntersectionStrip(), SUMA_isinbox(), SUMA_isinsphere(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_Load_Surface_Object(), SUMA_LoadSpec(), SUMA_Make_Edge_List(), SUMA_MakeColorMap(), SUMA_MakeColorMap_v2(), SUMA_MakeConsistent(), SUMA_makeNI_CrossHair(), SUMA_MapSurface(), SUMA_MemberFaceSets(), SUMA_morphToStd(), SUMA_MT_intersect_triangle(), SUMA_NodePath_to_EdgePath(), SUMA_NodePath_to_TriPath_Inters(), SUMA_NodePath_to_TriPath_Inters_OLD(), SUMA_NodeStrokeToConnectedNodes(), SUMA_OpenDrawnROI_NIML(), SUMA_Overlays_2_GLCOLAR4(), SUMA_pad_str(), SUMA_Paint_SO_ROIplanes(), SUMA_PercRange(), SUMA_Plane_Equation(), SUMA_Ply_Read(), SUMA_PolySurf3(), SUMA_PrependToROIdatum(), SUMA_PromptApply_cb(), SUMA_readANOVA1D(), SUMA_readColor(), SUMA_readMapDump(), SUMA_RegisterSpecSO(), SUMA_RenderToPixMap(), SUMA_SmoothAttr_Neighb(), SUMA_StringAppend(), SUMA_SureFit_Read_Coord(), SUMA_SureFit_Read_Topo(), SUMA_Surf_Plane_Intersect(), SUMA_Surf_Plane_Intersect_ROI(), SUMA_Surface_Curvature(), SUMA_SurfaceFileName(), SUMA_SurfNorm(), SUMA_triangulateRow(), SUMA_TriSurf3v(), SUMA_UniqueInt(), SUMA_UpdateViewerTitle(), SUMA_VolPar_Attr(), SUMA_XYZ_XYZmap(), SUMA_XYZmap_XYZ(), SUMA_z_dqsort(), and SUMA_z_qsort().

#define SUMA_free      SUMA_free_fn( FuncName, p )
 

Definition at line 4 of file SUMA_MiscFunc.h.

Referenced by main(), SUMA_AddNewPlane(), SUMA_Addto_ROIplane_List(), SUMA_Alloc_SegmentDO(), SUMA_Alloc_ViewState(), SUMA_AppendToROIdatum(), SUMA_AssembleAllROIList(), SUMA_AssembleColorPlaneList(), SUMA_AssignTriBranch(), SUMA_BrushStrokeToNodeStroke(), SUMA_Build_Mask_AllROI(), SUMA_BuildMessageLog(), SUMA_cb_createSurfaceCont(), SUMA_cb_DrawROI_Delete(), SUMA_cb_moreSurfInfo(), SUMA_ColorOverlayPlane_Info(), SUMA_Create_ColorScaledVect(), SUMA_Create_IRGB(), SUMA_CreateFileSelectionDialogStruct(), SUMA_CreateOverlayPointer(), SUMA_CreatePromptDialogStruct(), SUMA_DestroyROIActionData(), SUMA_DestroyTextShell(), SUMA_Dijkstra(), SUMA_divEdge(), SUMA_dqsortrow(), SUMA_DrawnROI_to_1DDrawROI(), SUMA_EmptyColorList(), SUMA_Engine(), SUMA_FileSelection_file_select_cb(), SUMA_FillToMask(), SUMA_Find_inIntVect(), SUMA_FinishedROI(), SUMA_fqsortrow(), SUMA_Free_1DDrawROI(), SUMA_Free_Axis(), SUMA_Free_ColorMap(), SUMA_Free_ColorScaledVect(), SUMA_Free_CrossHair(), SUMA_Free_Displayable_Object_Vect(), SUMA_free_Edge_List(), SUMA_free_FaceSet_Edge_Neighb(), SUMA_Free_FaceSetMarker(), SUMA_Free_FirstNeighb(), SUMA_Free_FreeSurfer(), SUMA_Free_IRGB(), SUMA_Free_IsInBox(), SUMA_Free_MemberFaceSets(), SUMA_Free_MorphInfo(), SUMA_Free_MT_intersect_triangle(), SUMA_Free_NIMLDrawROI(), SUMA_Free_Parsed_Name(), SUMA_Free_ROI_PlaneData(), SUMA_free_SegmentDO(), SUMA_Free_SO_map(), SUMA_Free_SphereMarker(), SUMA_free_SPI(), SUMA_free_STB(), SUMA_Free_SureFit(), SUMA_Free_SURFACE_CURVATURE(), SUMA_Free_Surface_Object(), SUMA_Free_SurfaceViewer_Struct(), SUMA_Free_SurfaceViewer_Struct_Vect(), SUMA_Free_ViewState(), SUMA_Free_ViewState_Hist(), SUMA_Free_VolPar(), SUMA_FreeActionStackData(), SUMA_FreeAssembleListStruct(), SUMA_FreeBSDatum(), SUMA_freeDrawnROI(), SUMA_FreeEngineListData(), SUMA_FreeFileSelectionDialogStruct(), SUMA_FreeMessageListData(), SUMA_FreeOverlayListDatum(), SUMA_FreeOverlayPointer(), SUMA_freePatch(), SUMA_FreePromptDialogStruct(), SUMA_freeROI(), SUMA_FreeROIDatum(), SUMA_FreeScrolledList(), SUMA_FreeSurfer_Read(), SUMA_generateEPS(), SUMA_GetContour(), SUMA_getPatch(), SUMA_GetStandardMap(), SUMA_help_message(), SUMA_help_message_Info(), SUMA_input(), SUMA_IntersectionStrip(), SUMA_isinbox(), SUMA_isinsphere(), SUMA_IV_FaceSetsextract(), SUMA_Load_Surface_Object(), SUMA_LoadSpec(), SUMA_Make_Edge_List(), SUMA_MakeConsistent(), SUMA_makeNI_CrossHair(), SUMA_makeNI_SurfIJK(), SUMA_makeNI_SurfIXYZ(), SUMA_MapSurface(), SUMA_MovePlaneDown(), SUMA_MovePlaneUp(), SUMA_NodePath_to_EdgePath(), SUMA_NodePath_to_TriPath_Inters(), SUMA_NodePath_to_TriPath_Inters_OLD(), SUMA_NodesInROI(), SUMA_OpenDrawnROI_1D(), SUMA_OpenDrawnROI_NIML(), SUMA_Overlays_2_GLCOLAR4(), SUMA_pad_str(), SUMA_Paint_SO_ROIplanes(), SUMA_PercRange(), SUMA_PlaneOrder_Info(), SUMA_Ply_Read(), SUMA_Ply_Write(), SUMA_PrependToROIdatum(), SUMA_Print_PlaneOrder(), SUMA_Print_Surface_Object(), SUMA_ProcessBrushStroke(), SUMA_PromptApply_cb(), SUMA_Read_SpecFile(), SUMA_readANOVA1D(), SUMA_readColor(), SUMA_readMapDump(), SUMA_ReleaseActionStackData(), SUMA_ReleaseOverlay(), SUMA_remove_workproc(), SUMA_remove_workproc2(), SUMA_RenderToPixMap(), SUMA_SaveDrawnROI_1D(), SUMA_SaveDrawnROINIML(), SUMA_Show_ColorOverlayPlanes(), SUMA_Show_VolPar(), SUMA_Surf_Plane_Intersect(), SUMA_Surf_Plane_Intersect_ROI(), SUMA_Surface_Curvature(), SUMA_SurfaceMetrics(), SUMA_SurfaceObject_Info(), SUMA_SurfNorm(), SUMA_SwitchState(), SUMA_tesselate(), SUMA_triangulateRow(), SUMA_UniqueInt(), SUMA_UpdateViewerTitle(), SUMA_VolPar_Info(), SUMA_workprocess(), SUMA_Write_DrawnROI_1D(), SUMA_Write_DrawnROI_NIML(), SUMA_XYZ_XYZmap(), SUMA_XYZmap_XYZ(), SUMA_z_dqsort(), and SUMA_z_qsort().

#define SUMA_malloc size       SUMA_malloc_fn( FuncName, size)
 

Definition at line 8 of file SUMA_MiscFunc.h.

Referenced by main(), SUMA_AddNewPlane(), SUMA_Addto_ROIplane_List(), SUMA_Align_to_VolPar(), SUMA_Alloc_Axis(), SUMA_Alloc_CrossHair(), SUMA_Alloc_DisplayObject_Struct(), SUMA_Alloc_FaceSetMarker(), SUMA_Alloc_SegmentDO(), SUMA_Alloc_SphereMarker(), SUMA_Alloc_SurfaceViewer_Struct(), SUMA_Alloc_SurfObject_Struct(), SUMA_Alloc_ViewState(), SUMA_Alloc_ViewState_Hist(), SUMA_Alloc_VolPar(), SUMA_allocate_FaceSet_Edge_Neighb(), SUMA_Allocate_SPI(), SUMA_AllocateDrawnROI(), SUMA_AllocateROI(), SUMA_AllocateScrolledList(), SUMA_AllocROIDatum(), SUMA_AssembleAllROIList(), SUMA_AssembleColorPlaneList(), SUMA_AssignTriBranch(), SUMA_Build_FirstNeighb(), SUMA_cb_createSurfaceCont(), SUMA_cb_DrawROI_Finish(), SUMA_cb_DrawROI_Join(), SUMA_Create_ColorScaledVect(), SUMA_Create_IRGB(), SUMA_Create_MorphInfo(), SUMA_Create_SO_map(), SUMA_CreateAssembleListStruct(), SUMA_CreateBrushStroke(), SUMA_CreateBSDatum(), SUMA_CreateFileSelectionDialogStruct(), SUMA_CreateInode(), SUMA_CreateList(), SUMA_CreateOverlayPointer(), SUMA_CreatePromptDialogStruct(), SUMA_CreateTestShellStruct(), SUMA_Dijkstra(), SUMA_DrawnROI_to_1DDrawROI(), SUMA_DrawnROI_to_NIMLDrawnROI(), SUMA_DrawROI_NewLabel(), SUMA_Extension(), SUMA_FillColorList(), SUMA_Find_ROIonSO(), SUMA_Find_ROIrelatedtoSO(), SUMA_GetContour(), SUMA_getPatch(), SUMA_grabPixels(), SUMA_InitializeEngineListData(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_Load_Surface_Object(), SUMA_LoadSpec(), SUMA_Make_Edge_List(), SUMA_MakeColorMap(), SUMA_MakeColorMap_v2(), SUMA_makeNI_SurfIJK(), SUMA_makeNI_SurfIXYZ(), SUMA_MemberFaceSets(), SUMA_MT_intersect_triangle(), SUMA_NIMLDrawnROI_to_DrawnROI(), SUMA_NodesInROI(), SUMA_OpenDrawnROI_1D(), SUMA_OpenDrawnROI_NIML(), SUMA_OverlaysToOrderedList(), SUMA_Paint_SO_ROIplanes(), SUMA_ParseFname(), SUMA_Ply_Read(), SUMA_Ply_Write(), SUMA_ProcessBrushStroke(), SUMA_PushActionStack(), SUMA_register_workproc(), SUMA_RegisterMessage(), SUMA_RegisterSpecSO(), SUMA_ScaleToMapOptInit(), SUMA_StringAppend(), SUMA_StripPath(), SUMA_Surface_Curvature(), and SUMA_VolPar_Attr().

#define SUMA_realloc ptr,
size       SUMA_realloc_fn( FuncName, ptr, size)
 

Definition at line 10 of file SUMA_MiscFunc.h.

Referenced by SUMA_DrawROI_NewLabel(), SUMA_Find_ROIonSO(), SUMA_Find_ROIrelatedtoSO(), SUMA_GetContour(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_NodeStrokeToConnectedNodes(), SUMA_register_workproc(), and SUMA_StringAppend().


Function Documentation

void SUMA_alloc_problem char *    s1
 

Taken from SUMA_alloc_problem

Definition at line 732 of file SUMA_MiscFunc.c.

Referenced by SUMA_Alloc_DisplayObject_Struct(), SUMA_Alloc_SurfObject_Struct(), SUMA_isinbox(), SUMA_isinsphere(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_StripPath(), and SUMA_SurfNorm().

00734 {
00735    static char FuncName[]={"SUMA_alloc_problem"};
00736    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00737 
00738    printf ("\n\n\a\33[1mError in memory allocation\33[0m\n");
00739    printf ("Error origin : %s\n\n",s1);
00740    printf ("Exiting Program ..\n\n");
00741    exit (0);
00742 }

char** SUMA_allocate2D int    rows,
int    cols,
int    element_size
 

Taken from allocate2D.c - Make matrix of given size (rows x cols) and type

The type is given by element_size (2 = ints, 4 = floats, 8 = doubles). Exits if the matrix could not be allocated.

char **allocate2D(int rows,int cols,int element_size) SIZE might vary depending on platform used !!!

This function was adapted from DSP_in_C functions in C Language Algorithms for Digital Signal Processing by Bruce Kimball, Paul Embree and Bruce Kimble 1991, Prentice Hall

Ziad Saad Oct_21_96

This function should not use SUMA_calloc because it can slow things down for Nxm arrays where N is very large.

Definition at line 767 of file SUMA_MiscFunc.c.

Referenced by SUMA_allocate_FaceSet_Edge_Neighb(), SUMA_Build_FirstNeighb(), SUMA_Create_ColorScaledVect(), SUMA_CreateOverlayPointer(), SUMA_Engine(), SUMA_GetStandardMap(), SUMA_input(), SUMA_Make_Edge_List(), SUMA_MakeColorMap(), SUMA_MakeColorMap_v2(), SUMA_MemberFaceSets(), SUMA_Point_At_Distance(), SUMA_PolySurf3(), SUMA_RegisterEngineData(), SUMA_RegisterEngineListCommand(), SUMA_SureFit_Read_Topo(), and SUMA_Surface_Curvature().

00769 {
00770    int i;
00771    char **A;
00772    static char FuncName[]={"SUMA_allocate2D"};
00773 
00774    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00775 
00776    /* try to allocate the request */
00777    switch(element_size) {
00778      case sizeof(short): {    /* integer matrix */
00779          short **int_matrix;
00780          int_matrix = (short **)calloc(rows,sizeof(short *));
00781          if(!int_matrix) {
00782              printf("\nError making pointers in %dx%d int matrix\n"
00783                          ,rows,cols);
00784              exit(1);
00785          }
00786          for(i = 0 ; i < rows ; i++) {
00787              int_matrix[i] = (short *)calloc(cols,sizeof(short));
00788              if(!int_matrix[i]) {
00789                  printf("\nError making row %d in %dx%d int matrix\n"
00790                          ,i,rows,cols);
00791                  exit(1);
00792              }
00793          }
00794          A = (char **)int_matrix;
00795          break;
00796      }
00797      case sizeof(float): {    /* float matrix */
00798          float **float_matrix;
00799          float_matrix = (float **)calloc(rows,sizeof(float *));
00800          if(!float_matrix) {
00801              printf("\nError making pointers in %dx%d float matrix\n"
00802                          ,rows,cols);
00803              exit(1);
00804          }
00805          for(i = 0 ; i < rows ; i++) {
00806              float_matrix[i] = (float *)calloc(cols,sizeof(float));
00807              if(!float_matrix[i]) {
00808                  printf("\nError making row %d in %dx%d float matrix\n"
00809                          ,i,rows,cols);
00810                  exit(1);
00811              }
00812          }
00813          A = (char **)float_matrix;
00814          break;
00815      }
00816      case sizeof(double): {   /* double matrix */
00817          double **double_matrix;
00818          double_matrix = (double **)calloc(rows,sizeof(double *));
00819          if(!double_matrix) {
00820              printf("\nError making pointers in %dx%d double matrix\n"
00821                          ,rows,cols);
00822              exit(1);
00823          }
00824          for(i = 0 ; i < rows ; i++) {
00825              double_matrix[i] = (double *)calloc(cols,sizeof(double));
00826              if(!double_matrix[i]) {
00827                  printf("\nError making row %d in %dx%d double matrix\n"
00828                          ,i,rows,cols);
00829                  exit(1);
00830              }
00831          }
00832          A = (char **)double_matrix;
00833          break;
00834      }
00835      default:
00836          printf("\nERROR in matrix_allocate: unsupported type\n");
00837          exit(1);
00838    }
00839    
00840    #if SUMA_MEMTRACE_FLAG
00841    if (SUMAg_CF->MemTrace) {
00842       ++SUMAg_CF->Mem->N_alloc;
00843       if (SUMAg_CF->Mem->N_MaxPointers <= SUMAg_CF->Mem->N_alloc) {
00844          /* must reallocate */
00845          /* SUMA_ShowMemTrace (SUMAg_CF->Mem, NULL);*/
00846          SUMAg_CF->Mem->N_MaxPointers += SUMA_MEMTRACE_BLOCK;
00847 
00848          SUMAg_CF->Mem->Pointers = (void **)realloc (SUMAg_CF->Mem->Pointers, sizeof(void*) * SUMAg_CF->Mem->N_MaxPointers);
00849          SUMAg_CF->Mem->Size  = (int *)realloc ((void *)SUMAg_CF->Mem->Size, sizeof(int) * SUMAg_CF->Mem->N_MaxPointers);
00850          if (!SUMAg_CF->Mem->Pointers || !SUMAg_CF->Mem->Pointers) {
00851             fprintf (SUMA_STDERR, "Error %s: Failed to reallocate.\nTurning off memory tracing.\n", \
00852                FuncName);
00853             /* free up allocated space, clean up pointers, turn off memory tracing DO NOT USE SUMA_free here*/
00854             if (SUMAg_CF->Mem->Pointers) free(SUMAg_CF->Mem->Pointers); SUMAg_CF->Mem->Pointers = NULL;
00855             if (SUMAg_CF->Mem->Size) free(SUMAg_CF->Mem->Size); SUMAg_CF->Mem->Size = NULL;
00856             SUMAg_CF->MemTrace = 0;
00857             SUMAg_CF->Mem->N_alloc = 0;
00858             SUMAg_CF->Mem->N_MaxPointers =0;
00859          }
00860       }
00861       SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = A;
00862       SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = rows * cols * element_size;
00863    }
00864    #endif
00865 
00866    SUMA_RETURN(A);
00867 }

SUMA_FACESET_FIRST_EDGE_NEIGHB* SUMA_allocate_FaceSet_Edge_Neighb int    N_FaceSet
 

Allocate space for SUMA_FACESET_FIRST_EDGE_NEIGHB * S = SUMA_allocate_FaceSet_Edge_Neighb (N_FaceSet);

Parameters:
N_FaceSet  (int) Number of FaceSets to be searched \ret S (SUMA_FACESET_FIRST_EDGE_NEIGHB *)
See also:
SUMA_free_FaceSet_Edge_Neighb

Definition at line 3997 of file SUMA_MiscFunc.c.

Referenced by SUMA_FaceSet_Edge_Neighb().

03998 {
03999    static char FuncName[]={"SUMA_FACESET_FIRST_EDGE_NEIGHB"};
04000    SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN;
04001    
04002    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04003 
04004    SFFN = SUMA_malloc(sizeof(SUMA_FACESET_FIRST_EDGE_NEIGHB));
04005    if (SFFN == NULL) {
04006       fprintf (SUMA_STDERR, "Error %s: Could not allocate for SFFN.\n", FuncName);
04007       SUMA_RETURN (NULL);
04008    }
04009    
04010    SFFN->FirstNeighb = (int **) SUMA_allocate2D(N_FaceSet, SUMA_MAX_FACESET_EDGE_NEIGHB, sizeof(int));
04011    SFFN->N_Neighb = (int *) SUMA_calloc (N_FaceSet, sizeof(int));
04012    if (SFFN->FirstNeighb == NULL || SFFN->N_Neighb == NULL) {
04013       fprintf (SUMA_STDERR, "Error %s: Could not allocate for FirstNeighb or N_Neighb.\n", FuncName);
04014       SUMA_RETURN (NULL);
04015    } 
04016    
04017    SFFN->N_Neighb_max = -1; /* ridiculously low */
04018    SFFN->N_FaceSet = N_FaceSet;
04019    SFFN->N_Neighb_min = 100; /* ridiculously high */
04020    SUMA_RETURN (SFFN);
04021 }

SUMA_NODE_FIRST_NEIGHB* SUMA_Build_FirstNeighb SUMA_EDGE_LIST   el,
int    N_Node
 

build the node neighbor structure. Nodes are neighbors is they share an edge ans = SUMA_Build_FirstNeighb (EL, N_Node)

Parameters:
EL  (SUMA_EDGE_LIST *) pointer to the EdgeList structure (usually SO->EL)
N_Node  (int) total number of nodes (usually SO->N_Node) \ret FN (SUMA_NODE_FIRST_NEIGHB *) pointer to the neighbor list structure

Definition at line 4414 of file SUMA_MiscFunc.c.

Referenced by SUMA_CreateIcosahedron(), SUMA_SureFit_Write(), and SUMA_SurfaceMetrics().

04415 {
04416    static char FuncName[]={"SUMA_Build_FirstNeighb"};
04417    int i, j, n1, n2,  **FirstNeighb, N_ELm1, jj, tmp, TessErr_Cnt=0;
04418    SUMA_Boolean skp;
04419    SUMA_NODE_FIRST_NEIGHB *FN;
04420    
04421    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04422 
04423    if (el == NULL || N_Node == 0) {
04424       fprintf(SUMA_STDERR, "Error %s: el == NULL or N_Node == 0, nothing to do.\n", FuncName);
04425       SUMA_RETURN (NULL);
04426    }   
04427    
04428    FN = (SUMA_NODE_FIRST_NEIGHB *)SUMA_malloc(sizeof(SUMA_NODE_FIRST_NEIGHB));
04429    if (FN == NULL) {
04430       fprintf(SUMA_STDERR, "Error %s: Could not allocate space for FN\n", FuncName);
04431       SUMA_RETURN (NULL);
04432    }
04433    
04434    /* allocate space for FN's matrices */
04435    FN->N_Node = N_Node;
04436    FN->N_Neighb_max = 0;
04437    
04438    FN->FirstNeighb = (int **) SUMA_allocate2D(FN->N_Node, SUMA_MAX_NUMBER_NODE_NEIGHB+1, sizeof (int));
04439    FN->N_Neighb = (int *) SUMA_calloc (FN->N_Node, sizeof(int));
04440    FN->NodeId = (int *) SUMA_calloc (FN->N_Node, sizeof(int));
04441    
04442    if (FN->FirstNeighb == NULL || FN->N_Neighb == NULL || FN->NodeId == NULL ){
04443       fprintf(SUMA_STDERR, "Error %s: Could not allocate space forFN->FirstNeighb &/| FN->N_Neighb &/| FN->NodeId.\n", FuncName);
04444       SUMA_RETURN (NULL);
04445    } 
04446    
04447    /*fprintf(SUMA_STDOUT, "%s: Creating list ...\n", FuncName);*/
04448    
04449    FN->N_Neighb_max = 0;
04450    N_ELm1 = el->N_EL-1;
04451    j=0;
04452    while (j < el->N_EL) 
04453    {
04454       n1 = el->EL[j][0];
04455       n2 = el->EL[j][1];
04456       
04457       if (FN->N_Neighb[n1] > SUMA_MAX_NUMBER_NODE_NEIGHB || FN->N_Neighb[n2] > SUMA_MAX_NUMBER_NODE_NEIGHB) {
04458          fprintf(SUMA_STDERR, "Critical Error %s\a: Maximum number of node neighbors for node %d or node %d exceeds %d (SUMA_MAX_NUMBER_NODE_NEIGHB)\n SUMA will try to launch but some functions may not work properly.\n", FuncName, n1, n2, SUMA_MAX_NUMBER_NODE_NEIGHB);
04459       }else {
04460          /*register the neighbors for both nodes*/
04461          FN->NodeId[n1] = n1; /* this field may come in handy when operations need to be performed on subsets of the nodes making up the surface */
04462          FN->NodeId[n2] = n2;
04463          FN->FirstNeighb[n1][FN->N_Neighb[n1]] = n2;
04464          FN->FirstNeighb[n2][FN->N_Neighb[n2]] = n1;
04465 
04466          /* increment neighbor count for nodes in edge */
04467          FN->N_Neighb[n1] += 1;
04468          FN->N_Neighb[n2] += 1;
04469 
04470          if (FN->N_Neighb[n1] > FN->N_Neighb_max) FN->N_Neighb_max = FN->N_Neighb[n1];
04471          if (FN->N_Neighb[n2] > FN->N_Neighb_max) FN->N_Neighb_max = FN->N_Neighb[n2];
04472 
04473          /* skip duplicate edges */
04474          if (j < N_ELm1) {
04475             skp = NOPE;
04476             do {
04477                if (el->EL[j+1][0] == el->EL[j][0] && el->EL[j+1][1] == el->EL[j][1]) {
04478                   ++j;
04479                } else {
04480                   skp = YUP;
04481                }
04482             } while (!skp && j < N_ELm1);
04483          }
04484       }
04485       
04486       ++j;
04487    }/* for j */
04488 
04489    /* now SUMA_reallocate for final FirstNeighb */
04490    FirstNeighb = (int **) SUMA_allocate2D(FN->N_Node, FN->N_Neighb_max, sizeof (int));
04491    if (FirstNeighb == NULL){
04492       fprintf(SUMA_STDERR, "Error %s: Could not allocate space for FirstNeighb\n", FuncName);
04493       SUMA_Free_FirstNeighb (FN);
04494       SUMA_RETURN (NULL);
04495    } 
04496 
04497    /* crop left over allocated space and rearrange neighboring nodes in order */
04498    for (i=0; i < N_Node; ++i) {
04499       #ifdef NoOrder
04500       for (j=0; j < FN->N_Neighb[i]; ++j) {
04501           FirstNeighb[i][j] = FN->FirstNeighb[i][j];
04502       }
04503       #else /* ordered nodes, Tue Jan  7 13:21:57 EST 2003 */
04504         /* copy first node */
04505         FirstNeighb[i][0] = FN->FirstNeighb[i][0];
04506         j = 1;
04507         jj = 1;
04508         while (j < FN->N_Neighb[i]) {
04509             if (SUMA_whichTri (el, i, FirstNeighb[i][jj-1], FN->FirstNeighb[i][j]) >= 0) {
04510                FirstNeighb[i][jj] = FN->FirstNeighb[i][j];
04511                /* now swap in FN->FirstNeighb[i] the positions of jj and j */
04512                tmp =  FN->FirstNeighb[i][jj];
04513                FN->FirstNeighb[i][jj] = FN->FirstNeighb[i][j];
04514                FN->FirstNeighb[i][j] = tmp;
04515                ++jj;
04516                j = jj;
04517             } else {
04518                ++j;
04519             }
04520         }
04521         if (jj != FN->N_Neighb[i]) {
04522             if (!TessErr_Cnt) {
04523                fprintf (SUMA_STDERR, "Error %s: Failed in copying neighbor list! jj=%d, FN->N_Neighb[%d]=%d\n", 
04524                   FuncName, jj, i, FN->N_Neighb[i]);
04525                fprintf (SUMA_STDERR, "\tIf this is a closed surface, the problem is likely due to a tessellation error.\n\tOne or more edges may not be part of 2 and only 2 triangles.\n\tNeighbor list for node %d will not be ordered as connected vertices.\n", 
04526                   i);
04527                fprintf (SUMA_STDERR, "\tFurther occurences of this error will not be reported.\n");
04528             }
04529             ++TessErr_Cnt;
04530             while (jj < FN->N_Neighb[i]) {
04531                FirstNeighb[i][jj] = FN->FirstNeighb[i][jj];
04532                ++jj;
04533             }
04534         }    
04535       #endif
04536    }
04537    if (TessErr_Cnt) {
04538       fprintf (SUMA_STDERR, "\t%d similar occurences of the error above were found in this mesh.\n", TessErr_Cnt);
04539    }
04540    SUMA_free2D((char **)FN->FirstNeighb, N_Node);
04541    FN->FirstNeighb = FirstNeighb;
04542    /* SUMA_disp_dmat (FN->FirstNeighb, N_Node, FN->N_Neighb_max, 0); */
04543    SUMA_RETURN (FN);
04544 }

void* SUMA_calloc_fn const char *    CallingFunc,
size_t    nmemb,
size_t    size
 

This function is very similar to SUMA_malloc_fn except that it uses calloc instead of malloc and SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc] = nmemb*size;

Parameters:
CF  (const char *) name of calling function
nmemb  (size_t) number of elements
size  (size_t) size of an element \ret ptr (void *) pointer to nmemb*size allocated space
See also:
SUMA_malloc_fn

Definition at line 110 of file SUMA_MiscFunc.c.

00110                                                                     {
00111       void *ptr;
00112       static char FuncName[]={"SUMA_calloc_fn"};
00113 
00114       #if SUMA_MEMTRACE_FLAG
00115          if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00116       #endif
00117 
00118       /* The allocation */
00119       ptr = calloc (nmemb, size);
00120 
00121       /* the block below is also used in SUMA_allocate2D */
00122       #if SUMA_MEMTRACE_FLAG
00123          if (SUMAg_CF->MemTrace) {
00124             ++SUMAg_CF->Mem->N_alloc;
00125             if (SUMAg_CF->Mem->N_MaxPointers <= SUMAg_CF->Mem->N_alloc) {
00126                /* must reallocate */
00127                /* SUMA_ShowMemTrace (SUMAg_CF->Mem, NULL);*/
00128                SUMAg_CF->Mem->N_MaxPointers += SUMA_MEMTRACE_BLOCK;
00129 
00130                SUMAg_CF->Mem->Pointers = (void **)realloc (SUMAg_CF->Mem->Pointers, sizeof(void*) * SUMAg_CF->Mem->N_MaxPointers);
00131                SUMAg_CF->Mem->Size  = (int *)realloc ((void *)SUMAg_CF->Mem->Size, sizeof(int) * SUMAg_CF->Mem->N_MaxPointers);
00132                if (!SUMAg_CF->Mem->Pointers || !SUMAg_CF->Mem->Pointers) {
00133                   fprintf (SUMA_STDERR, "Error %s: Failed to reallocate.\nTurning off memory tracing.\n", \
00134                      FuncName);
00135                   /* free up allocated space, clean up pointers, turn off memory tracing DO NOT USE SUMA_free here*/
00136                   if (SUMAg_CF->Mem->Pointers) free(SUMAg_CF->Mem->Pointers); SUMAg_CF->Mem->Pointers = NULL;
00137                   if (SUMAg_CF->Mem->Size) free(SUMAg_CF->Mem->Size); SUMAg_CF->Mem->Size = NULL;
00138                   SUMAg_CF->MemTrace = 0;
00139                   SUMAg_CF->Mem->N_alloc = 0;
00140                   SUMAg_CF->Mem->N_MaxPointers =0;
00141                   SUMA_RETURN(ptr);
00142                }
00143             }
00144             SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = ptr;
00145             SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = nmemb * size;
00146          }
00147          SUMA_RETURN(ptr);
00148       #else
00149          return(ptr);
00150       #endif
00151 
00152    }

int SUMA_compare_int int *    a,
int *    b
 

Definition at line 2078 of file SUMA_MiscFunc.c.

02079 {/*SUMA_compare_int*/
02080         if (*a < *b)
02081                 return (-1);
02082         else if (*a == *b)
02083                 return (0);
02084         else
02085                 return (1);
02086         
02087 }/*SUMA_compare_int*/

float* SUMA_Convexity float *    NodeList,
int    N_Node,
float *    NodeNormList,
SUMA_NODE_FIRST_NEIGHB   FN
 

C = SUMA_Convexity (NodeList, N_Node, NodeNormList, FN)

Parameters:
NodeList  (float *) N_Node x 3 vector containing the coordinates for each node
N_Node  (int) number of nodes
NodeNormList  (float *) N_Node x 3 vector (was matrix prior to SUMA 1.2) containing the unit normals at each node
FN  (SUMA_NODE_FIRST_NEIGHB *) first order node neighbor structure \ret C (float *) N_Node x 1 vector containing the curvature at each node. The curvature is the sum of the signed distance of all the neighboring nodes to the tangent plane. The sign if C[i] indicates the convexity.
C[i] = Sum(dj/dij) over all neighbors j of i dj is the distance of neighboring node j to the tangent plane at i dij is the length of the segment ij

You can consider the magnitude of C as a measure of the curvature at the node. Use it wisely.

The Normals are assumed to be unit vectors

Definition at line 5272 of file SUMA_MiscFunc.c.

Referenced by SUMA_input(), and SUMA_SurfaceMetrics().

05273 {
05274    static char FuncName[]={"SUMA_Convexity"};
05275    float *C, d, D, dij;
05276    int i, j, in, id, ind, ND;
05277    
05278    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05279 
05280    C = NULL;
05281    
05282    /* allocate for C */
05283    C = (float *)SUMA_calloc (N_N, sizeof(float));
05284    
05285    if (C == NULL) {
05286       fprintf (SUMA_STDERR,"Error %s: Could not allocate for C.\n", FuncName);
05287       SUMA_RETURN (C);
05288    }
05289    
05290    ND = 3;
05291    
05292    for (i=0; i < N_N; ++i) {
05293       id = ND * i;
05294       /* the plane at node i, having normal [NNL(id), NNL(id+1), NNL(id+2)] (id = 3*i) has the equation A X + B Y + C Z + D = 0
05295       NNL[id] NL[id]  + NNL[id+1] NNL[id+1]  + NNL[id+2] NL[id+2] + D = 0 */
05296       
05297       D = -NNL[id] * NL[id] - NNL[id+1] * NL[id+1] - NNL[id+2] * NL[id+2];
05298       
05299       for (j=0; j < FN->N_Neighb[i]; ++j) {
05300          /* find the distance between the neighboring node j and the tangent plane at i 
05301          d = (A X + B Y + C Z + D ) / (sqrt(A*A + B*B + C*C))
05302          denominator is norm of Normals which should be 1
05303          */
05304          in = FN->FirstNeighb[i][j];
05305          ind = in * ND;
05306          d = NNL[id] * NL[ind] + NNL[id+1] * NL[ind+1] + NNL[id+2] * NL[ind+2] + D ;
05307          
05308          /* calculate the distance between node i and it's neighbor */
05309          dij = sqrt( (NL[ind] - NL[id]) * (NL[ind] - NL[id]) + (NL[ind+1] - NL[id+1]) * (NL[ind+1] - NL[id+1]) + (NL[ind+2] - NL[id+2]) * (NL[ind+2] - NL[id+2]));
05310          
05311          /* assuming normals are normalized d is the cosine of the angle between the two vectors */
05312          /* if d > 0, then angle is > 0..90 degrees */
05313          
05314          /* as a measure of curvature, compute the sum of signed distances of negihbors to tangent plane at i.
05315          use distances normalized by length of segment ij to account for differences in segment length */
05316           
05317          C[i] += d/dij;
05318       }
05319    
05320    }
05321    
05322    /* Now write the results to disk just for debugging */
05323    #if 0
05324    {
05325       FILE *fid;
05326       fprintf(SUMA_STDOUT,"%s: Writing convexity to Conv.txt ...", FuncName);
05327       fid = fopen("Conv.txt","w");
05328       for (i=0; i < N_N; ++i) {
05329          fprintf(fid,"%f\n", C[i]);
05330       }
05331       fclose (fid);
05332       
05333       fprintf(SUMA_STDOUT,"%s: Done.\n", FuncName);
05334    }
05335    #endif
05336    
05337    SUMA_RETURN (C);
05338 } 

SUMA_IRGB* SUMA_Create_IRGB int    n_el
 

Allocate for irgb structure containing n_el elements in each vector.

See also:
SUMA_Free_IRGB

Definition at line 543 of file SUMA_MiscFunc.c.

Referenced by SUMA_Read_IRGB_file().

00544 {
00545    SUMA_IRGB *irgb=NULL;
00546    static char FuncName[]={"SUMA_Create_IRGB"};
00547    
00548    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00549    
00550    irgb = (SUMA_IRGB *)SUMA_malloc(sizeof(SUMA_IRGB));
00551    
00552    
00553    irgb->i = (int *)SUMA_calloc(n_el, sizeof(int));
00554    irgb->r = (float*)SUMA_calloc(n_el, sizeof(float));
00555    irgb->g = (float*)SUMA_calloc(n_el, sizeof(float));
00556    irgb->b = (float*)SUMA_calloc(n_el, sizeof(float));
00557    irgb->N = n_el;
00558    if (!irgb->i || !irgb->r || !irgb->g || !irgb->b) {
00559       SUMA_S_Crit ("Failed to allocate for i, r, g and/or b.");
00560       if (irgb) SUMA_free(irgb);
00561       SUMA_RETURN (NULL);
00562    }
00563    
00564    SUMA_RETURN(irgb);
00565 }

SUMA_MEMTRACE_STRUCT* SUMA_Create_MemTrace void   
 

Definition at line 227 of file SUMA_MiscFunc.c.

00227                                                    {
00228    static char FuncName[]={"SUMA_Create_MemTrace"};
00229    SUMA_MEMTRACE_STRUCT *Mem;
00230  
00231    /* you cannot use SUMAg_CF here because the function that allocates for SUMAg_CF calls that one */
00232    
00233    /* DO NOT USE SUMA_malloc function here ! */
00234    Mem = malloc (sizeof(SUMA_MEMTRACE_STRUCT));
00235    /* allocate for the Pointers and Size vectors */
00236    Mem->Pointers = (void **)calloc(SUMA_MEMTRACE_BLOCK, sizeof(void *));
00237    
00238    Mem->Size = (int *)calloc(SUMA_MEMTRACE_BLOCK, sizeof(int));
00239    Mem->N_MaxPointers = SUMA_MEMTRACE_BLOCK;
00240    Mem->N_alloc = 0;
00241    
00242    if (!Mem->Pointers || !Mem->Size) {
00243       fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
00244       return (NULL);
00245    }
00246    return(Mem);
00247 }

void SUMA_disp_dmat int **    v,
int    nr,
int    nc,
int    SpcOpt
 

File : Taken from disp_dmat.c Author : Ziad Saad Date : Tue Nov 17 13:19:26 CST 1998

Purpose : Displays on the terminal the 2D matrix of integers

Usage : SUMA_disp_dmat (int **v,int nr, int nc, int SpcOpt )

Input paramters : v (int **) the 2D matrix to display nr (int) the number of rows in v nc (int) the number of columns SpcOpt (int) : spacing option (0 for space, 1 for tab and 2 for comma)

Returns :

Support :

Side effects :

Definition at line 1082 of file SUMA_MiscFunc.c.

01083 {/*SUMA_disp_dmat*/
01084    char spc [40]; 
01085    int i,j;
01086    static char FuncName[]={"SUMA_disp_dmat"};
01087 
01088    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01089 
01090    if (!SpcOpt)
01091       sprintf(spc," ");
01092    else if (SpcOpt == 1)
01093       sprintf(spc,"\t");
01094    else
01095       sprintf(spc," , ");
01096 
01097    fprintf (SUMA_STDOUT,"\n");
01098    for (i=0; i < nr; ++i)
01099       {
01100          for (j=0; j < nc; ++j)
01101                fprintf (SUMA_STDOUT,"%d%s",v[i][j],spc);
01102          fprintf (SUMA_STDOUT,"\n");
01103       }
01104 }/*SUMA_disp_dmat*/

void SUMA_disp_dvect int *    v,
int    l
 

Definition at line 1302 of file SUMA_MiscFunc.c.

Referenced by SUMA_AssignTriBranch().

01303 {   int i;
01304    static char FuncName[]={"SUMA_disp_dvect"};
01305    
01306    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01307 
01308    fprintf (SUMA_STDOUT,"\n");
01309    if ((l-1) == 0)
01310       fprintf (SUMA_STDOUT, "%d\n",*v);
01311    else 
01312    {
01313    for (i=0;i<l;++i)
01314       fprintf (SUMA_STDOUT,"%d\t",v[i]);
01315 
01316    fprintf (SUMA_STDOUT,"\n");
01317    }
01318    SUMA_RETURNe;
01319 }

void SUMA_disp_mat float **    v,
int    nr,
int    nc,
int    SpcOpt
 

**

File : SUMA_MiscFunc.c Author : Ziad Saad Date : Tue Nov 17 13:19:26 CST 1998

Purpose : Displays on the terminal the 2D float matrix

Usage : SUMA_disp_mat (float **v,int nr, int nc, int SpcOpt )

Input paramters : v (float **) the 2D matrix to display nr (int) the number of rows in v nc (int) the number of columns SpcOpt (int) : spacing option (0 for space, 1 for tab and 2 for comma)

Definition at line 1129 of file SUMA_MiscFunc.c.

Referenced by SUMA_Surface_Curvature().

01130 {/*SUMA_disp_mat*/
01131    char spc [40]; 
01132     int i,j;
01133    static char FuncName[]={"SUMA_disp_mat"};
01134       
01135    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01136 
01137    if (!SpcOpt)
01138       sprintf(spc," ");
01139    else if (SpcOpt == 1)
01140       sprintf(spc,"\t");
01141    else
01142       sprintf(spc," , ");
01143    
01144    fprintf (SUMA_STDOUT,"\n");
01145    for (i=0; i < nr; ++i)
01146       {
01147          for (j=0; j < nc; ++j)
01148                fprintf (SUMA_STDOUT, "%4.2f%s",v[i][j],spc);
01149          fprintf (SUMA_STDOUT,"\n");
01150       }
01151 }/*SUMA_disp_mat*/

void SUMA_disp_vecdmat int *    v,
int    nr,
int    nc,
int    SpcOpt
 

**

File : SUMA_MiscFunc.c Author : Ziad Saad Date : Tue Nov 17 13:19:26 CST 1998, modified Tue Aug 20 11:11:29 EDT 2002

Purpose : Displays on the terminal a 2D int matrix stored in a 1D vector

Usage : SUMA_disp_vecdmat (float *v,int nr, int nc, int SpcOpt )

Input paramters : v (int *) (nr x nc) vector containing the 2D matrix to display nr (int) the number of rows in v nc (int) the number of columns SpcOpt (int) : spacing option (0 for space, 1 for tab and 2 for comma)

Definition at line 1224 of file SUMA_MiscFunc.c.

01225 {/*SUMA_disp_vecdmat*/
01226    char spc [40]; 
01227     int i,j;
01228    static char FuncName[]={"SUMA_disp_vectdmat"};
01229       
01230    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01231 
01232    if (!SpcOpt)
01233       sprintf(spc," ");
01234    else if (SpcOpt == 1)
01235       sprintf(spc,"\t");
01236    else
01237       sprintf(spc," , ");
01238    
01239    fprintf (SUMA_STDOUT,"\n");
01240    for (i=0; i < nr; ++i)
01241       {
01242          for (j=0; j < nc; ++j)
01243                fprintf (SUMA_STDOUT, "%d%s",v[i*nc+j],spc);
01244          fprintf (SUMA_STDOUT,"\n");
01245       }
01246 }/*SUMA_disp_vecdmat*/

void SUMA_disp_vecmat float *    v,
int    nr,
int    nc,
int    SpcOpt
 

**

File : SUMA_MiscFunc.c Author : Ziad Saad Date : Tue Nov 17 13:19:26 CST 1998, modified Tue Aug 20 11:11:29 EDT 2002

Purpose : Displays on the terminal a 2D float matrix stored in a vector

Usage : SUMA_disp_vecmat (float *v,int nr, int nc, int SpcOpt )

Input paramters : v (float *) (nr x nc) vector containing the 2D matrix to display nr (int) the number of rows in v nc (int) the number of columns SpcOpt (int) : spacing option (0 for space, 1 for tab and 2 for comma)

Definition at line 1176 of file SUMA_MiscFunc.c.

01177 {/*SUMA_disp_vecmat*/
01178    char spc [40]; 
01179     int i,j;
01180    static char FuncName[]={"SUMA_disp_vecmat"};
01181       
01182    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01183 
01184    if (!SpcOpt)
01185       sprintf(spc," ");
01186    else if (SpcOpt == 1)
01187       sprintf(spc,"\t");
01188    else
01189       sprintf(spc," , ");
01190    
01191    fprintf (SUMA_STDOUT,"\n");
01192    for (i=0; i < nr; ++i)
01193       {
01194          for (j=0; j < nc; ++j)
01195                fprintf (SUMA_STDOUT, "%4.2f%s",v[i*nc+j],spc);
01196          fprintf (SUMA_STDOUT,"\n");
01197       }
01198 }/*SUMA_disp_vecmat*/

void SUMA_disp_vect float *    v,
int    l
 

File : SUMA_MiscFunc.c from disp_vect.c Author : Ziad Saad Date : 23 Oct 1996

Purpose : displays a variable or vector of type float

Usage : void SUMA_disp_vect (float *v,int l);

Input Parameters: v, (float *) pointer to input vector or variable ln, (int) lenght of complex vector, set equal to 1 if vector is a variable

Definition at line 1266 of file SUMA_MiscFunc.c.

Referenced by SUMA_OpenDrawnROI_1D().

01267 { int i;
01268    static char FuncName[]={"SUMA_disp_vect"};
01269    
01270    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01271 
01272    fprintf (SUMA_STDOUT,"\n");
01273    if ((l-1) == 0)
01274       fprintf (SUMA_STDOUT,"%f\n",*v);
01275    else 
01276    {
01277    for (i=0;i<l;++i)
01278                  fprintf (SUMA_STDOUT,"%f\t",v[i]);
01279    fprintf (SUMA_STDOUT,"\n");
01280    }
01281    SUMA_RETURNe;
01282 }

int* SUMA_dqsortrow int **    X,
int    nr,
int    nc
 

Purpose : Sort a matrix of ints by rows Imagine that each row is a word, the function sorts the rows as if in a dictionary list

Usage : int * SUMA_dqsortrow (int **X, int nr, int nc)

Parameters:
X  (int ** ) matrix to sort by rows (if you need to preserve the original version of X you need to make a copy of it before calling the function )
nr  (int) number of rows
nc  (int) number of columns
\ret ndx (int *) index table, such that Xsorted = X(ndx,:);

See also:
SUMA_fqsortrow

Definition at line 2397 of file SUMA_MiscFunc.c.

Referenced by SUMA_Make_Edge_List().

02398 {/*SUMA_dqsortrow*/
02399    static char FuncName[]={"SUMA_dqsortrow"}; 
02400    int k,  *I;
02401    SUMA_QSORTROW_INT *Z_Q_dStrct;
02402    
02403    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02404    
02405    /* allocate for the structure */
02406    Z_Q_dStrct = (SUMA_QSORTROW_INT *) SUMA_calloc(nr, sizeof (SUMA_QSORTROW_INT));
02407    I = (int *) SUMA_calloc (nr,sizeof(int));
02408    
02409    if (!Z_Q_dStrct || !I)
02410       {
02411       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for Z_Q_dStrct || I\n", FuncName);
02412       SUMA_RETURN (NULL);
02413       }
02414 
02415    for (k=0; k < nr; ++k) /* copy the data into a structure */
02416       {
02417          Z_Q_dStrct[k].x = X[k];
02418          Z_Q_dStrct[k].ncol = nc;
02419          Z_Q_dStrct[k].Index = k;
02420       }
02421 
02422    /* sort the structure by comparing the rows in X */
02423    qsort(Z_Q_dStrct, nr, sizeof(SUMA_QSORTROW_INT), (int(*) (const void *, const void *)) compare_SUMA_QSORTROW_INT);
02424 
02425    /* recover the index table */
02426    for (k=0; k < nr; ++k) 
02427       {
02428          X[k] = Z_Q_dStrct[k].x;
02429          I[k] = Z_Q_dStrct[k].Index;
02430       }
02431    
02432    /* free the structure */
02433    SUMA_free(Z_Q_dStrct);
02434 
02435    /* return */
02436    SUMA_RETURN (I);
02437    
02438    
02439 }/*SUMA_dqsortrow*/

void SUMA_error_message char *    s1,
char *    s2,
int    ext
 

Taken from error_message.c Author : Ziad Saad Date : 26 Jan 95

Purpose : displays error message, and exits the program if ext = 1;

Usage : void error_message (s1,s2,ext);

Input Parameters: s1, (char*) pointer to string to be printed for error location. s2, (char*) pointer to string holding error message. ext (int) if ext = 1 the program is aborted

Header Files

Definition at line 950 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_AddDO(), SUMA_FreeSurfer_Read(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_Load_Surface_Object(), SUMA_SetupSVforDOs(), SUMA_SureFit_Read_Coord(), SUMA_SureFit_Read_Topo(), SUMA_SurfaceFileName(), and SUMA_SurfNorm().

00952  {
00953     static char FuncName[]={"SUMA_error_message"};
00954    
00955    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00956 
00957    printf ("\n\n\a\33[1mError: \33[0m%s\n",s2);
00958    printf ("\33[1mError origin:\33[0m %s\n\n",s1);
00959    if (ext == 1)
00960       {
00961         printf ("Exiting Program ..\n\n");
00962          exit (0);
00963       }
00964       else SUMA_RETURNe;
00965    
00966   }

float SUMA_etime struct timeval *    t,
int    Report
 

File : SUMA_MiscFunc.c from ~Zlib/code/etime.c Author : Ziad Saad Date : Mon Dec 28 13:06:36 CST 1998

Purpose : computes the time elapsed between different operations, for example:

float delta_t; struct timeval tt;

SUMA_etime (&tt, 0); :the zero tells the function to start a new counter

:operations are here ......

delta_t = SUMA_etime (&tt, 1); :computes the time between tt the time stamp (set in the previous call) :delta_t is the elapsed time in seconds

Usage : delta_t = SUMA_etime (tt, Report );

Input paramters : tt (struct timeval *) : a pointer that holds the time stamp structure Report (int ) : a (0/1) flag to signal time reporting or the start of a new timer

Returns : delta_t (float) : the time elapsed between the time stamp and the call to etime

Support : include <sys/time.h>

Side effects :

Definition at line 1365 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_BrushStrokeToNodeStroke(), SUMA_Dijkstra(), SUMA_Engine(), SUMA_input(), SUMA_MarkLineSurfaceIntersect(), and SUMA_Surf_Plane_Intersect().

01366 {/*SUMA_etime*/
01367    static char FuncName[]={"SUMA_etime"}; 
01368    struct  timeval  tn;
01369    float Time_Fact = 1000000.0;
01370    float delta_t;
01371 
01372    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01373 
01374    /* get time */
01375    gettimeofday(&tn,0);
01376    
01377    if (Report)
01378       {
01379          delta_t = (((tn.tv_sec - t->tv_sec)*Time_Fact) + (tn.tv_usec - t->tv_usec)) /Time_Fact;
01380       }
01381    else
01382       {
01383          t->tv_sec = tn.tv_sec;
01384          t->tv_usec = tn.tv_usec;
01385          delta_t = 0.0;
01386       }
01387       
01388    SUMA_RETURN (delta_t);
01389    
01390 }/*SUMA_etime*/

char* SUMA_Extension char *    filename,
char *    ext,
SUMA_Boolean    Remove
 

ans = SUMA_Extension(filename, ext, Remove); removes or enforces an arbitrary extension from/to a filename.

Parameters:
filename  (char *) input filename
ext  (char *) extension
Remove  (SUMA_Boolean) YUP = Remove extension if found Do nothing if it is not there already NOPE = Add extension if not there Do nothing if it is there already
Returns:
ans (char*) containing modified filename

  • You must free ans on your own Examples: { char *ans=NULL; ans = SUMA_Extension("Junk.niml.roi", ".niml.roi", YUP); SUMA_LH(ans); SUMA_free(ans);
ans = SUMA_Extension("Junk.niml.roi", ".niml.roi", NOPE); SUMA_LH(ans); SUMA_free(ans);

ans = SUMA_Extension("Junk.niml.roi", ".niml.roxi", NOPE); SUMA_LH(ans); SUMA_free(ans);

ans = SUMA_Extension("Junk.niml.roi", ".niml.roxi", YUP); SUMA_LH(ans); SUMA_free(ans);

ans = SUMA_Extension("Junk.niml.roi", "", YUP); SUMA_LH(ans); SUMA_free(ans);

ans = SUMA_Extension(".roi", "Junk.niml.roi", NOPE); SUMA_LH(ans); SUMA_free(ans);

ans = SUMA_Extension("", "", NOPE); SUMA_LH(ans); SUMA_free(ans);

exit(1); }

Definition at line 265 of file SUMA_StripPath.c.

00266 {
00267    static char FuncName[]={"SUMA_Extension"}; 
00268    char *ans = NULL;
00269    int i, next, nfilename, ifile;
00270    SUMA_Boolean NoMatch = NOPE, LocalHead = NOPE;
00271    
00272    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00273 
00274    if (!filename) SUMA_RETURN(NULL);
00275    nfilename = strlen(filename);
00276    
00277    if (!ext) {
00278       ans = (char *)SUMA_malloc((nfilename+1)*sizeof(char));
00279       ans = strcpy(ans,filename);
00280       SUMA_RETURN(ans);
00281    }
00282    next = strlen(ext);
00283    
00284    if (nfilename < next || next < 1 || nfilename < 1) {
00285       ans = (char *)SUMA_malloc((nfilename+1)*sizeof(char));
00286       ans = strcpy(ans,filename);
00287       SUMA_RETURN(ans);
00288    }
00289    
00290    ifile = nfilename - next;
00291    NoMatch = NOPE;
00292    i = 0;
00293    do {
00294       if (LocalHead) fprintf (SUMA_STDERR,"%s: Comparing %c %c\n", FuncName, filename[ifile+i], ext[i]);
00295       if (filename[ifile+i] != ext[i]) NoMatch = YUP;
00296       ++i;
00297    }  while (ifile < nfilename && i < next && NoMatch);
00298 
00299    if (NoMatch) {
00300       if (Remove) { /* nothing to do */
00301          SUMA_LH("NoMatch, nothing to do");
00302          ans = (char *)SUMA_malloc((nfilename+1)*sizeof(char));
00303          ans = strcpy(ans,filename);
00304          SUMA_RETURN(ans);
00305       } else { /* add extension */
00306          SUMA_LH("NoMatch, adding extensio");
00307          ans = (char *)SUMA_malloc((nfilename+next+1)*sizeof(char));
00308          sprintf(ans,"%s%s", filename, ext);
00309          SUMA_RETURN(ans);
00310       }
00311    }else {
00312       if (Remove) { /* remove it */
00313          SUMA_LH("Match, removing extension");
00314          ans = (char *)SUMA_malloc((nfilename - next+2)*sizeof(char));
00315          for (i=0; i< nfilename - next; ++i)  ans[i] = filename[i];
00316          ans[nfilename - next] = '\0'; /* for good measure */
00317       } else { /* nothing to do */
00318          SUMA_LH("Match, nothing to do");
00319          ans = (char *)SUMA_malloc((nfilename+1)*sizeof(char));
00320          ans = strcpy(ans,filename);
00321          SUMA_RETURN(ans);
00322       }
00323    }
00324    
00325    SUMA_RETURN (ans);
00326 
00327 }   

SUMA_FACESET_FIRST_EDGE_NEIGHB* SUMA_FaceSet_Edge_Neighb int **    EL,
int **    ELps,
int    N_EL
 

returns the FaceSet neighbor list. Neighboring triangles share one edge SFEN = SUMA_FaceSet_Edge_Neighb (EL, ELp, N_EL);

Parameters:
EL  (int **) sorted edge list, output of SUMA_Make_Edge_List
ELps  (int **) accompanying properties matrix, output of SUMA_Make_Edge_List
N_EL  (int) number of edges. IT IS ASSUMED THAT N_FACES = N_EL/3 \ret SFEN (SUMA_FACESET_FIRST_EDGE_NEIGHB *) structure containing the neighbor list see its typedef in SUMA_define.h for more info To free this pointer, make sure you use SUMA_free_FaceSet_Edge_Neighb first

Definition at line 4035 of file SUMA_MiscFunc.c.

04036 {   
04037    static char FuncName[]={"SUMA_FaceSet_Edge_Neighb"};
04038    int i, i1, F0, F1, in0, in1;
04039    SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN;
04040    
04041    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04042 
04043    
04044    SFFN = SUMA_allocate_FaceSet_Edge_Neighb(N_EL/3);
04045    if (SFFN == NULL) {
04046       fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_allocate_FaceSet_Edge_Neighb.\n", FuncName);
04047       SUMA_RETURN (NULL);
04048    }
04049    
04050    i = 0;
04051    while (i < N_EL-1) {
04052       i1 = i + 1;
04053       if (EL[i][0] != EL[i1][0] || EL[i][1] != EL[i1][1]) {
04054          /* edge is part of one triangle only, a cut edge */
04055          i += 1; /* move to next edge */
04056       } else {
04057          F0 = ELps[i][1]; F1 = ELps[i1][1];
04058          in0 = SFFN->N_Neighb[F0]; in1 = SFFN->N_Neighb[F1];
04059          if (in0 > SUMA_MAX_FACESET_EDGE_NEIGHB -1 || in1 > SUMA_MAX_FACESET_EDGE_NEIGHB -1) {
04060             fprintf (SUMA_STDERR, "Error %s: A faceset has more than three neighbors. Bad surface or non triangular mesh\n", FuncName);
04061             SUMA_RETURN (NULL);
04062          }
04063          SFFN->FirstNeighb[F0][in0] = F1; 
04064          SFFN->FirstNeighb[F1][in1] = F0;
04065          SFFN->N_Neighb[F0] ++;
04066          SFFN->N_Neighb[F1] ++;
04067          if (SFFN->N_Neighb[F0] > SFFN->N_Neighb_max) {
04068             SFFN->N_Neighb_max = SFFN->N_Neighb[F0];
04069          }
04070          if (SFFN->N_Neighb[F1] > SFFN->N_Neighb_max) {
04071             SFFN->N_Neighb_max = SFFN->N_Neighb[F1];
04072          }
04073          if (SFFN->N_Neighb[F0] < SFFN->N_Neighb_min) {
04074             SFFN->N_Neighb_min = SFFN->N_Neighb[F0];
04075          }
04076          if (SFFN->N_Neighb[F1] < SFFN->N_Neighb_min) {
04077             SFFN->N_Neighb_min = SFFN->N_Neighb[F1];
04078          }
04079          
04080          i += 2;
04081       }
04082    
04083    }
04084    
04085    fprintf (SUMA_STDERR, "%s: Done with FaceSet neighbors.\nN_Neighb_max = %d, N_Neighb_min = %d.\n", FuncName, SFFN->N_Neighb_max, SFFN->N_Neighb_min);
04086    #if 0
04087    for (i=0; i< N_FL; ++i) {
04088       fprintf (SUMA_STDERR, "%s: Tri %d, %d neighbs = ", FuncName, i, SFFN->N_Neighb[i]);
04089       for (i1=0; i1<SFFN->N_Neighb[i]; ++i1) {
04090          fprintf (SUMA_STDERR, "%d, ", SFFN->FirstNeighb[i][i1]); 
04091       }
04092       fprintf (SUMA_STDERR, "\n");
04093    }
04094    #endif
04095    
04096    SUMA_RETURN (SFFN);
04097 }   

int SUMA_filexists char *    f_name
 

Taken from filexists returns 1 if file can be read/found

Definition at line 315 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_FreeSurfer_Read(), SUMA_FS_Write(), SUMA_Load_Surface_Object(), SUMA_Ply_Write(), SUMA_Read_SpecFile(), SUMA_Read_SureFit_Param(), SUMA_RenderToPixMap(), SUMA_SureFit_Read_Coord(), SUMA_SureFit_Read_Topo(), SUMA_SureFit_Write(), and SUMA_VEC_Write().

00316 {/*SUMA_filexists*/
00317     FILE *outfile;
00318     static char FuncName[]={"SUMA_filexists"};
00319    
00320    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00321 
00322     outfile = fopen (f_name,"r");
00323     if (outfile == NULL) {
00324        SUMA_RETURN(0); 
00325    }
00326     else {
00327        fclose (outfile); 
00328    }
00329     
00330    SUMA_RETURN(1);
00331        
00332 }/*SUMA_filexists*/

int* SUMA_Find_inIntVect int *    x,
int    xsz,
int    val,
int *    nValLocation
 

Definition at line 5634 of file SUMA_MiscFunc.c.

05635 {/*SUMA_Find_inIntVect*/
05636    int k, *tmp, *ValLocation;
05637    static char FuncName[]={"SUMA_Find_inIntVect"};
05638    SUMA_Boolean LocalHead = NOPE;
05639    
05640    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05641 
05642    /* allocate the maximum  space for ValLocation */
05643    tmp = (int *) SUMA_calloc(xsz,sizeof(int));
05644 
05645    *nValLocation = 0;
05646    for (k = 0 ; k < xsz ; ++k)
05647    {
05648       if (x[k] == val)
05649          {
05650             tmp[*nValLocation] = k;
05651             ++*nValLocation;
05652          }
05653 
05654    }
05655 
05656    if (!*nValLocation)
05657       {
05658          SUMA_free (tmp);
05659          SUMA_RETURN (NULL);
05660       }
05661 
05662    /* Now, allocate just enough space for the SUMA_RETURNing vector */
05663       ValLocation = (int *) SUMA_calloc(*nValLocation,sizeof(int));
05664    /*copy the data into ValLocation*/
05665       SUMA_SCALE_VEC(tmp,ValLocation,1,*nValLocation,int,int);
05666    /* get rid of big array */
05667       SUMA_free(tmp);
05668 
05669    SUMA_RETURN (ValLocation);
05670 
05671 }/*SUMA_Find_inIntVect*/

int SUMA_FindEdge SUMA_EDGE_LIST   EL,
int    n1,
int    n2
 

finds the first occurence in EL of an edge formed by nodes n1 n2 eloc = SUMA_FindEdge (EL, int n1, int n2);.

Parameters:
EL  (SUMA_EDGE_LIST *) Pointer to edge list structure
n1  (int) index of node 1
n2  (int) index of node 2
Returns:
eloc (int) index into EL of first occurence of edge formed by nodes n1, n2 -1 if no edge is found.

Definition at line 3842 of file SUMA_MiscFunc.c.

Referenced by SUMA_NodePath_to_EdgePath(), SUMA_NodePath_to_TriPath_Inters(), and SUMA_NodeStrokeToConnectedNodes().

03843 {
03844    static char FuncName[]={"SUMA_FindEdge"};
03845    int eloc;
03846    SUMA_Boolean LocalHead = NOPE;
03847    
03848    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03849 
03850    /* make sure n1 is smallest*/
03851    if (n2 < n1) {
03852       eloc = n2; 
03853       n2 = n1; 
03854       n1 = eloc;
03855    }
03856    
03857    /* first location of edge starting with n1 */
03858    if ((eloc = EL->ELloc[n1]) < 0) {
03859       SUMA_S_Err ("Edge location of n1 not found. WEIRD");
03860       SUMA_RETURN (-1);
03861    }
03862    
03863    /* from there on, look for first occurence of n2 */
03864    do {
03865       /* if (LocalHead) fprintf (SUMA_STDERR,"%s: eloc %d, N_EL %d\n", FuncName, eloc, EL->N_EL);*/
03866       if (EL->EL[eloc][1] == n2) SUMA_RETURN (eloc);
03867       ++eloc;
03868    } while (eloc < EL->N_EL && EL->EL[eloc][0] == n1); 
03869    
03870    /* not found */
03871    SUMA_RETURN (-1);
03872 }

int SUMA_FindEdgeInTri SUMA_EDGE_LIST   EL,
int    n1,
int    n2,
int    Tri
 

finds the index of an edge in EL of an edge formed by nodes n1 n2 and belonging to triangle Tri eloc = SUMA_FindEdgeInTri (EL, int n1, int n2, int Tri);.

Parameters:
EL  (SUMA_EDGE_LIST *) Pointer to edge list structure
n1  (int) index of node 1
n2  (int) index of node 2
Tri  (int) index of triangle containing the edge you are looking for
Returns:
eloc (int) index into EL of edge formed by nodes n1, n2 and belonging to Tri -1 if no edge is found.

Definition at line 3805 of file SUMA_MiscFunc.c.

Referenced by SUMA_IntersectionStrip().

03806 {
03807    static char FuncName[]={"SUMA_FindEdgeInTri"};
03808    int eloc;
03809    
03810    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03811 
03812    /* make sure n1 is smallest*/
03813    if (n2 < n1) {
03814       eloc = n2; 
03815       n2 = n1; 
03816       n1 = eloc;
03817    }
03818    
03819    /* first location of edge starting with n1 */
03820    eloc = EL->ELloc[n1];
03821    
03822    /* from there on, look for first occurence of n2 and Tri for hosting triangle*/
03823    do {
03824       if (EL->EL[eloc][1] == n2 && EL->ELps[eloc][1] == Tri) SUMA_RETURN (eloc);
03825       ++eloc;
03826    } while (eloc < EL->N_EL && EL->EL[eloc][0] == n1); 
03827    
03828    /* not found */
03829    SUMA_RETURN (-1);
03830 }

int SUMA_float_file_size char *    f_name
 

count the number of float values in a file -1 if the file could not be open

Definition at line 704 of file SUMA_MiscFunc.c.

Referenced by SUMA_input(), SUMA_Load_Surface_Object(), and SUMA_LoadColorPlaneFile().

00705 { 
00706    int cnt=0,ex;
00707    float buf;
00708    static char FuncName[]={"SUMA_float_file_size"};
00709    FILE*internal_file;
00710    
00711    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00712 
00713    internal_file = fopen (f_name,"r");
00714    if (internal_file == NULL) {
00715                           printf ("\aCould not open %s \n",f_name);
00716                           SUMA_RETURN (-1);
00717                           }
00718    ex = fscanf (internal_file,"%f",&buf);                     
00719    while (ex != EOF)
00720    {
00721      ++cnt;
00722      ex = fscanf (internal_file,"%f",&buf);
00723    }
00724 
00725 
00726    fclose (internal_file);
00727    SUMA_RETURN (cnt);                            
00728 }

int* SUMA_fqsortrow float **    X,
int    nr,
int    nc
 

Purpose : Sort a matrix of floats by rows Imagine that each row is a word, the function sorts the rows as if in a dictionary list

Usage : int * SUMA_fqsortrow (float **X , int nr, int nc )

Parameters:
X  (float ** ) matrix to sort by rows (if you need to preserve the original version of X you need to make a copy of it before calling the function )
nr  (int) number of rows
nc  (int) number of columns
\ret ndx (int *) index table, such that Xsorted = X(ndx,:);

See also:
SUMA_dqsortrow

Definition at line 2308 of file SUMA_MiscFunc.c.

02309 {/*SUMA_fqsortrow*/
02310    static char FuncName[]={"SUMA_fqsortrow"}; 
02311    int k, *I;
02312    SUMA_QSORTROW_FLOAT *Z_Q_fStrct;
02313    
02314       
02315    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02316 
02317    /* allocate for the structure */
02318    Z_Q_fStrct = (SUMA_QSORTROW_FLOAT *) SUMA_calloc(nr, sizeof (SUMA_QSORTROW_FLOAT));
02319    I = (int *) SUMA_calloc (nr,sizeof(int));
02320    
02321    if (!Z_Q_fStrct || !I)
02322       {
02323       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for Z_Q_fStrct || I\n", FuncName);
02324       SUMA_RETURN (NULL);
02325       }
02326 
02327    for (k=0; k < nr; ++k) /* copy the data into a structure */
02328       {
02329          Z_Q_fStrct[k].x = X[k];
02330          Z_Q_fStrct[k].ncol = nc;
02331          Z_Q_fStrct[k].Index = k;
02332       }
02333 
02334    /* sort the structure by comparing the rows in X */
02335    qsort(Z_Q_fStrct, nr, sizeof(SUMA_QSORTROW_FLOAT), (int(*) (const void *, const void *)) compare_SUMA_QSORTROW_FLOAT);
02336 
02337    /* recover the index table */
02338    for (k=0; k < nr; ++k) 
02339       {
02340          X[k] = Z_Q_fStrct[k].x;
02341          I[k] = Z_Q_fStrct[k].Index;
02342       }
02343    
02344    /* free the structure */
02345    SUMA_free(Z_Q_fStrct);
02346 
02347    /* return */
02348    SUMA_RETURN (I);
02349    
02350    
02351 }/*SUMA_fqsortrow*/

void SUMA_free2D char **    a,
int    rows
 

Taken from free2D.c - Free all elements of matrix

Frees the 2D array (rows and cols) allocated using allocate2D

Error message and exit if improper structure is passed to it (null pointers or zero size matrix).

void free2D(char **a, int rows);

This function was adapted from DSP_in_C functions in C Language Algorithms for Digital Signal Processing by Bruce Kimball, Paul Embree and Bruce Kimble 1991, Prentice Hall

Ziad Saad Oct_22_96

This function should not use SUMA_free for freeing the pointers making up the matrix. Doing so would result in very slow execution times.

Definition at line 893 of file SUMA_MiscFunc.c.

Referenced by SUMA_Build_FirstNeighb(), SUMA_Engine(), SUMA_Free_ColorMap(), SUMA_Free_ColorScaledVect(), SUMA_free_Edge_List(), SUMA_free_FaceSet_Edge_Neighb(), SUMA_Free_FirstNeighb(), SUMA_Free_MemberFaceSets(), SUMA_Free_SureFit(), SUMA_Free_SURFACE_CURVATURE(), SUMA_FreeEngineData(), SUMA_FreeEngineListData(), SUMA_FreeOverlayPointer(), SUMA_GetStandardMap(), SUMA_input(), SUMA_Make_Edge_List(), SUMA_MemberFaceSets(), SUMA_PolySurf3(), SUMA_ReleaseEngineData(), and SUMA_Surface_Curvature().

00894 {
00895    int i;
00896    static char FuncName[]={"SUMA_free2D"};
00897    
00898    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00899 
00900 
00901       #if SUMA_MEMTRACE_FLAG
00902          if (SUMAg_CF->MemTrace && a) {
00903             SUMA_Boolean Found = NOPE;
00904             for (i=0; i < SUMAg_CF->Mem->N_alloc && !Found; ++i) {
00905                if (SUMAg_CF->Mem->Pointers[i] == a) {
00906                   SUMAg_CF->Mem->Pointers[i] = SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1];
00907                   SUMAg_CF->Mem->Size[i] = SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1];
00908                   SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = NULL;
00909                   SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = 0;
00910                   --SUMAg_CF->Mem->N_alloc;
00911                   Found = YUP;
00912                }
00913             }
00914             if (!Found) {
00915               fprintf (SUMA_STDERR, "Error %s: Pointer %p not found in Mem struct. \n", FuncName,a); 
00916             }
00917          }
00918       #endif
00919 
00920    /* free each row of data */
00921    for(i = 0 ; i < rows ; i++) free(a[i]);
00922 
00923    /* free each row pointer */
00924    free((char *)a);
00925    a = NULL;           /* set to null for error */
00926 
00927    SUMA_RETURNe;
00928 }

void SUMA_free_Edge_List SUMA_EDGE_LIST   SEL
 

SUMA_free_Edge_List (SEL)

Parameters:
SEL  (SUMA_EDGE_LIST *)

Definition at line 3555 of file SUMA_MiscFunc.c.

Referenced by SUMA_Free_Surface_Object(), and SUMA_GetContour().

03556 {
03557    static char FuncName[]={"SUMA_free_Edge_List"};
03558    
03559    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03560 
03561    if (SEL->EL) SUMA_free2D((char **)SEL->EL, SEL->N_EL);
03562    if (SEL->ELloc) SUMA_free(SEL->ELloc);
03563    if (SEL->ELps) SUMA_free2D((char **)SEL->ELps, SEL->N_EL);
03564    if (SEL->Tri_limb) SUMA_free2D((char **)SEL->Tri_limb, SEL->N_EL/3);
03565    if (SEL) SUMA_free(SEL);
03566    SUMA_RETURNe;
03567 }

SUMA_Boolean SUMA_Free_FirstNeighb SUMA_NODE_FIRST_NEIGHB   FN
 

frees the Node Neighbor structure formed in SUMA_Build_FirstNeighb

Definition at line 4549 of file SUMA_MiscFunc.c.

Referenced by SUMA_Build_FirstNeighb(), and SUMA_Free_Surface_Object().

04550 {
04551    static char FuncName[]={"SUMA_Free_FirstNeighb"};
04552    
04553    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04554 
04555    if (FN->NodeId) SUMA_free(FN->NodeId);
04556    if (FN->N_Neighb) SUMA_free(FN->N_Neighb);
04557    if (FN->FirstNeighb) SUMA_free2D ((char **)FN->FirstNeighb, FN->N_Node);
04558    if (FN) SUMA_free(FN);
04559    SUMA_RETURN (YUP);
04560 }

void* SUMA_free_fn const char *    CallingFunc,
void *    ptr
 

ptr = SUMA_free(const char *CF, ptr);

Parameters:
CF  (const char *) name of calling function
ptr  (void *)
Returns:
NULL
This function is the complement of SUMA_malloc_fn and SUMA_calloc_fn, it keeps track of freed memory. Its usage is slightly different from that of C's free function in that the function always returns a NULL so that one could with one function call free a pointer and set it to NULL.

Even if you are not tracking memory usage, this function checks that ptr is !NULL before freeing it. If you are doing massive amounts of freeing you may not want to use this function.

Definition at line 169 of file SUMA_MiscFunc.c.

00170    {
00171       static char FuncName[]={"SUMA_free_fn"};
00172       int i;
00173 
00174       #if SUMA_MEMTRACE_FLAG
00175          if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00176       #endif
00177 
00178 
00179       /* This block is also used in SUMA_free2D */
00180       #if SUMA_MEMTRACE_FLAG
00181 
00182          if (SUMAg_CF->MemTrace && ptr) {
00183             SUMA_Boolean Found = NOPE;
00184             for (i=0; i < SUMAg_CF->Mem->N_alloc && !Found; ++i) {
00185                if (SUMAg_CF->Mem->Pointers[i] == ptr) {
00186                   SUMAg_CF->Mem->Pointers[i] = SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1];
00187                   SUMAg_CF->Mem->Size[i] = SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1];
00188                   SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = NULL;
00189                   SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = 0;
00190                   --SUMAg_CF->Mem->N_alloc;
00191                   Found = YUP;
00192                }
00193             }
00194             if (!Found) {
00195               fprintf (SUMA_STDERR, "Error %s: Pointer %p not found in Mem struct. \n\tOffending Calling Function is %s\n", FuncName,ptr, CF); 
00196             }
00197          }
00198 
00199          if (ptr) free (ptr); 
00200          SUMA_RETURN(NULL);
00201       #else
00202          if (ptr) free (ptr); 
00203          return (NULL);
00204       #endif
00205    }

SUMA_IRGB* SUMA_Free_IRGB SUMA_IRGB   irgb
 

function to free SUMA_IRGB *.

Returns:
NULL
See also:
SUMA_Create_IRGB
  • This function frees all vectors in structure and the structure itself

Definition at line 574 of file SUMA_MiscFunc.c.

Referenced by SUMA_LoadColorPlaneFile(), and SUMA_Read_IRGB_file().

00575 {
00576    static char FuncName[]={"SUMA_Free_IRGB"};
00577    
00578    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00579    
00580    if (irgb) {
00581       if (irgb->i) SUMA_free(irgb->i);
00582       if (irgb->r) SUMA_free(irgb->r);
00583       if (irgb->g) SUMA_free(irgb->g);
00584       if (irgb->b) SUMA_free(irgb->b);
00585       SUMA_free(irgb);
00586    }
00587    
00588    SUMA_RETURN(NULL);
00589 }

SUMA_Boolean SUMA_Free_IsInBox SUMA_ISINBOX   IB
 

free SUMA_ISINBOX structure contents. Structure pointer is not freed

Definition at line 1669 of file SUMA_MiscFunc.c.

Referenced by SUMA_Engine(), SUMA_XYZ_XYZmap(), and SUMA_XYZmap_XYZ().

01670 {
01671    static char FuncName[]={"SUMA_Free_IsInBox"};
01672    
01673    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01674 
01675    if (IB == NULL) {
01676       fprintf (SUMA_STDERR,"Error SUMA_Free_IsInBox: pointer to null cannot be freed\n");
01677       SUMA_RETURN (NOPE);
01678    }
01679    if (IB->IsIn != NULL) SUMA_free(IB->IsIn);
01680    if (IB->d != NULL) SUMA_free(IB->d);
01681    IB->nIsIn = 0;
01682    SUMA_RETURN (YUP);   
01683 }

SUMA_Boolean SUMA_Free_MemTrace SUMA_MEMTRACE_STRUCT   Mem
 

Definition at line 301 of file SUMA_MiscFunc.c.

Referenced by SUMA_Free_CommonFields().

00301                                                              {
00302    static char FuncName[]={"SUMA_Free_MemTrace"};
00303          
00304    /* DO NOT USE SUMA_free function here ! */
00305    if (Mem->Pointers) free (Mem->Pointers);
00306    if (Mem->Size) free(Mem->Size);
00307    if (Mem) free (Mem);
00308    
00309    return(YUP);
00310 }

void* SUMA_Free_MT_intersect_triangle SUMA_MT_INTERSECT_TRIANGLE   MTI
 

free structure SUMA_MT_INTERSECT_TRIANGLE, returns NULL so you should use it as such: MTI = SUMA_Free_MT_intersect_triangle (MTI);.

See also:
SUMA_MT_intersect_triangle to find out why it is important to set MTI to NULL after freeing it

Definition at line 2901 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_BrushStrokeToNodeStroke(), SUMA_inNodeNeighb(), SUMA_MapSurface(), SUMA_MarkLineSurfaceIntersect(), and SUMA_MT_intersect_triangle().

02902 {
02903    static char FuncName[]={"SUMA_Free_MT_intersect_triangle"};
02904    
02905    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02906 
02907    if (MTI->t) SUMA_free(MTI->t);
02908    if (MTI->u) SUMA_free(MTI->u);
02909    if (MTI->v) SUMA_free(MTI->v);
02910    if (MTI->isHit) SUMA_free(MTI->isHit);
02911    if (MTI) SUMA_free(MTI);
02912    SUMA_RETURN(NULL);
02913 }

void* SUMA_Free_Parsed_Name SUMA_PARSED_NAME   Test
 

Definition at line 328 of file SUMA_StripPath.c.

00329 {
00330    static char FuncName[]={"SUMA_Free_Parsed_Name"}; 
00331 
00332    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00333 
00334    if (!Test) SUMA_RETURN (NULL);
00335    if (Test->Path) SUMA_free(Test->Path);
00336    if (Test->FileName) SUMA_free(Test->FileName);
00337    if (Test->Ext) SUMA_free(Test->Ext);
00338    if (Test->FileName_NoExt) SUMA_free(Test->FileName_NoExt);
00339    SUMA_free(Test);
00340    
00341    SUMA_RETURN (NULL);
00342 }

void SUMA_Free_SURFACE_CURVATURE SUMA_SURFACE_CURVATURE   SC
 

free the SUMA_SURFACE_CURVATURE structure

Definition at line 5147 of file SUMA_MiscFunc.c.

Referenced by SUMA_Free_Surface_Object(), and SUMA_Surface_Curvature().

05148 {
05149    static char FuncName[]={"SUMA_Free_SURFACE_CURVATURE"};
05150    
05151    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05152 
05153    if (SC == NULL) SUMA_RETURNe;
05154    if (SC->Kp1) SUMA_free(SC->Kp1);
05155    if (SC->Kp2) SUMA_free(SC->Kp2);
05156    if (SC->T1) SUMA_free2D ((char **)SC->T1, SC->N_Node);
05157    if (SC->T2) SUMA_free2D ((char **)SC->T2, SC->N_Node);
05158    if (SC) SUMA_free(SC);
05159    SUMA_RETURNe;
05160 }

SUMA_Boolean SUMA_FromToRotation float *    v0,
float *    v1,
float **    mtx
 

Code from Tomas Möller, John Hughes 1999: Tomas Möller and John F. Hughes. Efficiently building a matrix to rotate one vector to another. Journal of graphics tools, 4(4):1-4, 1999

SUMA_Boolean SUMA_FromToRotation (float *v0, float *v1, float **mtx)

determines rotation matrix required to rotate vector from to vector to

Parameters:
v0  (float *) 3x1 vector to be rotated into v1
v1  (float *) 3x1 vector
mtx  (float *) 4x4 matrix containing 3x3 rotation matrix in the top left corner
\ret YUP/NOPE

See also:
SUMA_mattoquat

Definition at line 2932 of file SUMA_MiscFunc.c.

Referenced by SUMA_Engine().

02933 {/* SUMA_FromToRotation */
02934    char FuncName[]={"SUMA_FromToRotation"};
02935    float v[3], vn;
02936    float e, h, f;
02937 
02938    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02939 
02940    /*normalize both vectors */
02941    vn = sqrt(v0[0]*v0[0] + v0[1]*v0[1] + v0[2]*v0[2]);
02942    if (vn == 0.0) {
02943       fprintf(SUMA_STDERR,"Error %s: v0 is null.\n",FuncName);
02944       SUMA_RETURN (NOPE);
02945    }
02946    v0[0] /= vn;
02947    v0[1] /= vn;
02948    v0[2] /= vn;
02949 
02950    vn = sqrt(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]);
02951    if (vn == 0.0) {
02952       fprintf(SUMA_STDERR,"Error %s: v1 is null.\n",FuncName);
02953       SUMA_RETURN (NOPE);
02954    }
02955    v1[0] /= vn;
02956    v1[1] /= vn;
02957    v1[2] /= vn;
02958 
02959    SUMA_MT_CROSS(v, v0, v1);
02960    e = SUMA_MT_DOT(v0, v1);
02961    f = (e < 0)? -e:e;
02962    if (f > 1.0 - SUMA_EPSILON)     /* "v0" and "v1"-vector almost parallel */
02963    {
02964       float u[3], v[3]; /* temporary storage vectors */
02965       float x[3];       /* vector most nearly orthogonal v1 "v0" */
02966       float c1, c2, c3; /* coefficients for later use */
02967       int i, j;
02968 
02969       x[0] = (v0[0] > 0.0)? v0[0] : -v0[0];
02970       x[1] = (v0[1] > 0.0)? v0[1] : -v0[1];
02971       x[2] = (v0[2] > 0.0)? v0[2] : -v0[2];
02972 
02973       if (x[0] < x[1]) 
02974       {
02975          if (x[0] < x[2]) 
02976          {
02977            x[0] = 1.0; x[1] = x[2] = 0.0;
02978          }
02979          else 
02980          {
02981            x[2] = 1.0; x[0] = x[1] = 0.0;
02982          }
02983       }
02984       else 
02985       {
02986          if (x[1] < x[2]) 
02987          {
02988            x[1] = 1.0; x[0] = x[2] = 0.0;
02989          }
02990          else 
02991          {
02992            x[2] = 1.0; x[0] = x[1] = 0.0;
02993          }
02994       }
02995 
02996       u[0] = x[0] - v0[0]; u[1] = x[1] - v0[1]; u[2] = x[2] - v0[2];
02997       v[0] = x[0] - v1[0];   v[1] = x[1] - v1[1];   v[2] = x[2] - v1[2];
02998 
02999       c1 = 2.0 / SUMA_MT_DOT(u, u);
03000       c2 = 2.0 / SUMA_MT_DOT(v, v);
03001       c3 = c1 * c2  * SUMA_MT_DOT(u, v);
03002 
03003       for (i = 0; i < 3; i++) {
03004          for (j = 0; j < 3; j++) {
03005            mtx[i][j] =  - c1 * u[i] * u[j]
03006                         - c2 * v[i] * v[j]
03007                         + c3 * v[i] * u[j];
03008          }
03009          mtx[i][i] += 1.0;
03010       }
03011    }
03012    else  /* the most common case, unless "v0"="v1", or "v0"=-"v1" */
03013    {
03014       #if 0
03015          /* unoptimized version - a good compiler will optimize this. */
03016          h = (1.0 - e)/SUMA_MT_DOT(v, v);
03017          mtx[0][0] = e + h * v[0] * v[0];  
03018          mtx[0][1] = h * v[0] * v[1] - v[2]; 
03019          mtx[0][2] = h * v[0] * v[2] + v[1];
03020 
03021          mtx[1][0] = h * v[0] * v[1] + v[2]; 
03022          mtx[1][1] = e + h * v[1] * v[1];    
03023          mtx[1][2] = h * v[1] * v[2] - v[0];
03024 
03025          mtx[2][0] = h * v[0] * v[2] - v[1]; 
03026          mtx[2][1] = h * v[1] * v[2] + v[0]; 
03027          mtx[2][2] = e + h * v[2] * v[2];
03028       #else
03029          /* ...otherwise use this hand optimized version (9 mults less) */
03030          float hvx, hvz, hvxy, hvxz, hvyz;
03031          h = (1.0 - e)/SUMA_MT_DOT(v, v);
03032          hvx = h * v[0];
03033          hvz = h * v[2];
03034          hvxy = hvx * v[1];
03035          hvxz = hvx * v[2];
03036          hvyz = hvz * v[1];
03037          mtx[0][0] = e + hvx * v[0]; 
03038          mtx[0][1] = hvxy - v[2];     
03039          mtx[0][2] = hvxz + v[1];
03040 
03041          mtx[1][0] = hvxy + v[2];  
03042          mtx[1][1] = e + h * v[1] * v[1]; 
03043          mtx[1][2] = hvyz - v[0];
03044 
03045          mtx[2][0] = hvxz - v[1];  
03046          mtx[2][1] = hvyz + v[0];     
03047          mtx[2][2] = e + hvz * v[2];
03048       #endif
03049    }   
03050    
03051    mtx[0][3] = 0.0;
03052    mtx[1][3] = 0.0;
03053    mtx[2][3] = 0.0;
03054    mtx[3][0] = 0.0;
03055    mtx[3][1] = 0.0;
03056    mtx[3][2] = 0.0;
03057    mtx[3][3] = 1.0;
03058    SUMA_RETURN (YUP);
03059 }

SUMA_Boolean SUMA_Get_Incident int    n1,
int    n2,
SUMA_EDGE_LIST   SEL,
int *    Incident,
int *    N_Incident
 

finds triangles incident to an edge ans = SUMA_Get_Incident( n1, n2, SEL, Incident, N_Incident);.

Parameters:
n1  (int) node 1
n2  (int) node 2
SEL  (SUMA_EDGE_LIST *) Edge List structure
Incident  (int *) a pre-allocated vector where incident triangle indices will be stored. MAKE SURE you allocate enough
N_Incident  (int *) pointer where the number of incident triangles is stored
\ret ans (SUMA_Boolean) YUP/NOPE

See also:
SUMA_Make_Edge_List , SUMA_Get_NodeIncident

Definition at line 3934 of file SUMA_MiscFunc.c.

Referenced by SUMA_FromIntEdgeToIntEdge(), SUMA_inNodeNeighb(), SUMA_IntersectionStrip(), SUMA_Surface_Curvature(), and SUMA_whichTri().

03935 {
03936    static char FuncName[] = {"SUMA_Get_Incident"};
03937    int nt, in1, iseek, m_N_EL;
03938    
03939    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03940 
03941    /*fprintf(SUMA_STDERR,"Entering %s: n1,n2 =%d,%d ...", FuncName,n1,n2);*/
03942    if (n1 > n2) {
03943       /*make the first node be the smallest */
03944       nt = n1;
03945       n1 = n2;
03946       n2 = nt;
03947    }
03948    
03949    /* find the location of the first edge with n1 */
03950    in1 = SEL->ELloc[n1];
03951    iseek = in1;
03952    m_N_EL = SEL->N_EL -1;
03953    *N_Incident = 0;
03954    while (SEL->EL[iseek][0] == n1) {
03955       if (SEL->EL[iseek][1] == n2) {
03956          Incident[*N_Incident] = SEL->ELps[iseek][1]; /* store the faceset index containing the edge */
03957          *N_Incident = *N_Incident + 1;
03958       }
03959       ++iseek;
03960       if (iseek > m_N_EL) {
03961          if (!*N_Incident) fprintf(SUMA_STDERR,"Warning %s: No Incident FaceSets found!\n", FuncName);
03962          SUMA_RETURN (YUP);
03963       }
03964       
03965    }
03966    if (!*N_Incident) fprintf(SUMA_STDERR,"Warning %s: No Incident FaceSets found!\n", FuncName);
03967    /*fprintf(SUMA_STDERR,"Leaving %s.\n", FuncName);*/
03968    SUMA_RETURN(YUP);   
03969 }

SUMA_Boolean SUMA_Get_NodeIncident int    n1,
SUMA_SurfaceObject   SO,
int *    Incident,
int *    N_Incident
 

finds triangles incident to a node ans = SUMA_Get_NodeIncident(n1, SEL, Incident, N_Incident);.

Parameters:
n1  (int) node 1
SO  (SUMA_SurfaceObject *)
Incident  (int *) a pre-allocated vector where incident triangle indices will be stored. MAKE SURE you allocate enough
N_Incident  (int *) pointer where the number of incident triangles is stored
\ret ans (SUMA_Boolean) YUP/NOPE

See also:
SUMA_Make_Edge_List , SUMA_Get_Incident

Definition at line 3888 of file SUMA_MiscFunc.c.

03889 {
03890    static char FuncName[] = {"SUMA_Get_NodeIncident"};
03891    int i, n3, N_Neighb;
03892    
03893    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03894    
03895    *N_Incident = 0;
03896    
03897    N_Neighb = SO->FN->N_Neighb[n1];
03898    if (N_Neighb < 3) {
03899       fprintf (SUMA_STDERR, "Warning %s: Node %d has less than 3 neighbors.\n", FuncName, n1);
03900       /* nothing found */
03901       SUMA_RETURN(YUP);
03902    }
03903    
03904    i = 0;
03905    while ((i < N_Neighb )) { 
03906       if ( i+1 == N_Neighb) n3 = SO->FN->FirstNeighb[n1][0];
03907       else n3 = SO->FN->FirstNeighb[n1][i+1];
03908       if ((Incident[*N_Incident] = SUMA_whichTri (SO->EL, n1, SO->FN->FirstNeighb[n1][i], n3)) < 0) {
03909          fprintf (SUMA_STDERR, "Error %s: Triangle formed by nodes %d %d %d not found.\n", 
03910             FuncName, n1, SO->FN->FirstNeighb[n1][i], n3);
03911          SUMA_RETURN(NOPE);
03912       }
03913       ++*N_Incident;
03914       ++i;
03915    }
03916 
03917    SUMA_RETURN(YUP);   
03918 }

SUMA_Boolean SUMA_Householder float *    Ni,
float **    Q
 

Definition at line 5178 of file SUMA_MiscFunc.c.

Referenced by SUMA_Surface_Curvature().

05179 {
05180    static char FuncName[] = {"SUMA_Householder"};
05181    float mNi, e[3], b[3], mb;
05182    int ii;
05183    #ifdef TAUBIN_Householder
05184    float d[3], s[3], nd, ns;
05185    #endif
05186 
05187    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05188    
05189    e[0] = 1.0; e[1] = 0.0; e[2] = 0.0;
05190    
05191    #ifndef TAUBIN_Householder
05192       /* generic algorithm */
05193       mNi = sqrt(Ni[0] * Ni[0] + Ni[1] * Ni[1] + Ni[2] * Ni[2]);
05194       for (ii=0; ii < 3; ++ii) 
05195          b[ii] = Ni[ii] + mNi * e[ii];
05196       mb = sqrt(b[0] * b[0] + b[1] * b[1] + b[2] * b[2]);
05197 
05198       if (mb == 0) {
05199          fprintf (SUMA_STDERR,"Error %s: mb = 0\n",FuncName);
05200          SUMA_RETURN (NOPE);
05201       }
05202 
05203       b[0] /= mb; b[1] /= mb; b[2] /= mb;
05204    #else
05205       /* Taubin's algorithm Estimating the tensor of curvature of a surface from a polyhedral approximation */ 
05206       /* calculate difference and sum vectors with their norms (save sqrt for later) */
05207       
05208       d[0] = e[0] - Ni[0]; d[1] = e[1] - Ni[1]; d[2] = e[2] - Ni[2]; 
05209       nd = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
05210       
05211       s[0] = e[0] + Ni[0]; s[1] = e[1] + Ni[1]; s[2] = e[2] + Ni[2];
05212       ns = s[0]*s[0] + s[1]*s[1] + s[2]*s[2];
05213       
05214       if (!nd || !ns) {
05215          fprintf (SUMA_STDERR,"Error %s: nd || ns = 0\n",FuncName);
05216          SUMA_RETURN (NOPE);
05217       }
05218       
05219       if (nd > ns) {
05220          nd = sqrt(nd);
05221          b[0] = d[0] / nd;
05222          b[1] = d[1] / nd;
05223          b[2] = d[2] / nd;
05224          /*Q(:,1) will be equal to -Ni*/
05225          
05226       } else {
05227          ns = sqrt(ns);
05228          b[0] = s[0] / ns;
05229          b[1] = s[1] / ns;
05230          b[2] = s[2] / ns;
05231          /*Q(:,1) will be equal to  Ni */
05232       }
05233       
05234    #endif 
05235    
05236    /* calc Q = I - 2 b * b' */
05237    Q[0][0] = 1 - 2 * b[0] * b[0];
05238    Q[1][0] = - 2 * b[1] * b[0];
05239    Q[2][0] = - 2 * b[2] * b[0];
05240 
05241    Q[0][1] = - 2 * b[0] * b[1];
05242    Q[1][1] = 1 - 2 * b[1] * b[1];
05243    Q[2][1] = - 2 * b[2] * b[1];
05244 
05245    Q[0][2] = - 2 * b[0] * b[2];
05246    Q[1][2] = - 2 * b[1] * b[2];
05247    Q[2][2] = 1 - 2 * b[2] * b[2];
05248 
05249    SUMA_RETURN (YUP);   
05250 }

int SUMA_isConsistent int *    T,
int *    t
 

This function compares the winding of two triangles, determines their consistency and corrects it.

Parameters:
T  (int *) a b c nodes forming the reference triangle
t  (int *) d c b (or whatever combination you choose, c b d for example)
Returns:
1: Consistent -1: Inconsisten 0: less than 2 nodes shared

Definition at line 3219 of file SUMA_MiscFunc.c.

Referenced by SUMA_Take_A_Hike().

03220 {
03221    static char FuncName[]={"SUMA_isConsistent"};
03222    static int ic, in, LOC[2], loc[2], d, D;
03223    
03224    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03225 
03226    ic = 0;   /* common node index*/
03227    in = 0; /* number of node searched in T */
03228    while (ic < 2 && in < 3) {
03229       if (t[0] == T[in]) {
03230          LOC[ic] = in; /* location of icth node in 1st triangle */
03231          loc[ic] = 0; /* location of icth node in 2nt triangle */
03232          ++ic;
03233       }else {
03234          if (t[1] == T[in]) {
03235             LOC[ic] = in; /* location of icth node in 1st triangle */
03236             loc[ic] = 1; /* location of icth node in 2nt triangle */
03237             ++ic;
03238          }else {
03239             if (t[2] == T[in]) {
03240                LOC[ic] = in; /* location of icth node in 1st triangle */
03241                loc[ic] = 2; /* location of icth node in 2nt triangle */
03242                ++ic;
03243             }
03244          }
03245       }
03246       ++in; /* look for next node */
03247    }
03248    if (ic != 2) {
03249       fprintf(SUMA_STDERR,"Error %s: Triangles do not share 2 nodes.\n", FuncName);
03250       SUMA_RETURN (0);
03251    }
03252    
03253    D = (LOC[1]-LOC[0]);
03254    d = (loc[1]-loc[0]);
03255    /*fprintf(SUMA_STDERR,"%s: T[%d, %d, %d], t[%d, %d, %d]\n", FuncName, T[0], T[1], T[2], t[0], t[1], t[2]);
03256    fprintf(SUMA_STDERR,"%s: LOC[0,1]=[%d, %d], loc[0,1] = [%d, %d]\n", FuncName, LOC[0], LOC[1], loc[0], loc[1]);
03257    fprintf(SUMA_STDERR,"%s: D = %d, d = %d\n", FuncName, D, d);*/   
03258    if (d > 1 || d < -1) d = - d /2 ;
03259    if (D > 1 || D < -1) D = - D /2 ;
03260    /*fprintf(SUMA_STDERR,"%s: D = %d, d = %d\n", FuncName, D, d);*/   
03261 
03262    if (d != D) {
03263       /*fprintf(SUMA_STDERR,"%s: Triangles consistent.\n", FuncName);*/
03264       SUMA_RETURN (1);
03265    }
03266    
03267       
03268    /*fprintf(SUMA_STDERR,"%s: Triangles NOT consistent.\n", FuncName);*/
03269    in = t[0];
03270    t[0] = t[2];
03271    t[2] = in;
03272    SUMA_RETURN (-1);
03273 }

SUMA_Boolean SUMA_isExtension char *    filename,
char *    ext
 

ans = SUMA_isExtension(filename, ext); YUP if filename has the extension ext.

Definition at line 202 of file SUMA_StripPath.c.

00203 {
00204    static char FuncName[]={"SUMA_isExtension"}; 
00205    int cnt, N_ext, N_filename;
00206       
00207    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00208 
00209    if (!filename) SUMA_RETURN(NOPE);
00210    if (!ext) SUMA_RETURN(NOPE);
00211    N_ext = strlen(ext);
00212    N_filename = strlen(filename);
00213    if (N_ext > N_filename) SUMA_RETURN(NOPE);
00214 
00215    cnt = 1;
00216    while (cnt <= N_ext) {
00217       if (filename[N_filename-cnt] != ext[N_ext-cnt]) SUMA_RETURN(NOPE);
00218       ++cnt; 
00219    } 
00220    
00221    SUMA_RETURN(YUP);
00222 }

SUMA_ISINBOX SUMA_isinbox float *    NodeList,
int    nr,
float *    S_cent,
float *    S_dim,
int    BoundIn
 

**

File : SUMA_MiscFunc from ~Zlib/code/ isinbox.c Author : Ziad Saad Date : Fri Nov 20 23:52:52 CST 1998

Purpose : determines which nodes lie inside a box

Usage : Ret = SUMA_isinbox (float * XYZ, int nr, S_cent , S_dim , BoundIn)

Input paramters : XYZ (float * ) : Nx3 vector containing the XYZ of the nodes to consider nr (int ) : that's N, the number of nodes S_cent (float *) : a 3x1 vector containing the XYZ coordinates of the center of the box S_dim (float *) : a 3x1 containing the size of the box from side to side along the three dimentions BoundIn (int) : 0/1 set to 0 if you want to have exclusive boundary conditions

Returns : a structure of the type SUMA_ISINBOX with the following fields

IsIn (int *) : a pointer to an [nIsIn x 1] vector that will contain indices into the rows of XYZ that locates the nodes inside the box. d (float *): The distance between each of the nodes and the center of the box nIsIn (int) : the number of nodes in the box

Support :

Side effects :

Definition at line 1558 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_Engine(), SUMA_XYZ_XYZmap(), and SUMA_XYZmap_XYZ().

01559 {/*SUMA_isinbox*/
01560    
01561    static char FuncName[]={"SUMA_isinbox"}; 
01562    float t0, t1, t2, hdim0, hdim1, hdim2, *d;
01563    int k , *IsIn, id, ND;
01564    SUMA_ISINBOX IsIn_strct;
01565 
01566    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01567    
01568    ND = 3;
01569    /*
01570    fprintf(SUMA_STDOUT,"%f %f %f, %f %f %f, %d, %f, %f, %f\n",\
01571       S_cent[0], S_cent[1], S_cent[2], S_dim[0], S_dim[1], S_dim[2], nr, XYZ[0], XYZ[1], XYZ[2]);
01572    */
01573       
01574    IsIn_strct.nIsIn = 0;   
01575 
01576    hdim0 = S_dim[0]/2;
01577    hdim1 = S_dim[1]/2;
01578    hdim2 = S_dim[2]/2;
01579    
01580    IsIn = (int *) SUMA_calloc (nr, sizeof(int));
01581    d = (float *)SUMA_calloc(nr, sizeof(float));
01582    
01583    if (!IsIn || !d)
01584       {
01585          SUMA_alloc_problem (FuncName);
01586          SUMA_RETURN (IsIn_strct);
01587       }
01588 
01589    if (BoundIn) /* split into two to avoid checking for this condition all the time */
01590       {
01591          /*fprintf(SUMA_STDERR,"%s: inbound\n", FuncName);*/
01592          for (k=0; k < nr; ++k)
01593             {
01594             /*fprintf(SUMA_STDERR,"%s: inbound %d\n", FuncName, k);*/
01595             /* relative distance to center */
01596                id = ND * k;
01597                t0 = hdim0 - fabs(XYZ[id] - S_cent[0]);   
01598                t1 = hdim1 - fabs(XYZ[id+1] - S_cent[1]);   
01599                t2 = hdim2 - fabs(XYZ[id+2] - S_cent[2]);   
01600                
01601                if (t0 >= 0)
01602                   if (t1 >= 0)
01603                      if (t2 >= 0)
01604                         {
01605                            IsIn[IsIn_strct.nIsIn] = k;
01606                            d[IsIn_strct.nIsIn] = sqrt(t0*t0+t1*t1+t2*t2);
01607                            ++(IsIn_strct.nIsIn);
01608                         }
01609             }         
01610             /*fprintf(SUMA_STDERR,"%s: outbound\n", FuncName);*/
01611 
01612       }
01613    else
01614       {
01615          for (k=0; k < nr; ++k)
01616             {
01617                /* relative distance to center */
01618                id = ND * k;
01619                t0 = hdim0 - fabs(XYZ[id] - S_cent[0]);   
01620                t1 = hdim1 - fabs(XYZ[id+1] - S_cent[1]);   
01621                t2 = hdim2 - fabs(XYZ[id+2] - S_cent[2]);   
01622                
01623                if (t0 > 0)
01624                   if (t1 > 0)
01625                      if (t2 > 0)
01626                         {
01627                            IsIn[IsIn_strct.nIsIn] = k;
01628                            d[IsIn_strct.nIsIn] = sqrt(t0*t0+t1*t1+t2*t2);
01629                            ++(IsIn_strct.nIsIn);
01630                         }
01631             }
01632       }
01633    
01634    if (IsIn_strct.nIsIn) {
01635       /*fprintf(SUMA_STDERR,"%s: SUMA_realloc\n", FuncName);*/
01636 
01637       /* get ridd of extra allocation space*/
01638       IsIn_strct.IsIn = (int *) SUMA_calloc (IsIn_strct.nIsIn, sizeof(int));
01639       IsIn_strct.d = (float *)SUMA_calloc(IsIn_strct.nIsIn, sizeof(float));
01640 
01641       if (!IsIn_strct.IsIn || !IsIn_strct.d)
01642          {
01643             IsIn_strct.nIsIn = 0;
01644             SUMA_alloc_problem(FuncName);
01645             SUMA_RETURN (IsIn_strct);
01646          }
01647 
01648       SUMA_COPY_VEC (IsIn, IsIn_strct.IsIn , IsIn_strct.nIsIn, int , int);
01649       SUMA_COPY_VEC (d, IsIn_strct.d, IsIn_strct.nIsIn, float, float);
01650    } else {
01651       /*fprintf(SUMA_STDERR,"%s: NADA\n", FuncName);*/
01652       IsIn_strct.IsIn = NULL;
01653       IsIn_strct.d = NULL;
01654    }
01655    
01656    /*fprintf(SUMA_STDERR,"%s: freeing\n", FuncName);*/
01657    SUMA_free(IsIn);
01658    SUMA_free(d);
01659    /*fprintf(SUMA_STDERR,"%s: freed\n", FuncName);*/
01660 
01661    SUMA_RETURN (IsIn_strct) ;
01662 
01663 }/*SUMA_isinbox*/

SUMA_ISINSPHERE SUMA_isinsphere float *    NodeList,
int    nr,
float *    S_cent,
float    S_rad,
int    BoundIn
 

File : SUMA_MiscFunc.c, from ~Zlib/code/isinsphere.c Author : Ziad Saad Date : Fri Nov 20 22:56:31 CST 1998

Purpose : determines which nodes lie inside a sphere

Usage : Ret = SUMA_isinsphere (NodeList, nr, S_cent , S_rad , BoundIn)

Input paramters : NodeList (float * ) : Nx3 vector containing the NodeList of the nodes to consider nr (int ) : that's N, the number of nodes S_cent (float *) : a 3x1 vector containing the NodeList coordinates of the center of the sphere S_rad (float ) : the radius of the sphere BoundIn (int) : 0/1 set to 0 for exclusive boundary

Returns : a structure of the type SUMA_ISINSPHERE with the following fields

.IsIn (int *) : a pointer to an [nIsIn x 1] vector will contain the indices into the rows of NodeList that locates the nodes inside the sphere. .nIsIn (int) : the number of nodes in the sphere .d (float *) : a pointer to an [nIsIn x 1] vector containing the distance of those nodes inside the sphere to the center.

Support :

Side effects :

Definition at line 1432 of file SUMA_MiscFunc.c.

01433 {/*SUMA_isinsphere*/
01434    static char FuncName[]={"SUMA_isinsphere"}; 
01435    float *t, t0, t1, t2, ta;
01436    int k, *IsIn, id, ND;
01437    SUMA_ISINSPHERE IsIn_strct;
01438    
01439    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01440 
01441    ND = 3;
01442    IsIn_strct.nIsIn = 0;
01443       
01444    t = (float *) SUMA_calloc (nr, sizeof(float));
01445    IsIn = (int *) SUMA_calloc (nr, sizeof(int));
01446    
01447    if (!t || !IsIn)
01448       {
01449          SUMA_alloc_problem (FuncName);
01450          SUMA_RETURN (IsIn_strct);
01451       }
01452    
01453    
01454    if (BoundIn) /* split into two to avoid checking for this condition all the time */
01455       {
01456          for (k=0; k < nr; ++k)
01457             {
01458                id = ND * k;
01459                /* Net distance to center */
01460                t0 = NodeList[id] - S_cent[0];   
01461                t1 = NodeList[id+1] - S_cent[1];   
01462                t2 = NodeList[id+2] - S_cent[2];   
01463 
01464                ta = sqrt (t0 * t0 + t1 * t1 + t2 * t2);
01465                
01466                if (ta <= S_rad)
01467                   {
01468                      IsIn[IsIn_strct.nIsIn] = k;
01469                      t[IsIn_strct.nIsIn] = ta;
01470                      ++(IsIn_strct.nIsIn);
01471                   }
01472             }
01473       }
01474    else
01475       {
01476          for (k=0; k < nr; ++k)
01477             {
01478                id = ND * k;
01479                /* Net distance to center */
01480                t0 = NodeList[id] - S_cent[0];   
01481                t1 = NodeList[id+1] - S_cent[1];   
01482                t2 = NodeList[id+2] - S_cent[2];   
01483 
01484                ta = sqrt (t0 * t0 + t1 * t1 + t2 * t2);
01485                
01486                if (ta < S_rad)
01487                   {
01488                      IsIn[IsIn_strct.nIsIn] = k;
01489                      t[IsIn_strct.nIsIn] = ta;
01490                      ++(IsIn_strct.nIsIn);
01491                   }
01492             }
01493       }
01494          
01495    /* get ridd of extra allocation space*/
01496    IsIn_strct.d = (float *) SUMA_calloc (IsIn_strct.nIsIn, sizeof(float));
01497    IsIn_strct.IsIn = (int *) SUMA_calloc (IsIn_strct.nIsIn, sizeof(int));
01498    
01499    if (!IsIn_strct.d || !IsIn_strct.IsIn )
01500       {
01501          IsIn_strct.nIsIn = 0;
01502          SUMA_alloc_problem(FuncName);
01503          SUMA_RETURN (IsIn_strct);
01504       }
01505    
01506    SUMA_COPY_VEC (t, IsIn_strct.d, IsIn_strct.nIsIn, float , float);
01507    SUMA_COPY_VEC (IsIn, IsIn_strct.IsIn , IsIn_strct.nIsIn, int , int);
01508    
01509    SUMA_free(t);
01510    SUMA_free(IsIn);
01511    
01512    SUMA_RETURN (IsIn_strct);
01513    
01514 }/*SUMA_isinsphere*/

SUMA_Boolean SUMA_isNumString char *    s,
void *    p
 

function that tests whether a string contains N numbers.

Parameters:
str  (char *) null terminated string
N  (void *) This is an integer in disguise
Returns:
YUP: If str is NULL or N numbers were found in str

Definition at line 5470 of file SUMA_MiscFunc.c.

05471 {
05472    static char FuncName[]={"SUMA_isNumString"};
05473    char *endp, *strtp;
05474    int nd, N;
05475    SUMA_Boolean eos, FoundTip;
05476    double d;
05477    SUMA_Boolean LocalHead = YUP;
05478    
05479    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05480    
05481    if (!s) SUMA_RETURN(YUP); 
05482    
05483    N = (int)p;
05484    
05485    /* clean s by removing trailing junk then replacing non characters by space*/
05486    FoundTip = NOPE;
05487    for (nd=strlen(s)-1; nd >=0; --nd) {
05488       if (!isdigit(s[nd]) && s[nd] != '.'  && s[nd] != '-' && s[nd] != '+') {
05489          if (!FoundTip) {
05490             s[nd]= '\0'; /* remove */
05491          } else {
05492             s[nd] = ' '; /* blank */
05493          }
05494       }else {
05495          FoundTip = YUP;
05496       }
05497    }
05498    
05499    if (LocalHead) fprintf (SUMA_STDERR, "%s: string now:%s:\n", FuncName, s);
05500    
05501    /* parse s */
05502    strtp = s;
05503    endp = NULL;
05504    nd = 0;
05505    eos = NOPE;
05506    while (!eos) {
05507       d = strtod(strtp, &endp);
05508       if (LocalHead) fprintf (SUMA_STDERR, "%s: value %f, ERANGE: %d, EDOM %d, errno %d\n", FuncName, d, ERANGE, EDOM, errno); 
05509       
05510 
05511       if (endp == strtp && *endp=='\0') { 
05512          eos = YUP;
05513       } else {
05514          strtp = endp;
05515          ++nd;
05516       }
05517    }
05518    
05519    if (LocalHead) fprintf (SUMA_STDERR,"%s: Read %d/%d values.\n", FuncName, nd,N);
05520    if (N != nd) {
05521       SUMA_RETURN(NOPE);
05522    } else {
05523       SUMA_RETURN(YUP);
05524    }
05525    
05526 }   

int SUMA_isTriLinked int *    T,
int *    t,
int *    cn
 

This function determines how many nodes two triangles share. N_cn = SUMA_isTriLinked (T, t, cn);.

Parameters:
T  (int *) a b c nodes forming the reference triangle
t  (int *) d c b (or whatever combination you choose, c b d for example)
cn  (int *) vector of three elements to contain the indices of nodes common to the two triangles when the function returns.
Returns:
N_cn (int) number of common nodes. Values in cn beyond N_cn - 1 are undefined.

Definition at line 3179 of file SUMA_MiscFunc.c.

Referenced by SUMA_NodePath_to_TriPath_Inters().

03180 {
03181    static char FuncName[]={"SUMA_isTriLinked"};
03182    int ic, in;
03183    
03184    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03185 
03186    ic = 0;   /* common node index*/
03187    in = 0; /* number of node searched in T */
03188    while (ic < 2 && in < 3) {
03189       if (t[0] == T[in]) {
03190          cn[ic] = t[0]; 
03191          ++ic;
03192       }else {
03193          if (t[1] == T[in]) {
03194             cn[ic] = t[1]; 
03195             ++ic;
03196          }else {
03197             if (t[2] == T[in]) {
03198                cn[ic] = t[2]; 
03199                ++ic;
03200             }
03201          }
03202       }
03203       ++in; /* look for next node */
03204    }
03205    
03206    SUMA_RETURN (ic);
03207 }

int SUMA_iswordin const char *    sbig,
const char *    ssub
 

File : Taken from iswordin.c Author : Ziad Saad Date : Mon Sep 22 18:52:28 CDT 1997

Purpose : To find out if an array of characters is an element of another array of characters

Input paramters :

S (char *) : Mother String (character array) Ssub (char *) : Subset array

Usage : int SUMA_iswordin (const char *S, const char *Ssub );

(you could use space characters in the two strings like: SUMA_iswordin ("Hello The Gump","The Gu"); would return a 1 SUMA_iswordin ("Hello The Gump",""); would return a 1 SUMA_iswordin ("Hello The Gump","Tha"); would return a 0 SUMA_iswordin ("Hello The Gump"," "); would return a 1 SUMA_iswordin ("Hel","Hello sdsd"); would return a 0

Returns : returns 1 if Ssub is part of S returns 0 if Ssub is not part of S returns -1 if either Ssub or S is NULL returns -2 if both Ssub and S are NULL

Support :

Side effects :

Definition at line 1012 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_FreeSurfer_Read(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_LoadSpec(), SUMA_ParseLHS_RHS(), SUMA_Read_SpecFile(), SUMA_Read_SureFit_Param(), SUMA_SureFit_Read_Coord(), SUMA_SureFit_Read_Topo(), and SUMA_SurfaceMetrics().

01013 {/*SUMA_iswordin*/
01014    int i=0,j=0;
01015    static char FuncName[]={"SUMA_iswordin"};
01016 
01017    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01018 
01019    if (sbig == NULL && ssub == NULL) SUMA_RETURN (-2);
01020    if (sbig == NULL || ssub == NULL) SUMA_RETURN (-1);
01021 
01022    if (strlen(sbig) < strlen(ssub))
01023        SUMA_RETURN (0);
01024 
01025    j=0;
01026    while (sbig[i] != '\0' && ssub[j] != '\0')
01027    {
01028        if (sbig[i] == ssub[j])
01029           {
01030              ++j;
01031              /*printf ("j=%d ",j);*/
01032           }
01033        else j=0;
01034    ++i;
01035    }
01036 
01037    if (j == strlen (ssub)) {
01038       SUMA_RETURN (1);
01039    }
01040    else {
01041       SUMA_RETURN (0);
01042    }
01043 
01044 }/*SUMA_iswordin*/

SUMA_EDGE_LIST* SUMA_Make_Edge_List int *    FaceSetList,
int    N_FaceSet,
int    N_Node,
float *    NodeList
 

ans = SUMA_Make_Edge_List (FL, N_FL, N_Node, NodeList);

This function creates a list of all the edges making up the FaceSets

Parameters:
FL  (int *) FaceSetList vector (was matrix, prior to SUMA 1.2 ( N_FL x 3)
N_FL  (int) number of facesets (triangles) in FL
N_Node  (int) number of nodes forming the mesh
NodeList  (float *) vector containing XYZ of each node. This was added to compute the length of each edge. \ret ans (SUMA_EDGE_LIST *) NULL/failure or the following fields EL (int **) sorted edge list ELps (int **) edge list properties Le (float *) length of each edge in EL. Since EL can have multiple edges, which are shared by different triangles, Le would also have duplicate length values. This is tolerated for efficiency of indexing. N_EL (int) Number of edges see SUMA_define.h for more info
to free ans, use SUMA_free_Edge_List

DO NOT MODIFY WHAT THIS FUNCTION RETURNS without serious thought. Complicated functions depend on it.

Definition at line 3593 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_CreateIcosahedron(), SUMA_GetContour(), SUMA_SureFit_Write(), and SUMA_SurfaceMetrics().

03594 {
03595    static char FuncName[]={"SUMA_Make_Edge_List"};
03596    int i, ie, ip, *isort_EL, **ELp, lu, ht, *iTri_limb, icur, in1, in2;
03597    float dx, dy, dz;
03598    SUMA_EDGE_LIST *SEL;
03599    
03600    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03601 
03602    /* allocate and form the List of edges */
03603    SEL = (SUMA_EDGE_LIST *) SUMA_malloc(sizeof(SUMA_EDGE_LIST));
03604 
03605    SEL->N_EL = 3 * N_FL;
03606    SEL->EL = (int **) SUMA_allocate2D (SEL->N_EL, 2, sizeof(int)); /* edge list */
03607    SEL->ELloc = (int *)SUMA_calloc(N_Node, sizeof(int));
03608    SEL->Le = (float *) SUMA_calloc (SEL->N_EL, sizeof(float)); /* length of each edge */
03609    ELp = (int **) SUMA_allocate2D (SEL->N_EL, 2, sizeof(int)); /* edge property list */
03610                                                          /* 1st column, 1 = is flipped from orientation in triangle, -1 as present in triangle 
03611                                                               2nd column, index of triangle (FaceSet) that edge is a part of */    
03612    SEL->ELps = (int **) SUMA_allocate2D (SEL->N_EL, 3, sizeof(int)); /*sorted edge property list */
03613    
03614    /*fprintf(SUMA_STDERR, "%s: SEL->NEL %d\n", FuncName, SEL->N_EL/3);*/
03615    
03616    SEL->Tri_limb = (int **) SUMA_allocate2D (SEL->N_EL/3, 3, sizeof(int)); 
03617    iTri_limb = (int *)SUMA_calloc (SEL->N_EL/3,sizeof(int)); 
03618    
03619    if (SEL == NULL || SEL->EL == NULL || ELp == NULL || SEL->ELps == NULL || SEL->Tri_limb == NULL || iTri_limb== NULL || SEL->ELloc == NULL) {
03620       fprintf(SUMA_STDERR, "Error %s: Failed to allocate for EL, ELp.\n", FuncName);
03621       SUMA_RETURN (NULL);
03622    }
03623 
03624    /* form the edge list */
03625    /*fprintf(SUMA_STDERR, "%s: Forming edge list ...\n", FuncName);*/
03626    for (i=0; i< N_FL; ++i) {/* begin, form edge list */
03627       /* first edge, 0->1*/
03628       ie = 3*i;
03629       ip = 3*i;
03630       if (FL[ip] > FL[ip+1]) {
03631          /* flip it, to make sorting easier */
03632          SEL->EL[ie][0] = FL[ip+1];
03633          SEL->EL[ie][1] = FL[ip];
03634          /* store parameters */
03635          ELp[ie][0] = 1; /* flip happened */
03636       } else { 
03637          /* no flip necessary */
03638          SEL->EL[ie][0] = FL[ip];
03639          SEL->EL[ie][1] = FL[ip+1];
03640          ELp[ie][0] = -1; /* NO flip happened */
03641       }
03642       ELp[ie][1] = i; /* FaceSetMember */
03643 
03644       /* second edge, 1->2*/
03645       ie += 1;
03646       if (FL[ip+1] > FL[ip+2]) {
03647          /* flip it, to make sorting easier */
03648          SEL->EL[ie][0] = FL[ip+2];
03649          SEL->EL[ie][1] = FL[ip+1];
03650          /* store parameters */
03651          ELp[ie][0] = 1; /* flip happened */
03652       } else { 
03653          /* no flip necessary */
03654          SEL->EL[ie][0] = FL[ip+1];
03655          SEL->EL[ie][1] = FL[ip+2];
03656          ELp[ie][0] = -1; /* NO flip happened */
03657       }
03658       ELp[ie][1] = i; /* FaceSetMember */
03659       
03660       /* third edge, 2->0*/
03661       ie += 1;
03662       if (FL[ip+2] > FL[ip]) {
03663          /* flip it, to make sorting easier */
03664          SEL->EL[ie][0] = FL[ip];
03665          SEL->EL[ie][1] = FL[ip+2];
03666          /* store parameters */
03667          ELp[ie][0] = 1; /* flip happened */
03668       } else { 
03669          /* no flip necessary */
03670          SEL->EL[ie][0] = FL[ip+2];
03671          SEL->EL[ie][1] = FL[ip];
03672          ELp[ie][0] = -1; /* NO flip happened */
03673       }
03674       ELp[ie][1] = i; /* FaceSetMember */
03675       
03676    }/* end, form edge list */
03677    /*fprintf(SUMA_STDERR,"%s: Edge list done.\n", FuncName);*/
03678    
03679    #if 0
03680       fprintf(SUMA_STDERR,"%s: Node1 Node2 | FlipVal Triangle\n", FuncName); 
03681       for (i=0; i < SEL->N_EL; ++i) {
03682          fprintf (SUMA_STDERR, "%d %d | %d %d\n", SEL->EL[i][0], SEL->EL[i][1], ELp[i][0], ELp[i][1]);
03683       }
03684    #endif
03685 
03686    /* now sort the Edge list */
03687    /*fprintf(SUMA_STDERR,"%s: Sorting edge list...\n", FuncName);*/
03688    isort_EL = SUMA_dqsortrow (SEL->EL, SEL->N_EL, 2);
03689    
03690    /* reorder ELp to match sorted EL */
03691    for (i=0; i< SEL->N_EL; ++i) {
03692       SEL->ELps[i][0] = ELp[isort_EL[i]][0];
03693       SEL->ELps[i][1] = ELp[isort_EL[i]][1];
03694    }
03695    
03696    /*fprintf(SUMA_STDERR,"%s: Sorting edge list done.\n", FuncName);*/
03697    
03698    if (isort_EL) SUMA_free(isort_EL);
03699    isort_EL = NULL;
03700    
03701    
03702    #if 0
03703       fprintf(SUMA_STDERR,"%s: Node1 Node2 | FlipVal Triangle\n", FuncName); 
03704       for (i=0; i < SEL->N_EL; ++i) {
03705          fprintf (SUMA_STDERR, "%d %d | %d %d\n", SEL->EL[i][0], SEL->EL[i][1], SEL->ELps[i][0], SEL->ELps[i][1]);
03706       }
03707    #endif
03708    
03709    /* calculate the length of each edge */
03710    for (ie=0; ie < SEL->N_EL; ++ie) {
03711       in1 = 3 * SEL->EL[ie][0]; in2 = 3 * SEL->EL[ie][1];
03712       dx = (NodeList[in2] - NodeList[in1]);
03713       dy = (NodeList[in2+1] - NodeList[in1+1]);
03714       dz = (NodeList[in2+2] - NodeList[in1+2]);
03715       SEL->Le[ie] = (float) sqrt (  dx * dx + dy * dy + dz * dz );
03716    }
03717    
03718    /* free unsorted ELp */
03719    if (ELp) SUMA_free2D((char **)ELp, SEL->N_EL);
03720    ELp = NULL;
03721    
03722    SEL->max_N_Hosts = -1;
03723    SEL->min_N_Hosts = 100;
03724    /* do a search for some funky stuff */
03725    i=0;
03726    while (i < SEL->N_EL) {
03727       /* store the location of this edge for the triangle hosting it */
03728       ht = SEL->ELps[i][1]; /* host triangle index */
03729       SEL->Tri_limb[ht][iTri_limb[ht]] = i;
03730       iTri_limb[ht] += 1;
03731       
03732       SEL->ELps[i][2] = 1; /* number of triangles hosting edge */
03733       lu = 1; 
03734       while (i+lu < SEL->N_EL) {
03735          if (SEL->EL[i+lu][0] == SEL->EL[i][0] && SEL->EL[i+lu][1] == SEL->EL[i][1]) {/* found matching edge */
03736             SEL->ELps[i][2] += 1; /* number of triangles hosting edge */
03737             SEL->ELps[i+lu][2] = -1; /* flag to mean that this edge is a duplicte in the list */
03738 
03739             /* store the location of this edge for the triangle hosting it */
03740             ht = SEL->ELps[i+lu][1]; /* host triangle index */
03741             SEL->Tri_limb[ht][iTri_limb[ht]] = i+lu;
03742             iTri_limb[ht] += 1;
03743 
03744             ++lu;
03745          }else break;
03746          
03747       }
03748       if (SEL->max_N_Hosts < SEL->ELps[i][2]) SEL->max_N_Hosts = SEL->ELps[i][2];
03749       if (SEL->min_N_Hosts > SEL->ELps[i][2]) SEL->min_N_Hosts = SEL->ELps[i][2]; 
03750       i += lu;
03751    }
03752    
03753    fprintf(SUMA_STDERR,"%s: Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SEL->min_N_Hosts, SEL->max_N_Hosts);
03754    if (SEL->min_N_Hosts == 1 || SEL->max_N_Hosts == 1) {
03755       fprintf(SUMA_STDERR,"Warning %s: You have edges that form a border in the surface.\n", FuncName);
03756    }
03757    if (SEL->min_N_Hosts > 2 || SEL->max_N_Hosts > 2) {
03758       fprintf(SUMA_STDERR,"Warning %s: You have edges that belong to more than two triangles. Bad for analysis assuming surface is a 2-manifold..\n", FuncName);
03759    }
03760    
03761    #if 0
03762       fprintf(SUMA_STDERR,"%s:(ELindex) Node1 Node2 | FlipVal Triangle N_hosts\n", FuncName); 
03763       for (i=0; i < SEL->N_EL; ++i) {
03764          fprintf (SUMA_STDERR, "(%d) %d %d | %d %d %d\n", i, SEL->EL[i][0], SEL->EL[i][1], SEL->ELps[i][0], SEL->ELps[i][1], SEL->ELps[i][2]);
03765       }
03766       fprintf(SUMA_STDERR,"%s:Tri_limb\n", FuncName); 
03767       for (i=0; i < SEL->N_EL/3; ++i) {
03768          fprintf (SUMA_STDERR, "%d %d %d\n", SEL->Tri_limb[i][0], SEL->Tri_limb[i][1], SEL->Tri_limb[i][2]);
03769       }
03770    #endif
03771    
03772    /* store where each node's listing begins
03773    ELloc is used to quickly find a certain edge in EL
03774    to find the edge formed by nodes na-nb
03775    find the minimum of na and nb (say it's nb)
03776    the first reference of an edge containing nb starts at EL(ELloc(nb),:)
03777    NOTE: ELloc contains an entry for each node in FaceSetList, except the largest node index since that's never in the 
03778    first column of EL */
03779    /* fprintf(SUMA_STDERR, "%s: storing locations ...\n", FuncName); */
03780    for (i=0; i < N_Node; ++i) SEL->ELloc[i] = -1;
03781    i = 0;
03782    icur = SEL->EL[0][0];
03783    SEL->ELloc[icur] = i; 
03784    while (i < SEL->N_EL) {
03785       if (SEL->EL[i][0] != icur) {
03786          icur = SEL->EL[i][0];
03787          SEL->ELloc[icur] = i;
03788       }
03789       ++i;
03790    }
03791 
03792    SUMA_RETURN (SEL);
03793 }

SUMA_Boolean SUMA_MakeConsistent int *    FaceSetList,
int    N_FaceSet,
SUMA_EDGE_LIST   SEL
 

Makes sure the triangles in FaceSetList are of a consistent orientation.

ans = SUMA_MakeConsistent (FaceSetList, N_FaceSet, SEL)

Parameters:
FaceSetList  (int *) N_FaceSet x 3 vector (was matrix prior to SUMA 1.2) containing triangle definition
N_FaceSet  int
SEL  (SUMA_EDGE_LIST *) pointer Edgelist structure as output by SUMA_Make_Edge_List
\ret ans (SUMA_Boolean) YUP, NOPE

See also:
SUMA_Make_Edge_List

Definition at line 4113 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_CreateIcosahedron(), and SUMA_SurfaceMetrics().

04114 {
04115    /* see for more documentation labbook NIH-2 test mesh  p61 */
04116    int i, it, NP, ip, N_flip=0, *isflip, *ischecked, ht0, ht1, NotConsistent, miss, miss_cur, N_iter, EdgeSeed, TriSeed, N_checked;
04117    static char FuncName[]={"SUMA_MakeConsistent"};
04118    SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN;
04119    SUMA_Boolean LocalHead = NOPE;
04120    
04121    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04122 
04123    NP = 3;
04124    isflip = (int *)SUMA_calloc(SEL->N_EL/3, sizeof(int));
04125    ischecked = (int *)SUMA_calloc(SEL->N_EL/3, sizeof(int));
04126    
04127    if (isflip == NULL || ischecked == NULL ) {
04128       fprintf(SUMA_STDERR, "Error %s: Failed to allocate for isflip\n", FuncName);
04129       SUMA_RETURN (NOPE);
04130    }
04131    
04132    
04133    /* Now, go through the sorted edge list and flip what needs flipping*/
04134    N_iter = 0;
04135    miss = 0;
04136    miss_cur = SEL->N_EL;
04137    N_checked = 1;
04138    while (miss_cur != miss) {
04139       miss_cur = miss;
04140       miss = 0;
04141       
04142       /* both methods work just fine here */
04143       #if 0
04144          /*start with the first edge as an edge seed */
04145          EdgeSeed = 0;
04146          i=EdgeSeed;
04147          ht0 = SEL->ELps[i][1];
04148       #else      
04149          /* start with the first edge of the seed triangle as an edge seed */
04150          TriSeed = 0;
04151          i = SEL->Tri_limb[TriSeed][0];
04152          ht0 = TriSeed;
04153       #endif
04154       
04155       ischecked[ht0] = 1;
04156       while (i < SEL->N_EL) {
04157          ht0 = SEL->ELps[i][1];
04158          /* make sure edge is not part of three triangles, if it is, skip it */
04159          if (SEL->ELps[i][2] > 3) {
04160             ++i;
04161             fprintf(SUMA_STDERR, "%s: Bad edge (#%d: %d--%d), part of more than 2 triangles, skip it\n", FuncName, i, SEL->EL[i][0], SEL->EL[i][1]); 
04162             continue;
04163          }
04164          if (SEL->ELps[i][2] == 2) {
04165             /* that's a good edge, see if the next edge after it is consistent */
04166             NotConsistent = SEL->ELps[i][0] * SEL->ELps[i+1][0]; /* if 1 then edges were either both flipped or not flipped in the list */
04167             ht1 = SEL->ELps[i+1][1];
04168             if (ischecked[ht0] && !ischecked[ht1]) {
04169                if (NotConsistent == 0) {
04170                   fprintf(SUMA_STDERR, "Error %s: NotConsistent = 0 here. This should not be.\n", FuncName);
04171                   SUMA_RETURN (NOPE);
04172                }
04173                if (NotConsistent < 0) {
04174                   /* triangles hosting these edges are consistent */
04175                   /* next triangle needs no flipping */
04176                   ischecked[ht1] = 1;
04177                   ++N_checked;
04178                } else {
04179                   /* triangles hosting these edges are NOT consistent */
04180                   /* flip the next triangle */
04181                   ip = NP * ht1;
04182                   it = FL[ip];
04183                   FL[ip] = FL[ip+2];
04184                   FL[ip+2] = it;
04185                   /* Now make sure the flip is reflected in ELps */
04186                   it = SEL->Tri_limb[ht1][0]; SEL->ELps[it][0] *= -1;
04187                   it = SEL->Tri_limb[ht1][1]; SEL->ELps[it][0] *= -1;
04188                   it = SEL->Tri_limb[ht1][2]; SEL->ELps[it][0] *= -1;
04189                   N_flip += 1;
04190                   isflip[ht1] = 1;
04191                   ischecked[ht1] = 1;
04192                   ++N_checked;
04193                }
04194                ++i; 
04195                continue;
04196             } 
04197             
04198             /*try if next edge's host is in good shape */
04199             if (ischecked [ht1] && !ischecked[ht0]) {
04200                if (NotConsistent == 0) {
04201                   fprintf(SUMA_STDERR, "Error %s: NotConsistent = 0 here. This should not be.\n", FuncName);
04202                   SUMA_RETURN (NOPE);
04203                }
04204                if (NotConsistent < 0) {
04205                   /* triangles hosting these edges are consistent */
04206                   /* 1st triangle needs no flipping */
04207                   ischecked[ht0] = 1;
04208                   ++N_checked;
04209                } else {
04210                   /* triangles hosting these edges are NOT consistent */
04211                   /* flip the 1st triangle */
04212                   ip = NP * ht0;
04213                   it = FL[ip];
04214                   FL[ip] = FL[ip+2];
04215                   FL[ip+2] = it;
04216                   /* Now make sure the flip is reflected in ELps */
04217                   it = SEL->Tri_limb[ht0][0]; SEL->ELps[it][0] *= -1;
04218                   it = SEL->Tri_limb[ht0][1]; SEL->ELps[it][0] *= -1;
04219                   it = SEL->Tri_limb[ht0][2]; SEL->ELps[it][0] *= -1;
04220                   N_flip += 1;
04221                   isflip[ht0] = 1;
04222                   ischecked[ht0] = 1;
04223                   ++N_checked;
04224                }
04225                ++i; 
04226                continue;
04227             } 
04228             if (!ischecked[ht0] && !ischecked [ht1]) { /* a good lead that was missed on this pass */
04229                if (LocalHead) fprintf(SUMA_STDERR,"%s: Miss = %d, MissCur = %d\n", FuncName, miss, miss_cur); 
04230                ++miss;
04231             }
04232          }
04233          ++i;   
04234       }
04235       if (LocalHead) fprintf(SUMA_STDERR,"%s: Miss = %d, MissCur = %d\n", FuncName, miss, miss_cur);
04236       ++N_iter;
04237    }
04238 
04239    if (LocalHead) fprintf(SUMA_STDERR,"%s: %d iterations required to check the surface.\n", FuncName, N_iter);
04240    fprintf(SUMA_STDERR,"%s: %d/%d (%f%%) triangles checked.\n", FuncName, N_checked, SEL->N_EL/3, (float)N_checked/(SEL->N_EL/3)*100.0);
04241    if (N_flip) {
04242       fprintf(SUMA_STDERR,"%s: %d triangles were flipped to make them consistent with the triangle containing the first edge in the list.\n", FuncName, N_flip);
04243    } else fprintf(SUMA_STDERR,"%s: All checked triangles were consistent with the triangle containing the first edge in the list.\n", FuncName);
04244    if (miss) {
04245       fprintf(SUMA_STDERR,"%s: %d segments with two neighbors were skipped. Not good in general.\n", FuncName, miss);
04246    }
04247    #if 0
04248       /* now show the fixed mesh list */
04249       fprintf (SUMA_STDERR,"%s: %d triangles were flipped \n", FuncName, N_flip);
04250       for (i=0; i < SEL->N_EL/3; ++i) {
04251          ip = NP * i;
04252          if (isflip[i]) fprintf (SUMA_STDERR,"\t%d %d %d\t(%d)\t*\n", FL[ip], FL[ip+1], FL[ip+2], ischecked[i]);
04253             else fprintf (SUMA_STDERR,"\t%d %d %d\t(%d)\n", FL[ip], FL[ip+1], FL[ip+2], ischecked[i]);
04254       }
04255    #endif
04256       
04257    /* freedom */
04258    if (LocalHead) fprintf(SUMA_STDERR,"%s: Free time \n", FuncName);
04259    if (isflip) SUMA_free(isflip);
04260    if (ischecked) SUMA_free(ischecked);
04261    if (LocalHead) fprintf(SUMA_STDERR,"%s: returning.\n", FuncName);
04262    
04263    SUMA_RETURN (YUP);
04264 }

void* SUMA_malloc_fn const char *    CallingFunc,
size_t    size
 

ptr = SUMA_malloc_fn (const char *CF, size ); \purpose a wrapper around malloc function that allows one to keep track of allocated memory. For the tracking to occurr, you need to have SUMA_MEMTRACE_FLAG set to 1 (when compiling) and then turn the flag SUMAg_CF->MemTrace on. ifdef SUMA_MEMTRACE_FLAG and SUMAg_CF->MemTrace then when size bytes are allocated to ptr the following happens: SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc] = ptr; SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc] = size; ++SUMAg_CF->Mem->N_alloc;

otherwise, only ptr = malloc (size) is executed.

Parameters:
CF  (const char *) name of calling function
size  (size_t) \ret ptr (void *)

Definition at line 23 of file SUMA_MiscFunc.c.

References SUMA_Boolean.

00024    {
00025       void *ptr;
00026       static char FuncName[]={"SUMA_malloc_fn"};
00027 
00028       #if SUMA_MEMTRACE_FLAG
00029          if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00030       #endif
00031       /* The allocation */
00032       ptr = malloc (size);
00033 
00034       #if SUMA_MEMTRACE_FLAG
00035          if (SUMAg_CF->MemTrace) {
00036             ++SUMAg_CF->Mem->N_alloc;
00037             if (SUMAg_CF->Mem->N_MaxPointers <= SUMAg_CF->Mem->N_alloc) {
00038                /* must reallocate */
00039                SUMAg_CF->Mem->N_MaxPointers += SUMA_MEMTRACE_BLOCK;
00040                SUMAg_CF->Mem->Pointers = (void **)realloc (SUMAg_CF->Mem->Pointers, sizeof(void*) * SUMAg_CF->Mem->N_MaxPointers);
00041                SUMAg_CF->Mem->Size  = (int *)realloc (SUMAg_CF->Mem->Size, sizeof(int) * SUMAg_CF->Mem->N_MaxPointers);
00042               if (!SUMAg_CF->Mem->Pointers || !SUMAg_CF->Mem->Pointers) {
00043                   fprintf (SUMA_STDERR, "Error %s: Failed to reallocate.\nTurning off memory tracing.\n", \
00044                            FuncName);
00045                   /* free up allocated space, clean up pointers, turn off memory tracing */
00046                   if (SUMAg_CF->Mem->Pointers) free(SUMAg_CF->Mem->Pointers); 
00047                   if (SUMAg_CF->Mem->Size) free(SUMAg_CF->Mem->Size); 
00048                   SUMAg_CF->MemTrace = 0;
00049                   SUMAg_CF->Mem->N_alloc = 0;
00050                   SUMAg_CF->Mem->N_MaxPointers = 0;
00051                   SUMA_RETURN(ptr);
00052                }
00053             }
00054             SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = ptr;
00055             SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = size;
00056          }
00057          SUMA_RETURN(ptr);
00058       #else
00059          return(ptr);
00060       #endif
00061    }

SUMA_Boolean SUMA_mattoquat float **    mat,
float *    q
 

Definition at line 3074 of file SUMA_MiscFunc.c.

Referenced by SUMA_Engine().

03075 {
03076    double tr, s;
03077    int i,j,k, nxt[3] = {1, 2, 0};
03078    static char FuncName[]={"SUMA_mattoquat"};
03079    
03080    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03081 
03082    /* calculate the trace */
03083    tr = mat[0][0] + mat[1][1] + mat[2][2];
03084    if (tr > 0.0) {
03085       s = sqrt(tr + 1.0);
03086       q[3] = s * 0.5;
03087       s = 0.5/s;
03088       
03089       q[0] = (mat[1][2] - mat[2][1])*s;
03090       q[1] = (mat[2][0] - mat[0][2])*s;
03091       q[2] = (mat[0][1] - mat[1][0])*s;
03092    
03093    } /* tr > 0.0 */ else {
03094       i = 0;
03095       if (mat[1][1] > mat[0][0]) i = 1;
03096       if (mat[2][2] > mat[i][i]) i = 2;
03097       j = nxt[i]; k = nxt[j];
03098    
03099       s = sqrt( (mat[i][i] - (mat[j][j]+mat[k][k])) + 1.0);
03100       q[i] = s * 0.5;
03101       s = 0.5/s;
03102       q[3] = (mat[j][k] - mat[k][j])*s;
03103       q[j] = (mat[i][j] + mat[j][i])*s;
03104       q[k] = (mat[i][k] + mat[k][i])*s;
03105    } /* tr < 0.0 */
03106    SUMA_RETURN (YUP);
03107 }

SUMA_MT_INTERSECT_TRIANGLE* SUMA_MT_intersect_triangle float *    P0,
float *    P1,
float *    NodeList,
int    N_Node,
int *    FaceSetList,
int    N_FaceSet,
SUMA_MT_INTERSECT_TRIANGLE   prevMTI
 

SUMA_MT_INTERSECT_TRIANGLE * SUMA_MT_intersect_triangle(float *P0, float *P1, float *NodeList, int N_Node, int *FaceSetList, int N_FaceSet, SUMA_MT_INTERSECT_TRIANGLE *prevMTI)

Parameters:
P0  (float *) 3x1 containing XYZ of point 0
P1  (float *) 3x1 containing XYZ of point 1
NodeList  (float *) N_Node x 3 vector containing the XYZ of nodes making up FaceSetList
N_Node  (int) number of nodes in NodeList
FaceSetList  (int *) N_FaceSet x 3 with each triplet representing a triangle. Triangles are defined by their indices into NodeList
N_FaceSet  (int) number of triangles in FaceSetList
PrevMTI  (SUMA_MT_INTERSECT_TRIANGLE *) To keep the function from reallocating for MTI each time you call it, you can pass the previous MTI structure to the next call. If the number of facesets is the same as in the previous call and PrevMTI is not NULL then MTI is not reallocated for. If PrevMTI is not null and the last N_FaceSet was different from the current, PrevMTI is freed and a new one is returned. This change appears to save about 18% of the function's execution time. Be careful not to free PrevMTI without setting it to NULL and then send it to SUMA_MT_intersect_triangle.
\ret MTI (SUMA_MT_INTERSECT_TRIANGLE *) pointer to structure containing isHit (SUMA_Boolean *) N_FaceSet x 1 vector. isHit[i] = YUP --> FaceSet i is pierced by ray P0-->P1 t (float *) signed distance to the plane in which the triangle lies u & v(float *) location withing the triangle of the intersection point

See also:
Algorithm from:Moller & Trumbore 97 Tomas Möller and Ben Trumbore. Fast, minimum storage ray-triangle intersection. Journal of graphics tools, 2(1):21-28, 1997
NOTE: Tue Jan 7 15:07:05 EST 2003 Shruti noted that problems occured when a ray intersected a node. She is correct, if a ray intersects a node, it may or may not be detected and the results are undetermined. This is only expected to happen with synthesized data and checking for such situations will slow the function down. If you must use such data, I recommend you add a tiny bit of noise to the vertex coordinates or to your normals.

Definition at line 2599 of file SUMA_MiscFunc.c.

Referenced by main(), SUMA_BrushStrokeToNodeStroke(), SUMA_inNodeNeighb(), SUMA_MapSurface(), and SUMA_MarkLineSurfaceIntersect().

02600 {
02601    static char FuncName[]={"SUMA_MT_intersect_triangle"};
02602    double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
02603    double det,inv_det;
02604    int iface, ND, id, NP, ip;
02605    double vert0[3],vert1[3], vert2[3], dir[3], dirn, orig[3];
02606    float tmin, tmax, dii, disttest;
02607    static SUMA_MT_INTERSECT_TRIANGLE *MTI = NULL;
02608    static int N_FaceSet_Previous = 0, entry = 0;
02609    SUMA_Boolean LocalHead = NOPE;
02610    
02611    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02612 
02613    tmin = 10000000.0;
02614    tmax = 0.0;
02615    
02616    if (!PrevMTI) { /* nothing preallocated */
02617       entry = 0;
02618       if (LocalHead) fprintf(SUMA_STDERR,"%s: First entry or nothing pre-allocated.\n", FuncName);
02619    } else { /* returning a used MTI, check number of facesets */
02620       if (N_FaceSet_Previous != N_FaceSet) { /* must reallocate */
02621          if (LocalHead) fprintf(SUMA_STDERR,"%s: Reallocating for MTI, a change in number of FaceSets.\n", FuncName);
02622          /* free current MTI */
02623          PrevMTI = SUMA_Free_MT_intersect_triangle (PrevMTI);
02624          entry = 0;
02625       }else if (LocalHead) fprintf(SUMA_STDERR,"%s: Reusing.\n", FuncName);
02626    }
02627    
02628    if (!entry) {
02629       MTI = (SUMA_MT_INTERSECT_TRIANGLE *)SUMA_malloc(sizeof(SUMA_MT_INTERSECT_TRIANGLE));
02630       if (MTI == NULL) {
02631          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for MTI\n", FuncName);
02632          SUMA_RETURN (NULL);
02633       }
02634       MTI->t = NULL;
02635       MTI->u = NULL;
02636       MTI->v = NULL;
02637       MTI->isHit = NULL;
02638    } else {
02639       MTI = PrevMTI;
02640    }
02641 
02642    /* direction from two points */
02643    orig[0] = (double)P0[0];
02644    orig[1] = (double)P0[1];
02645    orig[2] = (double)P0[2];
02646    
02647    dir[0] = (double)P1[0] - orig[0];
02648    dir[1] = (double)P1[1] - orig[1];
02649    dir[2] = (double)P1[2] - orig[2];
02650    dirn = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]);
02651    dir[0] /= dirn;
02652    dir[1] /= dirn;
02653    dir[2] /= dirn;
02654    
02655    if (!entry) {
02656       MTI->isHit = (SUMA_Boolean *)SUMA_malloc(N_FaceSet*sizeof(SUMA_Boolean));
02657       MTI->t = (float *)SUMA_calloc(N_FaceSet, sizeof(float));
02658       MTI->u = (float *)SUMA_calloc(N_FaceSet, sizeof(float));
02659       MTI->v = (float *)SUMA_calloc(N_FaceSet, sizeof(float));
02660    
02661       if (MTI->isHit == NULL || MTI->t == NULL || MTI->u == NULL || MTI->v == NULL) {
02662          fprintf(SUMA_STDERR,"Error : Failed to allocate for MTI->isHit | MTI->t | MTI->u | MTI->v\n");
02663          SUMA_RETURN (NULL);
02664       }
02665    }
02666    
02667    MTI->N_hits = 0;
02668    ND = 3;
02669    NP = 3;
02670    for (iface= 0; iface < N_FaceSet; ++iface) {/* iface */
02671       /* set up the coordinates in a humane nomenclature */
02672       ip = NP * iface;
02673       id = ND * FaceSetList[ip];
02674       vert0[0] = (double)NodeList[id];
02675        vert0[1] = (double)NodeList[id+1];
02676       vert0[2] = (double)NodeList[id+2];
02677       
02678       id = ND * FaceSetList[ip+1];
02679       vert1[0] = (double)NodeList[id];
02680        vert1[1] = (double)NodeList[id+1];
02681       vert1[2] = (double)NodeList[id+2];
02682       
02683       id = ND * FaceSetList[ip+2];
02684       vert2[0] = (double)NodeList[id];
02685        vert2[1] = (double)NodeList[id+1];
02686       vert2[2] = (double)NodeList[id+2];
02687       
02688       
02689       /* find vectors for two edges sharing vert0 */
02690       SUMA_MT_SUB(edge1, vert1, vert0);
02691       SUMA_MT_SUB(edge2, vert2, vert0);
02692 
02693       /* begin calculating determinant - also used to calculate U parameter */
02694       SUMA_MT_CROSS(pvec, dir, edge2);
02695 
02696       /* if determinant is near zero, ray lies in plane of triangle */
02697       det = SUMA_MT_DOT(edge1, pvec);
02698 
02699    #ifdef SUMA_MT_TEST_CULL           /* define TEST_CULL if culling is desired */
02700       if (det < SUMA_EPSILON)
02701          MTI->isHit[iface] = NOPE;
02702       else {
02703          /* calculate distance from vert0 to ray origin */
02704          SUMA_MT_SUB(tvec, orig, vert0);
02705 
02706          /* calculate U parameter and test bounds */
02707          MTI->u[iface] = (float)SUMA_MT_DOT(tvec, pvec);
02708          if (MTI->u[iface] < 0.0 || MTI->u[iface] > det)
02709             MTI->isHit[iface] = NOPE;
02710          else {
02711             /* prepare to test V parameter */
02712             SUMA_MT_CROSS(qvec, tvec, edge1);
02713 
02714              /* calculate V parameter and test bounds */
02715             MTI->v[iface] = (float)SUMA_MT_DOT(dir, qvec);
02716             if (MTI->v[iface] < 0.0 || MTI->u[iface] + MTI->v[iface] > det)
02717                MTI->isHit[iface] = NOPE;
02718             else {
02719                /* calculate t, scale parameters, ray intersects triangle */
02720                MTI->t[iface] = (float)SUMA_MT_DOT(edge2, qvec);
02721                inv_det = 1.0 / det;
02722                MTI->t[iface] *= (float)inv_det;
02723                MTI->u[iface] *= (float)inv_det;
02724                MTI->v[iface] *= (float)inv_det;         
02725                MTI->isHit[iface] = YUP;
02726                ++MTI->N_hits;
02727                /* store shortest distance triangle info */
02728                if (MTI->t[iface] < 0) disttest = -MTI->t[iface];
02729                   else disttest = MTI->t[iface];
02730                    
02731                if (disttest < tmin) {
02732                   tmin = disttest;
02733                   MTI->ifacemin = iface;
02734                   /* calculate the location of the intersection in XYZ coords */
02735                   MTI->P[0] = vert0[0] + MTI->u[iface] * (vert1[0] - vert0[0] ) + MTI->v[iface] * (vert2[0] - vert0[0] );
02736                   MTI->P[1] = vert0[1] + MTI->u[iface] * (vert1[1] - vert0[1] ) + MTI->v[iface] * (vert2[1] - vert0[1] );
02737                   MTI->P[2] = vert0[2] + MTI->u[iface] * (vert1[2] - vert0[2] ) + MTI->v[iface] * (vert2[2] - vert0[2] );
02738                   /* find out which node is closest to P */
02739                   MTI->inodeminlocal = 0;
02740                   MTI->d = (vert0[0] - MTI->P[0])*(vert0[0] - MTI->P[0]) + (vert0[1] - MTI->P[1])*(vert0[1] - MTI->P[1]) + (vert0[2] - MTI->P[2])*(vert0[2] - MTI->P[2]);
02741                   dii = (vert1[0] - MTI->P[0])*(vert1[0] - MTI->P[0]) + (vert1[1] - MTI->P[1])*(vert1[1] - MTI->P[1]) + (vert1[2] - MTI->P[2])*(vert1[2] - MTI->P[2]);
02742                   if (dii < MTI->d) {
02743                      MTI->d = dii;
02744                      MTI->inodeminlocal = 1;
02745                   }
02746                   dii = (vert2[0] - MTI->P[0])*(vert2[0] - MTI->P[0]) + (vert2[1] - MTI->P[1])*(vert2[1] - MTI->P[1]) + (vert2[2] - MTI->P[2])*(vert2[2] - MTI->P[2]);
02747                   if (dii < MTI->d) {
02748                      MTI->d = dii;
02749                      MTI->inodeminlocal = 2;
02750                   }
02751                   MTI->d = (float)sqrt((double)MTI->d);
02752                }
02753                if (disttest > tmax) {
02754                   tmax = disttest;
02755                   MTI->ifacemax = iface;
02756                }
02757             }
02758          }
02759       }
02760    #else                    /* the non-culling branch */
02761       if (det > -SUMA_EPSILON && det < SUMA_EPSILON)
02762          MTI->isHit[iface] = NOPE;
02763       else {
02764          inv_det = 1.0 / det;
02765 
02766          /* calculate distance from vert0 to ray origin */
02767          SUMA_MT_SUB(tvec, orig, vert0);
02768 
02769          /* calculate U parameter and test bounds */
02770          MTI->u[iface] = (float)SUMA_MT_DOT(tvec, pvec) * inv_det;
02771          if (MTI->u[iface] < 0.0 || MTI->u[iface] > 1.0)
02772             MTI->isHit[iface] = NOPE;
02773          else {
02774             /* prepare to test V parameter */
02775             SUMA_MT_CROSS(qvec, tvec, edge1);
02776 
02777             /* calculate V parameter and test bounds */
02778             MTI->v[iface] = (float)SUMA_MT_DOT(dir, qvec) * inv_det;
02779             if (MTI->v[iface] < 0.0 || MTI->u[iface] + MTI->v[iface] > 1.0)
02780                MTI->isHit[iface] = NOPE;
02781             else {
02782                /* calculate t, ray intersects triangle */
02783                MTI->t[iface] = (float)SUMA_MT_DOT(edge2, qvec) * inv_det;         
02784                MTI->isHit[iface] = YUP;
02785                ++MTI->N_hits;
02786                /* store shortest distance triangle info */
02787                if (MTI->t[iface] < 0) disttest = -MTI->t[iface];
02788                   else  disttest = MTI->t[iface];
02789                
02790                if (disttest < tmin) {
02791                   tmin = disttest;
02792                   MTI->ifacemin = iface;
02793                   /* calculate the location of the intersection in XYZ coords */
02794                   MTI->P[0] = vert0[0] + MTI->u[iface] * (vert1[0] - vert0[0] ) + MTI->v[iface] * (vert2[0] - vert0[0] );
02795                   MTI->P[1] = vert0[1] + MTI->u[iface] * (vert1[1] - vert0[1] ) + MTI->v[iface] * (vert2[1] - vert0[1] );
02796                   MTI->P[2] = vert0[2] + MTI->u[iface] * (vert1[2] - vert0[2] ) + MTI->v[iface] * (vert2[2] - vert0[2] );
02797                   /* find out which node is closest to P */
02798                   MTI->inodeminlocal = 0;
02799                   MTI->d = (vert0[0] - MTI->P[0])*(vert0[0] - MTI->P[0]) + (vert0[1] - MTI->P[1])*(vert0[1] - MTI->P[1]) + (vert0[2] - MTI->P[2])*(vert0[2] - MTI->P[2]);
02800                   dii = (vert1[0] - MTI->P[0])*(vert1[0] - MTI->P[0]) + (vert1[1] - MTI->P[1])*(vert1[1] - MTI->P[1]) + (vert1[2] - MTI->P[2])*(vert1[2] - MTI->P[2]);
02801                   if (dii < MTI->d) {
02802                      MTI->d = dii;
02803                      MTI->inodeminlocal = 1;
02804                   }
02805                   dii = (vert2[0] - MTI->P[0])*(vert2[0] - MTI->P[0]) + (vert2[1] - MTI->P[1])*(vert2[1] - MTI->P[1]) + (vert2[2] - MTI->P[2])*(vert2[2] - MTI->P[2]);
02806                   if (dii < MTI->d) {
02807                      MTI->d = dii;
02808                      MTI->inodeminlocal = 2;
02809                   }
02810                   MTI->d = (float)sqrt((double)MTI->d);
02811                   ip = NP * iface + MTI->inodeminlocal;
02812                   MTI->inodemin = FaceSetList[ip];
02813                }
02814                if (disttest > tmax) {
02815                   tmax = disttest;
02816                   MTI->ifacemax = iface;
02817                }
02818             }
02819          }
02820       }
02821    #endif
02822    }/*iface */
02823    MTI->N_el = N_FaceSet;
02824    
02825    ++entry;
02826    N_FaceSet_Previous = N_FaceSet;
02827 
02828    SUMA_RETURN (MTI);
02829 }

SUMA_Boolean SUMA_MT_isIntersect_Triangle float *    P0,
float *    P1,
float *    vert0,
float *    vert1,
float *    vert2,
float *    iP,
float *    d,
int *    closest_vert
 

Definition at line 2469 of file SUMA_MiscFunc.c.

Referenced by SUMA_BrushStrokeToNodeStroke(), and SUMA_inNodeNeighb().

02470 {  static char FuncName[]={"SUMA_MT_isIntersect_Triangle"};
02471    double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
02472    double det,inv_det, u, v, t;
02473    double dir[3], dirn, orig[3];
02474    SUMA_Boolean hit = NOPE;
02475    
02476    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02477    
02478    /* direction from two points */
02479    orig[0] = (double)P0[0];
02480    orig[1] = (double)P0[1];
02481    orig[2] = (double)P0[2];
02482    
02483    dir[0] = (double)P1[0] - orig[0];
02484    dir[1] = (double)P1[1] - orig[1];
02485    dir[2] = (double)P1[2] - orig[2];
02486    dirn = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]);
02487    dir[0] /= dirn;
02488    dir[1] /= dirn;
02489    dir[2] /= dirn;
02490 
02491    /* find vectors for two edges sharing vert0 */
02492    SUMA_MT_SUB(edge1, vert1, vert0);
02493    SUMA_MT_SUB(edge2, vert2, vert0);
02494 
02495    /* begin calculating determinant - also used to calculate U parameter */
02496    SUMA_MT_CROSS(pvec, dir, edge2);
02497 
02498    /* if determinant is near zero, ray lies in plane of triangle */
02499    det = SUMA_MT_DOT(edge1, pvec);
02500    
02501    hit = NOPE;
02502    
02503       if (det > -SUMA_EPSILON && det < SUMA_EPSILON) {
02504          /* no hit, will return below */
02505          hit = NOPE;
02506       } else {
02507          inv_det = 1.0 / det;
02508 
02509          /* calculate distance from vert0 to ray origin */
02510          SUMA_MT_SUB(tvec, orig, vert0);
02511 
02512          /* calculate U parameter and test bounds */
02513          u = SUMA_MT_DOT(tvec, pvec) * inv_det;
02514          if (u < 0.0 || u > 1.0) {
02515             /* no hit, will return below */
02516             hit = NOPE;
02517          } else {
02518             /* prepare to test V parameter */
02519             SUMA_MT_CROSS(qvec, tvec, edge1);
02520 
02521             /* calculate V parameter and test bounds */
02522             v = SUMA_MT_DOT(dir, qvec) * inv_det;
02523             if (v < 0.0 || u + v > 1.0) {
02524                 /* no hit, will return below */
02525                 hit = NOPE;
02526             } else {
02527                hit = YUP;
02528                
02529                if (iP) {
02530                   /* calculate t, ray intersects triangle */
02531                   t = SUMA_MT_DOT(edge2, qvec) * inv_det;         
02532 
02533                   /* calculate the location of the intersection (iP) in XYZ coords */
02534                   iP[0] = vert0[0] + u * (vert1[0] - vert0[0] ) + v * (vert2[0] - vert0[0] );
02535                   iP[1] = vert0[1] + u * (vert1[1] - vert0[1] ) + v * (vert2[1] - vert0[1] );
02536                   iP[2] = vert0[2] + u * (vert1[2] - vert0[2] ) + v * (vert2[2] - vert0[2] );
02537                   
02538                   if (d) {
02539                      /* find out which node is closest to P */
02540                      d[0] = (vert0[0] - iP[0])*(vert0[0] - iP[0]) + (vert0[1] - iP[1])*(vert0[1] - iP[1]) + (vert0[2] - iP[2])*(vert0[2] - iP[2]);
02541                      *closest_vert = 0;
02542                      d[1] = (vert1[0] - iP[0])*(vert1[0] - iP[0]) + (vert1[1] - iP[1])*(vert1[1] - iP[1]) + (vert1[2] - iP[2])*(vert1[2] - iP[2]);
02543                      if (d[1] < d[*closest_vert]) {
02544                         *closest_vert = 1;
02545                      }
02546                      d[2] = (vert2[0] - iP[0])*(vert2[0] - iP[0]) + (vert2[1] - iP[1])*(vert2[1] - iP[1]) + (vert2[2] - iP[2])*(vert2[2] - iP[2]);
02547                      if (d[2] < d[*closest_vert]) {
02548                         *closest_vert = 2;
02549                      }
02550                      d[0] = (float)sqrt((double)d[0]);
02551                      d[1] = (float)sqrt((double)d[1]);
02552                      d[2] = (float)sqrt((double)d[2]);
02553                   }
02554                }
02555 
02556             }
02557          }
02558       }
02559    
02560    SUMA_RETURN (hit);
02561 }

char* SUMA_pad_str char *    str,
char    pad_val,
int    pad_ln,
int    opt
 

Function to pad a string to a certain length

char * SUMA_pad_str (char *str, char pad_val , int pad_ln , int opt)

str, (char *) string with the original string pad_char, (char ) padding character pad_ln, (int) final padded lenght, opt, (int) 0 if padding occurs to the left of str (00005) 1 if padding occurs to the right of str (50000) Returns : a pointer to the padded string .

Definition at line 5355 of file SUMA_MiscFunc.c.

Referenced by SUMA_RenderToPixMap().

05356 {/*SUMA_pad_str*/
05357     static char FuncName[]={"SUMA_pad_str"};
05358    int lo,i;
05359     char *strp , *buf1;
05360 
05361    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05362 
05363     assert (str);
05364 
05365     lo = (int)strlen(str);
05366 
05367    buf1 = (char *)SUMA_calloc (pad_ln-lo+2,sizeof (char));
05368     strp = (char *)SUMA_calloc (pad_ln+lo+2,sizeof (char));
05369 
05370    for (i=0;i<pad_ln-lo;++i)
05371        {
05372           if (i == 0) sprintf (buf1,"%c",pad_val);
05373              else sprintf (buf1,"%s%c",buf1,pad_val);
05374 
05375        }
05376     if (opt == 0)
05377        sprintf (strp,"%s%s",buf1,str);
05378     else if (opt == 1)
05379        {
05380           sprintf (strp,"%s%s",str,buf1);
05381 
05382       }         
05383        else 
05384           {
05385              fprintf (SUMA_STDERR, "Error %s: Wrong opt paramter, only (0,1) allowed\n", FuncName);
05386              SUMA_free(strp);
05387             SUMA_free(buf1);
05388             SUMA_RETURN (NULL);
05389           }
05390 
05391     SUMA_free(buf1);
05392 
05393     SUMA_RETURN (strp);
05394 
05395 }/*SUMA_pad_str*/

SUMA_PARSED_NAME* SUMA_ParseFname char *    FileName
 

ans = SUMA_ParseFname (FileName); parses a file name into its elements.

Parameters:
FileName  (char *) obvious ...
Returns:
ans (SUMA_PARSED_NAME *) pointer to structure with following fields: .FileName (char *) containing filename without path. if empty .FileName = '\0' .Path (char *) containing path including last slash. If no path exists, Path is "./" .Ext (char *) containing extension including the dot. If no extension exists, Ext = '\0' .FileName_NoExt (char *) filename without extension.
See also:
SUMA_Free_Parsed_Name

Definition at line 120 of file SUMA_StripPath.c.

00121 {/*SUMA_ParseFname*/
00122    static char FuncName[]={"SUMA_ParseFname"};
00123    char PathDelimiter='/'; 
00124    int i, j, iExt , iFile, iPath, N_FileName;
00125         SUMA_PARSED_NAME *NewName = NULL;
00126    SUMA_Boolean FoundPath = NOPE, FoundExt, FoundFile;
00127         
00128    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00129 
00130 
00131         N_FileName = strlen(FileName);
00132    iExt = N_FileName;
00133    iPath = -1;
00134    iFile = 0;
00135    FoundPath = NOPE;
00136    FoundExt = NOPE;
00137         if (N_FileName ){
00138                 NewName = (SUMA_PARSED_NAME *) SUMA_malloc(sizeof(SUMA_PARSED_NAME));
00139       
00140       i = N_FileName -1;
00141                 while (i > -1 && !FoundPath) {
00142                         if (FileName[i] == '.' && !FoundExt) {
00143             iExt = i;
00144             FoundExt = YUP;
00145          } else if (FileName[i] == PathDelimiter) {
00146             FoundPath = YUP;
00147             iPath = i;
00148             iFile = i+1;
00149          }
00150                         --i;
00151                 }
00152       
00153       if (iFile == iExt) {
00154          /* .file, not an extension */
00155          FoundExt = NOPE;
00156       }
00157       
00158       if (iFile ==  N_FileName) FoundFile = NOPE;
00159       else FoundFile = YUP;
00160       
00161       if (FoundPath) {
00162          NewName->Path = (char *)SUMA_malloc(sizeof(char)*(iPath+2));
00163          for (i=0; i<= iPath; ++i) NewName->Path[i] = FileName[i];
00164          NewName->Path[i] = '\0';
00165       }else {
00166          NewName->Path = (char *)SUMA_malloc(sizeof(char)*(3));
00167          sprintf(NewName->Path, "./");
00168       }
00169       
00170       if (FoundFile) {
00171          NewName->FileName = (char *)SUMA_malloc(sizeof(char)*(N_FileName - iFile + 2));
00172          for (i=iFile; i< N_FileName; ++i) NewName->FileName[i-iFile] = FileName[i];
00173          NewName->FileName[i-iFile] = '\0';
00174       }else {
00175          NewName->FileName = (char *)SUMA_malloc(sizeof(char));
00176          NewName->FileName[0] = '\0';
00177       }      
00178                 
00179       if (FoundExt) {
00180                    NewName->FileName_NoExt = (char *)SUMA_malloc(sizeof(char)*(N_FileName - iFile +2));
00181          NewName->Ext = (char *)SUMA_malloc(sizeof(char)*(N_FileName - iExt+2));
00182          for (i=iFile; i< iExt; ++i) NewName->FileName_NoExt[i-iFile] = FileName[i];
00183          NewName->FileName_NoExt[i-iFile] = '\0';
00184          for (i=iExt; i < N_FileName; ++i) NewName->Ext[i-iExt] = FileName[i];
00185          NewName->Ext[i-iExt] = '\0';
00186       } else {
00187          NewName->FileName_NoExt = (char *)SUMA_malloc(sizeof(char));
00188          NewName->Ext = (char *)SUMA_malloc(sizeof(char));
00189          NewName->FileName_NoExt[0] = '\0';
00190          NewName->Ext[0] = '\0';
00191       }
00192       
00193         }
00194    
00195         SUMA_RETURN (NewName);
00196 }/*SUMA_ParseFname*/

float** SUMA_Point_At_Distance float *    U,
float *    P1,
float    d
 

** Function: SUMA_Point_At_Distance Usage : P2 = SUMA_Point_At_Distance (U, P1, d)

Returns the two points that are at a distance d from P1 along the direction of U

Input paramters :

Parameters:
U  (float *) 3x1 vector specifying directions along x, y, z axis
P1  (float *) 3x1 vector containing the XYZ of P1
d  (float) distance from P1
Returns :
Returns:
P2 (float **) 2x3 matrix containg XYZ of 2 points equidistant from P1 along U (first row) and -U (second row) NULL if there are problems in the land of chocolate
Support :
See also:
Point_At_Distance.m , To free P2, use: SUMA_free2D((char **)P2, 2);

Definition at line 1717 of file SUMA_MiscFunc.c.

Referenced by main(), and SUMA_Engine().

01718 {/*SUMA_Point_At_Distance*/
01719    static char FuncName[]={"SUMA_Point_At_Distance"}; 
01720    float bf, **P2, P1orig[3], Uorig[3];
01721    float m, n, p, q, D, A, B, C;
01722    int flip, i;
01723    SUMA_Boolean LocalHead = NOPE;
01724    
01725    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01726 
01727    if (d == 0) {
01728       fprintf(SUMA_STDERR,"Error %s: d is 0. Not good, Not good at all.\n", FuncName);
01729       SUMA_RETURN (NULL);
01730    }
01731    
01732    if (LocalHead) {
01733       fprintf (SUMA_STDOUT,"%s: U %f, %f, %f, P1 %f %f %f, d %f\n", FuncName,\
01734          U[0], U[1], U[2], P1[0], P1[1], P1[2], d);
01735    }
01736          
01737    /* store initial values */
01738    P1orig[0] = P1[0];    
01739    P1orig[1] = P1[1]; 
01740    P1orig[2] = P1[2]; 
01741 
01742    Uorig[0] = U[0];
01743    Uorig[1] = U[1];
01744    Uorig[2] = U[2];
01745    
01746    /* normalize U such that U(0) = 1 */
01747    flip = 0;
01748    if (U[0] == 0) { /* must flip X with some other coordinate */
01749       if (U[1] != 0) {/*U[1] != 0; */
01750          U[0] = U[1]; U[1] = 0;
01751          bf = P1[0]; P1[0] = P1[1]; P1[1] = bf;
01752          flip = 1;
01753       } else {   /*U[1] = 0; */
01754          if (U[2] != 0) { /* U[2] != 0 */
01755             U[0] = U[2]; U[2] = 0;
01756             bf = P1[0]; P1[0] = P1[2]; P1[2] = bf;
01757             flip = 2;
01758          } else { /* U[2] = 0 */
01759             fprintf(SUMA_STDERR, "Error %s: 0 direction vector.\n", FuncName);
01760             SUMA_RETURN (NULL);
01761          }
01762       }/*U[1] = 0; */
01763    }/*U[0] = 0; */
01764 
01765    if (LocalHead) fprintf (SUMA_STDERR, "%s: flip = %d\n", FuncName, flip);
01766       
01767    if (LocalHead) fprintf (SUMA_STDERR, "%s: U original: %f, %f, %f\n", FuncName, U[0], U[1], U[2]);
01768    U[1] /= U[0];
01769    U[2] /= U[0];
01770    U[0] = 1.0; 
01771    if (LocalHead) fprintf (SUMA_STDERR, "%s: U normalized: %f, %f, %f\n", FuncName, U[0], U[1], U[2]);
01772    
01773    /* Now U is clean, calculate P2 */   
01774    m = U[1];
01775    n = U[2];
01776 
01777    q = P1[1] - m*P1[0];
01778    p = P1[2] - n*P1[0];
01779 
01780    if (LocalHead) fprintf (SUMA_STDERR, "%s: m=%f n=%f, p=%f, q=%f\n", FuncName, m, n, p, q);
01781 
01782    /* Now find P2 */
01783    A = (1 + n*n + m*m);
01784    B = -2 * P1[0] + 2 * m * (q - P1[1]) + 2 * n * (p - P1[2]);
01785    C = P1[0]*P1[0] + (q - P1[1])*(q - P1[1]) + (p - P1[2])*(p - P1[2]) - d*d;
01786 
01787    D = B*B - 4*A*C;
01788    
01789    if (LocalHead) fprintf (SUMA_STDERR, "%s: A=%f B=%f, C=%f, D=%f\n", FuncName, A, B, C, D);
01790    
01791    if (D < 0) {
01792       fprintf(SUMA_STDERR, "Error %s: Negative Delta.\n", FuncName);
01793       SUMA_RETURN (NULL);
01794    }
01795 
01796    P2 = (float **)SUMA_allocate2D(2,3, sizeof(float));
01797    if (P2 == NULL) {
01798       fprintf(SUMA_STDERR, "Error %s: Could not allocate for 6 floats! What is this? What is the matter with you?!\n", FuncName);
01799       SUMA_RETURN (NULL);
01800    }
01801 
01802    P2[0][0] = (-B + sqrt(D)) / (2 *A);
01803    P2[1][0] = (-B - sqrt(D)) / (2 *A);
01804 
01805    P2[0][1] = m * P2[0][0] + q;
01806    P2[1][1] = m * P2[1][0] + q;
01807 
01808    P2[0][2] = n * P2[0][0] + p;
01809    P2[1][2] = n * P2[1][0] + p;
01810 
01811 
01812    /* if flipping was performed, undo it */
01813    if (flip == 1) {
01814     for (i=0; i < 2; ++i) {
01815        bf = P2[i][1];
01816        P2[i][1] = P2[i][0];
01817        P2[i][0] = bf;
01818       }
01819    } else if (flip == 2){
01820     for (i=0; i < 2; ++i) {
01821        bf = P2[i][2]; 
01822        P2[i][2] = P2[i][0];
01823        P2[i][0] = bf;
01824       }
01825    }   
01826 
01827    for (i=0; i < 3; ++i) {
01828       P1[i] = P1orig[i];
01829       U[i] = Uorig[i];
01830    }
01831 
01832    if (LocalHead) {
01833       fprintf(SUMA_STDOUT,"%s: P1 = %f, %f, %f\n  ", \
01834        FuncName, P1[0], P1[1], P1[2]);
01835       fprintf(SUMA_STDOUT,"%s: P2 = %f, %f, %f\n    %f, %f, %f\n", \
01836        FuncName, P2[0][0], P2[0][1], P2[0][2], P2[1][0], P2[1][1], P2[1][2]);
01837       fprintf(SUMA_STDOUT,"%s: U = %f, %f, %f\n  ", \
01838        FuncName, U[0], U[1], U[2]);
01839    }
01840 
01841    
01842    /* make sure 1st point is along the same direction */
01843    Uorig[0] = P2[0][0] - P1[0]; /* use Uorig, not needed anymore */
01844    Uorig[1] = P2[0][1] - P1[1];
01845    Uorig[2] = P2[0][2] - P1[2];
01846 
01847    SUMA_DOTP_VEC(Uorig, U, bf, 3, float, float)
01848    if (LocalHead) fprintf(SUMA_STDOUT,"%s: Dot product = %f\n", FuncName, bf);
01849    if (bf < 0) {
01850       if (LocalHead) fprintf(SUMA_STDOUT,"%s: Flipping at end...\n", FuncName);
01851       for (i=0; i< 3; ++i) {
01852          bf = P2[0][i];
01853          P2[0][i] = P2[1][i]; P2[1][i] = bf;
01854       }
01855    }
01856    
01857    if (LocalHead) {
01858       fprintf(SUMA_STDOUT,"%s: P2 = %f, %f, %f\n    %f, %f, %f\n", \
01859        FuncName, P2[0][0], P2[0][1], P2[0][2], P2[1][0], P2[1][1], P2[1][2]);
01860    }
01861 SUMA_RETURN (P2);
01862    
01863 }/*SUMA_Point_At_Distance*/

SUMA_Boolean SUMA_Point_To_Line_Distance float *    NodeList,
int    N_points,
float *    P1,
float *    P2,
float *    d2,
float *    d2min,
int *    i2min
 

Function: SUMA_Point_To_Line_Distance Usage : Ret = SUMA_Point_To_Line_Distance (float *NodeList, int N_nodes, float *P1, float *P2, float *d2, float *d2min, int *i2min)

Calculates the squared distance between the points in NodeList and the line formed by P1-P2

Input paramters :

Parameters:
NodeList  (float *) N_nodes x 3 vector containing XYZ of N_nodes nodes
N_nodes  (int) Number of nodes in NodeList
P1  (float *) 3x1 vector containing the XYZ of P1
P2  (float *) 3x1 vector containing the XYZ of P2
d2  (float *) N_nodes x 1 vector containing the squared distance of each node in NodeList to the line P1-P2 d2 must be pointing to a pre-allocated space
d2min  (float *) pointer to the smallest squared distance
i2min  (int *) pointer to the index (into NodeList) of the node with the shortest distance
The squared distance is returned to save on a square root operation which may not be necessary to compute for all nodes

Returns :

Returns:
Ret (SUMA_Boolean) YUP/NOPE for success/failure
See also:
labbook NIH-2, p 37

Definition at line 1891 of file SUMA_MiscFunc.c.

01892 {
01893    static char FuncName[]={"SUMA_Point_To_Line_Distance"};
01894    float U[3], Un, xn, yn, zn, dx, dy, dz;
01895    int i, id, ND;
01896    
01897    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01898    
01899    ND = 3;
01900    if (N_points < 1) {
01901       fprintf(SUMA_STDERR,"Error %s: N_points is 0.\n",FuncName);
01902       SUMA_RETURN (NOPE);
01903    }
01904    /* Calculate normalized unit vector of line formed by P1, P2 */
01905    U[0] = P2[0] - P1[0];
01906    U[1] = P2[1] - P1[1];
01907    U[2] = P2[2] - P1[2];
01908    Un = sqrt(U[0]*U[0] + U[1]*U[1] + U[2]*U[2]);
01909    
01910    if (Un == 0) {
01911       fprintf(SUMA_STDERR,"Error %s: P1 and P2 are identical.\n",FuncName);
01912       SUMA_RETURN (NOPE);
01913    }
01914    
01915    U[0] /= Un;
01916    U[1] /= Un;
01917    U[2] /= Un;
01918    
01919    /* calculate the distances and keep track of the minimum distance while you're at it */
01920    
01921    /*bad practise, only returned pointers are allocated for in functions */
01922    /*
01923    d2 = (float *)SUMA_calloc(N_points, sizeof(float)); */
01924    
01925    if (d2 == NULL) {
01926       fprintf(SUMA_STDERR,"Error %s: d2 not allocated for.\n",FuncName);
01927       SUMA_RETURN (NOPE);
01928    }
01929    
01930    
01931    /* do the first point to initialize d2min without an extra if statement */
01932     i = 0;
01933     xn = NodeList[0] - P1[0];
01934     yn = NodeList[1] - P1[1];
01935     zn = NodeList[2] - P1[2];
01936     
01937     dx = (U[1]*zn - yn*U[2]);
01938     dy = (U[0]*zn - xn*U[2]);
01939     dz = (U[0]*yn - xn*U[1]);
01940     
01941     d2[i] = dx*dx+dy*dy +dz*dz; /* save the sqrt for speed */
01942     *d2min = d2[i];
01943     *i2min = i;
01944     /* Now do the rest */
01945    for (i=1; i < N_points; ++i) {
01946       id = ND * i;
01947       xn = NodeList[id] - P1[0];
01948       yn = NodeList[id+1] - P1[1];
01949       zn = NodeList[id+2] - P1[2];
01950 
01951       dx = (U[1]*zn - yn*U[2]);
01952       dy = (U[0]*zn - xn*U[2]);
01953       dz = (U[0]*yn - xn*U[1]);
01954 
01955       d2[i] = dx*dx+dy*dy +dz*dz; /* save the sqrt for speed */
01956       if (d2[i] < *d2min) {
01957          *d2min = d2[i];
01958          *i2min = i;
01959       }
01960    }
01961    SUMA_RETURN (YUP);
01962 }

SUMA_Boolean SUMA_Point_To_Point_Distance float *    NodeList,
int    N_points,
float *    P1,
float *    d2,
float *    d2min,
int *    i2min
 

Function: SUMA_Point_To_Point_Distance Usage : Ret = SUMA_Point_To_Point_Distance (float *NodeList, int N_nodes, float *P1, float *d2, float *d2min, int *i2min)

Calculates the squared distance between the points in NodeList and P1-P2

Input paramters :

Parameters:
NodeList  (float *) N_nodes x 3 vector containing XYZ of N_nodes nodes
N_nodes  (int) Number of nodes in NodeList
P1  (float *) 3x1 vector containing the XYZ of P1
d2  (float *) N_nodes x 1 vector containing the squared distance of each node in NodeList to P1 d2 must be pointing to a pre-allocated space
d2min  (float *) pointer to the smallest squared distance
i2min  (int *) pointer to the index (into NodeList) of the node with the shortest distance
The squared distance is returned to save on a square root operation which may not be necessary to compute for all nodes

Returns :

Returns:
Ret (SUMA_Boolean) YUP/NOPE for success/failure

Definition at line 1987 of file SUMA_MiscFunc.c.

01988 {
01989    static char FuncName[]={"SUMA_Point_To_Point_Distance"};
01990    float xn, yn, zn;
01991    int i, id, ND;
01992    
01993    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01994 
01995    ND = 3;
01996    if (N_points < 1) {
01997       fprintf(SUMA_STDERR,"Error %s: N_points is 0.\n",FuncName);
01998       SUMA_RETURN (NOPE);
01999    }
02000    
02001    
02002    /* calculate the distances and keep track of the minimum distance while you're at it */
02003    
02004    if (d2 == NULL) {
02005       fprintf(SUMA_STDERR,"Error %s: d2 not allocated for.\n",FuncName);
02006       SUMA_RETURN (NOPE);
02007    }
02008    
02009    
02010    /* do the first point to initialize d2min without an extra if statement */
02011     i = 0;
02012     xn = NodeList[0] - P1[0];
02013     yn = NodeList[1] - P1[1];
02014     zn = NodeList[2] - P1[2];
02015     
02016     d2[i] = xn*xn + yn*yn + zn*zn; /* save the sqrt for speed */
02017     *d2min = d2[i];
02018     *i2min = i;
02019     /* Now do the rest */
02020    for (i=1; i < N_points; ++i) {
02021       id = ND * i;
02022       xn = NodeList[id] - P1[0];
02023       yn = NodeList[id+1] - P1[1];
02024       zn = NodeList[id+2] - P1[2];
02025 
02026 
02027        d2[i] = xn*xn + yn*yn + zn*zn; /* save the sqrt for speed */
02028       if (d2[i] < *d2min) {
02029          *d2min = d2[i];
02030          *i2min = i;
02031       }
02032    }
02033    SUMA_RETURN (YUP);
02034 }

float* SUMA_PolySurf3 float *    NodeList,
int    N_Node,
int *    FaceSetList,
int    N_FaceSet,
int    PolyDim,
float *    FaceNormList,
SUMA_Boolean    SignedArea
 

Calculate the area of planar polygons A = SUMA_PolySurf3 (NodeList, int N_Node, int *FaceSets, int N_FaceSet, int PolyDim, float *FaceNormList, SUMA_Boolean SignedArea)

Parameters:
NodeList  (float *) (N_Node x 3) vector containing XYZ of each node
N_Node  number of nodes in NodeList
FaceSets  (int *) vector (matrix, prior to SUMA 1.2) (N_FaceSet x PolyDim) defining the polygons by their indices into NodeList
N_FaceSet  (int) number of polygons
PolyDim  (int) dimension of polygons (3 triangles)
FaceNormList  (float *) N_FaceSet x 3 vector of normals to polygons
SignedArea  (SUMA_Boolean) signed or unsigned areas positive means the vertices are oriented counterclockwise around the polygon when viewed from the side of the plane poited to by the normal
Returns:
A (float *) vector containing the area of each polygon in FaceSets
See also:
SUMA_TriSurf3
Algorithm by Dan Sunday http://geometryalgorithms.com

Definition at line 4682 of file SUMA_MiscFunc.c.

Referenced by SUMA_SurfaceMetrics().

04683 {
04684    static char FuncName[]={"SUMA_PolySurf3"};
04685    float **V, *A, ax, ay, az, an;
04686    int i, ii, coord, kk, jj, id, ND, ip, NP;
04687    
04688    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04689 
04690    ND = 3;
04691    NP = PolyDim;
04692    A = (float *) SUMA_calloc (N_FaceSet, sizeof(float));
04693    V = (float **) SUMA_allocate2D(PolyDim+2, 3, sizeof(float));
04694    
04695    if (A == NULL || V == NULL) {
04696       fprintf(SUMA_STDERR,"Error %s; Failed to allocate for A or V\n", FuncName);
04697       SUMA_RETURN (NULL);
04698    }
04699 
04700    for (i=0; i < N_FaceSet; ++i) {
04701       ip = NP * i;
04702       if (FaceNormList[ip] > 0) ax = FaceNormList[ip];
04703          else ax = -FaceNormList[ip];
04704       
04705       if (FaceNormList[ip+1] > 0) ay = FaceNormList[ip+1];
04706          else ay = -FaceNormList[ip+1];
04707       
04708       if (FaceNormList[ip+2] > 0) az = FaceNormList[ip+2];
04709          else az = -FaceNormList[ip+2];
04710    
04711    
04712       coord = 3;
04713       if (ax > ay) {
04714          if (ax > az) coord = 1;
04715       } else {
04716          if (ay > az) coord = 2;
04717       }
04718    
04719       for (ii=0; ii< PolyDim; ++ii) {
04720          ip = NP * i;
04721          id = ND * FaceSets[ip+ii];
04722          V[ii][0] = NodeList[id];
04723          V[ii][1] = NodeList[id+1];
04724          V[ii][2] = NodeList[id+2];
04725       }
04726       ii = PolyDim;
04727       V[ii][0] = V[0][0]; V[ii][1] = V[0][1]; V[ii][2] = V[0][2];
04728       ii = PolyDim + 1;
04729       V[ii][0] = V[1][0]; V[ii][1] = V[1][1]; V[ii][2] = V[1][2];
04730       
04731       /* compute area of 2D projection */
04732       jj = 2;
04733       kk = 0;
04734       for (ii=1; ii < PolyDim+1; ++ii) {
04735          switch (coord) {
04736             case 1:
04737                A[i] = A[i] + ( V[ii][1] * (V[jj][2] - V[kk][2]) );
04738                break;
04739             case 2:
04740                A[i] = A[i] + ( V[ii][0] * (V[jj][2] - V[kk][2]) );
04741                break;
04742             case 3:
04743                A[i] = A[i] + ( V[ii][0] * (V[jj][1] - V[kk][1]) );
04744                break;
04745          }
04746          
04747          ++jj;
04748          ++kk;
04749          
04750       }
04751       
04752       /* scale to get area before projection  */
04753       an = (float) sqrt(ax * ax + ay * ay + az * az);
04754       switch (coord) {
04755          case 1:
04756             A[i] = (A[i] * (an / (2*ax)));
04757             break;
04758          case 2:
04759             A[i] = (A[i] * (an / (2*ay)));
04760             break;
04761          case 3:
04762             A[i] = (A[i] * (an / (2*az)));
04763             break;
04764       }
04765       
04766       if (!SignedArea) {
04767          if (A[i] < 0) A[i] = -A[i];
04768       }
04769    } /* for i*/
04770    
04771    SUMA_free2D((char **)V, PolyDim+2);
04772    SUMA_RETURN (A);
04773 }

int SUMA_Read_2Ddfile char *    f_name,
int **    x,
int    n_rows,
int    n_cols
 

Purpose : Reads a file of integer numbers, with n_cols values per line

Usage : ans = SUMA_Read_2Ddfile (char *f_name, int **x,int n_rows, int n_cols)

Input paramters :

Parameters:
x  , (int)** array where the values will be stored.
f_name  , (char)* string holding file name.
n_rows  , (int) number of rows to be read from file.
n_cols  , (int) number of columns per line.
\ret Number of rows read (maybe incomplete rows)

Definition at line 660 of file SUMA_MiscFunc.c.

00661 {/*SUMA_Read_2Ddfile*/
00662    int ir, ic, ex;
00663    FILE*internal_file;
00664    static char FuncName[]={"SUMA_Read_2Ddfile"};
00665 
00666    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00667 
00668    internal_file = fopen (f_name,"r");
00669    if (internal_file == NULL) {
00670       fprintf (SUMA_STDERR,"%s: \aCould not open %s \n",FuncName, f_name);
00671       SUMA_RETURN (-1);
00672    }
00673 
00674 
00675 
00676    ir = 0;
00677    while (ir < n_rows)
00678    {
00679        ic = 0;
00680       while (ic < n_cols)
00681          {
00682             ex = fscanf (internal_file,"%d",&x[ir][ic]);   
00683             if (ex == EOF)
00684                {
00685                   fprintf(stderr,"Error SUMA_Read_2Ddfile: Premature EOF\n");
00686                   fclose (internal_file);
00687                   SUMA_RETURN(ir);
00688                }
00689             ++ic;
00690          }
00691       ++ir;
00692    }
00693 
00694    fclose (internal_file);
00695    SUMA_RETURN (ir);      
00696       
00697 }/*SUMA_Read_2Ddfile*/

int SUMA_Read_2Dfile char *    f_name,
float **    x,
int    n_rows,
int    n_cols
 

**

File : Read_2Dfile.c Author : Ziad Saad Date : Sat Nov 14 18:52:31 CST 1998/remix Wed Feb 6 17:22:32 EST 2002

Purpose : Reads a file of float numbers, with n_cols values per line

Usage : n_rows_read = SUMA_Read_2Dfile ( char *f_name, float **x, int n_cols, int n_rows)

Input paramters : f_name, (char)* string holding file name. x, (float)** array where the values will be stored. n_cols, (int) number of columns per line. n_rows, (int) number of rows .

Returns : n_rows_read, (int) number of rows read from file. -1 if critcial operations fail. if EOF is reached before n_rows, n_rows_read reflects the number of rows read.

Support :

Side effects :

Definition at line 501 of file SUMA_MiscFunc.c.

Referenced by SUMA_input().

00502 {/*SUMA_Read_2Dfile*/
00503    int ir=0, ic=0, ex;
00504    FILE*internal_file;
00505    static char FuncName[]={"SUMA_Read_2Dfile"};
00506 
00507    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00508 
00509 
00510    internal_file = fopen (f_name,"r");
00511    if (internal_file == NULL) {
00512                           fprintf (SUMA_STDERR,"%s: \aCould not open %s \n",FuncName, f_name);
00513                           SUMA_RETURN (-1);
00514                           }
00515    ir = 0;
00516    while (ir < n_rows)
00517    {
00518        ic = 0;
00519       while (ic < n_cols)
00520          {
00521             ex = fscanf (internal_file,"%f",&x[ir][ic]);   
00522             if (ex == EOF)
00523                {
00524                   fprintf(stderr,"Error SUMA_Read_2Dfile: Premature EOF\n");
00525                   fclose (internal_file);
00526                   SUMA_RETURN (n_rows);
00527                }
00528             ++ic;
00529          }
00530       ++ir;
00531    }
00532 
00533    fclose (internal_file);
00534    SUMA_RETURN (ir);      
00535       
00536 }/*SUMA_Read_2Dfile*/

int SUMA_Read_dfile int *    x,
char *    f_name,
int    n_points
 

File : Read_file.c Author : Ziad Saad Date : 19 Dec. 1994

Purpose : Reads a file sequence of int numbers, one value per line .

Usage :

int SUMA_Read_dfile (int *x,char *f_name,int n_points); or int SUMA_Read_file (float *x,char *f_name,int n_points);

Input Parameters: x, (int*) or (float *) array where the values will be stored. f_name, (char)* string holding file name. n_points, (int) number of points to be read from file. if set to 0, then all the file will be read .

Output parameters : Number of points read.

Side effects : function does not check for array overflow while reading file.

Definition at line 361 of file SUMA_MiscFunc.c.

Referenced by SUMA_Load_Surface_Object().

00363 { /* pass a 0 to n_points if you want to read till EOF */
00364    int cnt=0,ex,dec;
00365    static char FuncName[]={"SUMA_Read_dfile"};
00366    FILE*internal_file;
00367 
00368    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00369 
00370    internal_file = fopen (f_name,"r");
00371    if (internal_file == NULL) {
00372                           fprintf(SUMA_STDERR, "\aCould not open %s \n",f_name);
00373                           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00374                           exit (0);
00375                           }
00376    ex = fscanf (internal_file,"%d",&x[cnt]);                     
00377    while (ex != EOF)
00378    {
00379      ++cnt;
00380      /* NOT WORKING, RETURNS SIZEOF (FLOAT) .....
00381      if (sizeof(x) < cnt)
00382       {
00383         fprintf(SUMA_STDERR, "%d = sizeof(x)\n",sizeof(x));
00384         fprintf(SUMA_STDERR, "\nNot Enough Memory Allocated \n\a");
00385         fprintf(SUMA_STDERR, "Exiting @SUMA_Read_file function\n");
00386         exit (0);
00387       }
00388      ............................................ */
00389      ex = fscanf (internal_file,"%d",&x[cnt]);
00390 
00391      if ((n_points != 0) && (cnt == n_points)) ex = EOF;
00392    }
00393 
00394    if (cnt < n_points) 
00395       {
00396        fprintf(SUMA_STDERR, "\a\nAttempt to read %d points failed,\n",n_points);
00397        fprintf(SUMA_STDERR, " file contains %d points only.\n",cnt);
00398        do {
00399 
00400        fprintf(SUMA_STDERR, "End Execution (Yes (1) No (0) ? : ");
00401        ex=scanf ("%d",&dec);
00402        } while (ex != 1 || (dec != 1 && dec !=0));
00403        if (dec)
00404         {
00405           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00406       exit (0);
00407       }
00408       else fprintf(SUMA_STDERR, "\nContinuing execution with %d points\n",cnt);
00409 
00410       }
00411 
00412    fclose (internal_file);
00413    SUMA_RETURN (cnt);                            
00414 }

int SUMA_Read_file float *    x,
char *    f_name,
int    n_points
 

Definition at line 415 of file SUMA_MiscFunc.c.

Referenced by SUMA_Load_Surface_Object().

00417 { /* pass a 0 to n_points if you want to read till EOF */
00418    int cnt=0,ex,dec;
00419    FILE*internal_file;
00420    static char FuncName[]={"SUMA_Read_file"};
00421    
00422    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00423 
00424    internal_file = fopen (f_name,"r");
00425    if (internal_file == NULL) {
00426                           fprintf(SUMA_STDERR, "\aCould not open %s \n",f_name);
00427                           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00428                           exit (0);
00429                           }
00430    ex = fscanf (internal_file,"%f",&x[cnt]);                     
00431    while (ex != EOF)
00432    {
00433      ++cnt;
00434      
00435      ex = fscanf (internal_file,"%f",&x[cnt]);
00436 
00437      if ((n_points != 0) && (cnt == n_points)) ex = EOF;
00438    }
00439 
00440    if (cnt < n_points) 
00441       {
00442        fprintf(SUMA_STDERR, "\a\nAttempt to read %d points failed,\n",n_points);
00443        fprintf(SUMA_STDERR, " file contains %d points only.\n",cnt);
00444        do {
00445 
00446        fprintf(SUMA_STDERR, "End Execution (Yes (1) No (0) ? : ");
00447        ex=scanf ("%d",&dec);
00448        } while (ex != 1 || (dec != 1 && dec !=0));
00449        if (dec)
00450         {
00451           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00452               exit (0);
00453       }
00454       else fprintf(SUMA_STDERR, "\nContinuing execution with %d points\n",cnt);
00455 
00456       }
00457 
00458    fclose (internal_file);
00459    return (cnt);                            
00460 }

SUMA_IRGB* SUMA_Read_IRGB_file char *    f_name,
int    n_rows
 

Function to read a node color file formatted as: i r g b (int float float float).

Parameters:
f_name  (char *) filename
n_rows  (int) number of rows in filename
Returns:
irgb (SUMA_IRGB *) with n_rows
See also:
SUMA_Create_IRGB , SUMA_Free_IRGB

Definition at line 601 of file SUMA_MiscFunc.c.

Referenced by SUMA_LoadColorPlaneFile().

00602 {/*SUMA_Read_2Dfile*/
00603    int ir=0, ic=0, ex;
00604    FILE*internal_file;
00605    SUMA_IRGB *irgb=NULL;
00606    static char FuncName[]={"SUMA_Read_IRGB_file"};
00607 
00608    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00609 
00610    internal_file = fopen (f_name,"r");
00611    if (internal_file == NULL) {
00612       fprintf (SUMA_STDERR,"%s: \aCould not open %s \n",FuncName, f_name);
00613       SUMA_RETURN (NULL);
00614    }
00615    
00616    if (!(irgb = SUMA_Create_IRGB(n_rows))) {
00617       fprintf (SUMA_STDERR,"%s: Failed to create irgb.\n",FuncName);
00618       SUMA_RETURN (NULL);
00619    }
00620    
00621    ir = 0;
00622    while (ir < n_rows)
00623    {
00624       ex = fscanf (internal_file,"%d %f %f %f",
00625                            &(irgb->i[ir]), &(irgb->r[ir]),
00626                            &(irgb->g[ir]), &(irgb->b[ir]));   
00627       if (ex == EOF)
00628          {
00629             fprintf(stderr,"Error %s: Premature EOF\n%d out of %d lines read.", FuncName, ir, n_rows);
00630             fclose (internal_file);
00631             SUMA_Free_IRGB (irgb);
00632             SUMA_RETURN (NULL);
00633          }
00634       ++ir;
00635    }
00636 
00637    fclose (internal_file);
00638 
00639    SUMA_RETURN (irgb);      
00640       
00641 }/*SUMA_Read_2Dfile*/

int SUMA_ReadNumStdin float *    fv,
int    nv
 

Function to get a bunch of numbers from stdin

int SUMA_ReadNumStdin (float *fv, int nv)

Parameters:
fv  (float *) pointer to nv x 1 vector that will hold the input.
nr  (int) number of values to be read and stored in fv \ret nvr (int) number of values actually read from stdin -1 in case of error

Definition at line 5410 of file SUMA_MiscFunc.c.

Referenced by SUMA_input().

05411 {   
05412    int i=0, nvr = 0;
05413    char *endp, *strtp, s[SUMA_MAX_STRING_LENGTH], cbuf;
05414    static char FuncName[]={"SUMA_ReadNumStdin"};
05415    SUMA_Boolean eos, LocalHead = NOPE;
05416    
05417    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05418 
05419    fflush (stdin);
05420    
05421    while ((cbuf = getc(stdin)) != '\n' && i < SUMA_MAX_STRING_LENGTH-1) {
05422       if (cbuf == ',' || cbuf == '\t') {/* change , and tab  to space*/
05423          cbuf = ' ';
05424       }
05425          s[i] = cbuf;
05426          ++ i;
05427    }
05428    
05429    if (i == SUMA_MAX_STRING_LENGTH-1) {
05430       fprintf(SUMA_STDERR,"Error %s: No more than %d characters are allowed on stdin.\n", FuncName, SUMA_MAX_STRING_LENGTH-1);
05431       fflush(stdin);
05432       SUMA_RETURN(-1);
05433    }
05434    
05435    s[i] = '\0';
05436    
05437    if (!i) SUMA_RETURN(0);
05438    
05439    /* parse s */
05440    strtp = s;
05441    endp = NULL;
05442    nvr = 0;
05443    eos = NOPE;
05444    while (nvr < nv && !eos) {
05445       fv[nvr] = strtod(strtp, &endp);
05446       if (LocalHead) fprintf (SUMA_STDERR, "Local Debug %s: ERANGE: %d, EDOM %d, errno %d\n", FuncName, ERANGE, EDOM, errno); 
05447       
05448       if (endp == strtp) { 
05449          eos = YUP;
05450       } else {
05451          ++nvr;
05452          strtp = endp;
05453       }
05454    }
05455    
05456    if (eos && nvr < nv) {
05457       fprintf (SUMA_STDERR, "Warning %s: Expected to read %d elements, read only %d.\n", FuncName, nv, nvr);
05458    }
05459    
05460    SUMA_RETURN(nvr);
05461 }

void* SUMA_realloc_fn const char *    CallingFunc,
void *    ptr,
size_t    size
 

Definition at line 63 of file SUMA_MiscFunc.c.

References SUMA_Boolean.

00064    {
00065       void *ptr2;
00066       int i;
00067       static char FuncName[]={"SUMA_realloc_fn"};
00068 
00069       #if SUMA_MEMTRACE_FLAG
00070          if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00071       #endif
00072 
00073       /* The allocation */
00074       ptr2 = realloc(ptr, size);
00075 
00076       #if SUMA_MEMTRACE_FLAG
00077          if (SUMAg_CF->MemTrace) {
00078             SUMA_Boolean Found = NOPE;
00079             /* find the pointer that's being changed*/
00080             for (i=0; i < SUMAg_CF->Mem->N_alloc && !Found; ++i) {
00081                if (SUMAg_CF->Mem->Pointers[i] == ptr) {
00082                  /* cleanup that one and replace with new*/
00083                   SUMAg_CF->Mem->Pointers[i] = ptr2;
00084                   SUMAg_CF->Mem->Size[i] = size;
00085                   Found = YUP;
00086                }   
00087             }
00088 
00089             if (!Found) {
00090               fprintf (SUMA_STDERR, "Error %s: Pointer %p not found in Mem struct. \n", FuncName,ptr); 
00091             }
00092          }
00093 
00094          SUMA_RETURN(ptr2);
00095       #else
00096          return(ptr2);
00097       #endif
00098 
00099    }

void SUMA_Show_Edge_List SUMA_EDGE_LIST   SEL,
FILE *    Out
 

SUMA_Show_Edge_List (SEL, File *Out)

Parameters:
SEL  (SUMA_EDGE_LIST *)
Out  (FILE *) file pointer or stdout if Out is NULL

Definition at line 3524 of file SUMA_MiscFunc.c.

03525 {
03526    static char FuncName[]={"SUMA_Show_Edge_List"};
03527    int i;
03528    
03529    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03530    
03531    if (Out == NULL) Out = stdout;
03532    
03533    fprintf(Out,"\nEL contents:\n");
03534    fprintf(Out,"i-\t[EL[i][0] EL[i][1]]\t[ELps[i][0] ELps[i][1] ELps[i][2] ELps[i][3]]\n");
03535    for (i=0; i < EL->N_EL; ++i) {
03536       fprintf(Out,"%d-\t[%d %d]\t[%d %d %d %d]\n", 
03537                i, EL->EL[i][0], EL->EL[i][1], EL->ELps[i][0], EL->ELps[i][1], EL->ELps[i][2], EL->ELps[i][3]);
03538    
03539    }
03540    fprintf(Out,"\nTriLimb contents:\n");
03541    fprintf(Out,"ti-\t[Edge1 Edge2 Edge3]\n");
03542    for (i=0; i < EL->N_EL/3; ++i) { 
03543       fprintf(Out,"t%d-\t[%d %d %d]\n",
03544          i, EL->Tri_limb[i][0], EL->Tri_limb[i][1],EL->Tri_limb[i][2]);
03545    }
03546    
03547    SUMA_RETURNe;
03548 }

SUMA_Boolean SUMA_Show_MT_intersect_triangle SUMA_MT_INTERSECT_TRIANGLE   MTI,
FILE *    Out
 

Show contents of SUMA_MT_INTERSECT_TRIANGLE structure

Definition at line 2835 of file SUMA_MiscFunc.c.

02836 {
02837    static char FuncName[]={"SUMA_Show_MT_intersect_triangle"};
02838    int MaxShow = 5, i,j;
02839    
02840    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02841 
02842    if (Out == NULL) Out = stdout;
02843       
02844    if (MTI == NULL) {
02845       fprintf (Out, "NULL Surface Object Pointer\n");
02846       SUMA_RETURN(NOPE);
02847    }
02848    
02849    fprintf (Out,"\n---------------------------------\n");
02850    if (!MTI->N_el) {
02851       fprintf (Out,"Zero elements in structure\n");
02852       SUMA_RETURN (YUP);
02853    }
02854    
02855    if (MTI->isHit == NULL) {
02856       fprintf (SUMA_STDERR,"Error SUMA_Show_MT_intersect_triangle: isHit is NULL\n\n");
02857       SUMA_RETURN (NOPE);
02858    }
02859    else {
02860       if (MaxShow > MTI->N_el) MaxShow = MTI->N_el; 
02861       fprintf (Out, "Intersection results (showing first %d out of %d elements):\n", MaxShow, MTI->N_el);
02862       for (i=0; i < MaxShow; ++i)   {
02863          fprintf (Out, "\tisHit: %d t %f u %f v %f", MTI->isHit[i], MTI->t[i], MTI->u[i],MTI->v[i]);
02864       }
02865          fprintf (Out, "\n");
02866       
02867       if (MTI->N_hits) {
02868          fprintf (Out, "\n%d hits.\n", MTI->N_hits);
02869          fprintf (Out, "Minimum Distance: %d t %f u %f v %f\n", \
02870                   MTI->ifacemin, MTI->t[MTI->ifacemin], MTI->u[MTI->ifacemin],MTI->v[MTI->ifacemin]);
02871          fprintf (Out, "Intersection point P at Minimum Distance FaceSet:\n%f, %f, %f\n", \
02872                   MTI->P[0], MTI->P[1], MTI->P[2]);
02873          fprintf (Out, "Closest node is number %d in Minimum Distance Faceset (%d in NodeList) at %f distance.\n",\
02874                   MTI->inodeminlocal, MTI->inodemin, MTI->d);                           
02875          fprintf (Out, "Maximum Distance: %d t %f u %f v %f\n\n", \
02876                   MTI->ifacemax, MTI->t[MTI->ifacemax], MTI->u[MTI->ifacemax],MTI->v[MTI->ifacemax]);
02877          fprintf (Out, "Intersection of ray with surface (showing first %d out of %d elements):\n", MaxShow, MTI->N_el);
02878          i = 0;
02879          j = 0;
02880          while (i< MTI->N_el && j < MTI->N_hits) {
02881             if (MTI->isHit[i]) {
02882                ++j;
02883                fprintf (Out, "\tisHit: %d t %f u %f v %f\n", MTI->isHit[i], MTI->t[i], MTI->u[i],MTI->v[i]);
02884             }
02885             ++i;
02886          }
02887          fprintf (Out, "\n");
02888       } else {
02889          fprintf (Out, "No Intersection of ray with surface\n");
02890       }
02891 
02892    }
02893    SUMA_RETURN (YUP);
02894 }

void SUMA_ShowMemTrace SUMA_MEMTRACE_STRUCT   Mem,
FILE *    Out
 

Definition at line 250 of file SUMA_MiscFunc.c.

Referenced by SUMA_input().

00251 {
00252    static char FuncName[]={"SUMA_ShowMemTrace"};
00253    int i, *isort = NULL, *mem_sz_sort = NULL, Tot;
00254    
00255    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00256    
00257    if (!Out) Out = SUMA_STDERR;
00258    if (!Mem) {
00259       fprintf (Out,"\nNull struct. Nothing to show.\n");
00260       SUMA_RETURNe;
00261    }
00262    
00263    fprintf (Out,"\nShowing SUMA_MEMTRACE_STRUCT: %p\n", Mem);    
00264    fprintf (Out,"->N_alloc: %d allocated elements.\n", Mem->N_alloc);
00265    fprintf (Out,"->N_MaxPointers: %d\n", Mem->N_MaxPointers);
00266    
00267    /* sort the pointers by their sizes */
00268    /* make a copy of Mem->Size to keep it from getting modified then sort it.
00269    Do not use SUMA_calloc here because that'll increment N_alloc after space is allocated! */
00270    mem_sz_sort = (int *)calloc(Mem->N_alloc, sizeof(int));
00271    if (!mem_sz_sort) {
00272       fprintf (SUMA_STDERR, "Error %s: Could not allocate for mem_sz_sort.\n", FuncName);
00273       SUMA_RETURNe;
00274    }
00275    
00276    #if 1
00277    for (i=0; i < Mem->N_alloc; ++i) mem_sz_sort[i] = Mem->Size[i];
00278    isort = SUMA_z_dqsort_nsc (mem_sz_sort, Mem->N_alloc); /* this version of SUMA_z_dqsort does not use SUMA_calloc for allocation thus keeping the memory trace unchanged */
00279    
00280    Tot = 0;
00281    for (i=0; i < Mem->N_alloc; ++i) {
00282       fprintf (Out,"->[%d]\tPointer %p\t %d bytes.\n", i, Mem->Pointers[isort[i]], Mem->Size[isort[i]]);
00283       Tot += Mem->Size[isort[i]];
00284    }
00285    #else
00286      
00287    Tot = 0;
00288    for (i=0; i < Mem->N_alloc; ++i) {
00289       fprintf (Out,"->[%d]\tPointer %p\t %d bytes.\n", i, Mem->Pointers[i], Mem->Size[i]);
00290       Tot += Mem->Size[i];
00291    }
00292    #endif
00293    
00294    fprintf (Out,"Total Memory Allocated %f Mbytes.\n", (float)Tot/1000000.0);
00295    if (mem_sz_sort) free(mem_sz_sort); /* mem_sz_sort should not be freed with SUMA_free */
00296    if (isort) free(isort); /* isort should not be freed with SUMA_free */
00297    SUMA_RETURNe;
00298    
00299 }

float* SUMA_SmoothAttr_Neighb float *    attr,
int    N_attr,
float *    attr_sm,
SUMA_NODE_FIRST_NEIGHB   fn
 

Smooth the attributes of the nodes based on the neighboring values. Nodes are neighbors if they are connected by an edge in the triangulation.

Parameters:
attr  (float *) pointer to vector of type tp containing a node's attribute
tp  (SUMA_VARTYPE) type of values in attr (SUMA_float, SUMA_int)
attr_sm  (float *) pointer to smoothed version of attr. If you pass NULL then the pointer is allocated for and returned from the function. If attr_sm is not null then it is assumed to have the required allocated space for the proper type.
fn  (SUMA_NODE_FIRST_NEIGHB) structure containing the first order neighbors of the nodes. It is assumed that fn contains the neighbors info for all nodes whose attributes are in attr. That is from 0 to N_attr. \ret attr_sm (float *) pointer to smoothed version of attr

Definition at line 4351 of file SUMA_MiscFunc.c.

Referenced by SUMA_input(), and SUMA_SurfaceMetrics().

04352 {
04353    static char FuncName[]={"SUMA_SmoothAttr_Neighb"};
04354    int i, j;
04355     
04356    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04357 
04358    if (attr_sm && attr_sm == attr) {
04359       fprintf (SUMA_STDERR, "Error %s: attr and attr_sm point to the same location. BAD!\n",FuncName);
04360       SUMA_RETURN (NULL); 
04361    }
04362    if (fn == NULL) {
04363       fprintf (SUMA_STDERR, "Error %s: fn is null, nothing to do.\n",FuncName);
04364       SUMA_RETURN (NULL); 
04365    }
04366    if (fn->N_Node != N_attr) {
04367       fprintf (SUMA_STDERR, "Error %s: N_attr (%d) must be equal to fn->N_Node (%d).\n",FuncName, N_attr, fn->N_Node);
04368       SUMA_RETURN (NULL); 
04369    }
04370    
04371    attr_sm = (float *)attr_sm;
04372    if (attr_sm == NULL) {
04373       attr_sm = (float *)SUMA_calloc (N_attr, sizeof(float));
04374    }
04375    
04376    if (attr_sm == NULL)
04377    {
04378       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for returning variable.\n", FuncName);
04379       SUMA_RETURN (NULL);
04380    } 
04381    
04382    for (i=0; i < N_attr; ++i) {
04383       /* make sure node id corresponds to i. That is you have a full set of nodes 0..N_attr */
04384       if (fn->NodeId[i] != i) {
04385          /* It's OK not to die here. This does occur in patches */
04386          /*fprintf (SUMA_STDERR, "Warning %s: fn does not seem to contain an explicit list of neighbors, from 0..N_attr. fn->NodeId[i] = %d, i = %d. Skipping node %d.\n", \
04387             FuncName, fn->NodeId[i], i, i); */
04388          /*SUMA_free(attr_sm); 
04389          attr_sm = NULL;
04390          SUMA_RETURN (attr_sm);*/
04391          continue;
04392       }
04393       attr_sm[i] = attr[i];
04394       for (j=0; j < fn->N_Neighb[i]; ++j)
04395       {
04396          attr_sm[i] += attr[fn->FirstNeighb[i][j]]; 
04397       }   
04398       attr_sm[i] /= (fn->N_Neighb[i]+1);
04399    }
04400    
04401    SUMA_RETURN (attr_sm);   
04402 } 

SUMA_STRING* SUMA_StringAppend SUMA_STRING   SS,
char *    newstring
 

Appends newstring to string in SS->s while taking care of resizing space allocated for s.

Parameters:
SS  (SUMA_STRING *) pointer to string structure
newstring  (char *) pointer to string to add to SS
Returns:
SS (SUMA_STRING *) pointer to string structure with SS->s now containing newstring
  • When SS is null, 1000 characters are allocated for s (initialization) and s[0] = '\0';
  • When newstring is NULL, space allocated for SS->s is resized to the correct dimension and a null character is placed at the end.

Definition at line 5783 of file SUMA_MiscFunc.c.

Referenced by SUMA_BuildMessageLog(), SUMA_ColorOverlayPlane_Info(), SUMA_help_message_Info(), SUMA_PlaneOrder_Info(), SUMA_SurfaceObject_Info(), and SUMA_VolPar_Info().

05784 {
05785    static char FuncName[]={"SUMA_StringAppend"};
05786    int N_inc = 0, N_cur = 0;
05787    int N_chunk = 1000;
05788    SUMA_Boolean LocalHead = NOPE;
05789    
05790    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05791    
05792    if (!SS) {
05793       if (LocalHead) fprintf (SUMA_STDERR, "%s: Allocating for SS.\n", FuncName);
05794       SS = (SUMA_STRING *) SUMA_malloc (sizeof(SUMA_STRING));
05795       SS->s = (char *) SUMA_calloc (N_chunk, sizeof(char));
05796       SS->s[0] = '\0';
05797       SS->N_alloc = N_chunk;
05798       SUMA_RETURN (SS);
05799    }
05800    
05801    if (newstring) {
05802       if (LocalHead) fprintf (SUMA_STDERR, "%s: Appending to SS->s.\n", FuncName);
05803       N_inc = strlen (newstring);
05804       N_cur = strlen (SS->s);
05805       if (SS->N_alloc < N_cur+N_inc+1) { /* must reallocate */
05806          if (LocalHead) fprintf (SUMA_STDERR, "%s: Must reallocate for SS->s.\n", FuncName);
05807          SS->N_alloc = N_cur+N_inc+N_chunk+1;
05808          SS->s = (char *)SUMA_realloc (SS->s, sizeof(char)*SS->N_alloc);
05809          if (!SS->s) {
05810             fprintf (SUMA_STDERR, "Error %s: Failed to reallocate for s.\n", FuncName);
05811             SUMA_RETURN (NULL);
05812          }
05813       }
05814       /* append */
05815       sprintf (SS->s, "%s%s", SS->s, newstring);
05816    }else {
05817       /* shrink SS->s to small size */
05818       N_cur = strlen (SS->s);
05819       if (SS->N_alloc > N_cur+1) {
05820          if (LocalHead) fprintf (SUMA_STDERR, "%s: Shrink realloc for SS->s.\n", FuncName);
05821          SS->N_alloc = N_cur+1;
05822          SS->s = (char *)SUMA_realloc (SS->s, sizeof(char)*SS->N_alloc);
05823          if (!SS->s) {
05824             fprintf (SUMA_STDERR, "Error %s: Failed to reallocate for s.\n", FuncName);
05825             SUMA_RETURN (NULL);
05826          }
05827          /*put a null at the end */
05828          SS->s[SS->N_alloc-1] = '\0';
05829       }
05830    }
05831    
05832    SUMA_RETURN (SS);
05833 
05834 }

int SUMA_StringToNum char *    s,
float *    fv,
int    N
 

function that parses a string of numbers into a float vector.

Parameters:
str  (char *) null terminated string
fv  (float*) vector where values will be stored
N  (int) This is the number of values desired
Returns:
int: This is the number of values read. The function will register in fv more that N values (to keep from running over preallocated space), but it will return the full number of values found.
-1 in case of error
See also:
SUMA_isNumString

Definition at line 5542 of file SUMA_MiscFunc.c.

Referenced by SUMA_HighlightBox(), SUMA_JumpFocusFace(), SUMA_JumpFocusNode(), SUMA_JumpIndex(), SUMA_JumpXYZ(), SUMA_LookAtCoordinates(), SUMA_OpenDrawnROI_NIML(), and SUMA_SetLight0().

05543 {
05544    static char FuncName[]={"SUMA_StringToNum"};
05545    char *endp, *strtp;
05546    int nd;
05547    SUMA_Boolean eos, FoundTip;
05548    double d;
05549    SUMA_Boolean LocalHead = YUP;
05550    
05551    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05552    
05553    if (!s) SUMA_RETURN(0); 
05554       
05555    /* clean s by removing trailing junk then replacing non characters by space*/
05556    FoundTip = NOPE;
05557    for (nd=strlen(s)-1; nd >=0; --nd) {
05558       if (!isdigit(s[nd]) && s[nd] != '.' && s[nd] != '-' && s[nd] != '+') {
05559          if (!FoundTip) {
05560             s[nd]= '\0'; /* remove */
05561          } else {
05562             s[nd] = ' '; /* blank */
05563          }
05564       }else {
05565          FoundTip = YUP;
05566       }
05567    }
05568    
05569    if (LocalHead) fprintf (SUMA_STDERR, "%s: string now:%s:\n", FuncName, s);
05570    
05571    /* parse s */
05572    strtp = s;
05573    endp = NULL;
05574    nd = 0;
05575    eos = NOPE;
05576    while (!eos) {
05577       d = strtod(strtp, &endp);
05578       if (LocalHead) fprintf (SUMA_STDERR, "%s: value %f, ERANGE: %d, EDOM %d, errno %d\n", FuncName, d, ERANGE, EDOM, errno); 
05579       
05580       if (endp == strtp && *endp=='\0') { 
05581          eos = YUP;
05582       } else {
05583          if (nd < N) fv[nd] = (float)d;
05584          strtp = endp;
05585          ++nd;
05586       }
05587    }
05588    
05589    if (LocalHead) fprintf (SUMA_STDERR,"%s: Read %d/%d values.\n", FuncName, nd, N);
05590    
05591    SUMA_RETURN(nd);
05592    
05593 }   

SUMA_FileName SUMA_StripPath char *    FileName
 

** File : SUMA_StripPath.c

Author:
Ziad Saad Date : Thu Jan 24 10:55:18 EST 2002
Purpose :

splits a path/filename into its path and filename components

Usage : Ans = SUMA_StripPath (Name)

Input paramters :

Parameters:
Name  (char *) something like /hello/something
Returns :
Returns:
ans (SUMA_FileName) .Path (char *) and .FileName (char *)
Support :
See also:
SUMA_define.h
NOTE: SUMA_ParseFname() is better than this function

To Compile as stand alone: gcc -DSUMA_StripPath_STAND_ALONE -Wall -o $1 $1.c -SUMA_lib.a -I/usr/X11R6/include -I./

Definition at line 53 of file SUMA_StripPath.c.

References SUMA_Boolean.

00054 {/*SUMA_StripPath*/
00055    char FuncName[100],  PathDelimiter[1]; 
00056    int i, j, NotFound=1, N_FileName;
00057         SUMA_FileName NewName;
00058         
00059    /* initialize function name for verbose output */
00060    sprintf (FuncName,"SUMA_StripPath");
00061    sprintf (PathDelimiter,"/");
00062         
00063         N_FileName = strlen(FileName);
00064         if (N_FileName ){
00065                 i = N_FileName -1;
00066                 while (i > -1 && NotFound) {
00067                         if (FileName[i] == PathDelimiter[0]) NotFound = 0;
00068                         --i;
00069                 }
00070                 if (!NotFound && i > -1) {
00071                         NewName.Path = (char *)SUMA_malloc(sizeof(char)*(N_FileName+1));
00072                         NewName.FileName = (char *)SUMA_malloc(sizeof(char)*(N_FileName+1));
00073                         if (NewName.Path == NULL || NewName.FileName == NULL) {
00074                                 SUMA_alloc_problem (FuncName);
00075                         }
00076                         for (j=0; j<=i+1; ++j) {
00077                                 NewName.Path[j] = FileName[j];
00078                         }
00079          NewName.Path[j] = '\0';
00080          
00081                         /*fprintf(stdout,"jbegin=%d/%d\n", i+2, N_FileName);*/
00082                         for (j=i+2; j < N_FileName; ++j) NewName.FileName[j-i-2] = FileName[j];
00083          NewName.FileName[j-i-2] = '\0';
00084          
00085                         /* fprintf(stdout,"All Path (%d chars)/%d: %s\n", (i+2),  strlen(NewName.Path), NewName.Path);
00086                         fprintf(stdout,"All FileName (%d chars)/%d: %s\n", (N_FileName-i-2), strlen(NewName.FileName), NewName.FileName); */
00087                 }
00088                 else {
00089                         NewName.Path = (char *)SUMA_malloc(sizeof(char)*(N_FileName+1));
00090                         NewName.FileName = (char *)SUMA_malloc(sizeof(char)*(N_FileName+1));
00091                         if (NewName.Path == NULL || NewName.FileName == NULL) {
00092                                 SUMA_alloc_problem (FuncName);
00093                         }
00094                         sprintf(NewName.Path,"./");             
00095                         sprintf(NewName.FileName,"%s", FileName);
00096                 }
00097         }
00098         else {
00099                 NewName.Path = NULL;
00100                 NewName.FileName = NULL;
00101         }
00102         return (NewName);
00103 }/*SUMA_StripPath*/

SUMA_SURFACE_CURVATURE* SUMA_Surface_Curvature float *    NodeList,
int    N_Node,
float *    NodeNormList,
float *    Face_A,
int    N_FaceSet,
SUMA_NODE_FIRST_NEIGHB   FN,
SUMA_EDGE_LIST   el
 

function to calculate the curvature tensor at each node SC = SUMA_Surface_Curvature (NodeList, N_Node, NodeNormList, A, N_FaceSet, FN, SUMA_EDGE_LIST *SEL)

Parameters:
NodeList  (float *) N_Node x 3 vector containing the XYZ coordinates of the nodes
N_Node  (int) number of nodes in NodeList
NodeNormList  (float *) N_Node x 3 vector (was matrix prior to SUMA 1.2) containing the normal vector at each node
A  (float *) N_FaceSet x 1 vector containing the area of each triangle making up the mesh
N_FaceSet  (int) number of triangles making up the mesh
FN  (SUMA_NODE_FIRST_NEIGHB *) structure containing Node Neighbors
SEL  (SUMA_EDGE_LIST *) structure containing the Edge List
\ret SC (SUMA_SURFACE_CURVATURE *) structure containing the curvature info, see typedef of struct for more info

See also:
SUMA_Free_SURFACE_CURVATURE for freeing SC , SUMA_Build_FirstNeighb for creating FN , SUMA_Make_Edge_List for creating SEL
The algorithm is the one presented in G. Taubin Estimating the tensor of curvature of surface from a polyhedral approximation see also labbook NIH-2 pp 65 and (Test_)SUMA_Surface_Curvature.m script

Definition at line 4808 of file SUMA_MiscFunc.c.

Referenced by SUMA_input(), and SUMA_SurfaceMetrics().

04809 { 
04810    static char FuncName[] = {"SUMA_Surface_Curvature"};
04811    int i, N_Neighb, j, ji, Incident[MAX_INCIDENT_TRI], N_Incident, kk, ii, id, ND; 
04812    float  Ntmp[3],  vi[3], vj[3], *Num, NumNorm, num, denum, sWij, T1e[3], T2e[3], mg, c, s;
04813    float **fa33, **fb33, **fc33, **Ni, **Nit, *Wij, *Kij, **Tij, **I, **Mi, **Q, **Qt, **fa22, **mMi, **mMir;
04814    SUMA_Boolean *SkipNode;
04815    SUMA_SURFACE_CURVATURE *SC;
04816    
04817    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04818    
04819    if (!A || !NodeList || !NodeNormList || !FN || !SEL) {
04820       fprintf (SUMA_STDERR, "Error %s: One of your inputs is NULL.\n", FuncName);
04821       SUMA_RETURN(NULL);
04822    }
04823    
04824    SC = (SUMA_SURFACE_CURVATURE *)SUMA_malloc (sizeof(SUMA_SURFACE_CURVATURE));
04825    if (!SC) {
04826       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SC.\n", FuncName);
04827       SUMA_RETURN(NULL);
04828    }
04829    
04830    Wij = (float *)SUMA_calloc (FN->N_Neighb_max, sizeof(float));
04831    Kij = (float *)SUMA_calloc (FN->N_Neighb_max, sizeof(float));
04832    Num = (float *)SUMA_calloc (3, sizeof(float));
04833    SkipNode = (SUMA_Boolean *) SUMA_calloc (N_Node, sizeof(SUMA_Boolean));
04834    mMi = (float **) SUMA_allocate2D (2,2, sizeof(float));
04835    mMir =(float **) SUMA_allocate2D (2,2, sizeof(float));
04836    fa22 =(float **) SUMA_allocate2D (2,2, sizeof(float));
04837    Tij = (float **) SUMA_allocate2D (FN->N_Neighb_max, 3, sizeof(float));
04838    Ni =  (float **) SUMA_allocate2D (3, 1, sizeof(float));
04839    Nit = (float **) SUMA_allocate2D (1, 3, sizeof(float));
04840    fa33 =(float **) SUMA_allocate2D (3, 3, sizeof(float));
04841    fb33 =(float **) SUMA_allocate2D (3, 3, sizeof(float));
04842    fc33 =(float **) SUMA_allocate2D (3, 3, sizeof(float));
04843    I =   (float **) SUMA_allocate2D (3, 3, sizeof(float));
04844    Q =   (float **) SUMA_allocate2D (3, 3, sizeof(float));
04845    Qt =  (float **) SUMA_allocate2D (3, 3, sizeof(float));
04846    Mi =  (float **) SUMA_allocate2D (3, 3, sizeof(float));
04847    SC->T1 = (float **) SUMA_allocate2D (N_Node, 3, sizeof(float));
04848    SC->T2 = (float **) SUMA_allocate2D (N_Node, 3, sizeof(float));
04849    SC->Kp1 =(float *)SUMA_calloc (N_Node, sizeof(float));
04850    SC->Kp2 =(float *)SUMA_calloc (N_Node, sizeof(float));
04851 
04852    if (!fa22 || !mMir || !mMi || !Wij || !Kij || !Tij || !Ni || !Nit || !fa33 || !fb33 || !fc33 || !I || !Num || !SkipNode || !Mi || !Q || !Qt || !SC->T1 || !SC->T2 || !SC->Kp1 || !SC->Kp2) {
04853       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for Wij, Kij, Tij.\n", FuncName);
04854       if (Wij) SUMA_free(Wij);
04855       if (Kij) SUMA_free(Kij);
04856       if (Num) SUMA_free(Num);
04857       if (SkipNode) SUMA_free(SkipNode);
04858       if (mMi) SUMA_free2D((char **)mMi, 2);
04859       if (mMir) SUMA_free2D((char **)mMir, 2);
04860       if (fa22) SUMA_free2D((char **)fa22, 2);
04861       if (Tij) SUMA_free2D((char **)Tij, FN->N_Neighb_max);
04862       if (Ni) SUMA_free2D((char **)Ni, 3);
04863       if (Nit) SUMA_free2D((char **)Nit, 1);
04864       if (fa33) SUMA_free2D((char **)fa33, 3);
04865       if (fb33) SUMA_free2D((char **)fb33, 3);
04866       if (I) SUMA_free2D((char **)I, 3);
04867       if (Q) SUMA_free2D((char **)Q, 3);
04868       if (Qt) SUMA_free2D((char **)Qt, 3);
04869       if (Mi) SUMA_free2D((char **)Mi, 3);
04870       if (SC) SUMA_Free_SURFACE_CURVATURE (SC);      
04871       SUMA_RETURN(NULL);
04872    }
04873 
04874    /* 3x3 identity matrix */
04875    I[0][0] = I[1][1] = I[2][2] = 1.0; I[0][1] = I[0][2] = I[1][0] = I[1][2] = I[2][0] = I[2][1] = 0.0;
04876    
04877    /* initialize SC */
04878    SC->N_SkipNode = 0;
04879    SC->N_Node = N_Node;
04880    
04881    fprintf (SUMA_STDERR, "%s: Beginning curvature computations:\n", FuncName);
04882    
04883    ND = 3;
04884    SC->N_SkipNode = 0;
04885    for (i=0; i < N_Node; ++i) { /* for i */
04886       #ifdef DBG_1
04887          if (!(i%10000)) {
04888             fprintf (SUMA_STDERR, "%s: [%d]/[%d] %.2f/100%% completed\n", FuncName, i, N_Node, (float)i / N_Node * 100);
04889          }
04890       #endif
04891       SkipNode[i] = NOPE;
04892       /* sanity copies */
04893       N_Neighb = FN->N_Neighb[i];
04894       id = ND * i;
04895       Ni[0][0] = NodeNormList[id]; Ni[1][0] = NodeNormList[id+1]; Ni[2][0] = NodeNormList[id+2]; /* Normal vector at i*/
04896       Nit[0][0] = NodeNormList[id]; Nit[0][1] = NodeNormList[id+1]; Nit[0][2] = NodeNormList[id+2]; /* transpose of Ni */ 
04897       vi[0] = NodeList[id]; vi[1] = NodeList[id+1]; vi[2] = NodeList[id+2];  /* node coordinate vector */ 
04898       #ifdef DBG_2
04899          fprintf (SUMA_STDERR, "%s: Looping over neighbors, i = %d\n", FuncName, i);
04900       #endif
04901       j=0;
04902       sWij = 0.0;
04903       while (j < N_Neighb) {
04904          ji = FN->FirstNeighb[i][j]; /* index of the jth first neighbor of i */
04905          id = ND * ji;
04906          vj[0] = NodeList[id]; vj[1] = NodeList[id+1]; vj[2] = NodeList[id+2];  /* node coordinate vector at jth neighbor */
04907          
04908          /* calculate Tij */
04909          #ifdef DBG_2
04910             fprintf (SUMA_STDERR, "%s: Mat Op j=%d\n", FuncName, j);
04911          #endif
04912          
04913          /* fa33 = Ni*Ni' */
04914          SUMA_MULT_MAT(Ni,Nit,fa33,3,1,3,float,float,float); 
04915          
04916          /* fb33 = I - fa33 */
04917          SUMA_SUB_MAT(I, fa33, fb33, 3, 3, float, float, float); 
04918 
04919          /* fa33 = vi - vj (only 1st column is meaningful)*/
04920          fa33[0][0] = vi[0] - vj[0];  fa33[1][0] = vi[1] - vj[1]; fa33[2][0] = vi[2] - vj[2];
04921          
04922          /* Num = fc33 = (I - Ni*Ni') * (vi - vj) (only 1st column in fc33 is meaningful)*/
04923          SUMA_MULT_MAT(fb33, fa33, fc33, 3, 3, 1, float, float, float);
04924          Num[0] = fc33[0][0]; Num[1] = fc33[1][0]; Num[2] = fc33[2][0];
04925 
04926          /* Calculate Tij at this j, a 3x1 vector unit length normalized projection projection of vj-vi onto the plane perp. to Ni */
04927          NumNorm = (float)sqrt(Num[0]*Num[0] + Num[1]*Num[1] + Num[2]*Num[2]);
04928          if (NumNorm == 0) {
04929             fprintf (SUMA_STDERR, "Warning %s: NumNorm = 0 for node %d.\n", FuncName, i); 
04930             SkipNode[i] = YUP;
04931             SC->N_SkipNode++;
04932             break;
04933          }
04934          
04935          Tij[j][0] = Num[0] / NumNorm; 
04936          Tij[j][1] = Num[1] / NumNorm; 
04937          Tij[j][2] = Num[2] / NumNorm;
04938          
04939          #ifdef DBG_2
04940             fprintf(SUMA_STDOUT,"%s: i,j, ji =%d,%d, %d Ni = %f %f %f\n Tij(%d,:) = %f %f %f.\n", \
04941                FuncName, i, j, ji,Ni[0][0], Ni[1][0], Ni[2][0], j, Tij[j][0], Tij[j][1], Tij[j][2]);
04942          #endif
04943           
04944          /* calculate Kij(j) the directional curvature along ij*/
04945          /* fa33 = (vj - vi) (only 1st column is meaningful)*/
04946          fa33[0][0] = (vj[0] - vi[0]);  fa33[1][0] = (vj[1] - vi[1]); fa33[2][0] = (vj[2] - vi[2]);
04947          /* Num = fb33 = Ni' * fa33 (only 1st value in fb33 is meaningful)*/
04948          SUMA_MULT_MAT(Nit, fa33, fb33, 1, 3, 1, float, float, float);
04949          num = fb33[0][0]; 
04950          /* denum = sum((vj - vi)^2) */
04951          denum = fa33[0][0] * fa33[0][0] + fa33[1][0] * fa33[1][0]+ fa33[2][0] * fa33[2][0]; 
04952          
04953          Kij[j] = 2 * num / denum;
04954          #ifdef DBG_2
04955             fprintf(SUMA_STDOUT,"%s: Kij[%d] = %f\n", FuncName, j, Kij[j]);
04956          #endif
04957          
04958          /* calculate the weights for integration, Wij */
04959             /* find the incident triangles */
04960             if (!SUMA_Get_Incident(i, ji, SEL, Incident, &N_Incident))
04961             {
04962                fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
04963                if (Wij) SUMA_free(Wij);
04964                if (Kij) SUMA_free(Kij);
04965                if (Num) SUMA_free(Num);
04966                if (SkipNode) SUMA_free(SkipNode);
04967                if (mMi) SUMA_free2D((char **)mMi, 2);
04968                if (mMir) SUMA_free2D((char **)mMir, 2);
04969                if (fa22) SUMA_free2D((char **)fa22, 2);
04970                if (Tij) SUMA_free2D((char **)Tij, FN->N_Neighb_max);
04971                if (Ni) SUMA_free2D((char **)Ni, 3);
04972                if (Nit) SUMA_free2D((char **)Nit, 1);
04973                if (fa33) SUMA_free2D((char **)fa33, 3);
04974                if (fb33) SUMA_free2D((char **)fb33, 3);
04975                if (I) SUMA_free2D((char **)I, 3);
04976                if (Q) SUMA_free2D((char **)Q, 3);
04977                if (Qt) SUMA_free2D((char **)Qt, 3);
04978                if (Mi) SUMA_free2D((char **)Mi, 3);
04979                if (SC) SUMA_Free_SURFACE_CURVATURE (SC);      
04980                SUMA_RETURN(NULL);
04981             }
04982 
04983             #ifdef DBG_2
04984                fprintf (SUMA_STDERR,"%s: Incidents ...\n", FuncName);
04985                for (kk=0; kk < N_Incident; ++kk) {
04986                   fprintf (SUMA_STDERR,"\t %d", Incident[kk]);
04987                }
04988                fprintf (SUMA_STDERR,"\n");
04989             #endif
04990 
04991             if (N_Incident != 2 && N_Incident != 1)
04992             {
04993                fprintf (SUMA_STDERR,"Warning %s: Unexpected N_Incident = %d at i,j = %d,%d\n", FuncName, N_Incident, i, j);
04994                SkipNode[i] = YUP;
04995                ++SC->N_SkipNode;
04996                break;
04997             }
04998             Wij[j] = 0.0; 
04999             for (ii=0; ii < N_Incident; ++ii) {
05000                Wij[j] = Wij[j] + fabs(A[Incident[ii]]);
05001             }
05002             sWij += Wij[j];
05003             if (Wij[j] == 0.0) {
05004                fprintf (SUMA_STDERR,"Warning %s: Null Wij[%d] at i,j=%d,%d\n", FuncName, j, i, j);
05005                SkipNode[i] = YUP;
05006                ++SC->N_SkipNode;
05007                break; 
05008             }
05009          
05010          ++j;
05011          
05012       }/* while j*/
05013       if (!SkipNode[i]) {
05014             /* make the sum of the weights be equal to 1*/
05015             #ifdef DBG_2   
05016                fprintf (SUMA_STDERR,"%s: Wij:\n", FuncName);
05017             #endif
05018             for (ii=0; ii < N_Neighb; ++ii) {
05019                Wij[ii] /= sWij; 
05020                /*   fprintf (SUMA_STDERR,"Wij[%d]=%f\t", ii, Wij[ii]);*/
05021             }
05022             #ifdef DBG_2   
05023                fprintf (SUMA_STDERR,"\n");
05024             #endif
05025             /* calculate Mi */
05026             Mi[0][0] = Mi[1][0] = Mi[2][0] = Mi[0][1] = Mi[1][1] = Mi[2][1] = Mi[0][2] = Mi[1][2] = Mi[2][2] = 0.0;
05027             for (j=0; j < N_Neighb; ++j) {
05028                /* calculate fc33 = Tij(j,:)' * Tij(j,:) transpose on Tij is flipped from equation because Tij(j,:) should be a column vector */
05029                 fa33[0][0] = Tij[j][0]; fa33[1][0] = Tij[j][1]; fa33[2][0] = Tij[j][2];
05030                fb33[0][0] = Tij[j][0]; fb33[0][1] = Tij[j][1]; fb33[0][2] = Tij[j][2];
05031                SUMA_MULT_MAT (fa33, fb33, fc33, 3, 1, 3, float, float, float);
05032                
05033                for (ii=0; ii < 3; ++ii) {
05034                   for (kk=0; kk < 3; ++kk) {
05035                      Mi[ii][kk] = Mi[ii][kk] + Wij[j] * Kij[j] * fc33[ii][kk];
05036                   }
05037                }
05038             }
05039             #ifdef DBG_2   
05040                SUMA_disp_mat (Mi, 3, 3, 1);
05041             #endif
05042             /* calculate Householder of Ni */
05043             Ntmp[0] = Ni[0][0]; Ntmp[1] = Ni[1][0]; Ntmp[2] = Ni[2][0];
05044             if (!SUMA_Householder(Ntmp, Q)) {
05045                fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Householder for node %d.\n ", FuncName, i);
05046                mg = 0.0;
05047                SkipNode[i] = YUP;
05048                SC->N_SkipNode++;
05049             } else {
05050                T1e[0] = Q[0][1]; T1e[1] = Q[1][1]; T1e[2] = Q[2][1];
05051                T2e[0] = Q[0][2]; T2e[1] = Q[1][2]; T2e[2] = Q[2][2];  /* T tilda 1, T tilda2 */
05052                SUMA_TRANSP_MAT (Q, Qt, 3, 3, float, float);
05053                #ifdef DBG_2   
05054                   SUMA_disp_mat (Q, 3, 3, 1);
05055                   SUMA_disp_mat (Qt, 3, 3, 1);
05056                #endif
05057                
05058                /* Mi (aka fb33) = Q' * Mi * Q; Mi should become a 3x3 with 2x2  non zero minor in lower right */
05059                SUMA_MULT_MAT (Qt, Mi, fa33, 3, 3, 3, float, float, float);
05060                SUMA_MULT_MAT (fa33, Q, Mi, 3, 3, 3, float, float, float);
05061                #ifdef DBG_2   
05062                   SUMA_disp_mat (Mi, 3, 3, 1);
05063                #endif
05064                mMi[0][0] = Mi[1][1]; mMi[0][1] = Mi[1][2];
05065                mMi[1][0] = Mi[2][1]; mMi[1][1] = Mi[2][2]; 
05066                
05067                /*compute c ( = cos(theta) ) & s ( = sin(theta) )from the Givens rotation to null out the bottom left element of the non zero minor mMi*/
05068                mg = sqrt(mMi[0][0]*mMi[0][0] + mMi[1][0]*mMi[1][0]);
05069                c = mMi[0][0] / mg;
05070                s = mMi[1][0] / mg;
05071                /* rotate mMi */
05072                fa22[0][0] =  c; fa22[0][1] = s; 
05073                fa22[1][0] = -s; fa22[1][1] = c; 
05074                SUMA_MULT_MAT(fa22, mMi, mMir, 2, 2, 2, float, float, float);
05075                #ifdef DBG_2   
05076                   fprintf (SUMA_STDERR,"%s: mg = %f, c = %f, s = %f\n", FuncName,  mg, c, s);
05077                #endif   
05078                /* calculate the principal directions */
05079                SC->T1[i][0] = c * T1e[0] - s * T2e[0];               
05080                SC->T1[i][1] = c * T1e[1] - s * T2e[1];               
05081                SC->T1[i][2] = c * T1e[2] - s * T2e[2];   
05082                            
05083                SC->T2[i][0] = s * T1e[0] + c * T2e[0];               
05084                SC->T2[i][1] = s * T1e[1] + c * T2e[1];               
05085                SC->T2[i][2] = s * T1e[2] + c * T2e[2];   
05086                
05087                /* calculate the principal curvatures and mean curvatures etc ... */
05088                SC->Kp1[i] = 3 * mMir[0][0] - mMir[1][1];
05089                SC->Kp2[i] = 3 * mMir[1][1] - mMir[0][0];
05090                #ifdef DBG_2   
05091                   fprintf (SUMA_STDERR,"%s: SC->Kp1[i] = %f, SC->Kp2[i] = %f, mKp[i] = %f\n", FuncName,  SC->Kp1[i], SC->Kp2[i], (SC->Kp1[i]+SC->Kp2[i])/2);
05092                #endif   
05093             }
05094             
05095          #ifdef DBG_3
05096             { int jnk; fprintf(SUMA_STDOUT,"Pausing ..."); jnk = getchar(); fprintf(SUMA_STDOUT,"\n"); }
05097          #endif
05098          
05099       } /* not skipped (yet)*/
05100       if (SkipNode[i]) {
05101          SC->T1[i][0] = SC->T1[i][1] = SC->T1[i][2] = 0.0;
05102          SC->T2[i][0] = SC->T2[i][1] = SC->T2[i][2] = 0.0;
05103          SC->Kp1[i] = SC->Kp2[i] = 0.0;
05104       }
05105    }/* for i */
05106 
05107    /* write out the results to a file (debugging only)*/
05108    {
05109       FILE *fid;
05110       fprintf(SUMA_STDOUT,"%s: Writing Kp1 & Kp2 to Curvs_c.txt ...", FuncName);
05111       fid = fopen("Curvs_c.txt","w");
05112       for (ii=0; ii < SC->N_Node; ++ii) {
05113          /*fprintf(fid,"%f %f\n", (SC->Kp1[ii]+SC->Kp2[ii])/2, SC->Kp1[ii]*SC->Kp2[ii]);*/
05114          fprintf(fid,"%f %f\n", SC->Kp1[ii], SC->Kp2[ii]);
05115       }
05116       fclose (fid);
05117       
05118       fprintf(SUMA_STDOUT,"%s: Done.\n", FuncName);
05119    }
05120    
05121    /* free the left overs */
05122    if (Wij) SUMA_free(Wij);
05123    if (Kij) SUMA_free(Kij);
05124    if (Num) SUMA_free(Num);
05125    if (SkipNode) SUMA_free(SkipNode);
05126    if (mMi) SUMA_free2D((char **)mMi, 2);
05127    if (mMir) SUMA_free2D((char **)mMir, 2);
05128    if (fa22) SUMA_free2D((char **)fa22, 2);
05129    if (Tij) SUMA_free2D((char **)Tij, FN->N_Neighb_max);
05130    if (Ni) SUMA_free2D((char **)Ni, 3);
05131    if (Nit) SUMA_free2D((char **)Nit, 1);
05132    if (fa33) SUMA_free2D((char **)fa33, 3);
05133    if (fb33) SUMA_free2D((char **)fb33, 3);
05134    if (I) SUMA_free2D((char **)I, 3);
05135    if (Q) SUMA_free2D((char **)Q, 3);
05136    if (Qt) SUMA_free2D((char **)Qt, 3);
05137    if (Mi) SUMA_free2D((char **)Mi, 3);
05138    
05139    fprintf (SUMA_STDERR, "%s: Done with curvature computations.\n", FuncName);
05140 
05141    SUMA_RETURN (SC);
05142 }

SUMA_Boolean SUMA_TriNorm float *    n0,
float *    n1,
float *    n2,
float *    norm
 

calculate the normal to a triangle A = SUMA_TriNorm (n1, n2, n3, normal)

Parameters:
n1  (float *)pointer to vector containing XYZ of node 1
n2  (float *)pointer to vector containing XYZ of node 2
n3  (float *)pointer to vector containing XYZ of node 3
normal  (float *)pointer to vector to contain normal of triangle.
Returns:
A (SUMA_Boolean) NOPE if the norm of the normal = 0. In that case, occuring with FreeSurfer surfaces, normal is 1.0 1.0 1.0
See also:
SUMA_SurfNorm

Definition at line 4572 of file SUMA_MiscFunc.c.

Referenced by SUMA_SurfNorm().

04573 {
04574    static char FuncName[]={"SUMA_TriNorm"};
04575    int i;
04576    float d1[3], d2[3], d;
04577    
04578    for (i=0; i<3; ++i) {
04579          d1[i] = n0[i] - n1[i];
04580          d2[i] = n1[i] - n2[i];
04581    }
04582    norm[0] = d1[1]*d2[2] - d1[2]*d2[1];
04583         norm[1] = d1[2]*d2[0] - d1[0]*d2[2];
04584         norm[2] = d1[0]*d2[1] - d1[1]*d2[0];  
04585    
04586    d = sqrt(norm[0] * norm[0] + norm[1] * norm[1] + norm[2] * norm[2]);
04587    
04588    if (d==0.0) {
04589       norm[0] = norm[1] = norm[2] = 1.0;
04590       SUMA_RETURN (NOPE);
04591    }else {
04592       for (i=0; i<3; ++i) norm[i] /= d;
04593       SUMA_RETURN (YUP);
04594    }
04595 }

float SUMA_TriSurf3 float *    n0,
float *    n1,
float *    n2
 

calculate the area of a triangle A = SUMA_TriSurf3 (n1, n2, n3, normal)

Parameters:
n1  (float *)pointer to vector containing XYZ of node 1
n2  (float *)pointer to vector containing XYZ of node 2
n3  (float *)pointer to vector containing XYZ of node 3
normal  (float *)pointer to vector containing normal of triangle.
Returns:
A (float) area of triangle
See also:
SUMA_PolySurf3 , SUMA_TriNorm , SUMA_TRI_AREA for macro version

Definition at line 4609 of file SUMA_MiscFunc.c.

Referenced by SUMA_SurfaceMetrics().

04610 {
04611    static char FuncName[]={"SUMA_TriSurf3"};
04612    float dv[3], dw[3], cross[3], A; 
04613    int i, ii, coord, kk, jj;
04614    
04615    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04616    
04617    SUMA_MT_SUB (dv, n1, n0);
04618    SUMA_MT_SUB (dw, n2, n0);
04619    SUMA_MT_CROSS(cross,dv,dw);
04620    SUMA_NORM(A, cross);
04621    A *= 0.5;
04622    
04623    SUMA_RETURN (A); 
04624 }

float* SUMA_TriSurf3v float *    NodeList,
int *    FaceSets,
int    N_FaceSet
 

calculate the area of a triangle A = SUMA_TriSurf3v (NodeList, FaceSets, N_FaceSet, )

Parameters:
NodeList  (float *)pointer to vector containing XYZ of nodes (typically SO->NodeList)
FaceSets  (int *) pointer to vector (3*N_FaceSet long) containing triangle indices (typically SO->FaceSetList)
N_FaceSet  (int) number of triangles, (typically SO->N_FaceSet)
Returns:
A (float *) vector of triangle areas (N_FaceSet elements long)
See also:
SUMA_PolySurf3 , SUMA_TriNorm , SUMA_TRI_AREA for macro version

Definition at line 4638 of file SUMA_MiscFunc.c.

Referenced by SUMA_SurfaceMetrics().

04639 {
04640    static char FuncName[]={"SUMA_TriSurf3v"};
04641    float *A = NULL, *n0, *n1, *n2, a;
04642    int i, i3;
04643 
04644    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
04645    
04646    A = (float *) SUMA_calloc (N_FaceSet, sizeof(float));
04647    if (A == NULL ) {
04648       fprintf(SUMA_STDERR,"Error %s; Failed to allocate for A \n", FuncName);
04649       SUMA_RETURN (NULL);
04650    }  
04651    
04652    for (i=0;  i<N_FaceSet; ++i) {
04653       i3 = 3*i;
04654       n0 = &(NodeList[3*FaceSets[i3]]);
04655       n1 = &(NodeList[3*FaceSets[i3+1]]);
04656       n2 = &(NodeList[3*FaceSets[i3+2]]);
04657       SUMA_TRI_AREA( n0, n1, n2, A[i]); 
04658       /* A[i] = SUMA_TriSurf3 (n0, n1, n2); */
04659    }
04660    
04661    SUMA_RETURN (A);
04662 }

int* SUMA_UniqueInt int *    y,
int    xsz,
int *    kunq,
int    Sorted
 

Definition at line 5710 of file SUMA_MiscFunc.c.

Referenced by SUMA_1DROI_to_DrawnROI(), and SUMA_NodesInROI().

05711 {/*SUMA_UniqueInt*/
05712    int *xtmp, *xunq, k ,*x;
05713    SUMA_Boolean LocalHead = NOPE;
05714    static char FuncName[]={"SUMA_UniqueInt"};
05715 
05716    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
05717    *kunq = 0;
05718 
05719    if (!xsz)
05720     {
05721       SUMA_RETURN(NULL);
05722    }
05723    if (!Sorted)
05724     {/* must sort y , put in a new location so that y is not disturbed*/
05725       x = (int *)SUMA_calloc(xsz, sizeof(int));
05726       if (!x)
05727          {
05728             fprintf (SUMA_STDERR,"Error %s: Failed to allocate for x.", FuncName);
05729             SUMA_RETURN (NULL);
05730          }
05731       for (k=0; k < xsz; ++k)
05732          x[k] = y[k];
05733       qsort(x,xsz,sizeof(int), (int(*) (const void *, const void *)) SUMA_compare_int);
05734    }
05735    else
05736       x = y;
05737 
05738    if (!xsz)   /* Nothing sent ! */
05739     SUMA_RETURN (NULL);
05740 
05741    xtmp = (int *) SUMA_calloc(xsz,sizeof(int));
05742    if (xtmp == NULL)
05743     {
05744       fprintf (SUMA_STDERR,"Error %s: Could not allocate memory", FuncName);
05745       SUMA_RETURN (NULL);
05746    }
05747 
05748    *kunq = 0;
05749    xtmp[0] = x[0];
05750    for (k=1;k<xsz;++k)
05751     {
05752       if ((x[k] != x[k - 1]))
05753          {
05754             ++*kunq;
05755             xtmp[*kunq] = x[k];   
05756          }
05757    }
05758    ++*kunq;
05759    
05760    
05761    /* get rid of extra space allocated */
05762    xunq = (int *) SUMA_calloc(*kunq,sizeof(int));
05763    SUMA_COPY_VEC(xtmp,xunq,*kunq,int,int);
05764 
05765    SUMA_free(xtmp); 
05766 
05767    if (!Sorted)
05768       SUMA_free (x);
05769 
05770    SUMA_RETURN (xunq);
05771 }/*SUMA_UniqueInt*/

int SUMA_whichTri SUMA_EDGE_LIST   EL,
int    n1,
int    n2,
int    n3
 

This function determines which triangle, if any is formed by the specified nodes Tri = SUMA_wichTri (EL, n1, n2, n3);.

Parameters:
EL  (SUMA_EDGE_LIST *) structure to edge list
n1  (int) first node
n2  (int) second node
n3  (int) third node
Returns:
Tri index of triangle containing n1, n2 and n3 -1 if no such triangle was found

Definition at line 3123 of file SUMA_MiscFunc.c.

Referenced by SUMA_BrushStrokeToNodeStroke(), SUMA_Build_FirstNeighb(), SUMA_Get_NodeIncident(), and SUMA_NodePath_to_TriPath_Inters().

03124 {
03125    static char FuncName[]={"SUMA_whichTri"};
03126    int IncTri_E1[100], IncTri_E2[100], N_IncTri_E1 = 0, N_IncTri_E2 = 0, i, j, Tri= -1;
03127    SUMA_Boolean Found = NOPE;
03128    
03129    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
03130    
03131    /* find incident triangles to n1-n2 edge */
03132    if (!SUMA_Get_Incident(n1, n2, EL, IncTri_E1, &N_IncTri_E1)) {
03133       fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
03134       SUMA_RETURN (-1);
03135    }
03136    
03137    /* find incident triangles to n1-n3 edge */
03138    if (!SUMA_Get_Incident(n1, n3, EL, IncTri_E2, &N_IncTri_E2)) {
03139       fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
03140       SUMA_RETURN (-1);
03141    }
03142    
03143    /* check that we did not go overboard */
03144    if (N_IncTri_E1 > 99 || N_IncTri_E2 > 99 ) {
03145       fprintf (SUMA_STDERR,"Error %s: Exceeded preallocated space.\n", FuncName);
03146       SUMA_RETURN (-1);
03147    }
03148 
03149    /* find triangle incident to both edges */
03150    i=0;
03151    Found = NOPE;
03152    while (i < N_IncTri_E1 && !Found) {
03153       j = 0;
03154       while (j < N_IncTri_E2 && !Found) {
03155          if (IncTri_E2[j] == IncTri_E1[i]) { 
03156             Found = YUP;
03157             Tri = IncTri_E2[j];
03158          }
03159          ++j;
03160       }
03161       ++i;
03162    }
03163    
03164    if (!Found) SUMA_RETURN (-1);
03165    
03166    SUMA_RETURN (Tri);
03167 }

int* SUMA_z_dqsort int *    x,
int    nx
 

Definition at line 2171 of file SUMA_MiscFunc.c.

Referenced by SUMA_DrawnROI_to_1DDrawROI(), SUMA_OpenDrawnROI_1D(), and SUMA_Overlays_2_GLCOLAR4().

02172 {/*SUMA_z_dqsort*/
02173    static char FuncName[]={"SUMA_z_dqsort"}; 
02174    int *I, k;
02175    SUMA_Z_QSORT_INT *Z_Q_iStrct;
02176    
02177    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02178 
02179    /* allocate for the structure
02180  */
02181    Z_Q_iStrct = (SUMA_Z_QSORT_INT *) SUMA_calloc(nx, sizeof (SUMA_Z_QSORT_INT));
02182    I = (int *) SUMA_calloc (nx,sizeof(int));
02183 
02184    if (!Z_Q_iStrct || !I)
02185       {
02186          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02187          SUMA_RETURN (NULL);
02188       }
02189 
02190    for (k=0; k < nx; ++k) /* copy the data into a structure */
02191       {
02192          Z_Q_iStrct[k].x = x[k];
02193          Z_Q_iStrct[k].Index = k;
02194       }
02195 
02196    /* sort the structure by it's field value */
02197    qsort(Z_Q_iStrct, nx, sizeof(SUMA_Z_QSORT_INT), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_INT);
02198 
02199    /* recover the index table */
02200    for (k=0; k < nx; ++k) /* copy the data into a structure */
02201       {
02202          x[k] = Z_Q_iStrct[k].x;
02203          I[k] = Z_Q_iStrct[k].Index;
02204       }
02205 
02206    /* free the structure */
02207    SUMA_free(Z_Q_iStrct);
02208 
02209    /* return */
02210    SUMA_RETURN (I);
02211 
02212       
02213 }/*SUMA_z_dqsort*/

int* SUMA_z_dqsort_nsc int *    x,
int    nx
 

same as SUMA_z_dqsort but does not use SUMA_calloc or SUMA_free functions.

Definition at line 2218 of file SUMA_MiscFunc.c.

Referenced by SUMA_ShowMemTrace().

02219 {/*SUMA_z_dqsort_nsc*/
02220    static char FuncName[]={"SUMA_z_dqsort_nsc"}; 
02221    int *I, k;
02222    SUMA_Z_QSORT_INT *Z_Q_iStrct;
02223    
02224    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02225 
02226    /* allocate for the structure
02227  */
02228    Z_Q_iStrct = (SUMA_Z_QSORT_INT *) calloc(nx, sizeof (SUMA_Z_QSORT_INT));
02229    I = (int *) calloc (nx,sizeof(int));
02230 
02231    if (!Z_Q_iStrct || !I)
02232       {
02233          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02234          SUMA_RETURN (NULL);
02235       }
02236 
02237    for (k=0; k < nx; ++k) /* copy the data into a structure */
02238       {
02239          Z_Q_iStrct[k].x = x[k];
02240          Z_Q_iStrct[k].Index = k;
02241       }
02242 
02243    /* sort the structure by it's field value */
02244    qsort(Z_Q_iStrct, nx, sizeof(SUMA_Z_QSORT_INT), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_INT);
02245 
02246    /* recover the index table */
02247    for (k=0; k < nx; ++k) /* copy the data into a structure */
02248       {
02249          x[k] = Z_Q_iStrct[k].x;
02250          I[k] = Z_Q_iStrct[k].Index;
02251       }
02252 
02253    /* free the structure */
02254    free(Z_Q_iStrct);
02255 
02256    /* return */
02257    SUMA_RETURN (I);
02258 
02259       
02260 }/*SUMA_z_dqsort_nsc*/

int* SUMA_z_qsort float *    x,
int    nx
 

**

File : from ~/Programs/C/Z/Zlib/code/SUMA_z_qsort.c Author : Ziad Saad Date : Fri Nov 20 15:30:55 CST 1998

Purpose : A sorting function that uses C library's qsort and returns an index table with it. So, if you're sorting vector x, you'll get y (y is STORED IN x, make a copy of x before calling the function if you want to preserve the unsorted version of x), a sorted version of x, and I such that x(I) = y;

Usage : I = SUMA_z_qsort ( x , nx ); I = SUMA_z_dqsort ( x , nx );

Input paramters : x (*float) vector of floats, sorted array is returned in x nx (int) number of elements in x

If you are sorting integers, use SUMA_z_dqsort where x is an (int *)

Returns : I (int *) [nx x 1] vector containing the index table x, of course, is sorted

Support :

Side effects :

Definition at line 2127 of file SUMA_MiscFunc.c.

Referenced by SUMA_MapSurface(), and SUMA_PercRange().

02128 {/*SUMA_z_qsort*/
02129    static char FuncName[]={"SUMA_z_qsort"}; 
02130    int *I, k;
02131    SUMA_Z_QSORT_FLOAT *Z_Q_fStrct;
02132    
02133    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02134 
02135    /* allocate for the structure */
02136    Z_Q_fStrct = (SUMA_Z_QSORT_FLOAT *) SUMA_calloc(nx, sizeof (SUMA_Z_QSORT_FLOAT));
02137    I = (int *) SUMA_calloc (nx, sizeof(int));
02138 
02139    if (!Z_Q_fStrct || !I)
02140       {
02141          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02142          SUMA_RETURN (NULL);
02143       }
02144 
02145    for (k=0; k < nx; ++k) /* copy the data into a structure */
02146       {
02147          Z_Q_fStrct[k].x = x[k];
02148          Z_Q_fStrct[k].Index = k;
02149       }
02150 
02151    /* sort the structure by it's field value */
02152    qsort(Z_Q_fStrct, nx, sizeof(SUMA_Z_QSORT_FLOAT), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_FLOAT);
02153 
02154    /* recover the index table */
02155    for (k=0; k < nx; ++k) /* copy the data into a structure */
02156       {
02157          x[k] = Z_Q_fStrct[k].x;
02158          I[k] = Z_Q_fStrct[k].Index;
02159       }
02160 
02161    /* free the structure */
02162    SUMA_free(Z_Q_fStrct);
02163 
02164    /* return */
02165    SUMA_RETURN (I);
02166 
02167 
02168 }/*SUMA_z_qsort*/


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