Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

SUMA_MiscFunc.c File Reference

#include "SUMA_suma.h"

Go to the source code of this file.


Data Structures

struct  SUMA_QSORTROW_FLOAT
struct  SUMA_QSORTROW_INT
struct  SUMA_Z_QSORT_DOUBLE
struct  SUMA_Z_QSORT_FLOAT
struct  SUMA_Z_QSORT_INT

Defines

#define SUMA_Z_QSORT_structs
#define SUMA_CORNER_OF_VOXEL(center, dxyz, cn, P)
 Returns the coordinates of a voxel corner.

#define SUMA_EDGE_OF_VOXEL(center, dxyz, en, P0, P1)
 Returns the coordinates of the two points that form an edge of a voxel.

#define SUMA_IS_POINT_IN_SEGMENT(p, p0, p1)
 find out if a point p on the line formed by points p0 and p1 is between p0 and p1 ans = SUMA_IS_POINT_IN_SEGMENT(p, p0, p1); if ans then p is between p0 and p1 p, p0, p1 (float *) xyz of points

#define MAX_INCIDENT_TRI   200
#define DBG_1
#define TAUBIN_Householder

Enumerations

enum  SUMA_TAKE_A_HIKE { SUMA_NO_NEIGHB, SUMA_NO_MORE_TO_VISIT, SUMA_VISITED_ALL, SUMA_BAD_SEED }

Functions

void * SUMA_malloc_fn (const char *CF, size_t size)
void * SUMA_free_fn (const char *CF, void *ptr)
void * SUMA_calloc_fn (const char *CF, size_t nmemb, size_t size)
void * SUMA_realloc_fn (const char *CF, void *ptr, size_t size)
SUMA_MEMTRACE_STRUCTSUMA_Create_MemTrace (void)
float * SUMA_Sph2Cart (float *sph, int Nval, float *center)
 Function to change a bunch of spherical coordinates to cartesian ones.

float * SUMA_Cart2Sph (float *coord, int Nval, float *center)
 Function to change a bunch of cartesian coordinates to spherical ones.

void SUMA_ShowMemTrace (SUMA_MEMTRACE_STRUCT *Mem, FILE *Out)
SUMA_Boolean SUMA_Free_MemTrace (SUMA_MEMTRACE_STRUCT *Mem)
int SUMA_Read_dfile (int *x, char *f_name, int n_points)
int SUMA_Read_file (float *x, char *f_name, int n_points)
int SUMA_Read_2Dfile (char *f_name, float **x, int n_cols, int n_rows)
SUMA_IRGBSUMA_Create_IRGB (int n_el)
 Allocate for irgb structure containing n_el elements in each vector.

SUMA_IRGBSUMA_Free_IRGB (SUMA_IRGB *irgb)
 function to free SUMA_IRGB *

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

int SUMA_Read_2Ddfile (char *f_name, int **x, int n_rows, int n_cols)
int SUMA_float_file_size (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_ci (const char *sbig, const char *ssub)
 case insensitive version of SUMA_iswordin

int SUMA_iswordin (const char *sbig, const char *ssub)
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, SUMA_INDEXING_ORDER d_order, FILE *fout, SUMA_Boolean AddRowInd)
void SUMA_disp_vecdmat (int *v, int nr, int nc, int SpcOpt, SUMA_INDEXING_ORDER d_order, FILE *fout, SUMA_Boolean AddRowInd)
void SUMA_disp_vecucmat (unsigned char *v, int nr, int nc, int SpcOpt, SUMA_INDEXING_ORDER d_order, FILE *fout, SUMA_Boolean AddRowInd)
 same as SUMA_disp_vecdmat, except with unsigned char * instead of int *

void SUMA_disp_vect (float *v, int l)
void SUMA_disp_dvect (int *v, int l)
float SUMA_etime (struct timeval *t, int Report)
SUMA_ISINSPHERE SUMA_isinsphere (float *NodeList, int nr, float *S_cent, float S_rad, int BoundIn)
SUMA_Boolean SUMA_Free_IsInSphere (SUMA_ISINSPHERE *IB)
SUMA_ISINBOX SUMA_isinbox (float *XYZ, int nr, float *S_cent, float *S_dim, int BoundIn)
SUMA_Boolean SUMA_Free_IsInBox (SUMA_ISINBOX *IB)
byteSUMA_isinpoly (float *P, float *NodeList, int *FaceSetList, int N_FaceSet, int FaceSetDim, int *dims, int *N_in, byte *usethis, byte *culled)
 Determines is a point in 2D is inside a polygon with no holes. The function's parameters are abit strange because of the intended use.

float ** SUMA_Point_At_Distance (float *U, float *P1, float d)
double ** SUMA_dPoint_At_Distance (double *U, double *P1, double 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 compare_SUMA_Z_QSORT_FLOAT (SUMA_Z_QSORT_FLOAT *a, SUMA_Z_QSORT_FLOAT *b)
int compare_SUMA_Z_QSORT_DOUBLE (SUMA_Z_QSORT_DOUBLE *a, SUMA_Z_QSORT_DOUBLE *b)
int compare_SUMA_Z_QSORT_INT (SUMA_Z_QSORT_INT *a, SUMA_Z_QSORT_INT *b)
int SUMA_compare_int (int *a, int *b)
int * SUMA_z_qsort (float *x, int nx)
int * SUMA_z_doubqsort (double *x, int nx)
int * SUMA_z_dqsort (int *x, int nx)
int * SUMA_z_dqsort_nsc (int *x, int nx)
int compare_SUMA_QSORTROW_FLOAT (SUMA_QSORTROW_FLOAT *a, SUMA_QSORTROW_FLOAT *b)
int * SUMA_fqsortrow (float **X, int nr, int nc)
int compare_SUMA_QSORTROW_INT (SUMA_QSORTROW_INT *a, SUMA_QSORTROW_INT *b)
int * SUMA_dqsortrow (int **X, int nr, int nc)
SUMA_Boolean SUMA_isVoxelIntersect_Triangle (float *center, float *dxyz, float *vert0, float *vert1, float *vert2)
 does a voxel intersect a triangle ? (i.e. one of the edges intersects a triangle)

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)
SUMA_Boolean SUMA_Show_MT_intersect_triangle (SUMA_MT_INTERSECT_TRIANGLE *MTI, FILE *Out)
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);

SUMA_Boolean SUMA_FromToRotation (float *v0, float *v1, float **mtx)
SUMA_Boolean SUMA_mattoquat (float **mat, float *q)
int SUMA_whichTri (SUMA_EDGE_LIST *EL, int n1, int n2, int n3, int IOtrace)
 This function determines which triangle, if any is formed by the specified nodes Tri = SUMA_wichTri (EL, n1, n2, n3);.

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);.

int SUMA_isConsistent (int *T, int *t)
int SUMA_Next_Best_Seed (SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN, int *visited, int N_FL)
SUMA_TAKE_A_HIKE SUMA_Take_A_Hike (SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN, int *visited, int *N_visited, int *Consistent, int *FL, int N_FL, int seed)
void SUMA_Show_Edge_List (SUMA_EDGE_LIST *EL, FILE *Out)
void SUMA_free_Edge_List (SUMA_EDGE_LIST *SEL)
SUMA_EDGE_LISTSUMA_Make_Edge_List (int *FL, int N_FL, int N_Node, float *NodeList, char *ownerid)
SUMA_EDGE_LISTSUMA_Make_Edge_List_eng (int *FL, int N_FL, int N_Node, float *NodeList, int debug, char *ownerid)
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);

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);

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);

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

void SUMA_free_FaceSet_Edge_Neighb (SUMA_FACESET_FIRST_EDGE_NEIGHB *S)
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)
SUMA_Boolean SUMA_MakeConsistent (int *FL, int N_FL, SUMA_EDGE_LIST *SEL, int detail, int *trouble)
float * SUMA_SmoothAttr_Neighb (float *attr, int N_attr, float *attr_sm, SUMA_NODE_FIRST_NEIGHB *fn, int nr)
float * SUMA_SmoothAttr_Neighb_Rec (float *attr, int N_attr, float *attr_sm_orig, SUMA_NODE_FIRST_NEIGHB *fn, int nr, int N_rep)
 float * SUMA_SmoothAttr_Neighb_Rec (float *attr, int N_attr, float *attr_sm_orig, SUMA_NODE_FIRST_NEIGHB *fn, int nr, int N_rep) A wrapper function to call SUMA_SmoothAttr_Neighb repeatedly See SUMA_SmoothAttr_Neighb for input and output options. The only additional option is N_Rec the number of repeated smoothing calls.

SUMA_NODE_FIRST_NEIGHBSUMA_Build_FirstNeighb (SUMA_EDGE_LIST *el, int N_Node, char *ownerid)
SUMA_Boolean SUMA_Free_FirstNeighb (SUMA_NODE_FIRST_NEIGHB *FN)
SUMA_Boolean SUMA_TriNorm (float *n0, float *n1, float *n2, float *norm)
float SUMA_TriSurf3 (float *n0, float *n1, float *n2)
float * SUMA_TriSurf3v (float *NodeList, int *FaceSets, int N_FaceSet)
float * SUMA_PolySurf3 (float *NodeList, int N_Node, int *FaceSets, int N_FaceSet, int PolyDim, float *FaceNormList, SUMA_Boolean SignedArea)
SUMA_SURFACE_CURVATURESUMA_Surface_Curvature (float *NodeList, int N_Node, float *NodeNormList, float *A, int N_FaceSet, SUMA_NODE_FIRST_NEIGHB *FN, SUMA_EDGE_LIST *SEL)
void SUMA_Free_SURFACE_CURVATURE (SUMA_SURFACE_CURVATURE *SC)
SUMA_Boolean SUMA_Householder (float *Ni, float **Q)
float * SUMA_Convexity (float *NL, int N_N, float *NNL, SUMA_NODE_FIRST_NEIGHB *FN)
float * SUMA_Convexity_Engine (float *NL, int N_N, float *NNL, SUMA_NODE_FIRST_NEIGHB *FN, char *DetailFile)
 float * SUMA_Convexity_Engine (float *NL, int N_N, float *NNL, SUMA_NODE_FIRST_NEIGHB *FN, char *DetailFile) This function does the computations for SUMA_Convexity with the additional option of outputing detailed results to an ASCII file for debugging.

char * SUMA_pad_str (char *str, char pad_val, int pad_ln, int opt)
char SUMA_ReadCharStdin (char def, int case_sensitive, char *allowed)
int SUMA_ReadNumStdin (float *fv, int nv)
int * SUMA_Find_inIntVect (int *x, int xsz, int val, int *nValLocation)
int * SUMA_UniqueInt (int *y, int xsz, int *kunq, int Sorted)
int * SUMA_UniqueInt_ind (int *ys, int N_y, int *kunq, int **iup)
 In addition to returning the unique set of values, The function creates a vector of indices specifying which values in y were retained.

int * SUMA_reorder (int *y, int *isort, int N_isort)
 creates a reordered version of a vector yr = SUMA_reorder(y, isort, N_isort);

int SUMA_suck_file (char *fname, char **fbuf)
 A function to suck in an ascii file Shamelessly stolen from Bob's suck_file.

char * SUMA_file_suck (char *fname, int *nread)
 Another version of SUMA_suck_file that hopes to avoid the silly error on OSX.


Variables

SUMA_CommonFieldsSUMAg_CF

Define Documentation

#define DBG_1
 

Definition at line 5715 of file SUMA_MiscFunc.c.

#define MAX_INCIDENT_TRI   200
 

Definition at line 5714 of file SUMA_MiscFunc.c.

Referenced by SUMA_Surface_Curvature().

#define SUMA_CORNER_OF_VOXEL center,
dxyz,
cn,
 
 

Returns the coordinates of a voxel corner.

Parameters:
center  (float *): center of voxel
dxyz  (float *): dimensions of voxel
en  (int): corner of voxel (0 -- 7)
P0  (float *): corner coords (set by macro)

Definition at line 3033 of file SUMA_MiscFunc.c.

#define SUMA_EDGE_OF_VOXEL center,
dxyz,
en,
P0,
P1   
 

Returns the coordinates of the two points that form an edge of a voxel.

Parameters:
center  (float *): center of voxel
dxyz  (float *): dimensions of voxel
en  (int): edge of voxel (0 -- 11)
P0  (float *): first point forming edge (set by macro)
P1  (float *): second point forming edge (set by macro)

Definition at line 3076 of file SUMA_MiscFunc.c.

Referenced by SUMA_isVoxelIntersect_Triangle().

#define SUMA_IS_POINT_IN_SEGMENT p,
p0,
p1   
 

Value:

(  (  (  \
                                                   (p[0] >  p0[0] && p[0] <  p1[0]) ||   \
                                                   (p[0] <  p0[0] && p[0] >  p1[0]) ||   \
                                                   (p[0] == p0[0] || p[0] == p1[0]) ) \
                                                   && \
                                                   (  \
                                                   (p[1] >  p0[1] && p[1] <  p1[1]) ||   \
                                                   (p[1] <  p0[1] && p[1] >  p1[1]) ||   \
                                                   (p[1] == p0[1] || p[1] == p1[1]) ) \
                                                   && \
                                                   (  \
                                                   (p[2] >  p0[2] && p[2] <  p1[2]) ||   \
                                                   (p[2] <  p0[2] && p[2] >  p1[2]) ||   \
                                                   (p[2] == p0[2] || p[2] == p1[2]) ) \
                                                   ) ? 1 : 0 )
find out if a point p on the line formed by points p0 and p1 is between p0 and p1 ans = SUMA_IS_POINT_IN_SEGMENT(p, p0, p1); if ans then p is between p0 and p1 p, p0, p1 (float *) xyz of points

  • NOTE: macro does not check that three points are colinear (as they should be)!

Definition at line 3141 of file SUMA_MiscFunc.c.

Referenced by SUMA_isVoxelIntersect_Triangle().

#define SUMA_Z_QSORT_structs
 

Sorting Functions

Definition at line 2561 of file SUMA_MiscFunc.c.

#define TAUBIN_Householder
 

Computes the householder matrix for a 3x1 vector Vh = Q * V will have all elements but the first = 0

ans = SUMA_Householder (float *V, float **Q)

Parameters:
V  (float *) 3x1 column vector
Q  (float **) 3x3 (pre-allocated) matrix that will contain the Householder matrix
\ret ans (SUMA_Boolean) YUP/NOPE (failure)

The code for this function contains two algorithms, one is identical to Taubin's suggestion and one is a generic Householder algorithm.

Definition at line 6115 of file SUMA_MiscFunc.c.


Enumeration Type Documentation

enum SUMA_TAKE_A_HIKE
 

Enumeration values:
SUMA_NO_NEIGHB 
SUMA_NO_MORE_TO_VISIT 
SUMA_VISITED_ALL 
SUMA_BAD_SEED 

Definition at line 3865 of file SUMA_MiscFunc.c.

Referenced by SUMA_Take_A_Hike().


Function Documentation

int compare_SUMA_QSORTROW_FLOAT SUMA_QSORTROW_FLOAT   a,
SUMA_QSORTROW_FLOAT   b
 

Definition at line 2855 of file SUMA_MiscFunc.c.

References a, SUMA_QSORTROW_FLOAT::ncol, and SUMA_QSORTROW_FLOAT::x.

Referenced by SUMA_fqsortrow().

02856    {
02857       int k;
02858       
02859       for (k=0; k < a->ncol ; ++k)
02860          {
02861             if (a->x[k] < b->x[k])
02862                return (-1);
02863             else if (a->x[k] > b->x[k])
02864                return (1);
02865          }
02866       return (0); /* They're similar */
02867    }

int compare_SUMA_QSORTROW_INT SUMA_QSORTROW_INT   a,
SUMA_QSORTROW_INT   b
 

Definition at line 2943 of file SUMA_MiscFunc.c.

References a, SUMA_QSORTROW_INT::ncol, and SUMA_QSORTROW_INT::x.

Referenced by SUMA_dqsortrow().

02944    {
02945       int k;
02946       
02947       for (k=0; k < a->ncol ; ++k)
02948          {
02949             if (a->x[k] < b->x[k])
02950                return (-1);
02951             else if (a->x[k] > b->x[k])
02952                return (1);
02953          }
02954       return (0); /* They're similar */
02955    }

int compare_SUMA_Z_QSORT_DOUBLE SUMA_Z_QSORT_DOUBLE   a,
SUMA_Z_QSORT_DOUBLE   b
 

Definition at line 2592 of file SUMA_MiscFunc.c.

References a, and SUMA_Z_QSORT_DOUBLE::x.

Referenced by SUMA_z_doubqsort().

02593    {
02594       if (a->x < b->x)
02595          return (-1);
02596       else if (a->x == b->x)
02597          return (0);
02598       else if (a->x > b->x)
02599          return (1);
02600       /* this will never be reached but it will shut the compiler up */
02601       return (0);
02602    }

int compare_SUMA_Z_QSORT_FLOAT SUMA_Z_QSORT_FLOAT   a,
SUMA_Z_QSORT_FLOAT   b
 

Definition at line 2580 of file SUMA_MiscFunc.c.

References a, and SUMA_Z_QSORT_FLOAT::x.

Referenced by SUMA_z_qsort().

02581    {
02582       if (a->x < b->x)
02583          return (-1);
02584       else if (a->x == b->x)
02585          return (0);
02586       else if (a->x > b->x)
02587          return (1);
02588       /* this will never be reached but it will shut the compiler up */
02589       return (0);
02590    }

int compare_SUMA_Z_QSORT_INT SUMA_Z_QSORT_INT   a,
SUMA_Z_QSORT_INT   b
 

Definition at line 2605 of file SUMA_MiscFunc.c.

References a, and SUMA_Z_QSORT_INT::x.

Referenced by SUMA_z_dqsort(), and SUMA_z_dqsort_nsc().

02606    {
02607       if (a->x < b->x)
02608          return (-1);
02609       else if (a->x == b->x)
02610          return (0);
02611       else if (a->x > b->x)
02612          return (1);
02613       /* this will never be reached but it will shut the compiler up */
02614       return (0);
02615    }

void SUMA_alloc_problem char *    s1
 

Taken from SUMA_alloc_problem

Definition at line 831 of file SUMA_MiscFunc.c.

References SUMA_ENTRY.

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

00833 {
00834    static char FuncName[]={"SUMA_alloc_problem"};
00835    SUMA_ENTRY;
00836 
00837    printf ("\n\n\aError in memory allocation\n");
00838    printf ("Error origin : %s\n\n",s1);
00839    printf ("Exiting Program ..\n\n");
00840    exit (0);
00841 }

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 866 of file SUMA_MiscFunc.c.

References calloc, cols, free, i, SUMA_CommonFields::Mem, SUMA_CommonFields::MemTrace, SUMA_MEMTRACE_STRUCT::N_alloc, SUMA_MEMTRACE_STRUCT::N_MaxPointers, pause_mcw_malloc(), SUMA_MEMTRACE_STRUCT::Pointers, realloc, resume_mcw_malloc(), rows, SUMA_MEMTRACE_STRUCT::Size, SUMA_ENTRY, SUMA_MEMTRACE_BLOCK, SUMA_RETURN, and SUMA_SL_Err.

Referenced by SUMA_AFNI_Extract_Colors(), SUMA_allocate_FaceSet_Edge_Neighb(), SUMA_ApplyAffine(), SUMA_Build_FirstNeighb(), SUMA_CalcNeighbDist(), SUMA_Chung_Smooth_Weights(), SUMA_dPoint_At_Distance(), SUMA_Engine(), SUMA_Get_AFNI_Default_Color_Maps(), SUMA_GetStandardMap(), SUMA_input(), SUMA_Linearize_Color_Map(), SUMA_Make_Edge_List_eng(), SUMA_MakeColorMap(), SUMA_MakeColorMap_v2(), SUMA_MemberFaceSets(), SUMA_Point_At_Distance(), SUMA_PolySurf3(), SUMA_Read_Color_Map_1D(), SUMA_RegisterEngineData(), SUMA_RegisterEngineListCommand(), SUMA_ScaleToMap(), SUMA_ScaleToMap_alaAFNI(), SUMA_SureFit_Read_Topo(), and SUMA_Surface_Curvature().

00868 {
00869    int i;
00870    char **A;
00871    static char FuncName[]={"SUMA_allocate2D"};
00872 
00873    SUMA_ENTRY;
00874    
00875    #ifdef USE_SUMA_MALLOC
00876       SUMA_SL_Err("NO LONGER SUPPORTED");
00877       SUMA_RETURN(NULL);
00878    #else
00879       pause_mcw_malloc();
00880    #endif
00881    
00882    /* try to allocate the request */
00883    switch(element_size) {
00884      case sizeof(short): {    /* integer matrix */
00885          short **int_matrix;
00886          int_matrix = (short **)calloc(rows,sizeof(short *));
00887          if(!int_matrix) {
00888              printf("\nError making pointers in %dx%d int matrix\n"
00889                          ,rows,cols);
00890              exit(1);
00891          }
00892          for(i = 0 ; i < rows ; i++) {
00893              int_matrix[i] = (short *)calloc(cols,sizeof(short));
00894              if(!int_matrix[i]) {
00895                  printf("\nError making row %d in %dx%d int matrix\n"
00896                          ,i,rows,cols);
00897                  exit(1);
00898              }
00899          }
00900          A = (char **)int_matrix;
00901          break;
00902      }
00903      case sizeof(float): {    /* float matrix */
00904          float **float_matrix;
00905          float_matrix = (float **)calloc(rows,sizeof(float *));
00906          if(!float_matrix) {
00907              printf("\nError making pointers in %dx%d float matrix\n"
00908                          ,rows,cols);
00909              exit(1);
00910          }
00911          for(i = 0 ; i < rows ; i++) {
00912              float_matrix[i] = (float *)calloc(cols,sizeof(float));
00913              if(!float_matrix[i]) {
00914                  printf("\nError making row %d in %dx%d float matrix\n"
00915                          ,i,rows,cols);
00916                  exit(1);
00917              }
00918          }
00919          A = (char **)float_matrix;
00920          break;
00921      }
00922      case sizeof(double): {   /* double matrix */
00923          double **double_matrix;
00924          double_matrix = (double **)calloc(rows,sizeof(double *));
00925          if(!double_matrix) {
00926              printf("\nError making pointers in %dx%d double matrix\n"
00927                          ,rows,cols);
00928              exit(1);
00929          }
00930          for(i = 0 ; i < rows ; i++) {
00931              double_matrix[i] = (double *)calloc(cols,sizeof(double));
00932              if(!double_matrix[i]) {
00933                  printf("\nError making row %d in %dx%d double matrix\n"
00934                          ,i,rows,cols);
00935                  exit(1);
00936              }
00937          }
00938          A = (char **)double_matrix;
00939          break;
00940      }
00941      default:
00942          printf("\nERROR in matrix_allocate: unsupported type\n");
00943          exit(1);
00944    }
00945    
00946    #ifdef USE_SUMA_MALLOC
00947    SUMA_SL_Err("NO LONGER SUPPORTED");
00948    SUMA_RETURN(NULL);
00949 
00950    #if SUMA_MEMTRACE_FLAG
00951    if (SUMAg_CF->MemTrace) {
00952       ++SUMAg_CF->Mem->N_alloc;
00953       if (SUMAg_CF->Mem->N_MaxPointers <= SUMAg_CF->Mem->N_alloc) {
00954          /* must reallocate */
00955          /* SUMA_ShowMemTrace (SUMAg_CF->Mem, NULL);*/
00956          SUMAg_CF->Mem->N_MaxPointers += SUMA_MEMTRACE_BLOCK;
00957 
00958          SUMAg_CF->Mem->Pointers = (void **)realloc (SUMAg_CF->Mem->Pointers, sizeof(void*) * SUMAg_CF->Mem->N_MaxPointers);
00959          SUMAg_CF->Mem->Size  = (int *)realloc ((void *)SUMAg_CF->Mem->Size, sizeof(int) * SUMAg_CF->Mem->N_MaxPointers);
00960          if (!SUMAg_CF->Mem->Pointers || !SUMAg_CF->Mem->Pointers) {
00961             fprintf (SUMA_STDERR, "Error %s: Failed to reallocate.\nTurning off memory tracing.\n", \
00962                FuncName);
00963             /* free up allocated space, clean up pointers, turn off memory tracing DO NOT USE SUMA_free here*/
00964             if (SUMAg_CF->Mem->Pointers) free(SUMAg_CF->Mem->Pointers); SUMAg_CF->Mem->Pointers = NULL;
00965             if (SUMAg_CF->Mem->Size) free(SUMAg_CF->Mem->Size); SUMAg_CF->Mem->Size = NULL;
00966             SUMAg_CF->MemTrace = 0;
00967             SUMAg_CF->Mem->N_alloc = 0;
00968             SUMAg_CF->Mem->N_MaxPointers =0;
00969          }
00970       }
00971       SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = A;
00972       SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = rows * cols * element_size;
00973    }
00974    #endif
00975    
00976    #else
00977       resume_mcw_malloc();
00978    #endif
00979    
00980    SUMA_RETURN(A);
00981 }

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 4828 of file SUMA_MiscFunc.c.

References SUMA_FACESET_FIRST_EDGE_NEIGHB::FirstNeighb, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_FaceSet, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb_max, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb_min, SUMA_allocate2D(), SUMA_calloc, SUMA_ENTRY, SUMA_malloc, SUMA_MAX_FACESET_EDGE_NEIGHB, and SUMA_RETURN.

Referenced by SUMA_FaceSet_Edge_Neighb().

04829 {
04830    static char FuncName[]={"SUMA_FACESET_FIRST_EDGE_NEIGHB"};
04831    SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN;
04832    
04833    SUMA_ENTRY;
04834 
04835    SFFN = SUMA_malloc(sizeof(SUMA_FACESET_FIRST_EDGE_NEIGHB));
04836    if (SFFN == NULL) {
04837       fprintf (SUMA_STDERR, "Error %s: Could not allocate for SFFN.\n", FuncName);
04838       SUMA_RETURN (NULL);
04839    }
04840    
04841    SFFN->FirstNeighb = (int **) SUMA_allocate2D(N_FaceSet, SUMA_MAX_FACESET_EDGE_NEIGHB, sizeof(int));
04842    SFFN->N_Neighb = (int *) SUMA_calloc (N_FaceSet, sizeof(int));
04843    if (SFFN->FirstNeighb == NULL || SFFN->N_Neighb == NULL) {
04844       fprintf (SUMA_STDERR, "Error %s: Could not allocate for FirstNeighb or N_Neighb.\n", FuncName);
04845       SUMA_RETURN (NULL);
04846    } 
04847    
04848    SFFN->N_Neighb_max = -1; /* ridiculously low */
04849    SFFN->N_FaceSet = N_FaceSet;
04850    SFFN->N_Neighb_min = 100; /* ridiculously high */
04851    SUMA_RETURN (SFFN);
04852 }

SUMA_NODE_FIRST_NEIGHB* SUMA_Build_FirstNeighb SUMA_EDGE_LIST   el,
int    N_Node,
char *    ownerid
 

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 5327 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_NODE_FIRST_NEIGHB::FirstNeighb, i, SUMA_NODE_FIRST_NEIGHB::idcode_str, SUMA_NODE_FIRST_NEIGHB::LinkedPtrType, n1, n2, SUMA_EDGE_LIST::N_EL, SUMA_NODE_FIRST_NEIGHB::N_links, SUMA_NODE_FIRST_NEIGHB::N_Neighb, SUMA_NODE_FIRST_NEIGHB::N_Neighb_max, SUMA_NODE_FIRST_NEIGHB::N_Node, SUMA_NODE_FIRST_NEIGHB::NodeId, SUMA_NODE_FIRST_NEIGHB::owner_id, SUMA_allocate2D(), SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_free2D(), SUMA_Free_FirstNeighb(), SUMA_LINKED_ND_FRST_NEI_TYPE, SUMA_malloc, SUMA_MAX_NUMBER_NODE_NEIGHB, SUMA_NEW_ID, SUMA_RETURN, and SUMA_whichTri().

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

05328 {
05329    static char FuncName[]={"SUMA_Build_FirstNeighb"};
05330    int i, j, n1, n2,  **FirstNeighb, N_ELm1, jj, tmp, TessErr_Cnt=0, IOtrace = 0;
05331    SUMA_Boolean skp;
05332    SUMA_NODE_FIRST_NEIGHB *FN;
05333    
05334    SUMA_ENTRY;
05335 
05336    if (DBG_trace > 1) IOtrace = 1;
05337    
05338    if (el == NULL || N_Node == 0) {
05339       fprintf(SUMA_STDERR, "Error %s: el == NULL or N_Node == 0, nothing to do.\n", FuncName);
05340       SUMA_RETURN (NULL);
05341    }   
05342    
05343    FN = (SUMA_NODE_FIRST_NEIGHB *)SUMA_malloc(sizeof(SUMA_NODE_FIRST_NEIGHB));
05344    if (FN == NULL) {
05345       fprintf(SUMA_STDERR, "Error %s: Could not allocate space for FN\n", FuncName);
05346       SUMA_RETURN (NULL);
05347    }
05348    
05349    FN->N_links = 0;
05350    if (ownerid) sprintf(FN->owner_id, "%s", ownerid);
05351    else FN->owner_id[0] = '\0';
05352    FN->LinkedPtrType = SUMA_LINKED_ND_FRST_NEI_TYPE;
05353    
05354    FN->idcode_str = NULL;
05355    SUMA_NEW_ID(FN->idcode_str, NULL);
05356    
05357    /* allocate space for FN's matrices */
05358    FN->N_Node = N_Node;
05359    FN->N_Neighb_max = 0;
05360    
05361    FN->FirstNeighb = (int **) SUMA_allocate2D(FN->N_Node, SUMA_MAX_NUMBER_NODE_NEIGHB+1, sizeof (int));
05362    FN->N_Neighb = (int *) SUMA_calloc (FN->N_Node, sizeof(int));
05363    FN->NodeId = (int *) SUMA_calloc (FN->N_Node, sizeof(int));
05364    
05365    if (FN->FirstNeighb == NULL || FN->N_Neighb == NULL || FN->NodeId == NULL ){
05366       fprintf(SUMA_STDERR, "Error %s: Could not allocate space forFN->FirstNeighb &/| FN->N_Neighb &/| FN->NodeId.\n", FuncName);
05367       SUMA_RETURN (NULL);
05368    } 
05369    
05370    /*fprintf(SUMA_STDOUT, "%s: Creating list ...\n", FuncName);*/
05371    
05372    FN->N_Neighb_max = 0;
05373    N_ELm1 = el->N_EL-1;
05374    j=0;
05375    while (j < el->N_EL) 
05376    {
05377       n1 = el->EL[j][0];
05378       n2 = el->EL[j][1];
05379       
05380       if (FN->N_Neighb[n1] > SUMA_MAX_NUMBER_NODE_NEIGHB || FN->N_Neighb[n2] > SUMA_MAX_NUMBER_NODE_NEIGHB) {
05381          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);
05382       }else {
05383          /*register the neighbors for both nodes*/
05384          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 */
05385          FN->NodeId[n2] = n2;
05386          FN->FirstNeighb[n1][FN->N_Neighb[n1]] = n2;
05387          FN->FirstNeighb[n2][FN->N_Neighb[n2]] = n1;
05388 
05389          /* increment neighbor count for nodes in edge */
05390          FN->N_Neighb[n1] += 1;
05391          FN->N_Neighb[n2] += 1;
05392 
05393          if (FN->N_Neighb[n1] > FN->N_Neighb_max) FN->N_Neighb_max = FN->N_Neighb[n1];
05394          if (FN->N_Neighb[n2] > FN->N_Neighb_max) FN->N_Neighb_max = FN->N_Neighb[n2];
05395 
05396          /* skip duplicate edges */
05397          if (j < N_ELm1) {
05398             skp = NOPE;
05399             do {
05400                if (el->EL[j+1][0] == el->EL[j][0] && el->EL[j+1][1] == el->EL[j][1]) {
05401                   ++j;
05402                } else {
05403                   skp = YUP;
05404                }
05405             } while (!skp && j < N_ELm1);
05406          }
05407       }
05408       
05409       ++j;
05410    }/* for j */
05411 
05412    /* now SUMA_reallocate for final FirstNeighb */
05413    FirstNeighb = (int **) SUMA_allocate2D(FN->N_Node, FN->N_Neighb_max, sizeof (int));
05414    if (FirstNeighb == NULL){
05415       fprintf(SUMA_STDERR, "Error %s: Could not allocate space for FirstNeighb\n", FuncName);
05416       SUMA_Free_FirstNeighb (FN);
05417       SUMA_RETURN (NULL);
05418    } 
05419 
05420    /* crop left over allocated space and rearrange neighboring nodes in order */
05421    for (i=0; i < N_Node; ++i) {
05422       #ifdef NoOrder
05423       for (j=0; j < FN->N_Neighb[i]; ++j) {
05424           FirstNeighb[i][j] = FN->FirstNeighb[i][j];
05425       }
05426       #else /* ordered nodes, Tue Jan  7 13:21:57 EST 2003 */
05427         /* copy first node */
05428         FirstNeighb[i][0] = FN->FirstNeighb[i][0];
05429         j = 1;
05430         jj = 1;
05431         while (j < FN->N_Neighb[i]) {
05432             if (SUMA_whichTri (el, i, FirstNeighb[i][jj-1], FN->FirstNeighb[i][j], IOtrace) >= 0) {
05433                FirstNeighb[i][jj] = FN->FirstNeighb[i][j];
05434                /* now swap in FN->FirstNeighb[i] the positions of jj and j */
05435                tmp =  FN->FirstNeighb[i][jj];
05436                FN->FirstNeighb[i][jj] = FN->FirstNeighb[i][j];
05437                FN->FirstNeighb[i][j] = tmp;
05438                ++jj;
05439                j = jj;
05440             } else {
05441                ++j;
05442             }
05443         }
05444         if (jj != FN->N_Neighb[i]) {
05445             if (!TessErr_Cnt) {
05446                fprintf (SUMA_STDERR,"Error %s:\n"
05447                                     " Failed in copying neighbor list! jj=%d, FN->N_Neighb[%d]=%d\n"
05448                                     " If this is a closed surface, the problem is likely due to a\n"
05449                                     " tessellation error. One or more edges may not be part of 2 \n"
05450                                     " and only 2 triangles. Neighbor list for node %d will not be\n"
05451                                     " ordered as connected vertices.\n"
05452                                     " Further occurences of this error will not be reported.\n"
05453                                     ,  FuncName, jj, i, FN->N_Neighb[i], i);
05454             }
05455             ++TessErr_Cnt;
05456             while (jj < FN->N_Neighb[i]) {
05457                FirstNeighb[i][jj] = FN->FirstNeighb[i][jj];
05458                ++jj;
05459             }
05460         }    
05461       #endif
05462    }
05463    if (TessErr_Cnt) {
05464       fprintf (SUMA_STDERR, " %d similar occurences of the error above were found in this mesh.\n", TessErr_Cnt);
05465    }
05466    SUMA_free2D((char **)FN->FirstNeighb, N_Node);
05467    FN->FirstNeighb = FirstNeighb;
05468    /* SUMA_disp_dmat (FN->FirstNeighb, N_Node, FN->N_Neighb_max, 0); */
05469    SUMA_RETURN (FN);
05470 }

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

Definition at line 217 of file SUMA_MiscFunc.c.

References calloc.

00218    {
00219       return (calloc(nmemb, size));
00220    }

float* SUMA_Cart2Sph float *    coord,
int    Nval,
float *    center
 

Function to change a bunch of cartesian coordinates to spherical ones.

Parameters:
coord  (float *) Nval*3 XYZ coords
Nval  (int) number of coord triplets
center  (float *) 3x1 XYZ of center (CARTESIAN). If NULL center is 0 0 0 center is subtracted from each coord triplet before xformation
Returns:
sph (float *) Nval*3 [rho, theta(azimuth), phi(elevation)] spherical coords
See also:
SUMA_CART_2_SPH

Definition at line 319 of file SUMA_MiscFunc.c.

References i, SUMA_CART_2_SPH, SUMA_ENTRY, SUMA_malloc, SUMA_RETURN, SUMA_SL_Crit, and v.

00320 {
00321    static char FuncName[]={"SUMA_Cart2Sph"};
00322    float v[3], *f;
00323    int i, i3;
00324    float *sph=NULL;
00325    
00326    SUMA_ENTRY;
00327    
00328    if (Nval <= 0) {
00329       SUMA_RETURN(NULL);
00330    }
00331    
00332    sph = (float *)SUMA_malloc(Nval*sizeof(float)*3);
00333    if (!sph) {
00334       SUMA_SL_Crit("Failed to allocate");
00335       SUMA_RETURN(NULL);
00336    }
00337    
00338    for (i=0; i<Nval; ++i) {
00339       i3 = 3*i;
00340       if (center) {
00341          v[0] = coord[i3+0] - center[0]; 
00342          v[1] = coord[i3+1] - center[1]; 
00343          v[2] = coord[i3+2] - center[2]; 
00344       } else {
00345          v[0] = coord[i3+0]; 
00346          v[1] = coord[i3+1]; 
00347          v[2] = coord[i3+2]; 
00348       }
00349       f = &(sph[i3]);
00350       SUMA_CART_2_SPH(v,f);
00351    }
00352    
00353    SUMA_RETURN(sph);
00354 }

int SUMA_compare_int int *    a,
int *    b
 

Definition at line 2618 of file SUMA_MiscFunc.c.

References a.

Referenced by SUMA_UniqueInt().

02619 {/*SUMA_compare_int*/
02620     if (*a < *b)
02621       return (-1);
02622    else if (*a == *b)
02623       return (0);
02624    else
02625       return (1);
02626    
02627 }/*SUMA_compare_int*/

float* SUMA_Convexity float *    NL,
int    N_N,
float *    NNL,
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 (the - sign was added May 06 04 ) 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

Aug 14 03 This function actually calls SUMA_Convexity_Engine with NULL for DetailFile parameter. See SUMA_Convexity_Engine May 06 04: This function was modified to return +ve values for convex regions and negative for concave ones. It used to be the opposite.

Definition at line 6217 of file SUMA_MiscFunc.c.

References SUMA_Convexity_Engine(), SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_input(), and SUMA_SurfaceMetrics_eng().

06218 {
06219    static char FuncName[]={"SUMA_Convexity"};
06220    float *C=NULL;
06221    
06222    SUMA_ENTRY;
06223    
06224    C = SUMA_Convexity_Engine (NL, N_N, NNL, FN, NULL);
06225    
06226    SUMA_RETURN(C);
06227    
06228 }

float* SUMA_Convexity_Engine float *    NL,
int    N_N,
float *    NNL,
SUMA_NODE_FIRST_NEIGHB   FN,
char *    DetailFile
 

float * SUMA_Convexity_Engine (float *NL, int N_N, float *NNL, SUMA_NODE_FIRST_NEIGHB *FN, char *DetailFile) This function does the computations for SUMA_Convexity with the additional option of outputing detailed results to an ASCII file for debugging.

See documentation for SUMA_Convexity for all parameters except DetailFile

Parameters:
DetailFile  (char *) if not NULL, then you'll get an output file named by DetailFile with debugging info: i n d1 d1ij d1/d1ij .. dn dnij dn/dnij where i is node index n = FN->N_Neighb[i] d1 and d1ij are the distances (read the function for details... The matlab function ProcessConv_detail is used to parse the contents of DetailFile Make sure changes made to this file are reflected in that function. NOTE: Pre-existing files will get overwritten. MAY 06 04: The values are +ve for concave areas (i.e. fundus of sulcus) and negative for convex areas. This is counter to the name of the function and the user's expectation (want fundus to have lower value --> dark color). So to fix this injustice I changed the sign of C

Definition at line 6252 of file SUMA_MiscFunc.c.

References SUMA_NODE_FIRST_NEIGHB::FirstNeighb, i, ind, SUMA_NODE_FIRST_NEIGHB::N_Neighb, SUMA_NODE_FIRST_NEIGHB::N_Neighb_max, SUMA_calloc, SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_Convexity().

06253 {
06254    static char FuncName[]={"SUMA_Convexity_Engine"};
06255    float *C, d, D, dij;
06256    int i, j, jj, in, id, ind, ND;
06257    FILE *fid = NULL;
06258    
06259    SUMA_ENTRY;
06260 
06261    C = NULL;
06262    
06263    /* allocate for C */
06264    C = (float *)SUMA_calloc (N_N, sizeof(float));
06265    
06266    if (C == NULL) {
06267       fprintf (SUMA_STDERR,"Error %s: Could not allocate for C.\n", FuncName);
06268       SUMA_RETURN (C);
06269    }
06270    
06271 
06272    if (DetailFile) {
06273       fprintf (SUMA_STDERR,"%s:\nSaving convexity Info to %s.\n", FuncName, DetailFile);
06274       fid = fopen(DetailFile,"w");
06275    }
06276    
06277    ND = 3;
06278    for (i=0; i < N_N; ++i) {
06279       id = ND * i;
06280       /* 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
06281       NNL[id] NL[id]  + NNL[id+1] NNL[id+1]  + NNL[id+2] NL[id+2] + D = 0 */
06282       
06283       D = -NNL[id] * NL[id] - NNL[id+1] * NL[id+1] - NNL[id+2] * NL[id+2];
06284       
06285       if (DetailFile) fprintf(fid,"%d   %d   ", i, FN->N_Neighb[i]);
06286       
06287       for (j=0; j < FN->N_Neighb[i]; ++j) {
06288          /* find the distance between the neighboring node j and the tangent plane at i 
06289          d = (A X + B Y + C Z + D ) / (sqrt(A*A + B*B + C*C))
06290          denominator is norm of Normals which should be 1
06291          */
06292          in = FN->FirstNeighb[i][j];
06293          ind = in * ND;
06294          d = NNL[id] * NL[ind] + NNL[id+1] * NL[ind+1] + NNL[id+2] * NL[ind+2] + D ;
06295          
06296          /* calculate the distance between node i and it's neighbor */
06297          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]));
06298          
06299          /* assuming normals are normalized d is the cosine of the angle between the two vectors */
06300          /* if d > 0, then angle is > 0..90 degrees */
06301          
06302          /* as a measure of curvature, compute the sum of signed distances of negihbors to tangent plane at i.
06303          use distances normalized by length of segment ij to account for differences in segment length */
06304           
06305          C[i] -= d/dij; /* used to be C[i] += d/dij; prior to May 06 04 */
06306          
06307          if (DetailFile) fprintf(fid,"%f\t%f\t%f\t", d, dij, d/dij);
06308          
06309       }
06310       
06311       if (DetailFile) {
06312          /* fill with -1 until you reach FN->N_Neighb_max */
06313          for (jj=FN->N_Neighb[i]; jj < FN->N_Neighb_max; ++jj) fprintf(fid,"-1\t-1\t-1\t");
06314          fprintf(fid,"\n");
06315       }
06316    
06317    }
06318    
06319    if (DetailFile) fclose (fid);  /* close previous file */
06320    
06321    #if 0
06322    {
06323       /* Now write the results to disk just for debugging */
06324       fprintf(SUMA_STDOUT,"%s: Writing convexity to Conv.txt ...", FuncName);
06325       fid = fopen("Conv.txt","w");
06326       for (i=0; i < N_N; ++i) {
06327          fprintf(fid,"%f\n", C[i]);
06328       }
06329       fclose (fid);
06330       
06331       fprintf(SUMA_STDOUT,"%s: Done.\n", FuncName);
06332    }
06333    #endif
06334    
06335    SUMA_RETURN (C);
06336 } 

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 635 of file SUMA_MiscFunc.c.

References SUMA_IRGB::b, SUMA_IRGB::g, SUMA_IRGB::i, SUMA_IRGB::N, SUMA_IRGB::r, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_malloc, SUMA_RETURN, and SUMA_S_Crit.

Referenced by SUMA_Read_IRGB_file().

00636 {
00637    SUMA_IRGB *irgb=NULL;
00638    static char FuncName[]={"SUMA_Create_IRGB"};
00639    
00640    SUMA_ENTRY;
00641    
00642    irgb = (SUMA_IRGB *)SUMA_malloc(sizeof(SUMA_IRGB));
00643    
00644    
00645    irgb->i = (int *)SUMA_calloc(n_el, sizeof(int));
00646    irgb->r = (float*)SUMA_calloc(n_el, sizeof(float));
00647    irgb->g = (float*)SUMA_calloc(n_el, sizeof(float));
00648    irgb->b = (float*)SUMA_calloc(n_el, sizeof(float));
00649    irgb->N = n_el;
00650    if (!irgb->i || !irgb->r || !irgb->g || !irgb->b) {
00651       SUMA_S_Crit ("Failed to allocate for i, r, g and/or b.");
00652       if (irgb) SUMA_free(irgb);
00653       SUMA_RETURN (NULL);
00654    }
00655    
00656    SUMA_RETURN(irgb);
00657 }

SUMA_MEMTRACE_STRUCT* SUMA_Create_MemTrace void   
 

Definition at line 227 of file SUMA_MiscFunc.c.

References calloc, malloc, SUMA_MEMTRACE_STRUCT::N_alloc, SUMA_MEMTRACE_STRUCT::N_MaxPointers, SUMA_MEMTRACE_STRUCT::Pointers, SUMA_MEMTRACE_STRUCT::Size, SUMA_MEMTRACE_BLOCK, SUMA_RETURN, and SUMA_SL_Err.

Referenced by SUMA_Create_CommonFields().

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

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 1224 of file SUMA_MiscFunc.c.

References i, nc, nr, SUMA_ENTRY, SUMA_RETURNe, and v.

01225 {/*SUMA_disp_dmat*/
01226    char spc [40]; 
01227    int i,j;
01228    static char FuncName[]={"SUMA_disp_dmat"};
01229 
01230    SUMA_ENTRY;
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][j],spc);
01244          fprintf (SUMA_STDOUT,"\n");
01245       }
01246    SUMA_RETURNe;
01247 }/*SUMA_disp_dmat*/

void SUMA_disp_dvect int *    v,
int    l
 

Definition at line 1552 of file SUMA_MiscFunc.c.

References i, l, SUMA_ENTRY, SUMA_RETURNe, and v.

Referenced by SUMA_AssignTriBranch(), SUMA_ROIv2dataset(), and SUMA_ROIv2Grpdataset().

01553 {   int i;
01554    static char FuncName[]={"SUMA_disp_dvect"};
01555    
01556    SUMA_ENTRY;
01557 
01558    fprintf (SUMA_STDOUT,"\n");
01559    if ((l-1) == 0)
01560       fprintf (SUMA_STDOUT, "%d\n",*v);
01561    else 
01562    {
01563    for (i=0;i<l;++i)
01564       fprintf (SUMA_STDOUT,"%d\t",v[i]);
01565 
01566    fprintf (SUMA_STDOUT,"\n");
01567    }
01568    SUMA_RETURNe;
01569 }

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 1272 of file SUMA_MiscFunc.c.

References i, nc, nr, SUMA_ENTRY, SUMA_RETURNe, and v.

Referenced by SUMA_Read_Color_Map_1D(), and SUMA_Surface_Curvature().

01273 {/*SUMA_disp_mat*/
01274    char spc [40]; 
01275     int i,j;
01276    static char FuncName[]={"SUMA_disp_mat"};
01277       
01278    SUMA_ENTRY;
01279 
01280    if (!SpcOpt)
01281       sprintf(spc," ");
01282    else if (SpcOpt == 1)
01283       sprintf(spc,"\t");
01284    else
01285       sprintf(spc," , ");
01286    
01287    fprintf (SUMA_STDOUT,"\n");
01288    for (i=0; i < nr; ++i)
01289       {
01290          for (j=0; j < nc; ++j)
01291                fprintf (SUMA_STDOUT, "%4.2f%s",v[i][j],spc);
01292          fprintf (SUMA_STDOUT,"\n");
01293       }
01294    SUMA_RETURNe;
01295 }/*SUMA_disp_mat*/

void SUMA_disp_vecdmat int *    v,
int    nr,
int    nc,
int    SpcOpt,
SUMA_INDEXING_ORDER    d_order,
FILE *    fout,
SUMA_Boolean    AddRowInd
 

**

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, d_order, Out, AddRowInd)

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) d_order (SUMA_INDEXING_ORDER): Indicates how multiple values per node are stored in fin SUMA_ROW_MAJOR: The data in fin is stored in *** Row Major *** order. The ith value (start at 0) for node n is at index fin[vpn*n+i] SUMA_COLUMN_MAJOR: The data in fin is stored in *** Column Major *** order. The ith (start at 0) value for node n is at index fin[n+SO->N_Node*i]; etc... Out (FILE *) pointer to output file. If NULL then output is to stdout. AddRowInd (SUMA_Boolean) YUP = add the row index in the first column

See also:
SUMA_disp_vecucmat

Definition at line 1407 of file SUMA_MiscFunc.c.

References fout, i, nc, nr, SUMA_Boolean, SUMA_COLUMN_MAJOR, SUMA_ENTRY, SUMA_INDEXING_ORDER, SUMA_RETURNe, SUMA_ROW_MAJOR, SUMA_SL_Err, and v.

Referenced by SUMA_Pattie_Volume().

01409 {/*SUMA_disp_vecdmat*/
01410    char spc [40]; 
01411    int i,j;
01412    FILE *foutp;
01413    static char FuncName[]={"SUMA_disp_vectdmat"};
01414       
01415    SUMA_ENTRY;
01416 
01417    if (!fout) foutp = stdout;
01418    else foutp = fout;
01419    
01420    if (!SpcOpt)
01421       sprintf(spc," ");
01422    else if (SpcOpt == 1)
01423       sprintf(spc,"\t");
01424    else
01425       sprintf(spc," , ");
01426    
01427    if (!fout) fprintf (SUMA_STDOUT,"\n"); /* a blank 1st line when writing to screen */
01428    switch (d_order) {
01429       case SUMA_ROW_MAJOR:
01430          for (i=0; i < nr; ++i) {
01431             if (AddRowInd) fprintf (foutp, "%d%s", i, spc);
01432             for (j=0; j < nc; ++j) fprintf (foutp, "%d%s",v[i*nc+j],spc);
01433             fprintf (foutp,"\n");
01434          }
01435          break;
01436       case SUMA_COLUMN_MAJOR:
01437          for (i=0; i < nr; ++i) {
01438             if (AddRowInd) fprintf (foutp, "%d%s", i, spc);
01439             for (j=0; j < nc; ++j) fprintf (foutp, "%d%s",v[i+j*nr],spc);
01440             fprintf (foutp,"\n");
01441          }
01442          break;
01443       default:
01444          SUMA_SL_Err("Bad order.\n");
01445          SUMA_RETURNe;
01446          break;
01447    }
01448    SUMA_RETURNe;
01449 }/*SUMA_disp_vecdmat*/

void SUMA_disp_vecmat float *    v,
int    nr,
int    nc,
int    SpcOpt,
SUMA_INDEXING_ORDER    d_order,
FILE *    fout,
SUMA_Boolean    AddRowInd
 

**

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, d_order, Out )

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) d_order (SUMA_INDEXING_ORDER): Indicates how multiple values per node are stored in fin SUMA_ROW_MAJOR: The data in fin is stored in *** Row Major *** order. The ith value (start at 0) for node n is at index fin[vpn*n+i] SUMA_COLUMN_MAJOR: The data in fin is stored in *** Column Major *** order. The ith (start at 0) value for node n is at index fin[n+SO->N_Node*i]; etc... AddRowInd (SUMA_Boolean) YUP = add the row index in the first column Out (FILE *) pointer to output file. If NULL then output is to stdout.

Definition at line 1327 of file SUMA_MiscFunc.c.

References fout, i, LocalHead, nc, nr, SUMA_Boolean, SUMA_COLUMN_MAJOR, SUMA_ENTRY, SUMA_INDEXING_ORDER, SUMA_RETURNe, SUMA_ROW_MAJOR, SUMA_SL_Err, and v.

Referenced by SUMA_Pattie_Volume().

01329 {/*SUMA_disp_vecmat*/
01330    char spc [40]; 
01331    int i,j;
01332    FILE *foutp;
01333    static char FuncName[]={"SUMA_disp_vecmat"};
01334    SUMA_Boolean LocalHead = NOPE;
01335       
01336    SUMA_ENTRY;
01337 
01338    if (!fout) foutp = stdout;
01339    else foutp = fout;
01340    
01341    if (LocalHead) fprintf(SUMA_STDERR,"%s:\nExpecting to write %d rows/%d columns\n", FuncName, nr, nc);
01342    
01343    if (!SpcOpt)
01344       sprintf(spc," ");
01345    else if (SpcOpt == 1)
01346       sprintf(spc,"\t");
01347    else
01348       sprintf(spc," , ");
01349    
01350    if (!fout) fprintf (SUMA_STDOUT,"\n"); /* a blank 1st line when writing to screen */
01351    switch (d_order) {
01352       case SUMA_ROW_MAJOR:
01353          for (i=0; i < nr; ++i) {
01354             if (AddRowInd) fprintf (foutp, "%d%s", i, spc);
01355             for (j=0; j < nc; ++j) fprintf (foutp, "%f%s",v[i*nc+j],spc);
01356             fprintf (foutp,"\n");
01357          }
01358          break;
01359       case SUMA_COLUMN_MAJOR:
01360          for (i=0; i < nr; ++i) {
01361             if (AddRowInd) fprintf (foutp, "%d%s", i, spc);
01362             for (j=0; j < nc; ++j) fprintf (foutp, "%f%s",v[i+j*nr],spc);
01363             fprintf (foutp,"\n");
01364          }
01365          break;
01366       default:
01367          SUMA_SL_Err("Bad order.\n");
01368          SUMA_RETURNe;
01369          break;
01370    }
01371 
01372    SUMA_RETURNe;
01373 }/*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 1516 of file SUMA_MiscFunc.c.

References i, l, SUMA_ENTRY, SUMA_RETURNe, and v.

Referenced by SUMA_Chung_Smooth_Weights(), and SUMA_OpenDrawnROI_1D().

01517 { int i;
01518    static char FuncName[]={"SUMA_disp_vect"};
01519    
01520    SUMA_ENTRY;
01521 
01522    fprintf (SUMA_STDOUT,"\n");
01523    if ((l-1) == 0)
01524       fprintf (SUMA_STDOUT,"%f\n",*v);
01525    else 
01526    {
01527    for (i=0;i<l;++i)
01528                  fprintf (SUMA_STDOUT,"%f\t",v[i]);
01529    fprintf (SUMA_STDOUT,"\n");
01530    }
01531    SUMA_RETURNe;
01532 }

void SUMA_disp_vecucmat unsigned char *    v,
int    nr,
int    nc,
int    SpcOpt,
SUMA_INDEXING_ORDER    d_order,
FILE *    fout,
SUMA_Boolean    AddRowInd
 

same as SUMA_disp_vecdmat, except with unsigned char * instead of int *

Definition at line 1454 of file SUMA_MiscFunc.c.

References fout, i, nc, nr, SUMA_Boolean, SUMA_COLUMN_MAJOR, SUMA_ENTRY, SUMA_INDEXING_ORDER, SUMA_RETURNe, SUMA_ROW_MAJOR, SUMA_SL_Err, and v.

01456 {/*SUMA_disp_vecucmat*/
01457    char spc [40]; 
01458    int i,j;
01459    FILE *foutp;
01460    static char FuncName[]={"SUMA_disp_vecucmat"};
01461       
01462    SUMA_ENTRY;
01463 
01464    if (!fout) foutp = stdout;
01465    else foutp = fout;
01466    
01467    if (!SpcOpt)
01468       sprintf(spc," ");
01469    else if (SpcOpt == 1)
01470       sprintf(spc,"\t");
01471    else
01472       sprintf(spc," , ");
01473    
01474    if (!fout) fprintf (SUMA_STDOUT,"\n"); /* a blank 1st line when writing to screen */
01475    switch (d_order) {
01476       case SUMA_ROW_MAJOR:
01477          for (i=0; i < nr; ++i) {
01478             if (AddRowInd) fprintf (foutp, "%d%s", i, spc);
01479             for (j=0; j < nc; ++j) fprintf (foutp, "%d%s",v[i*nc+j],spc);
01480             fprintf (foutp,"\n");
01481          }
01482          break;
01483       case SUMA_COLUMN_MAJOR:
01484          for (i=0; i < nr; ++i) {
01485             if (AddRowInd) fprintf (foutp, "%d%s", i, spc);
01486             for (j=0; j < nc; ++j) fprintf (foutp, "%d%s",v[i+j*nr],spc);
01487             fprintf (foutp,"\n");
01488          }
01489          break;
01490       default:
01491          SUMA_SL_Err("Bad order.\n");
01492          SUMA_RETURNe;
01493          break;
01494    }
01495    SUMA_RETURNe;
01496 }/*SUMA_disp_vecucmat*/

double** SUMA_dPoint_At_Distance double *    U,
double *    P1,
double    d
 

Definition at line 2238 of file SUMA_MiscFunc.c.

References flip(), i, LocalHead, p, q, SUMA_allocate2D(), SUMA_Boolean, SUMA_DOTP_VEC, SUMA_ENTRY, SUMA_RETURN, and SUMA_SL_Warn.

02239 {/*SUMA_dPoint_At_Distance*/
02240    static char FuncName[]={"SUMA_dPoint_At_Distance"}; 
02241    double bf, **P2, P1orig[3], Uorig[3];
02242    double m, n, p, q, D, A, B, C, epsi = 0.000001;
02243    int flip, i;
02244    SUMA_Boolean LocalHead = NOPE;
02245    
02246    SUMA_ENTRY;
02247   
02248    SUMA_SL_Warn ("useless piece of junk, use SUMA_POINT_AT_DISTANCE instead!");
02249 
02250    if (d == 0) {
02251       fprintf(SUMA_STDERR,"Error %s: d is 0. Not good, Not good at all.\n", FuncName);
02252       SUMA_RETURN (NULL);
02253    }
02254    
02255    if (LocalHead) {
02256       fprintf (SUMA_STDOUT,"%s: U %f, %f, %f, P1 %f %f %f, d %f\n", FuncName,\
02257          U[0], U[1], U[2], P1[0], P1[1], P1[2], d);
02258    }
02259          
02260    /* store initial values */
02261    P1orig[0] = P1[0];    
02262    P1orig[1] = P1[1]; 
02263    P1orig[2] = P1[2]; 
02264 
02265    Uorig[0] = U[0];
02266    Uorig[1] = U[1];
02267    Uorig[2] = U[2];
02268    
02269    /* normalize U such that U(0) = 1 */
02270    flip = 0;
02271    if (fabs(U[0]) < epsi) { /* must flip X with some other coordinate */
02272       if (fabs(U[1]) > epsi) {/*U[1] != 0; */
02273          U[0] = U[1]; U[1] = 0;
02274          bf = P1[0]; P1[0] = P1[1]; P1[1] = bf;
02275          flip = 1;
02276       } else {   /*U[1] = 0; */
02277          if (fabs(U[2]) > epsi) { /* U[2] != 0 */
02278             U[0] = U[2]; U[2] = 0;
02279             bf = P1[0]; P1[0] = P1[2]; P1[2] = bf;
02280             flip = 2;
02281          } else { /* U[2] = 0 */
02282             fprintf(SUMA_STDERR, "Error %s: 0 direction vector.\n", FuncName);
02283             SUMA_RETURN (NULL);
02284          }
02285       }/*U[1] = 0; */
02286    }/*U[0] = 0; */
02287 
02288    if (LocalHead) fprintf (SUMA_STDERR, "%s: flip = %d\n", FuncName, flip);
02289       
02290    if (LocalHead) fprintf (SUMA_STDERR, "%s: U original: %f, %f, %f\n", FuncName, U[0], U[1], U[2]);
02291    U[1] /= U[0];
02292    U[2] /= U[0];
02293    U[0] = 1.0; 
02294    if (LocalHead) fprintf (SUMA_STDERR, "%s: U normalized: %f, %f, %f\n", FuncName, U[0], U[1], U[2]);
02295    
02296    /* Now U is clean, calculate P2 */   
02297    m = U[1];
02298    n = U[2];
02299 
02300    q = P1[1] - m*P1[0];
02301    p = P1[2] - n*P1[0];
02302 
02303    if (LocalHead) fprintf (SUMA_STDERR, "%s: m=%f n=%f, p=%f, q=%f\n", FuncName, m, n, p, q);
02304 
02305    /* Now find P2 */
02306    A = (1 + n*n + m*m);
02307    B = -2 * P1[0] + 2 * m * (q - P1[1]) + 2 * n * (p - P1[2]);
02308    C = P1[0]*P1[0] + (q - P1[1])*(q - P1[1]) + (p - P1[2])*(p - P1[2]) - d*d;
02309 
02310    D = B*B - 4*A*C;
02311    
02312    if (LocalHead) fprintf (SUMA_STDERR, "%s: A=%f B=%f, C=%f, D=%f\n", FuncName, A, B, C, D);
02313    
02314    if (D < 0) {
02315       fprintf(SUMA_STDERR, "Error %s: Negative Delta: %f.\n"
02316                            "Input values were: \n"
02317                            "U :[%f %f %f]\n"
02318                            "P1:[%f %f %f]\n"
02319                            "d :[%f]\n"
02320                            , FuncName, D, Uorig[0], Uorig[1], Uorig[2], 
02321                            P1orig[0], P1orig[1], P1orig[2], d);
02322       SUMA_RETURN(NULL);
02323    }
02324 
02325    P2 = (double **)SUMA_allocate2D(2,3, sizeof(double));
02326    if (P2 == NULL) {
02327       fprintf(SUMA_STDERR, "Error %s: Could not allocate for 6 floats! What is this? What is the matter with you?!\n", FuncName);
02328       SUMA_RETURN (NULL);
02329    }
02330 
02331    P2[0][0] = (-B + sqrt(D)) / (2 *A);
02332    P2[1][0] = (-B - sqrt(D)) / (2 *A);
02333 
02334    P2[0][1] = m * P2[0][0] + q;
02335    P2[1][1] = m * P2[1][0] + q;
02336 
02337    P2[0][2] = n * P2[0][0] + p;
02338    P2[1][2] = n * P2[1][0] + p;
02339 
02340 
02341    /* if flipping was performed, undo it */
02342    if (flip == 1) {
02343     for (i=0; i < 2; ++i) {
02344        bf = P2[i][1];
02345        P2[i][1] = P2[i][0];
02346        P2[i][0] = bf;
02347       }
02348    } else if (flip == 2){
02349     for (i=0; i < 2; ++i) {
02350        bf = P2[i][2]; 
02351        P2[i][2] = P2[i][0];
02352        P2[i][0] = bf;
02353       }
02354    }   
02355 
02356    for (i=0; i < 3; ++i) {
02357       P1[i] = P1orig[i];
02358       U[i] = Uorig[i];
02359    }
02360 
02361    if (LocalHead) {
02362       fprintf(SUMA_STDOUT,"%s: P1 = %f, %f, %f\n  ", \
02363        FuncName, P1[0], P1[1], P1[2]);
02364       fprintf(SUMA_STDOUT,"%s: P2 = %f, %f, %f\n    %f, %f, %f\n", \
02365        FuncName, P2[0][0], P2[0][1], P2[0][2], P2[1][0], P2[1][1], P2[1][2]);
02366       fprintf(SUMA_STDOUT,"%s: U = %f, %f, %f\n  ", \
02367        FuncName, U[0], U[1], U[2]);
02368    }
02369 
02370    
02371    /* make sure 1st point is along the same direction */
02372    Uorig[0] = P2[0][0] - P1[0]; /* use Uorig, not needed anymore */
02373    Uorig[1] = P2[0][1] - P1[1];
02374    Uorig[2] = P2[0][2] - P1[2];
02375 
02376    SUMA_DOTP_VEC(Uorig, U, bf, 3, double, double)
02377    if (LocalHead) fprintf(SUMA_STDOUT,"%s: Dot product = %f\n", FuncName, bf);
02378    if (bf < 0) {
02379       if (LocalHead) fprintf(SUMA_STDOUT,"%s: Flipping at end...\n", FuncName);
02380       for (i=0; i< 3; ++i) {
02381          bf = P2[0][i];
02382          P2[0][i] = P2[1][i]; P2[1][i] = bf;
02383       }
02384    }
02385    
02386    if (LocalHead) {
02387       fprintf(SUMA_STDOUT,"%s: P2 = %f, %f, %f\n    %f, %f, %f\n", \
02388        FuncName, P2[0][0], P2[0][1], P2[0][2], P2[1][0], P2[1][1], P2[1][2]);
02389    }
02390 SUMA_RETURN (P2);
02391    
02392 }/*SUMA_dPoint_At_Distance*/

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 2979 of file SUMA_MiscFunc.c.

References compare_SUMA_QSORTROW_INT(), SUMA_QSORTROW_INT::Index, nc, SUMA_QSORTROW_INT::ncol, nr, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_RETURN, and SUMA_QSORTROW_INT::x.

Referenced by SUMA_Make_Edge_List_eng().

02980 {/*SUMA_dqsortrow*/
02981    static char FuncName[]={"SUMA_dqsortrow"}; 
02982    int k,  *I;
02983    SUMA_QSORTROW_INT *Z_Q_dStrct;
02984    
02985    SUMA_ENTRY;
02986    
02987    /* allocate for the structure */
02988    Z_Q_dStrct = (SUMA_QSORTROW_INT *) SUMA_calloc(nr, sizeof (SUMA_QSORTROW_INT));
02989    I = (int *) SUMA_calloc (nr,sizeof(int));
02990    
02991    if (!Z_Q_dStrct || !I)
02992       {
02993       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for Z_Q_dStrct || I\n", FuncName);
02994       SUMA_RETURN (NULL);
02995       }
02996 
02997    for (k=0; k < nr; ++k) /* copy the data into a structure */
02998       {
02999          Z_Q_dStrct[k].x = X[k];
03000          Z_Q_dStrct[k].ncol = nc;
03001          Z_Q_dStrct[k].Index = k;
03002       }
03003 
03004    /* sort the structure by comparing the rows in X */
03005    qsort(Z_Q_dStrct, nr, sizeof(SUMA_QSORTROW_INT), (int(*) (const void *, const void *)) compare_SUMA_QSORTROW_INT);
03006 
03007    /* recover the index table */
03008    for (k=0; k < nr; ++k) 
03009       {
03010          X[k] = Z_Q_dStrct[k].x;
03011          I[k] = Z_Q_dStrct[k].Index;
03012       }
03013    
03014    /* free the structure */
03015    SUMA_free(Z_Q_dStrct);
03016 
03017    /* return */
03018    SUMA_RETURN (I);
03019    
03020    
03021 }/*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 1080 of file SUMA_MiscFunc.c.

References s2, SUMA_ENTRY, and SUMA_RETURNe.

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

01082  {
01083     static char FuncName[]={"SUMA_error_message"};
01084    
01085    SUMA_ENTRY;
01086 
01087    printf ("\n\n\aError: %s\n",s2);
01088    printf ("Error origin: %s\n\n",s1);
01089    if (ext == 1)
01090       {
01091         printf ("Exiting Program ..\n\n");
01092          exit (0);
01093       }
01094       else SUMA_RETURNe;
01095    
01096   }

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 1615 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

Referenced by calcWithOffsets(), main(), SUMA_BrushStrokeToNodeStroke(), SUMA_Dijkstra(), SUMA_Engine(), SUMA_EquateSurfaceSize(), SUMA_FindVoxelsInSurface(), SUMA_FindVoxelsInSurface_SLOW(), SUMA_FormNeighbOffset(), SUMA_GetM2M_NN(), SUMA_input(), SUMA_MarkLineSurfaceIntersect(), SUMA_Offset_GeomSmooth(), SUMA_ProjectSurfaceToSphere(), SUMA_SendToSuma(), and SUMA_Surf_Plane_Intersect().

01616 {/*SUMA_etime*/
01617    static char FuncName[]={"SUMA_etime"}; 
01618    struct  timeval  tn;
01619    float Time_Fact = 1000000.0;
01620    float delta_t;
01621 
01622    SUMA_ENTRY;
01623 
01624    /* get time */
01625    gettimeofday(&tn,0);
01626    
01627    if (Report)
01628       {
01629          delta_t = (((tn.tv_sec - t->tv_sec)*Time_Fact) + (tn.tv_usec - t->tv_usec)) /Time_Fact;
01630       }
01631    else
01632       {
01633          t->tv_sec = tn.tv_sec;
01634          t->tv_usec = tn.tv_usec;
01635          delta_t = 0.0;
01636       }
01637       
01638    SUMA_RETURN (delta_t);
01639    
01640 }/*SUMA_etime*/

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 4866 of file SUMA_MiscFunc.c.

References SUMA_FACESET_FIRST_EDGE_NEIGHB::FirstNeighb, i, i1, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb_max, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb_min, SUMA_allocate_FaceSet_Edge_Neighb(), SUMA_ENTRY, SUMA_MAX_FACESET_EDGE_NEIGHB, and SUMA_RETURN.

04867 {   
04868    static char FuncName[]={"SUMA_FaceSet_Edge_Neighb"};
04869    int i, i1, F0, F1, in0, in1;
04870    SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN;
04871    
04872    SUMA_ENTRY;
04873 
04874    
04875    SFFN = SUMA_allocate_FaceSet_Edge_Neighb(N_EL/3);
04876    if (SFFN == NULL) {
04877       fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_allocate_FaceSet_Edge_Neighb.\n", FuncName);
04878       SUMA_RETURN (NULL);
04879    }
04880    
04881    i = 0;
04882    while (i < N_EL-1) {
04883       i1 = i + 1;
04884       if (EL[i][0] != EL[i1][0] || EL[i][1] != EL[i1][1]) {
04885          /* edge is part of one triangle only, a cut edge */
04886          i += 1; /* move to next edge */
04887       } else {
04888          F0 = ELps[i][1]; F1 = ELps[i1][1];
04889          in0 = SFFN->N_Neighb[F0]; in1 = SFFN->N_Neighb[F1];
04890          if (in0 > SUMA_MAX_FACESET_EDGE_NEIGHB -1 || in1 > SUMA_MAX_FACESET_EDGE_NEIGHB -1) {
04891             fprintf (SUMA_STDERR, "Error %s: A faceset has more than three neighbors. Bad surface or non triangular mesh\n", FuncName);
04892             SUMA_RETURN (NULL);
04893          }
04894          SFFN->FirstNeighb[F0][in0] = F1; 
04895          SFFN->FirstNeighb[F1][in1] = F0;
04896          SFFN->N_Neighb[F0] ++;
04897          SFFN->N_Neighb[F1] ++;
04898          if (SFFN->N_Neighb[F0] > SFFN->N_Neighb_max) {
04899             SFFN->N_Neighb_max = SFFN->N_Neighb[F0];
04900          }
04901          if (SFFN->N_Neighb[F1] > SFFN->N_Neighb_max) {
04902             SFFN->N_Neighb_max = SFFN->N_Neighb[F1];
04903          }
04904          if (SFFN->N_Neighb[F0] < SFFN->N_Neighb_min) {
04905             SFFN->N_Neighb_min = SFFN->N_Neighb[F0];
04906          }
04907          if (SFFN->N_Neighb[F1] < SFFN->N_Neighb_min) {
04908             SFFN->N_Neighb_min = SFFN->N_Neighb[F1];
04909          }
04910          
04911          i += 2;
04912       }
04913    
04914    }
04915    
04916    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);
04917    #if 0
04918    for (i=0; i< N_FL; ++i) {
04919       fprintf (SUMA_STDERR, "%s: Tri %d, %d neighbs = ", FuncName, i, SFFN->N_Neighb[i]);
04920       for (i1=0; i1<SFFN->N_Neighb[i]; ++i1) {
04921          fprintf (SUMA_STDERR, "%d, ", SFFN->FirstNeighb[i][i1]); 
04922       }
04923       fprintf (SUMA_STDERR, "\n");
04924    }
04925    #endif
04926    
04927    SUMA_RETURN (SFFN);
04928 }   

char* SUMA_file_suck char *    fname,
int *    nread
 

Another version of SUMA_suck_file that hopes to avoid the silly error on OSX.

See also:
SUMA_suck_file

Definition at line 6814 of file SUMA_MiscFunc.c.

References close(), fd, read(), SUMA_ENTRY, SUMA_free, SUMA_malloc, SUMA_RETURN, and THD_filesize().

Referenced by SUMA_FreeSurfer_Read_eng().

06815 {
06816    static char FuncName[]={"SUMA_file_suck"};
06817    int  fd , ii = 0;
06818    unsigned long len; 
06819    char * buf = NULL;
06820 
06821    SUMA_ENTRY;
06822    
06823    *nread = 0;
06824    if( fname == NULL || fname[0] == '\0') SUMA_RETURN(0) ;
06825 
06826    len = THD_filesize( fname ) ;
06827    if( len <= 0 ) SUMA_RETURN(buf) ;
06828 
06829    buf = (char *) SUMA_malloc( sizeof(char) * (len+4) ) ;
06830    if( buf == NULL ) SUMA_RETURN(buf) ;
06831 
06832    fd = open( fname , O_RDONLY ) ;
06833    if( fd < 0 ) SUMA_RETURN(buf) ;
06834 
06835    ii = read( fd , buf , len ) ;
06836    close( fd ) ;
06837    if( ii <= 0 ){ SUMA_free(buf) ; buf = NULL; SUMA_RETURN(buf); }
06838    *nread = ii ; SUMA_RETURN(buf) ;
06839 }

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

Definition at line 6539 of file SUMA_MiscFunc.c.

References LocalHead, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_RETURN, and SUMA_SCALE_VEC.

06540 {/*SUMA_Find_inIntVect*/
06541    int k, *tmp, *ValLocation;
06542    static char FuncName[]={"SUMA_Find_inIntVect"};
06543    SUMA_Boolean LocalHead = NOPE;
06544    
06545    SUMA_ENTRY;
06546 
06547    /* allocate the maximum  space for ValLocation */
06548    tmp = (int *) SUMA_calloc(xsz,sizeof(int));
06549 
06550    *nValLocation = 0;
06551    for (k = 0 ; k < xsz ; ++k)
06552    {
06553       if (x[k] == val)
06554          {
06555             tmp[*nValLocation] = k;
06556             ++*nValLocation;
06557          }
06558 
06559    }
06560 
06561    if (!*nValLocation)
06562       {
06563          SUMA_free (tmp);
06564          SUMA_RETURN (NULL);
06565       }
06566 
06567    /* Now, allocate just enough space for the SUMA_RETURNing vector */
06568       ValLocation = (int *) SUMA_calloc(*nValLocation,sizeof(int));
06569    /*copy the data into ValLocation*/
06570       SUMA_SCALE_VEC(tmp,ValLocation,1,*nValLocation,int,int);
06571    /* get rid of big array */
06572       SUMA_free(tmp);
06573 
06574    SUMA_RETURN (ValLocation);
06575 
06576 }/*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 4671 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELloc, LocalHead, n1, n2, SUMA_EDGE_LIST::N_EL, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, and SUMA_S_Err.

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

04672 {
04673    static char FuncName[]={"SUMA_FindEdge"};
04674    int eloc;
04675    SUMA_Boolean LocalHead = NOPE;
04676    
04677    SUMA_ENTRY;
04678 
04679    /* make sure n1 is smallest*/
04680    if (n2 < n1) {
04681       eloc = n2; 
04682       n2 = n1; 
04683       n1 = eloc;
04684    }
04685    
04686    /* first location of edge starting with n1 */
04687    if ((eloc = EL->ELloc[n1]) < 0) {
04688       SUMA_S_Err ("Edge location of n1 not found. WEIRD");
04689       SUMA_RETURN (-1);
04690    }
04691    
04692    /* from there on, look for first occurence of n2 */
04693    do {
04694       /* if (LocalHead) fprintf (SUMA_STDERR,"%s: eloc %d, N_EL %d\n", FuncName, eloc, EL->N_EL);*/
04695       if (EL->EL[eloc][1] == n2) SUMA_RETURN (eloc);
04696       ++eloc;
04697    } while (eloc < EL->N_EL && EL->EL[eloc][0] == n1); 
04698    
04699    /* not found */
04700    SUMA_RETURN (-1);
04701 }

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 4634 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELloc, SUMA_EDGE_LIST::ELps, n1, n2, SUMA_EDGE_LIST::N_EL, SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_IntersectionStrip().

04635 {
04636    static char FuncName[]={"SUMA_FindEdgeInTri"};
04637    int eloc;
04638    
04639    SUMA_ENTRY;
04640 
04641    /* make sure n1 is smallest*/
04642    if (n2 < n1) {
04643       eloc = n2; 
04644       n2 = n1; 
04645       n1 = eloc;
04646    }
04647    
04648    /* first location of edge starting with n1 */
04649    eloc = EL->ELloc[n1];
04650    
04651    /* from there on, look for first occurence of n2 and Tri for hosting triangle*/
04652    do {
04653       if (EL->EL[eloc][1] == n2 && EL->ELps[eloc][1] == Tri) SUMA_RETURN (eloc);
04654       ++eloc;
04655    } while (eloc < EL->N_EL && EL->EL[eloc][0] == n1); 
04656    
04657    /* not found */
04658    SUMA_RETURN (-1);
04659 }

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 803 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_Load_Surface_Object_eng().

00804 { 
00805    int cnt=0,ex;
00806    float buf;
00807    static char FuncName[]={"SUMA_float_file_size"};
00808    FILE*internal_file;
00809    
00810    SUMA_ENTRY;
00811 
00812    internal_file = fopen (f_name,"r");
00813    if (internal_file == NULL) {
00814                           printf ("\aCould not open %s \n",f_name);
00815                           SUMA_RETURN (-1);
00816                           }
00817    ex = fscanf (internal_file,"%f",&buf);                     
00818    while (ex != EOF)
00819    {
00820      ++cnt;
00821      ex = fscanf (internal_file,"%f",&buf);
00822    }
00823 
00824 
00825    fclose (internal_file);
00826    SUMA_RETURN (cnt);                            
00827 }

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 2890 of file SUMA_MiscFunc.c.

References compare_SUMA_QSORTROW_FLOAT(), SUMA_QSORTROW_FLOAT::Index, nc, SUMA_QSORTROW_FLOAT::ncol, nr, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_RETURN, and SUMA_QSORTROW_FLOAT::x.

02891 {/*SUMA_fqsortrow*/
02892    static char FuncName[]={"SUMA_fqsortrow"}; 
02893    int k, *I;
02894    SUMA_QSORTROW_FLOAT *Z_Q_fStrct;
02895    
02896       
02897    SUMA_ENTRY;
02898 
02899    /* allocate for the structure */
02900    Z_Q_fStrct = (SUMA_QSORTROW_FLOAT *) SUMA_calloc(nr, sizeof (SUMA_QSORTROW_FLOAT));
02901    I = (int *) SUMA_calloc (nr,sizeof(int));
02902    
02903    if (!Z_Q_fStrct || !I)
02904       {
02905       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for Z_Q_fStrct || I\n", FuncName);
02906       SUMA_RETURN (NULL);
02907       }
02908 
02909    for (k=0; k < nr; ++k) /* copy the data into a structure */
02910       {
02911          Z_Q_fStrct[k].x = X[k];
02912          Z_Q_fStrct[k].ncol = nc;
02913          Z_Q_fStrct[k].Index = k;
02914       }
02915 
02916    /* sort the structure by comparing the rows in X */
02917    qsort(Z_Q_fStrct, nr, sizeof(SUMA_QSORTROW_FLOAT), (int(*) (const void *, const void *)) compare_SUMA_QSORTROW_FLOAT);
02918 
02919    /* recover the index table */
02920    for (k=0; k < nr; ++k) 
02921       {
02922          X[k] = Z_Q_fStrct[k].x;
02923          I[k] = Z_Q_fStrct[k].Index;
02924       }
02925    
02926    /* free the structure */
02927    SUMA_free(Z_Q_fStrct);
02928 
02929    /* return */
02930    SUMA_RETURN (I);
02931    
02932    
02933 }/*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 1007 of file SUMA_MiscFunc.c.

References a, free, i, SUMA_CommonFields::Mem, SUMA_CommonFields::MemTrace, SUMA_MEMTRACE_STRUCT::N_alloc, pause_mcw_malloc(), SUMA_MEMTRACE_STRUCT::Pointers, resume_mcw_malloc(), rows, SUMA_MEMTRACE_STRUCT::Size, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURNe, and SUMA_SL_Err.

Referenced by SUMA_ApplyAffine(), SUMA_Build_FirstNeighb(), SUMA_Engine(), SUMA_Free_ColorMap(), 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_GetStandardMap(), SUMA_input(), SUMA_Make_Edge_List_eng(), SUMA_MemberFaceSets(), SUMA_PolySurf3(), SUMA_ReleaseEngineData(), SUMA_Reposition_Touchup(), SUMA_ScaleToMap(), SUMA_ScaleToMap_alaAFNI(), and SUMA_Surface_Curvature().

01008 {
01009    int i;
01010    static char FuncName[]={"SUMA_free2D"};
01011    
01012    SUMA_ENTRY;
01013 
01014 
01015       #ifdef USE_SUMA_MALLOC
01016          SUMA_SL_Err("NO LONGER SUPPORTED");
01017          SUMA_RETURNe;
01018 
01019       #if SUMA_MEMTRACE_FLAG
01020          if (SUMAg_CF->MemTrace && a) {
01021             SUMA_Boolean Found = NOPE;
01022             for (i=0; i < SUMAg_CF->Mem->N_alloc && !Found; ++i) {
01023                if (SUMAg_CF->Mem->Pointers[i] == a) {
01024                   SUMAg_CF->Mem->Pointers[i] = SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1];
01025                   SUMAg_CF->Mem->Size[i] = SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1];
01026                   SUMAg_CF->Mem->Pointers[SUMAg_CF->Mem->N_alloc-1] = NULL;
01027                   SUMAg_CF->Mem->Size[SUMAg_CF->Mem->N_alloc-1] = 0;
01028                   --SUMAg_CF->Mem->N_alloc;
01029                   Found = YUP;
01030                }
01031             }
01032             if (!Found) {
01033               fprintf (SUMA_STDERR, "Error %s: Pointer %p not found in Mem struct. \n", FuncName,a); 
01034             }
01035          }
01036       #endif
01037       #else
01038          pause_mcw_malloc();
01039       #endif
01040       
01041    /* free each row of data */
01042    for(i = 0 ; i < rows ; i++) free(a[i]);
01043 
01044    /* free each row pointer */
01045    free((char *)a);
01046    a = NULL;           /* set to null for error */
01047 
01048    #ifdef USE_SUMA_MALLOC
01049       /* don't use ifndef, keep it parallel with stuff above */
01050       SUMA_SL_Err("NO LONGER SUPPORTED");
01051       SUMA_RETURNe;
01052 
01053    #else
01054       resume_mcw_malloc();
01055    #endif
01056    
01057    SUMA_RETURNe;
01058 }

void SUMA_free_Edge_List SUMA_EDGE_LIST   SEL
 

SUMA_free_Edge_List (SEL)

Parameters:
SEL  (SUMA_EDGE_LIST *)

Definition at line 4308 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELloc, SUMA_EDGE_LIST::ELps, SUMA_EDGE_LIST::idcode_str, SUMA_EDGE_LIST::N_EL, SUMA_EDGE_LIST::N_links, SUMA_ENTRY, SUMA_free, SUMA_free2D(), SUMA_RETURNe, SUMA_UnlinkFromPointer(), and SUMA_EDGE_LIST::Tri_limb.

Referenced by main(), SUMA_Free_Surface_Object(), SUMA_GetContour(), SUMA_LoadPrepInVol(), and SUMA_Make_Edge_List_eng().

04309 {
04310    static char FuncName[]={"SUMA_free_Edge_List"};
04311    
04312    SUMA_ENTRY;
04313    if (!SEL) SUMA_RETURNe;
04314    if (SEL->N_links) {
04315       SEL = (SUMA_EDGE_LIST*)SUMA_UnlinkFromPointer((void *)SEL);
04316       SUMA_RETURNe;
04317    }
04318    
04319    if (SEL->EL) SUMA_free2D((char **)SEL->EL, SEL->N_EL);
04320    if (SEL->ELloc) SUMA_free(SEL->ELloc);
04321    if (SEL->ELps) SUMA_free2D((char **)SEL->ELps, SEL->N_EL);
04322    if (SEL->Tri_limb) SUMA_free2D((char **)SEL->Tri_limb, SEL->N_EL/3);
04323    if (SEL->idcode_str) SUMA_free(SEL->idcode_str);
04324    if (SEL) SUMA_free(SEL);
04325    SUMA_RETURNe;
04326 }

void SUMA_free_FaceSet_Edge_Neighb SUMA_FACESET_FIRST_EDGE_NEIGHB   S
 

frees the dyamically allocated pointer of the type SUMA_FACESET_FIRST_EDGE_NEIGHB SUMA_free_FaceSet_Edge_Neighb (S)

Parameters:
S  (SUMA_FACESET_FIRST_EDGE_NEIGHB *)
See also:
SUMA_allocate_FaceSet_Edge_Neighb

Definition at line 4809 of file SUMA_MiscFunc.c.

References SUMA_FACESET_FIRST_EDGE_NEIGHB::FirstNeighb, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_FaceSet, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb, S, SUMA_ENTRY, SUMA_free, SUMA_free2D(), and SUMA_RETURNe.

04810 {
04811    static char FuncName[]={"SUMA_free_FaceSet_Edge_Neighb"};
04812    
04813    SUMA_ENTRY;
04814 
04815    if (S->FirstNeighb) SUMA_free2D((char **)S->FirstNeighb, S->N_FaceSet);
04816    if (S->N_Neighb) SUMA_free(S->N_Neighb);
04817    if (S) SUMA_free(S);
04818    SUMA_RETURNe;
04819 }

SUMA_Boolean SUMA_Free_FirstNeighb SUMA_NODE_FIRST_NEIGHB   FN
 

frees the Node Neighbor structure formed in SUMA_Build_FirstNeighb

Definition at line 5475 of file SUMA_MiscFunc.c.

References SUMA_NODE_FIRST_NEIGHB::FirstNeighb, SUMA_NODE_FIRST_NEIGHB::idcode_str, LocalHead, SUMA_NODE_FIRST_NEIGHB::N_links, SUMA_NODE_FIRST_NEIGHB::N_Neighb, SUMA_NODE_FIRST_NEIGHB::N_Node, SUMA_NODE_FIRST_NEIGHB::NodeId, SUMA_Boolean, SUMA_ENTRY, SUMA_free, SUMA_free2D(), SUMA_LH, SUMA_RETURN, and SUMA_UnlinkFromPointer().

Referenced by SUMA_Build_FirstNeighb(), and SUMA_Free_Surface_Object().

05476 {
05477    static char FuncName[]={"SUMA_Free_FirstNeighb"};
05478    SUMA_Boolean LocalHead = NOPE;
05479    
05480    SUMA_ENTRY;
05481    SUMA_LH("Entered");
05482    if (!FN) SUMA_RETURN(YUP);
05483 
05484    if (FN->N_links) {
05485       SUMA_LH("Just a link release");
05486       FN = (SUMA_NODE_FIRST_NEIGHB *)SUMA_UnlinkFromPointer((void *)FN);
05487       SUMA_RETURN (YUP);
05488    }
05489    
05490    /* no more links, go for it */
05491    SUMA_LH("No more links, here we go");
05492    if (FN->idcode_str) SUMA_free(FN->idcode_str); 
05493    if (FN->NodeId) SUMA_free(FN->NodeId);
05494    if (FN->N_Neighb) SUMA_free(FN->N_Neighb);
05495    if (FN->FirstNeighb) SUMA_free2D ((char **)FN->FirstNeighb, FN->N_Node);
05496    if (FN) SUMA_free(FN);
05497    SUMA_RETURN (YUP);
05498 }

void* SUMA_free_fn const char *    CF,
void *    ptr
 

Definition at line 212 of file SUMA_MiscFunc.c.

References free.

00213    {
00214       free(ptr);
00215       return (NULL);
00216    }

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 666 of file SUMA_MiscFunc.c.

References SUMA_IRGB::b, SUMA_IRGB::g, SUMA_IRGB::i, SUMA_IRGB::r, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

Referenced by SUMA_LoadColorPlaneFile().

00667 {
00668    static char FuncName[]={"SUMA_Free_IRGB"};
00669    
00670    SUMA_ENTRY;
00671    
00672    if (irgb) {
00673       if (irgb->i) SUMA_free(irgb->i);
00674       if (irgb->r) SUMA_free(irgb->r);
00675       if (irgb->g) SUMA_free(irgb->g);
00676       if (irgb->b) SUMA_free(irgb->b);
00677       SUMA_free(irgb);
00678    }
00679    
00680    SUMA_RETURN(NULL);
00681 }

SUMA_Boolean SUMA_Free_IsInBox SUMA_ISINBOX   IB
 

free SUMA_ISINBOX structure contents. Structure pointer is not freed

Definition at line 1943 of file SUMA_MiscFunc.c.

References SUMA_ISINBOX::d, SUMA_ISINBOX::IsIn, SUMA_ISINBOX::nIsIn, SUMA_Boolean, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

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

01944 {
01945    static char FuncName[]={"SUMA_Free_IsInBox"};
01946    
01947    SUMA_ENTRY;
01948 
01949    if (IB == NULL) {
01950       fprintf (SUMA_STDERR,"Error SUMA_Free_IsInBox: pointer to null cannot be freed\n");
01951       SUMA_RETURN (NOPE);
01952    }
01953    if (IB->IsIn != NULL) SUMA_free(IB->IsIn);
01954    if (IB->d != NULL) SUMA_free(IB->d);
01955    IB->nIsIn = 0;
01956    SUMA_RETURN (YUP);   
01957 }

SUMA_Boolean SUMA_Free_IsInSphere SUMA_ISINSPHERE   IB
 

free SUMA_ISINSPHERE structure contents. Structure pointer is not freed

Definition at line 1770 of file SUMA_MiscFunc.c.

References SUMA_ISINSPHERE::d, SUMA_ISINSPHERE::IsIn, SUMA_ISINSPHERE::nIsIn, SUMA_Boolean, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

Referenced by SUMA_LoadPrepInVol().

01771 {
01772    static char FuncName[]={"SUMA_Free_IsInSphere"};
01773    
01774    SUMA_ENTRY;
01775 
01776    if (IB == NULL) {
01777       fprintf (SUMA_STDERR,"Error SUMA_Free_IsInSphere: pointer to null cannot be freed\n");
01778       SUMA_RETURN (NOPE);
01779    }
01780    if (IB->IsIn != NULL) SUMA_free(IB->IsIn);
01781    if (IB->d != NULL) SUMA_free(IB->d);
01782    IB->nIsIn = 0;
01783    SUMA_RETURN (YUP);   
01784 }

SUMA_Boolean SUMA_Free_MemTrace SUMA_MEMTRACE_STRUCT   Mem
 

Definition at line 413 of file SUMA_MiscFunc.c.

References free, SUMA_MEMTRACE_STRUCT::Pointers, SUMA_MEMTRACE_STRUCT::Size, SUMA_Boolean, and SUMA_SL_Err.

Referenced by SUMA_Free_CommonFields().

00413                                                              {
00414    static char FuncName[]={"SUMA_Free_MemTrace"};
00415          
00416    #ifdef USE_SUMA_MALLOC
00417    SUMA_SL_Err("NO LONGER SUPPORTED");
00418    return(NOPE);
00419    /* DO NOT USE SUMA_free function here ! */
00420    if (Mem->Pointers) free (Mem->Pointers);
00421    if (Mem->Size) free(Mem->Size);
00422    if (Mem) free (Mem);
00423    #endif
00424    return(YUP);
00425 }

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 3656 of file SUMA_MiscFunc.c.

References SUMA_MT_INTERSECT_TRIANGLE::isHit, SUMA_ENTRY, SUMA_free, SUMA_RETURN, SUMA_MT_INTERSECT_TRIANGLE::t, SUMA_MT_INTERSECT_TRIANGLE::u, and SUMA_MT_INTERSECT_TRIANGLE::v.

Referenced by main(), SUMA_BrushStrokeToNodeStroke(), SUMA_FindVoxelsInSurface(), SUMA_FindVoxelsInSurface_SLOW(), SUMA_GetM2M_NN(), SUMA_inNodeNeighb(), SUMA_isSelfIntersect(), SUMA_MapSurface(), SUMA_MarkLineSurfaceIntersect(), SUMA_MT_intersect_triangle(), and SUMA_SurfGridIntersect().

03657 {
03658    static char FuncName[]={"SUMA_Free_MT_intersect_triangle"};
03659    
03660    SUMA_ENTRY;
03661 
03662    if (MTI->t) SUMA_free(MTI->t);
03663    if (MTI->u) SUMA_free(MTI->u);
03664    if (MTI->v) SUMA_free(MTI->v);
03665    if (MTI->isHit) SUMA_free(MTI->isHit);
03666    if (MTI) SUMA_free(MTI);
03667    SUMA_RETURN(NULL);
03668 }

void SUMA_Free_SURFACE_CURVATURE SUMA_SURFACE_CURVATURE   SC
 

free the SUMA_SURFACE_CURVATURE structure

Definition at line 6085 of file SUMA_MiscFunc.c.

References SUMA_SURFACE_CURVATURE::Kp1, SUMA_SURFACE_CURVATURE::Kp2, SUMA_SURFACE_CURVATURE::N_Node, SUMA_ENTRY, SUMA_free, SUMA_free2D(), SUMA_RETURNe, SUMA_SURFACE_CURVATURE::T1, and SUMA_SURFACE_CURVATURE::T2.

Referenced by SUMA_Free_Surface_Object(), and SUMA_Surface_Curvature().

06086 {
06087    static char FuncName[]={"SUMA_Free_SURFACE_CURVATURE"};
06088    
06089    SUMA_ENTRY;
06090 
06091    if (SC == NULL) SUMA_RETURNe;
06092    if (SC->Kp1) SUMA_free(SC->Kp1);
06093    if (SC->Kp2) SUMA_free(SC->Kp2);
06094    if (SC->T1) SUMA_free2D ((char **)SC->T1, SC->N_Node);
06095    if (SC->T2) SUMA_free2D ((char **)SC->T2, SC->N_Node);
06096    if (SC) SUMA_free(SC);
06097    SUMA_RETURNe;
06098 }

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 3687 of file SUMA_MiscFunc.c.

References i, SUMA_Boolean, SUMA_ENTRY, SUMA_EPSILON, SUMA_MT_CROSS, SUMA_MT_DOT, SUMA_RETURN, v, and v1.

Referenced by SUMA_Engine().

03688 {/* SUMA_FromToRotation */
03689    static char FuncName[]={"SUMA_FromToRotation"};
03690    float v[3], vn;
03691    float e, h, f;
03692 
03693    SUMA_ENTRY;
03694 
03695    /*normalize both vectors */
03696    vn = sqrt(v0[0]*v0[0] + v0[1]*v0[1] + v0[2]*v0[2]);
03697    if (vn == 0.0) {
03698       fprintf(SUMA_STDERR,"Error %s: v0 is null.\n",FuncName);
03699       SUMA_RETURN (NOPE);
03700    }
03701    v0[0] /= vn;
03702    v0[1] /= vn;
03703    v0[2] /= vn;
03704 
03705    vn = sqrt(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]);
03706    if (vn == 0.0) {
03707       fprintf(SUMA_STDERR,"Error %s: v1 is null.\n",FuncName);
03708       SUMA_RETURN (NOPE);
03709    }
03710    v1[0] /= vn;
03711    v1[1] /= vn;
03712    v1[2] /= vn;
03713 
03714    SUMA_MT_CROSS(v, v0, v1);
03715    e = SUMA_MT_DOT(v0, v1);
03716    f = (e < 0)? -e:e;
03717    if (f > 1.0 - SUMA_EPSILON)     /* "v0" and "v1"-vector almost parallel */
03718    {
03719       float u[3], v[3]; /* temporary storage vectors */
03720       float x[3];       /* vector most nearly orthogonal v1 "v0" */
03721       float c1, c2, c3; /* coefficients for later use */
03722       int i, j;
03723 
03724       x[0] = (v0[0] > 0.0)? v0[0] : -v0[0];
03725       x[1] = (v0[1] > 0.0)? v0[1] : -v0[1];
03726       x[2] = (v0[2] > 0.0)? v0[2] : -v0[2];
03727 
03728       if (x[0] < x[1]) 
03729       {
03730          if (x[0] < x[2]) 
03731          {
03732            x[0] = 1.0; x[1] = x[2] = 0.0;
03733          }
03734          else 
03735          {
03736            x[2] = 1.0; x[0] = x[1] = 0.0;
03737          }
03738       }
03739       else 
03740       {
03741          if (x[1] < x[2]) 
03742          {
03743            x[1] = 1.0; x[0] = x[2] = 0.0;
03744          }
03745          else 
03746          {
03747            x[2] = 1.0; x[0] = x[1] = 0.0;
03748          }
03749       }
03750 
03751       u[0] = x[0] - v0[0]; u[1] = x[1] - v0[1]; u[2] = x[2] - v0[2];
03752       v[0] = x[0] - v1[0];   v[1] = x[1] - v1[1];   v[2] = x[2] - v1[2];
03753 
03754       c1 = 2.0 / SUMA_MT_DOT(u, u);
03755       c2 = 2.0 / SUMA_MT_DOT(v, v);
03756       c3 = c1 * c2  * SUMA_MT_DOT(u, v);
03757 
03758       for (i = 0; i < 3; i++) {
03759          for (j = 0; j < 3; j++) {
03760            mtx[i][j] =  - c1 * u[i] * u[j]
03761                         - c2 * v[i] * v[j]
03762                         + c3 * v[i] * u[j];
03763          }
03764          mtx[i][i] += 1.0;
03765       }
03766    }
03767    else  /* the most common case, unless "v0"="v1", or "v0"=-"v1" */
03768    {
03769       #if 0
03770          /* unoptimized version - a good compiler will optimize this. */
03771          h = (1.0 - e)/SUMA_MT_DOT(v, v);
03772          mtx[0][0] = e + h * v[0] * v[0];  
03773          mtx[0][1] = h * v[0] * v[1] - v[2]; 
03774          mtx[0][2] = h * v[0] * v[2] + v[1];
03775 
03776          mtx[1][0] = h * v[0] * v[1] + v[2]; 
03777          mtx[1][1] = e + h * v[1] * v[1];    
03778          mtx[1][2] = h * v[1] * v[2] - v[0];
03779 
03780          mtx[2][0] = h * v[0] * v[2] - v[1]; 
03781          mtx[2][1] = h * v[1] * v[2] + v[0]; 
03782          mtx[2][2] = e + h * v[2] * v[2];
03783       #else
03784          /* ...otherwise use this hand optimized version (9 mults less) */
03785          float hvx, hvz, hvxy, hvxz, hvyz;
03786          h = (1.0 - e)/SUMA_MT_DOT(v, v);
03787          hvx = h * v[0];
03788          hvz = h * v[2];
03789          hvxy = hvx * v[1];
03790          hvxz = hvx * v[2];
03791          hvyz = hvz * v[1];
03792          mtx[0][0] = e + hvx * v[0]; 
03793          mtx[0][1] = hvxy - v[2];     
03794          mtx[0][2] = hvxz + v[1];
03795 
03796          mtx[1][0] = hvxy + v[2];  
03797          mtx[1][1] = e + h * v[1] * v[1]; 
03798          mtx[1][2] = hvyz - v[0];
03799 
03800          mtx[2][0] = hvxz - v[1];  
03801          mtx[2][1] = hvyz + v[0];     
03802          mtx[2][2] = e + hvz * v[2];
03803       #endif
03804    }   
03805    
03806    mtx[0][3] = 0.0;
03807    mtx[1][3] = 0.0;
03808    mtx[2][3] = 0.0;
03809    mtx[3][0] = 0.0;
03810    mtx[3][1] = 0.0;
03811    mtx[3][2] = 0.0;
03812    mtx[3][3] = 1.0;
03813    SUMA_RETURN (YUP);
03814 }

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

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

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
IOtrace  (int) if 1 then allows the use of SUMA_ENTRY and SUMA_RETURN \ret ans (SUMA_Boolean) YUP/NOPE
See also:
SUMA_Make_Edge_List , SUMA_Get_NodeIncident

Definition at line 4763 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELloc, SUMA_EDGE_LIST::ELps, n1, n2, SUMA_EDGE_LIST::N_EL, SUMA_Boolean, SUMA_ENTRY, and SUMA_RETURN.

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

04764 {
04765    static char FuncName[] = {"SUMA_Get_Incident"};
04766    int nt, in1, iseek, m_N_EL;
04767    
04768    if (IOtrace) SUMA_ENTRY;
04769 
04770    /*fprintf(SUMA_STDERR,"Entering %s: n1,n2 =%d,%d ...", FuncName,n1,n2);*/
04771    if (n1 > n2) {
04772       /*make the first node be the smallest */
04773       nt = n1;
04774       n1 = n2;
04775       n2 = nt;
04776    }
04777    
04778    /* find the location of the first edge with n1 */
04779    in1 = SEL->ELloc[n1];
04780    iseek = in1;
04781    m_N_EL = SEL->N_EL -1;
04782    *N_Incident = 0;
04783    while (SEL->EL[iseek][0] == n1) {
04784       if (SEL->EL[iseek][1] == n2) {
04785          Incident[*N_Incident] = SEL->ELps[iseek][1]; /* store the faceset index containing the edge */
04786          *N_Incident = *N_Incident + 1;
04787       }
04788       ++iseek;
04789       if (iseek > m_N_EL) {
04790          if (!*N_Incident) fprintf(SUMA_STDERR,"Warning %s: No Incident FaceSets found!\n", FuncName);
04791          if (IOtrace) { SUMA_RETURN (YUP); }
04792          else return(YUP);
04793       }
04794       
04795    }
04796    if (!*N_Incident) fprintf(SUMA_STDERR,"Warning %s: No Incident FaceSets found!\n", FuncName);
04797    /*fprintf(SUMA_STDERR,"Leaving %s.\n", FuncName);*/
04798    if (IOtrace) { SUMA_RETURN(YUP); }
04799    else return(YUP);   
04800 }

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 4717 of file SUMA_MiscFunc.c.

References SUMA_SurfaceObject::EL, SUMA_NODE_FIRST_NEIGHB::FirstNeighb, SUMA_SurfaceObject::FN, i, n1, SUMA_NODE_FIRST_NEIGHB::N_Neighb, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, and SUMA_whichTri().

Referenced by SUMA_Find_IminImax_Avg().

04718 {
04719    static char FuncName[] = {"SUMA_Get_NodeIncident"};
04720    int i, n3, N_Neighb;
04721    
04722    SUMA_ENTRY;
04723    
04724    *N_Incident = 0;
04725    
04726    N_Neighb = SO->FN->N_Neighb[n1];
04727    if (N_Neighb < 3) {
04728       fprintf (SUMA_STDERR, "Warning %s: Node %d has less than 3 neighbors.\n", FuncName, n1);
04729       /* nothing found */
04730       SUMA_RETURN(YUP);
04731    }
04732    
04733    i = 0;
04734    while ((i < N_Neighb )) { 
04735       if ( i+1 == N_Neighb) n3 = SO->FN->FirstNeighb[n1][0];
04736       else n3 = SO->FN->FirstNeighb[n1][i+1];
04737       if ((Incident[*N_Incident] = SUMA_whichTri (SO->EL, n1, SO->FN->FirstNeighb[n1][i], n3, 1)) < 0) {
04738          fprintf (SUMA_STDERR, "Error %s: Triangle formed by nodes %d %d %d not found.\n", 
04739             FuncName, n1, SO->FN->FirstNeighb[n1][i], n3);
04740          SUMA_RETURN(NOPE);
04741       }
04742       ++*N_Incident;
04743       ++i;
04744    }
04745 
04746    SUMA_RETURN(YUP);   
04747 }

SUMA_Boolean SUMA_Householder float *    Ni,
float **    Q
 

Definition at line 6116 of file SUMA_MiscFunc.c.

References Ni, SUMA_Boolean, SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_Surface_Curvature().

06117 {
06118    static char FuncName[] = {"SUMA_Householder"};
06119    float mNi, e[3], b[3], mb;
06120    int ii;
06121    #ifdef TAUBIN_Householder
06122    float d[3], s[3], nd, ns;
06123    #endif
06124 
06125    SUMA_ENTRY;
06126    
06127    e[0] = 1.0; e[1] = 0.0; e[2] = 0.0;
06128    
06129    #ifndef TAUBIN_Householder
06130       /* generic algorithm */
06131       mNi = sqrt(Ni[0] * Ni[0] + Ni[1] * Ni[1] + Ni[2] * Ni[2]);
06132       for (ii=0; ii < 3; ++ii) 
06133          b[ii] = Ni[ii] + mNi * e[ii];
06134       mb = sqrt(b[0] * b[0] + b[1] * b[1] + b[2] * b[2]);
06135 
06136       if (mb == 0) {
06137          fprintf (SUMA_STDERR,"Error %s: mb = 0\n",FuncName);
06138          SUMA_RETURN (NOPE);
06139       }
06140 
06141       b[0] /= mb; b[1] /= mb; b[2] /= mb;
06142    #else
06143       /* Taubin's algorithm Estimating the tensor of curvature of a surface from a polyhedral approximation */ 
06144       /* calculate difference and sum vectors with their norms (save sqrt for later) */
06145       
06146       d[0] = e[0] - Ni[0]; d[1] = e[1] - Ni[1]; d[2] = e[2] - Ni[2]; 
06147       nd = d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
06148       
06149       s[0] = e[0] + Ni[0]; s[1] = e[1] + Ni[1]; s[2] = e[2] + Ni[2];
06150       ns = s[0]*s[0] + s[1]*s[1] + s[2]*s[2];
06151       
06152       if (!nd || !ns) {
06153          fprintf (SUMA_STDERR,"Error %s: nd || ns = 0\n",FuncName);
06154          SUMA_RETURN (NOPE);
06155       }
06156       
06157       if (nd > ns) {
06158          nd = sqrt(nd);
06159          b[0] = d[0] / nd;
06160          b[1] = d[1] / nd;
06161          b[2] = d[2] / nd;
06162          /*Q(:,1) will be equal to -Ni*/
06163          
06164       } else {
06165          ns = sqrt(ns);
06166          b[0] = s[0] / ns;
06167          b[1] = s[1] / ns;
06168          b[2] = s[2] / ns;
06169          /*Q(:,1) will be equal to  Ni */
06170       }
06171       
06172    #endif 
06173    
06174    /* calc Q = I - 2 b * b' */
06175    Q[0][0] = 1 - 2 * b[0] * b[0];
06176    Q[1][0] = - 2 * b[1] * b[0];
06177    Q[2][0] = - 2 * b[2] * b[0];
06178 
06179    Q[0][1] = - 2 * b[0] * b[1];
06180    Q[1][1] = 1 - 2 * b[1] * b[1];
06181    Q[2][1] = - 2 * b[2] * b[1];
06182 
06183    Q[0][2] = - 2 * b[0] * b[2];
06184    Q[1][2] = - 2 * b[1] * b[2];
06185    Q[2][2] = 1 - 2 * b[2] * b[2];
06186 
06187    SUMA_RETURN (YUP);   
06188 }

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 3969 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_Take_A_Hike().

03970 {
03971    static char FuncName[]={"SUMA_isConsistent"};
03972    static int ic, in, LOC[2], loc[2], d, D;
03973    
03974    SUMA_ENTRY;
03975 
03976    ic = 0;   /* common node index*/
03977    in = 0; /* number of node searched in T */
03978    while (ic < 2 && in < 3) {
03979       if (t[0] == T[in]) {
03980          LOC[ic] = in; /* location of icth node in 1st triangle */
03981          loc[ic] = 0; /* location of icth node in 2nt triangle */
03982          ++ic;
03983       }else {
03984          if (t[1] == T[in]) {
03985             LOC[ic] = in; /* location of icth node in 1st triangle */
03986             loc[ic] = 1; /* location of icth node in 2nt triangle */
03987             ++ic;
03988          }else {
03989             if (t[2] == T[in]) {
03990                LOC[ic] = in; /* location of icth node in 1st triangle */
03991                loc[ic] = 2; /* location of icth node in 2nt triangle */
03992                ++ic;
03993             }
03994          }
03995       }
03996       ++in; /* look for next node */
03997    }
03998    if (ic != 2) {
03999       fprintf(SUMA_STDERR,"Error %s: Triangles do not share 2 nodes.\n", FuncName);
04000       SUMA_RETURN (0);
04001    }
04002    
04003    D = (LOC[1]-LOC[0]);
04004    d = (loc[1]-loc[0]);
04005    /*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]);
04006    fprintf(SUMA_STDERR,"%s: LOC[0,1]=[%d, %d], loc[0,1] = [%d, %d]\n", FuncName, LOC[0], LOC[1], loc[0], loc[1]);
04007    fprintf(SUMA_STDERR,"%s: D = %d, d = %d\n", FuncName, D, d);*/   
04008    if (d > 1 || d < -1) d = - d /2 ;
04009    if (D > 1 || D < -1) D = - D /2 ;
04010    /*fprintf(SUMA_STDERR,"%s: D = %d, d = %d\n", FuncName, D, d);*/   
04011 
04012    if (d != D) {
04013       /*fprintf(SUMA_STDERR,"%s: Triangles consistent.\n", FuncName);*/
04014       SUMA_RETURN (1);
04015    }
04016    
04017       
04018    /*fprintf(SUMA_STDERR,"%s: Triangles NOT consistent.\n", FuncName);*/
04019    in = t[0];
04020    t[0] = t[2];
04021    t[2] = in;
04022    SUMA_RETURN (-1);
04023 }

SUMA_ISINBOX SUMA_isinbox float *    XYZ,
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 1828 of file SUMA_MiscFunc.c.

References SUMA_ISINBOX::d, SUMA_ISINBOX::IsIn, SUMA_ISINBOX::nIsIn, nr, SUMA_alloc_problem(), SUMA_calloc, SUMA_COPY_VEC, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

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

01829 {/*SUMA_isinbox*/
01830    
01831    static char FuncName[]={"SUMA_isinbox"}; 
01832    float t0, t1, t2, hdim0, hdim1, hdim2, *d;
01833    int k , *IsIn, id, ND;
01834    SUMA_ISINBOX IsIn_strct;
01835 
01836    SUMA_ENTRY;
01837    
01838    ND = 3;
01839    /*
01840    fprintf(SUMA_STDOUT,"%f %f %f, %f %f %f, %d, %f, %f, %f\n",\
01841       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]);
01842    */
01843       
01844    IsIn_strct.nIsIn = 0;   
01845 
01846    hdim0 = S_dim[0]/2;
01847    hdim1 = S_dim[1]/2;
01848    hdim2 = S_dim[2]/2;
01849    
01850    IsIn = (int *) SUMA_calloc (nr, sizeof(int));
01851    d = (float *)SUMA_calloc(nr, sizeof(float));
01852    
01853    if (!IsIn || !d)
01854       {
01855          SUMA_alloc_problem (FuncName);
01856          SUMA_RETURN (IsIn_strct);
01857       }
01858 
01859    if (BoundIn) /* split into two to avoid checking for this condition all the time */
01860       {
01861          /*fprintf(SUMA_STDERR,"%s: inbound\n", FuncName);*/
01862          for (k=0; k < nr; ++k)
01863             {
01864             /*fprintf(SUMA_STDERR,"%s: inbound %d\n", FuncName, k);*/
01865             /* relative distance to center */
01866                id = ND * k;
01867                t0 = hdim0 - fabs(XYZ[id] - S_cent[0]);   
01868                
01869                if (t0 >= 0) {
01870                   t1 = hdim1 - fabs(XYZ[id+1] - S_cent[1]);   
01871                   if (t1 >= 0) {
01872                      t2 = hdim2 - fabs(XYZ[id+2] - S_cent[2]);   
01873                      if (t2 >= 0)
01874                         {
01875                            IsIn[IsIn_strct.nIsIn] = k;
01876                            d[IsIn_strct.nIsIn] = sqrt(t0*t0+t1*t1+t2*t2);
01877                            ++(IsIn_strct.nIsIn);
01878                         }
01879                   }
01880                }
01881             }         
01882             /*fprintf(SUMA_STDERR,"%s: outbound\n", FuncName);*/
01883 
01884       }
01885    else
01886       {
01887          for (k=0; k < nr; ++k)
01888             {
01889                /* relative distance to center */
01890                id = ND * k;
01891                t0 = hdim0 - fabs(XYZ[id] - S_cent[0]);   
01892                
01893                if (t0 > 0) {
01894                   t1 = hdim1 - fabs(XYZ[id+1] - S_cent[1]);   
01895                   if (t1 > 0) {
01896                      t2 = hdim2 - fabs(XYZ[id+2] - S_cent[2]);   
01897                      if (t2 > 0)
01898                         {
01899                            IsIn[IsIn_strct.nIsIn] = k;
01900                            d[IsIn_strct.nIsIn] = sqrt(t0*t0+t1*t1+t2*t2);
01901                            ++(IsIn_strct.nIsIn);
01902                         }
01903                   }
01904                }
01905             }
01906       }
01907    
01908    if (IsIn_strct.nIsIn) {
01909       /*fprintf(SUMA_STDERR,"%s: SUMA_realloc\n", FuncName);*/
01910 
01911       /* get ridd of extra allocation space*/
01912       IsIn_strct.IsIn = (int *) SUMA_calloc (IsIn_strct.nIsIn, sizeof(int));
01913       IsIn_strct.d = (float *)SUMA_calloc(IsIn_strct.nIsIn, sizeof(float));
01914 
01915       if (!IsIn_strct.IsIn || !IsIn_strct.d)
01916          {
01917             IsIn_strct.nIsIn = 0;
01918             SUMA_alloc_problem(FuncName);
01919             SUMA_RETURN (IsIn_strct);
01920          }
01921 
01922       SUMA_COPY_VEC (IsIn, IsIn_strct.IsIn , IsIn_strct.nIsIn, int , int);
01923       SUMA_COPY_VEC (d, IsIn_strct.d, IsIn_strct.nIsIn, float, float);
01924    } else {
01925       /*fprintf(SUMA_STDERR,"%s: NADA\n", FuncName);*/
01926       IsIn_strct.IsIn = NULL;
01927       IsIn_strct.d = NULL;
01928    }
01929    
01930    /*fprintf(SUMA_STDERR,"%s: freeing\n", FuncName);*/
01931    SUMA_free(IsIn);
01932    SUMA_free(d);
01933    /*fprintf(SUMA_STDERR,"%s: freed\n", FuncName);*/
01934 
01935    SUMA_RETURN (IsIn_strct) ;
01936 
01937 }/*SUMA_isinbox*/

byte* SUMA_isinpoly float *    P,
float *    NodeList,
int *    FaceSetList,
int    N_FaceSet,
int    FaceSetDim,
int *    dims,
int *    N_in,
byte   usethis,
byte   culled
 

Determines is a point in 2D is inside a polygon with no holes. The function's parameters are abit strange because of the intended use.

Parameters:
P  (float *) 3x1 vector containing XYZ of the point to test
NodeList  (float *) the proverbial nodelist xyz xyz xyz etc.
FaceSetList  (int *) the proverbial FaceSetList defining polygons
N_FaceSet  (int) number of polygons in each list
FaceSetDim  (int) number of points forming polygon
dims  (int) 2x1 vector indicating which dimensions to consider. Recall this a 2D inclusion function! For example, if dims = [ 0 1] then the z coordinate (2) is not considered if dims = [ 0 2] then the y coordinate (1) is not considered if dims = [ 2 1] then the x coordinate (0) is not considered
ams N_in (int *) to contain the number of polygons that contain p
Parameters:
usethis  (byte *) use this vector to store results (see return param)
Returns:
isin (byte *) if isin[iv] the point P is in polygon iv
core based on code by Paul Bourke, see copyright notice in suma -sources Does not work for polys with holes

Definition at line 1981 of file SUMA_MiscFunc.c.

References i, LocalHead, p, SUMA_Boolean, SUMA_ENTRY, SUMA_malloc, SUMA_MAX_PAIR, SUMA_MIN_PAIR, SUMA_RETURN, SUMA_SL_Crit, and SUMA_SL_Err.

Referenced by SUMA_FindVoxelsInSurface_SLOW().

01982 {
01983    static char FuncName[]={"SUMA_isinpoly"};
01984    byte *isin=NULL;
01985    int iv, i, ip, counter, ni;
01986    double xinters;
01987    float p1[2], p2[2], p[2], poly[300];
01988    SUMA_Boolean LocalHead = NOPE;
01989    
01990    SUMA_ENTRY;
01991    
01992    *N_in = 0;
01993    if (!usethis) {
01994       isin = (byte *)SUMA_malloc(sizeof(byte)*N_FaceSet);
01995       if (!isin) {
01996          SUMA_SL_Crit("Failed to allocate!");
01997          SUMA_RETURN(NOPE);
01998       }
01999    } else isin = usethis;
02000    if (FaceSetDim > 99) {
02001       SUMA_SL_Err("max FaceSetDim = 99");
02002       SUMA_RETURN(NULL);
02003    }
02004    if (dims[0] < 0 || dims[0] > 2 || dims[1] < 0 || dims[1] > 2) {
02005       SUMA_SL_Err("dims is a 2x1 vector with allowed values of 0 1 or 2 only.");
02006       SUMA_RETURN(NULL);
02007    }
02008 
02009    p[0] = P[dims[0]]; p[1] = P[dims[1]]; /* the point of interest */
02010    for (iv = 0; iv < N_FaceSet; ++iv) {
02011       counter = 0;
02012       for (i=0; i<FaceSetDim; ++i) { /* form the polygon coordinate vector */
02013          ni = FaceSetList[FaceSetDim*iv+i];
02014          poly[3*i] = NodeList[3*ni];  poly[3*i+1] = NodeList[3*ni+1]; poly[3*i+2] = NodeList[3*ni+2];
02015       }
02016       if (culled) if (culled[iv]) continue;
02017       
02018       p1[0] = poly[dims[0]]; p1[1] = poly[dims[1]]; /* the very first point */
02019       for (i=1; i <=FaceSetDim; ++i) {
02020          ip = i % FaceSetDim;
02021          p2[0] = poly[3*ip+dims[0]]; p2[1] = poly[3*ip+dims[1]];
02022          if (p[1] > SUMA_MIN_PAIR(p1[1], p2[1])) {
02023             if (p[1] <= SUMA_MAX_PAIR(p1[1], p2[1])) {
02024                if (p[0] <= SUMA_MAX_PAIR(p1[0], p2[0])) {
02025                   if (p1[1] != p2[1]) {
02026                      xinters = (p[1] - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0];
02027                      if (p1[0] == p2[0] || p[0] <= xinters) {
02028                         counter++; 
02029                      }
02030                   }
02031                }
02032             }
02033          }
02034          p1[0] = p2[0]; p1[1] = p2[1];
02035       }
02036    
02037       if (counter % 2 == 0) { 
02038          isin[iv] = 0;
02039       } else {
02040          isin[iv] = 1; ++(*N_in); /* p is inside polygon iv */
02041          #if 0
02042          if (LocalHead) 
02043          {
02044             int kk;
02045             fprintf(SUMA_STDERR,"\n%%hit!\nPoly = [");
02046             for (kk=0; kk < FaceSetDim; ++kk) {
02047                fprintf(SUMA_STDERR,"%.2f %.2f; ", poly[3*kk+dims[0]] , poly[3*kk+dims[1]]);
02048             } fprintf(SUMA_STDERR,"%.2f %.2f] \np = [%.3f %.3f];", poly[dims[0]], poly[dims[1]], p[0], p[1]);   
02049          }
02050          #endif
02051       }
02052    }
02053 
02054    SUMA_RETURN(isin);
02055 }

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 1683 of file SUMA_MiscFunc.c.

References SUMA_ISINSPHERE::d, SUMA_ISINSPHERE::IsIn, SUMA_ISINSPHERE::nIsIn, nr, SUMA_alloc_problem(), SUMA_calloc, SUMA_COPY_VEC, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

Referenced by SUMA_LoadPrepInVol().

01684 {/*SUMA_isinsphere*/
01685    static char FuncName[]={"SUMA_isinsphere"}; 
01686    float *t, t0, t1, t2, ta;
01687    int k, *IsIn, id, ND;
01688    SUMA_ISINSPHERE IsIn_strct;
01689    
01690    SUMA_ENTRY;
01691 
01692    ND = 3;
01693    IsIn_strct.nIsIn = 0;
01694       
01695    t = (float *) SUMA_calloc (nr, sizeof(float));
01696    IsIn = (int *) SUMA_calloc (nr, sizeof(int));
01697    
01698    if (!t || !IsIn)
01699       {
01700          SUMA_alloc_problem (FuncName);
01701          SUMA_RETURN (IsIn_strct);
01702       }
01703    
01704    
01705    if (BoundIn) /* split into two to avoid checking for this condition all the time */
01706       {
01707          for (k=0; k < nr; ++k)
01708             {
01709                id = ND * k;
01710                /* Net distance to center */
01711                t0 = NodeList[id] - S_cent[0];   
01712                t1 = NodeList[id+1] - S_cent[1];   
01713                t2 = NodeList[id+2] - S_cent[2];   
01714 
01715                ta = sqrt (t0 * t0 + t1 * t1 + t2 * t2);
01716                
01717                if (ta <= S_rad)
01718                   {
01719                      IsIn[IsIn_strct.nIsIn] = k;
01720                      t[IsIn_strct.nIsIn] = ta;
01721                      ++(IsIn_strct.nIsIn);
01722                   }
01723             }
01724       }
01725    else
01726       {
01727          for (k=0; k < nr; ++k)
01728             {
01729                id = ND * k;
01730                /* Net distance to center */
01731                t0 = NodeList[id] - S_cent[0];   
01732                t1 = NodeList[id+1] - S_cent[1];   
01733                t2 = NodeList[id+2] - S_cent[2];   
01734 
01735                ta = sqrt (t0 * t0 + t1 * t1 + t2 * t2);
01736                
01737                if (ta < S_rad)
01738                   {
01739                      IsIn[IsIn_strct.nIsIn] = k;
01740                      t[IsIn_strct.nIsIn] = ta;
01741                      ++(IsIn_strct.nIsIn);
01742                   }
01743             }
01744       }
01745          
01746    /* get ridd of extra allocation space*/
01747    IsIn_strct.d = (float *) SUMA_calloc (IsIn_strct.nIsIn, sizeof(float));
01748    IsIn_strct.IsIn = (int *) SUMA_calloc (IsIn_strct.nIsIn, sizeof(int));
01749    
01750    if (!IsIn_strct.d || !IsIn_strct.IsIn )
01751       {
01752          IsIn_strct.nIsIn = 0;
01753          SUMA_alloc_problem(FuncName);
01754          SUMA_RETURN (IsIn_strct);
01755       }
01756    
01757    SUMA_COPY_VEC (t, IsIn_strct.d, IsIn_strct.nIsIn, float , float);
01758    SUMA_COPY_VEC (IsIn, IsIn_strct.IsIn , IsIn_strct.nIsIn, int , int);
01759    
01760    SUMA_free(t);
01761    SUMA_free(IsIn);
01762    
01763    SUMA_RETURN (IsIn_strct);
01764    
01765 }/*SUMA_isinsphere*/

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 3929 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_NodePath_to_TriPath_Inters().

03930 {
03931    static char FuncName[]={"SUMA_isTriLinked"};
03932    int ic, in;
03933    
03934    SUMA_ENTRY;
03935 
03936    ic = 0;   /* common node index*/
03937    in = 0; /* number of node searched in T */
03938    while (ic < 2 && in < 3) {
03939       if (t[0] == T[in]) {
03940          cn[ic] = t[0]; 
03941          ++ic;
03942       }else {
03943          if (t[1] == T[in]) {
03944             cn[ic] = t[1]; 
03945             ++ic;
03946          }else {
03947             if (t[2] == T[in]) {
03948                cn[ic] = t[2]; 
03949                ++ic;
03950             }
03951          }
03952       }
03953       ++in; /* look for next node */
03954    }
03955    
03956    SUMA_RETURN (ic);
03957 }

SUMA_Boolean SUMA_isVoxelIntersect_Triangle float *    center,
float *    dxyz,
float *    vert0,
float *    vert1,
float *    vert2
 

does a voxel intersect a triangle ? (i.e. one of the edges intersects a triangle)

Parameters:
center  (float *) center of voxel
dxyz  (float *) dimensions of voxel
vert0  (float *) xyz first vertex of triangle
vert1  (float *) xyz of second vertex of triangle
vert2  (float *) xyz of third vertex of triangle
Returns:
YUP == intersects

Definition at line 3166 of file SUMA_MiscFunc.c.

References i, SUMA_Boolean, SUMA_EDGE_OF_VOXEL, SUMA_ENTRY, SUMA_IS_POINT_IN_SEGMENT, SUMA_MT_isIntersect_Triangle(), and SUMA_RETURN.

Referenced by SUMA_GetVoxelsIntersectingTriangle(), and SUMA_SurfGridIntersect().

03167 {
03168    static char FuncName[]={"SUMA_isVoxelIntersect_Triangle"};
03169    int i = 0;
03170    float P0[3], P1[3], iP[3];
03171    
03172    SUMA_ENTRY;
03173    
03174    /* loop accross all 12 edges and find out which pierces the triangle */
03175    for (i=0; i<12; ++i) {
03176       SUMA_EDGE_OF_VOXEL(center, dxyz, i, P0, P1);
03177       if (SUMA_MT_isIntersect_Triangle (P0, P1, vert0, vert1, vert2, iP, NULL, NULL)) {
03178          /* intersects, make sure intersection is between P0 and P1 */
03179          if (SUMA_IS_POINT_IN_SEGMENT(iP, P0, P1)) {
03180             if (0) fprintf(SUMA_STDERR, "%s:\n"
03181                                                 "Triangle %.3f, %.3f, %.3f\n"
03182                                                 "         %.3f, %.3f, %.3f\n"
03183                                                 "         %.3f, %.3f, %.3f\n"
03184                                                 "Intersects voxel at:\n"
03185                                                 "         %.3f, %.3f, %.3f\n", 
03186                                                 FuncName,
03187                                                 vert0[0], vert0[1], vert0[2],
03188                                                 vert1[0], vert1[1], vert1[2],
03189                                                 vert2[0], vert2[1], vert2[2],
03190                                                 center[0], center[1], center[2]);
03191             SUMA_RETURN(YUP);
03192          }
03193       }
03194    }  
03195    SUMA_RETURN(NOPE);
03196 }

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

See also:
SUMA_iswordin_ci

Definition at line 1154 of file SUMA_MiscFunc.c.

References i, SUMA_ENTRY, and SUMA_RETURN.

Referenced by main(), SUMA_CreateGenericArgParse(), SUMA_Engine(), SUMA_FreeSurfer_Read_eng(), SUMA_GuessAnatCorrect(), SUMA_GuessSide(), SUMA_IO_args_2_spec(), SUMA_isTypicalSOforVolSurf(), SUMA_iswordin_ci(), SUMA_IV_FaceSetsextract(), SUMA_IV_XYZextract(), SUMA_Load_Spec_Surf(), SUMA_LoadSpec_eng(), SUMA_ParseLHS_RHS(), SUMA_Read_SpecFile(), SUMA_Read_SureFit_Param(), SUMA_SO2nimlSO(), SUMA_SpecStructInfo(), SUMA_SureFit_Read_Coord(), SUMA_SureFit_Read_Topo(), and SUMA_SurfaceMetrics_eng().

01155 {/*SUMA_iswordin*/
01156    int i=0,j=0;
01157    static char FuncName[]={"SUMA_iswordin"};
01158 
01159    SUMA_ENTRY;
01160 
01161    if (sbig == NULL && ssub == NULL) SUMA_RETURN (-2);
01162    if (sbig == NULL || ssub == NULL) SUMA_RETURN (-1);
01163 
01164    if (strlen(sbig) < strlen(ssub))
01165        SUMA_RETURN (0);
01166 
01167    j=0;
01168    while (sbig[i] != '\0' && ssub[j] != '\0')
01169    {
01170        if (sbig[i] == ssub[j])
01171           {
01172              ++j;
01173              /*printf ("j=%d ",j);*/
01174           }
01175        else j=0;
01176    ++i;
01177    }
01178 
01179    if (j == strlen (ssub)) {
01180       SUMA_RETURN (1);
01181    }
01182    else {
01183       SUMA_RETURN (0);
01184    }
01185 
01186 }/*SUMA_iswordin*/

int SUMA_iswordin_ci const char *    sbig,
const char *    ssub
 

case insensitive version of SUMA_iswordin

Definition at line 1101 of file SUMA_MiscFunc.c.

References SUMA_copy_string(), SUMA_ENTRY, SUMA_free, SUMA_iswordin(), and SUMA_RETURN.

Referenced by SUMA_guess_surftype_argv().

01102 {
01103    static char FuncName[]={"SUMA_iswordin_ci"};
01104    char *sbigc, *ssubc;
01105    int ans;
01106    
01107    SUMA_ENTRY;
01108    sbigc = SUMA_copy_string((char *)sbig);
01109    ssubc = SUMA_copy_string((char *)ssub);
01110    
01111    ans = SUMA_iswordin (sbigc, ssubc);
01112    if (sbigc) SUMA_free(sbigc); sbigc = NULL;
01113    if (ssubc) SUMA_free(ssubc); ssubc = NULL;
01114    
01115    SUMA_RETURN(ans);
01116    
01117 } 

SUMA_EDGE_LIST* SUMA_Make_Edge_List int *    FL,
int    N_FL,
int    N_Node,
float *    NodeList,
char *    ownerid
 

call engine with debug flag set 20 Oct 2003 [rickr]

Definition at line 4331 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, SUMA_Make_Edge_List_eng(), and SUMA_RETURN.

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

04332 {
04333    static char FuncName[]={"SUMA_Make_Edge_List"};
04334    
04335    SUMA_ENTRY;
04336 
04337    SUMA_RETURN(SUMA_Make_Edge_List_eng(FL, N_FL, N_Node, NodeList, 1, ownerid));
04338 }

SUMA_EDGE_LIST* SUMA_Make_Edge_List_eng int *    FL,
int    N_FL,
int    N_Node,
float *    NodeList,
int    debug,
char *    ownerid
 

ans = SUMA_Make_Edge_List_eng (FL, N_FL, N_Node, NodeList, debug);

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.
debug  (int) flag to request extra output \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 4370 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELloc, SUMA_EDGE_LIST::ELps, i, SUMA_EDGE_LIST::idcode_str, SUMA_EDGE_LIST::Le, SUMA_EDGE_LIST::LinkedPtrType, LocalHead, SUMA_EDGE_LIST::max_N_Hosts, SUMA_EDGE_LIST::min_N_Hosts, SUMA_EDGE_LIST::N_Distinct_Edges, SUMA_EDGE_LIST::N_EL, SUMA_EDGE_LIST::N_links, SUMA_EDGE_LIST::owner_id, SUMA_allocate2D(), SUMA_Boolean, SUMA_calloc, SUMA_dqsortrow(), SUMA_ENTRY, SUMA_free, SUMA_free2D(), SUMA_free_Edge_List(), SUMA_LH, SUMA_LINKED_OVERLAY_TYPE, SUMA_malloc, SUMA_NEW_ID, SUMA_RETURN, SUMA_Show_Edge_List(), SUMA_SL_Crit, SUMA_SL_Err, and SUMA_EDGE_LIST::Tri_limb.

Referenced by SUMA_CreateIcosahedron(), SUMA_GetContour(), SUMA_LoadPrepInVol(), SUMA_Make_Edge_List(), and SUMA_SurfaceMetrics_eng().

04371 {
04372    static char FuncName[]={"SUMA_Make_Edge_List_eng"};
04373    int i, ie, ip, *isort_EL, **ELp, lu, ht, *iTri_limb, icur, in1, in2;
04374    float dx, dy, dz;
04375    SUMA_EDGE_LIST *SEL;
04376    SUMA_Boolean LocalHead = NOPE;
04377    
04378    SUMA_ENTRY;
04379 
04380    if (!FL) {
04381       SUMA_SL_Err("Null FL");
04382       SUMA_RETURN(NULL);
04383    }
04384    if (LocalHead) {
04385       fprintf(SUMA_STDERR,"%s: %d Facesets to work with.\n", FuncName, N_FL);
04386    }
04387    if (!N_FL) {
04388       SUMA_SL_Err("zero N_FL");
04389       SUMA_RETURN(NULL);
04390    }
04391    /* allocate and form the List of edges */
04392    SEL = (SUMA_EDGE_LIST *) SUMA_malloc(sizeof(SUMA_EDGE_LIST));
04393    SEL->idcode_str = NULL;
04394    SUMA_NEW_ID(SEL->idcode_str, NULL); 
04395    SEL->N_links = 0;
04396    if (ownerid) sprintf(SEL->owner_id, "%s", ownerid);
04397    else SEL->owner_id[0] = '\0';
04398    SEL->LinkedPtrType = SUMA_LINKED_OVERLAY_TYPE;
04399 
04400    SEL->N_EL = 3 * N_FL;
04401    SEL->EL = (int **) SUMA_allocate2D (SEL->N_EL, 2, sizeof(int)); /* edge list */
04402    SEL->ELloc = (int *)SUMA_calloc(N_Node, sizeof(int));
04403    SEL->Le = (float *) SUMA_calloc (SEL->N_EL, sizeof(float)); /* length of each edge */
04404    ELp = (int **) SUMA_allocate2D (SEL->N_EL, 2, sizeof(int)); /* edge property list */
04405                                                          /* 1st column, 1 = is flipped from orientation in triangle, -1 as present in triangle 
04406                                                               2nd column, index of triangle (FaceSet) that edge is a part of */    
04407    SEL->ELps = (int **) SUMA_allocate2D (SEL->N_EL, 3, sizeof(int)); /*sorted edge property list */
04408    
04409    /*fprintf(SUMA_STDERR, "%s: SEL->NEL %d\n", FuncName, SEL->N_EL/3);*/
04410    
04411    SEL->Tri_limb = (int **) SUMA_allocate2D (SEL->N_EL/3, 3, sizeof(int)); 
04412    iTri_limb = (int *)SUMA_calloc (SEL->N_EL/3,sizeof(int)); 
04413    
04414    if (SEL == NULL || SEL->EL == NULL || ELp == NULL || SEL->ELps == NULL || SEL->Tri_limb == NULL || iTri_limb== NULL || SEL->ELloc == NULL) {
04415       fprintf(SUMA_STDERR, "Error %s: Failed to allocate for EL, ELp.\n", FuncName);
04416       SUMA_RETURN (NULL);
04417    }
04418 
04419    /* form the edge list */
04420    SUMA_LH("Forming Edge List...\n");
04421    for (i=0; i< N_FL; ++i) {/* begin, form edge list */
04422       /* first edge, 0->1*/
04423       ie = 3*i;
04424       ip = 3*i;
04425       if (FL[ip] > FL[ip+1]) {
04426          /* flip it, to make sorting easier */
04427          SEL->EL[ie][0] = FL[ip+1];
04428          SEL->EL[ie][1] = FL[ip];
04429          /* store parameters */
04430          ELp[ie][0] = 1; /* flip happened */
04431       } else { 
04432          /* no flip necessary */
04433          SEL->EL[ie][0] = FL[ip];
04434          SEL->EL[ie][1] = FL[ip+1];
04435          ELp[ie][0] = -1; /* NO flip happened */
04436       }
04437       ELp[ie][1] = i; /* FaceSetMember */
04438 
04439       /* second edge, 1->2*/
04440       ie += 1;
04441       if (FL[ip+1] > FL[ip+2]) {
04442          /* flip it, to make sorting easier */
04443          SEL->EL[ie][0] = FL[ip+2];
04444          SEL->EL[ie][1] = FL[ip+1];
04445          /* store parameters */
04446          ELp[ie][0] = 1; /* flip happened */
04447       } else { 
04448          /* no flip necessary */
04449          SEL->EL[ie][0] = FL[ip+1];
04450          SEL->EL[ie][1] = FL[ip+2];
04451          ELp[ie][0] = -1; /* NO flip happened */
04452       }
04453       ELp[ie][1] = i; /* FaceSetMember */
04454       
04455       /* third edge, 2->0*/
04456       ie += 1;
04457       if (FL[ip+2] > FL[ip]) {
04458          /* flip it, to make sorting easier */
04459          SEL->EL[ie][0] = FL[ip];
04460          SEL->EL[ie][1] = FL[ip+2];
04461          /* store parameters */
04462          ELp[ie][0] = 1; /* flip happened */
04463       } else { 
04464          /* no flip necessary */
04465          SEL->EL[ie][0] = FL[ip+2];
04466          SEL->EL[ie][1] = FL[ip];
04467          ELp[ie][0] = -1; /* NO flip happened */
04468       }
04469       ELp[ie][1] = i; /* FaceSetMember */
04470       
04471    }/* end, form edge list */
04472    SUMA_LH("Edge list done.");
04473    
04474    if (LocalHead) SUMA_Show_Edge_List(SEL,NULL);
04475    
04476    #if 0
04477       fprintf(SUMA_STDERR,"%s: Node1 Node2 | FlipVal Triangle\n", FuncName); 
04478       for (i=0; i < SEL->N_EL; ++i) {
04479          fprintf (SUMA_STDERR, "%d %d | %d %d\n", SEL->EL[i][0], SEL->EL[i][1], ELp[i][0], ELp[i][1]);
04480       }
04481    #endif
04482 
04483    /* now sort the Edge list */
04484    SUMA_LH("Sorting edge list...");
04485    isort_EL = SUMA_dqsortrow (SEL->EL, SEL->N_EL, 2);
04486    
04487    /* reorder ELp to match sorted EL */
04488    for (i=0; i< SEL->N_EL; ++i) {
04489       SEL->ELps[i][0] = ELp[isort_EL[i]][0];
04490       SEL->ELps[i][1] = ELp[isort_EL[i]][1];
04491    }
04492    
04493    SUMA_LH("Sorting edge list done.");
04494    
04495    if (isort_EL) SUMA_free(isort_EL);
04496    isort_EL = NULL;
04497    
04498    
04499    #if 0
04500       fprintf(SUMA_STDERR,"%s: Node1 Node2 | FlipVal Triangle\n", FuncName); 
04501       for (i=0; i < SEL->N_EL; ++i) {
04502          fprintf (SUMA_STDERR, "%d %d | %d %d\n", SEL->EL[i][0], SEL->EL[i][1], SEL->ELps[i][0], SEL->ELps[i][1]);
04503       }
04504    #endif
04505    
04506    /* calculate the length of each edge */
04507    for (ie=0; ie < SEL->N_EL; ++ie) {
04508       in1 = 3 * SEL->EL[ie][0]; in2 = 3 * SEL->EL[ie][1];
04509       dx = (NodeList[in2] - NodeList[in1]);
04510       dy = (NodeList[in2+1] - NodeList[in1+1]);
04511       dz = (NodeList[in2+2] - NodeList[in1+2]);
04512       SEL->Le[ie] = (float) sqrt (  dx * dx + dy * dy + dz * dz );
04513    }
04514    
04515    /* free unsorted ELp */
04516    if (ELp) SUMA_free2D((char **)ELp, SEL->N_EL);
04517    ELp = NULL;
04518    
04519    SEL->max_N_Hosts = -1;
04520    SEL->min_N_Hosts = 1000;
04521    
04522    /* do a search for some funky stuff */
04523    SUMA_LH("Searching SEL for funky stuff");
04524    SEL->N_Distinct_Edges = 0;
04525    i=0;
04526    while (i < SEL->N_EL) {
04527       /* store the location of this edge for the triangle hosting it */
04528       ht = SEL->ELps[i][1]; /* host triangle index */
04529       SEL->Tri_limb[ht][iTri_limb[ht]] = i;
04530       iTri_limb[ht] += 1;
04531       SEL->N_Distinct_Edges += 1; /* a new edge */ 
04532       SEL->ELps[i][2] = 1; /* number of triangles hosting edge */
04533       lu = 1; 
04534       while (i+lu < SEL->N_EL) {
04535          if (SEL->EL[i+lu][0] == SEL->EL[i][0] && SEL->EL[i+lu][1] == SEL->EL[i][1]) {/* found matching edge */
04536             SEL->ELps[i][2] += 1; /* number of triangles hosting edge */
04537             SEL->ELps[i+lu][2] = -1; /* flag to mean that this edge is a duplicte in the list */
04538 
04539             /* store the location of this edge for the triangle hosting it */
04540             ht = SEL->ELps[i+lu][1]; /* host triangle index */
04541             SEL->Tri_limb[ht][iTri_limb[ht]] = i+lu;
04542             iTri_limb[ht] += 1;
04543 
04544             ++lu;
04545          }else break;
04546          
04547       }
04548       if (SEL->max_N_Hosts < SEL->ELps[i][2]) SEL->max_N_Hosts = SEL->ELps[i][2];
04549       if (SEL->min_N_Hosts > SEL->ELps[i][2]) SEL->min_N_Hosts = SEL->ELps[i][2]; 
04550       i += lu;
04551    }
04552    SUMA_LH("Do adjust your radio.\nNo funk here");
04553    
04554    if (SEL->max_N_Hosts == -1 || SEL->min_N_Hosts == 1000) {
04555       SUMA_SL_Crit("Bad bad news.\nCould not calculate max_N_Hosts &/| min_N_Hosts");
04556       SUMA_free_Edge_List(SEL); SEL = NULL;
04557       SUMA_RETURN(SEL);
04558    }
04559    
04560    {
04561       int winedonce = 0;
04562       if (debug && (SEL->min_N_Hosts == 1 || SEL->max_N_Hosts == 1)) {
04563          winedonce = 1;
04564          fprintf(SUMA_STDERR,"Warning %s:\n Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SEL->min_N_Hosts, SEL->max_N_Hosts);
04565          fprintf(SUMA_STDERR," You have edges that form a border in the surface.\n");
04566       }
04567       if (SEL->min_N_Hosts > 2 || SEL->max_N_Hosts > 2) {
04568          winedonce = 1;
04569          fprintf(SUMA_STDERR, "Warning %s:\n"
04570                               "Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SEL->min_N_Hosts, SEL->max_N_Hosts);
04571          fprintf(SUMA_STDERR, "Warning %s:\n"
04572                               " You have edges that belong to more than two triangles.\n"
04573                               " Bad for analysis assuming surface is a 2-manifold.\n", FuncName);
04574          if (debug) {
04575             int iii=0;
04576             fprintf(SUMA_STDERR, " These edges are formed by the following nodes:\n");
04577             for (iii = 0; iii < SEL->N_EL; ++iii) { 
04578                if (SEL->ELps[iii][2] > 2) fprintf (SUMA_STDERR," %d: Edge [%d %d] shared by %d triangles.\n", 
04579                                                 iii+1, SEL->EL[iii][0], SEL->EL[iii][1] , SEL->ELps[iii][2] );
04580             }
04581          }
04582       }
04583       if (debug && !winedonce) 
04584          fprintf(SUMA_STDERR,"%s: Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SEL->min_N_Hosts, SEL->max_N_Hosts);
04585    }
04586    #if 0
04587       fprintf(SUMA_STDERR,"%s:(ELindex) Node1 Node2 | FlipVal Triangle N_hosts\n", FuncName); 
04588       for (i=0; i < SEL->N_EL; ++i) {
04589          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]);
04590       }
04591       fprintf(SUMA_STDERR,"%s:Tri_limb\n", FuncName); 
04592       for (i=0; i < SEL->N_EL/3; ++i) {
04593          fprintf (SUMA_STDERR, "%d %d %d\n", SEL->Tri_limb[i][0], SEL->Tri_limb[i][1], SEL->Tri_limb[i][2]);
04594       }
04595    #endif
04596    
04597    /* store where each node's listing begins
04598    ELloc is used to quickly find a certain edge in EL
04599    to find the edge formed by nodes na-nb
04600    find the minimum of na and nb (say it's nb)
04601    the first reference of an edge containing nb starts at EL(ELloc(nb),:)
04602    NOTE: ELloc contains an entry for each node in FaceSetList, except the largest node index since that's never in the 
04603    first column of EL */
04604    
04605    SUMA_LH("storing locations ...");
04606    for (i=0; i < N_Node; ++i) SEL->ELloc[i] = -1;
04607    i = 0;
04608    icur = SEL->EL[0][0];
04609    SEL->ELloc[icur] = i; 
04610    while (i < SEL->N_EL) {
04611       if (SEL->EL[i][0] != icur) {
04612          icur = SEL->EL[i][0];
04613          SEL->ELloc[icur] = i;
04614       }
04615       ++i;
04616    }
04617    
04618    if (iTri_limb) SUMA_free(iTri_limb); /* Thanks B. Argall */
04619    SUMA_LH("Done with storage, returning...\n");
04620    
04621    SUMA_RETURN (SEL);
04622 }

SUMA_Boolean SUMA_MakeConsistent int *    FL,
int    N_FL,
SUMA_EDGE_LIST   SEL,
int    detail,
int *    trouble
 

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

ans = SUMA_MakeConsistent (FaceSetList, N_FaceSet, SEL, detail, trouble)

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
detail  (int) 0: quiet, except for errors and warnings 1: report at end 2: LocalHead gets turned on
trouble  (int *): a flag that is set to 1 if the surface had inconsistent mesh or if the surface could not be fully traversed. 0 if all went well and the mesh looks good (for the purposes of this function) \ret ans (SUMA_Boolean) YUP, NOPE
See also:
SUMA_Make_Edge_List

Definition at line 4949 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELps, i, LocalHead, SUMA_EDGE_LIST::N_EL, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_RETURN, SUMA_SL_Err, and SUMA_EDGE_LIST::Tri_limb.

Referenced by main(), SUMA_CreateIcosahedron(), SUMA_LoadPrepInVol(), SUMA_Pattie_Volume(), and SUMA_SurfaceMetrics_eng().

04950 {
04951    static char FuncName[]={"SUMA_MakeConsistent"};
04952    /* see for more documentation labbook NIH-2 test mesh  p61 */
04953    int i, it, NP, ip, N_flip=0, *isflip, *ischecked, ht0, ht1, NotConsistent, miss, miss_cur, N_iter, EdgeSeed, TriSeed, N_checked;
04954    SUMA_FACESET_FIRST_EDGE_NEIGHB *SFFN;
04955    SUMA_Boolean LocalHead = NOPE;
04956    
04957    SUMA_ENTRY;
04958 
04959    if (detail > 1) LocalHead = YUP;
04960    
04961    if (!SEL || !FL) {
04962       SUMA_SL_Err("NULL input!");
04963       SUMA_RETURN (NOPE);
04964    }
04965    
04966    NP = 3;
04967    isflip = (int *)SUMA_calloc(SEL->N_EL/3, sizeof(int));
04968    ischecked = (int *)SUMA_calloc(SEL->N_EL/3, sizeof(int));
04969    
04970    if (isflip == NULL || ischecked == NULL ) {
04971       fprintf(SUMA_STDERR, "Error %s: Failed to allocate for isflip\n", FuncName);
04972       SUMA_RETURN (NOPE);
04973    }
04974    
04975    
04976    /* Now, go through the sorted edge list and flip what needs flipping*/
04977    N_iter = 0;
04978    miss = 0;
04979    miss_cur = SEL->N_EL;
04980    N_checked = 1;
04981    while (miss_cur != miss) {
04982       miss_cur = miss;
04983       miss = 0;
04984       
04985       /* both methods work just fine here */
04986       #if 0
04987          /*start with the first edge as an edge seed */
04988          EdgeSeed = 0;
04989          i=EdgeSeed;
04990          ht0 = SEL->ELps[i][1];
04991       #else      
04992          /* start with the first edge of the seed triangle as an edge seed */
04993          TriSeed = 0;
04994          i = SEL->Tri_limb[TriSeed][0];
04995          ht0 = TriSeed;
04996       #endif
04997       
04998       ischecked[ht0] = 1;
04999       while (i < SEL->N_EL) {
05000          ht0 = SEL->ELps[i][1];
05001          /* make sure edge is not part of three triangles, if it is, skip it */
05002          if (SEL->ELps[i][2] > 3) {
05003             ++i;
05004             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]); 
05005             continue;
05006          }
05007          if (SEL->ELps[i][2] == 2) {
05008             /* that's a good edge, see if the next edge after it is consistent */
05009             NotConsistent = SEL->ELps[i][0] * SEL->ELps[i+1][0]; /* if 1 then edges were either both flipped or not flipped in the list */
05010             ht1 = SEL->ELps[i+1][1];
05011             if (ischecked[ht0] && !ischecked[ht1]) {
05012                if (NotConsistent == 0) {
05013                   fprintf(SUMA_STDERR, "Error %s: NotConsistent = 0 here. This should not be.\n", FuncName);
05014                   SUMA_RETURN (NOPE);
05015                }
05016                if (NotConsistent < 0) {
05017                   /* triangles hosting these edges are consistent */
05018                   /* next triangle needs no flipping */
05019                   ischecked[ht1] = 1;
05020                   ++N_checked;
05021                } else {
05022                   /* triangles hosting these edges are NOT consistent */
05023                   /* flip the next triangle */
05024                   ip = NP * ht1;
05025                   it = FL[ip];
05026                   FL[ip] = FL[ip+2];
05027                   FL[ip+2] = it;
05028                   /* Now make sure the flip is reflected in ELps */
05029                   it = SEL->Tri_limb[ht1][0]; SEL->ELps[it][0] *= -1;
05030                   it = SEL->Tri_limb[ht1][1]; SEL->ELps[it][0] *= -1;
05031                   it = SEL->Tri_limb[ht1][2]; SEL->ELps[it][0] *= -1;
05032                   N_flip += 1;
05033                   isflip[ht1] = 1;
05034                   ischecked[ht1] = 1;
05035                   ++N_checked;
05036                }
05037                ++i; 
05038                continue;
05039             } 
05040             
05041             /*try if next edge's host is in good shape */
05042             if (ischecked [ht1] && !ischecked[ht0]) {
05043                if (NotConsistent == 0) {
05044                   fprintf(SUMA_STDERR, "Error %s: NotConsistent = 0 here. This should not be.\n", FuncName);
05045                   SUMA_RETURN (NOPE);
05046                }
05047                if (NotConsistent < 0) {
05048                   /* triangles hosting these edges are consistent */
05049                   /* 1st triangle needs no flipping */
05050                   ischecked[ht0] = 1;
05051                   ++N_checked;
05052                } else {
05053                   /* triangles hosting these edges are NOT consistent */
05054                   /* flip the 1st triangle */
05055                   ip = NP * ht0;
05056                   it = FL[ip];
05057                   FL[ip] = FL[ip+2];
05058                   FL[ip+2] = it;
05059                   /* Now make sure the flip is reflected in ELps */
05060                   it = SEL->Tri_limb[ht0][0]; SEL->ELps[it][0] *= -1;
05061                   it = SEL->Tri_limb[ht0][1]; SEL->ELps[it][0] *= -1;
05062                   it = SEL->Tri_limb[ht0][2]; SEL->ELps[it][0] *= -1;
05063                   N_flip += 1;
05064                   isflip[ht0] = 1;
05065                   ischecked[ht0] = 1;
05066                   ++N_checked;
05067                }
05068                ++i; 
05069                continue;
05070             } 
05071             if (!ischecked[ht0] && !ischecked [ht1]) { /* a good lead that was missed on this pass */
05072                if (LocalHead) fprintf(SUMA_STDERR,"%s: Miss = %d, MissCur = %d\n", FuncName, miss, miss_cur); 
05073                ++miss;
05074             }
05075          }
05076          ++i;   
05077       }
05078       if (LocalHead) fprintf(SUMA_STDERR,"%s: Miss = %d, MissCur = %d\n", FuncName, miss, miss_cur);
05079       ++N_iter;
05080    }
05081 
05082    *trouble = 0;
05083    if (LocalHead) fprintf(SUMA_STDERR,"%s: %d iterations required to check the surface.\n", FuncName, N_iter);
05084    if (detail) 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);
05085    if (N_checked != SEL->N_EL/3) {
05086       *trouble = 1;
05087    }
05088    if (N_flip) {
05089       *trouble = 1;
05090       if (detail) 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);
05091    } else if (detail) fprintf(SUMA_STDERR,"%s: All checked triangles were consistent with the triangle containing the first edge in the list.\n", FuncName);
05092    if (miss) {
05093       if (detail) fprintf(SUMA_STDERR,"%s: %d segments with two neighbors were skipped. Not good in general.\n", FuncName, miss);
05094       *trouble = 1;
05095    }
05096    
05097    #if 0
05098       /* now show the fixed mesh list */
05099       fprintf (SUMA_STDERR,"%s: %d triangles were flipped \n", FuncName, N_flip);
05100       for (i=0; i < SEL->N_EL/3; ++i) {
05101          ip = NP * i;
05102          if (isflip[i]) fprintf (SUMA_STDERR,"\t%d %d %d\t(%d)\t*\n", FL[ip], FL[ip+1], FL[ip+2], ischecked[i]);
05103             else fprintf (SUMA_STDERR,"\t%d %d %d\t(%d)\n", FL[ip], FL[ip+1], FL[ip+2], ischecked[i]);
05104       }
05105    #endif
05106       
05107    /* freedom */
05108    if (LocalHead) fprintf(SUMA_STDERR,"%s: Free time \n", FuncName);
05109    if (isflip) SUMA_free(isflip);
05110    if (ischecked) SUMA_free(ischecked);
05111    if (LocalHead) fprintf(SUMA_STDERR,"%s: returning.\n", FuncName);
05112    
05113    SUMA_RETURN (YUP);
05114 }

void* SUMA_malloc_fn const char *    CF,
size_t    size
 

Definition at line 208 of file SUMA_MiscFunc.c.

References malloc.

00209    {
00210       return (malloc(size));
00211    }

SUMA_Boolean SUMA_mattoquat float **    mat,
float *    q
 

Definition at line 3829 of file SUMA_MiscFunc.c.

References i, mat, q, SUMA_Boolean, SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_Engine().

03830 {
03831    double tr, s;
03832    int i,j,k, nxt[3] = {1, 2, 0};
03833    static char FuncName[]={"SUMA_mattoquat"};
03834    
03835    SUMA_ENTRY;
03836 
03837    /* calculate the trace */
03838    tr = mat[0][0] + mat[1][1] + mat[2][2];
03839    if (tr > 0.0) {
03840       s = sqrt(tr + 1.0);
03841       q[3] = s * 0.5;
03842       s = 0.5/s;
03843       
03844       q[0] = (mat[1][2] - mat[2][1])*s;
03845       q[1] = (mat[2][0] - mat[0][2])*s;
03846       q[2] = (mat[0][1] - mat[1][0])*s;
03847    
03848    } /* tr > 0.0 */ else {
03849       i = 0;
03850       if (mat[1][1] > mat[0][0]) i = 1;
03851       if (mat[2][2] > mat[i][i]) i = 2;
03852       j = nxt[i]; k = nxt[j];
03853    
03854       s = sqrt( (mat[i][i] - (mat[j][j]+mat[k][k])) + 1.0);
03855       q[i] = s * 0.5;
03856       s = 0.5/s;
03857       q[3] = (mat[j][k] - mat[k][j])*s;
03858       q[j] = (mat[i][j] + mat[j][i])*s;
03859       q[k] = (mat[i][k] + mat[k][i])*s;
03860    } /* tr < 0.0 */
03861    SUMA_RETURN (YUP);
03862 }

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 3354 of file SUMA_MiscFunc.c.

References SUMA_MT_INTERSECT_TRIANGLE::d, SUMA_MT_INTERSECT_TRIANGLE::ifacemax, SUMA_MT_INTERSECT_TRIANGLE::ifacemin, SUMA_MT_INTERSECT_TRIANGLE::inodemin, SUMA_MT_INTERSECT_TRIANGLE::inodeminlocal, SUMA_MT_INTERSECT_TRIANGLE::isHit, LocalHead, SUMA_MT_INTERSECT_TRIANGLE::N_el, SUMA_MT_INTERSECT_TRIANGLE::N_hits, SUMA_MT_INTERSECT_TRIANGLE::N_poshits, SUMA_MT_INTERSECT_TRIANGLE::P, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_EPSILON, SUMA_Free_MT_intersect_triangle(), SUMA_malloc, SUMA_MT_CROSS, SUMA_MT_DOT, SUMA_MT_SUB, SUMA_RETURN, SUMA_MT_INTERSECT_TRIANGLE::t, SUMA_MT_INTERSECT_TRIANGLE::u, and SUMA_MT_INTERSECT_TRIANGLE::v.

Referenced by main(), SUMA_BrushStrokeToNodeStroke(), SUMA_FindVoxelsInSurface_SLOW(), SUMA_GetM2M_NN(), SUMA_inNodeNeighb(), SUMA_isSelfIntersect(), SUMA_MapSurface(), SUMA_MarkLineSurfaceIntersect(), and SUMA_SurfGridIntersect().

03355 {
03356    static char FuncName[]={"SUMA_MT_intersect_triangle"};
03357    double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
03358    double det,inv_det;
03359    int iface, ND, id, NP, ip;
03360    double vert0[3],vert1[3], vert2[3], dir[3], dirn, orig[3];
03361    float tmin, tmax, dii, disttest;
03362    static SUMA_MT_INTERSECT_TRIANGLE *MTI = NULL;
03363    static int N_FaceSet_Previous = 0, entry = 0;
03364    SUMA_Boolean LocalHead = NOPE;
03365    
03366    SUMA_ENTRY;
03367 
03368    tmin = 10000000.0;
03369    tmax = 0.0;
03370    
03371    if (!PrevMTI) { /* nothing preallocated */
03372       entry = 0;
03373       if (LocalHead) fprintf(SUMA_STDERR,"%s: First entry or nothing pre-allocated.\n", FuncName);
03374    } else { /* returning a used MTI, check number of facesets */
03375       if (N_FaceSet_Previous != N_FaceSet) { /* must reallocate */
03376          if (LocalHead) fprintf(SUMA_STDERR,"%s: Reallocating for MTI, a change in number of FaceSets.\n", FuncName);
03377          /* free current MTI */
03378          PrevMTI = SUMA_Free_MT_intersect_triangle (PrevMTI);
03379          entry = 0;
03380       }else if (LocalHead) fprintf(SUMA_STDERR,"%s: Reusing.\n", FuncName);
03381    }
03382    
03383    if (!entry) {
03384       MTI = (SUMA_MT_INTERSECT_TRIANGLE *)SUMA_malloc(sizeof(SUMA_MT_INTERSECT_TRIANGLE));
03385       if (MTI == NULL) {
03386          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for MTI\n", FuncName);
03387          SUMA_RETURN (NULL);
03388       }
03389       MTI->t = NULL;
03390       MTI->u = NULL;
03391       MTI->v = NULL;
03392       MTI->isHit = NULL;
03393    } else {
03394       MTI = PrevMTI;
03395    }
03396 
03397    /* direction from two points */
03398    orig[0] = (double)P0[0];
03399    orig[1] = (double)P0[1];
03400    orig[2] = (double)P0[2];
03401    
03402    dir[0] = (double)P1[0] - orig[0];
03403    dir[1] = (double)P1[1] - orig[1];
03404    dir[2] = (double)P1[2] - orig[2];
03405    dirn = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]);
03406    dir[0] /= dirn;
03407    dir[1] /= dirn;
03408    dir[2] /= dirn;
03409    
03410    if (!entry) {
03411       MTI->isHit = (SUMA_Boolean *)SUMA_malloc(N_FaceSet*sizeof(SUMA_Boolean));
03412       MTI->t = (float *)SUMA_calloc(N_FaceSet, sizeof(float));
03413       MTI->u = (float *)SUMA_calloc(N_FaceSet, sizeof(float));
03414       MTI->v = (float *)SUMA_calloc(N_FaceSet, sizeof(float));
03415    
03416       if (MTI->isHit == NULL || MTI->t == NULL || MTI->u == NULL || MTI->v == NULL) {
03417          fprintf(SUMA_STDERR,"Error : Failed to allocate for MTI->isHit | MTI->t | MTI->u | MTI->v\n");
03418          SUMA_RETURN (NULL);
03419       }
03420    }
03421    
03422    MTI->N_hits = 0; MTI->N_poshits = 0; 
03423    ND = 3;
03424    NP = 3;
03425    for (iface= 0; iface < N_FaceSet; ++iface) {/* iface */
03426       /* set up the coordinates in a humane nomenclature */
03427       ip = NP * iface;
03428       id = ND * FaceSetList[ip];
03429       vert0[0] = (double)NodeList[id];
03430        vert0[1] = (double)NodeList[id+1];
03431       vert0[2] = (double)NodeList[id+2];
03432       
03433       id = ND * FaceSetList[ip+1];
03434       vert1[0] = (double)NodeList[id];
03435        vert1[1] = (double)NodeList[id+1];
03436       vert1[2] = (double)NodeList[id+2];
03437       
03438       id = ND * FaceSetList[ip+2];
03439       vert2[0] = (double)NodeList[id];
03440        vert2[1] = (double)NodeList[id+1];
03441       vert2[2] = (double)NodeList[id+2];
03442       
03443       
03444       /* find vectors for two edges sharing vert0 */
03445       SUMA_MT_SUB(edge1, vert1, vert0);
03446       SUMA_MT_SUB(edge2, vert2, vert0);
03447 
03448       /* begin calculating determinant - also used to calculate U parameter */
03449       SUMA_MT_CROSS(pvec, dir, edge2);
03450 
03451       /* if determinant is near zero, ray lies in plane of triangle */
03452       det = SUMA_MT_DOT(edge1, pvec);
03453 
03454    #ifdef SUMA_MT_TEST_CULL           /* define TEST_CULL if culling is desired */
03455       if (det > -SUMA_EPSILON && det < SUMA_EPSILON)
03456          MTI->isHit[iface] = NOPE;
03457       else {
03458          /* calculate distance from vert0 to ray origin */
03459          SUMA_MT_SUB(tvec, orig, vert0);
03460 
03461          /* calculate U parameter and test bounds */
03462          MTI->u[iface] = (float)SUMA_MT_DOT(tvec, pvec);
03463          if (MTI->u[iface] < 0.0 || MTI->u[iface] > det)
03464             MTI->isHit[iface] = NOPE;
03465          else {
03466             /* prepare to test V parameter */
03467             SUMA_MT_CROSS(qvec, tvec, edge1);
03468 
03469              /* calculate V parameter and test bounds */
03470             MTI->v[iface] = (float)SUMA_MT_DOT(dir, qvec);
03471             if (MTI->v[iface] < 0.0 || MTI->u[iface] + MTI->v[iface] > det)
03472                MTI->isHit[iface] = NOPE;
03473             else {
03474                /* calculate t, scale parameters, ray intersects triangle */
03475                MTI->t[iface] = (float)SUMA_MT_DOT(edge2, qvec);
03476                inv_det = 1.0 / det;
03477                MTI->t[iface] *= (float)inv_det;
03478                MTI->u[iface] *= (float)inv_det;
03479                MTI->v[iface] *= (float)inv_det;         
03480                MTI->isHit[iface] = YUP;
03481                ++MTI->N_hits; 
03482                /* store shortest distance triangle info */
03483                if (MTI->t[iface] < 0) disttest = -MTI->t[iface];
03484                   else { disttest = MTI->t[iface]; ++MTI->N_poshits;}
03485                    
03486                if (disttest < tmin) {
03487                   tmin = disttest;
03488                   MTI->ifacemin = iface;
03489                   /* calculate the location of the intersection in XYZ coords */
03490                   MTI->P[0] = vert0[0] + MTI->u[iface] * (vert1[0] - vert0[0] ) + MTI->v[iface] * (vert2[0] - vert0[0] );
03491                   MTI->P[1] = vert0[1] + MTI->u[iface] * (vert1[1] - vert0[1] ) + MTI->v[iface] * (vert2[1] - vert0[1] );
03492                   MTI->P[2] = vert0[2] + MTI->u[iface] * (vert1[2] - vert0[2] ) + MTI->v[iface] * (vert2[2] - vert0[2] );
03493                   /* find out which node is closest to P */
03494                   MTI->inodeminlocal = 0;
03495                   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]);
03496                   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]);
03497                   if (dii < MTI->d) {
03498                      MTI->d = dii;
03499                      MTI->inodeminlocal = 1;
03500                   }
03501                   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]);
03502                   if (dii < MTI->d) {
03503                      MTI->d = dii;
03504                      MTI->inodeminlocal = 2;
03505                   }
03506                   MTI->d = (float)sqrt((double)MTI->d);
03507                }
03508                if (disttest > tmax) {
03509                   tmax = disttest;
03510                   MTI->ifacemax = iface;
03511                }
03512             }
03513          }
03514       }
03515    #else                    /* the non-culling branch */
03516       if (det > -SUMA_EPSILON && det < SUMA_EPSILON)
03517          MTI->isHit[iface] = NOPE;
03518       else {
03519          inv_det = 1.0 / det;
03520 
03521          /* calculate distance from vert0 to ray origin */
03522          SUMA_MT_SUB(tvec, orig, vert0);
03523 
03524          /* calculate U parameter and test bounds */
03525          MTI->u[iface] = (float)SUMA_MT_DOT(tvec, pvec) * inv_det;
03526          if (MTI->u[iface] < 0.0 || MTI->u[iface] > 1.0)
03527             MTI->isHit[iface] = NOPE;
03528          else {
03529             /* prepare to test V parameter */
03530             SUMA_MT_CROSS(qvec, tvec, edge1);
03531 
03532             /* calculate V parameter and test bounds */
03533             MTI->v[iface] = (float)SUMA_MT_DOT(dir, qvec) * inv_det;
03534             if (MTI->v[iface] < 0.0 || MTI->u[iface] + MTI->v[iface] > 1.0)
03535                MTI->isHit[iface] = NOPE;
03536             else {
03537                /* calculate t, ray intersects triangle */
03538                MTI->t[iface] = (float)SUMA_MT_DOT(edge2, qvec) * inv_det;         
03539                MTI->isHit[iface] = YUP;
03540                ++MTI->N_hits;
03541                /* store shortest distance triangle info */
03542                if (MTI->t[iface] < 0) disttest = -MTI->t[iface];
03543                   else  { disttest = MTI->t[iface]; ++MTI->N_poshits;}
03544                
03545                if (disttest < tmin) {
03546                   tmin = disttest;
03547                   MTI->ifacemin = iface;
03548                   /* calculate the location of the intersection in XYZ coords */
03549                   MTI->P[0] = vert0[0] + MTI->u[iface] * (vert1[0] - vert0[0] ) + MTI->v[iface] * (vert2[0] - vert0[0] );
03550                   MTI->P[1] = vert0[1] + MTI->u[iface] * (vert1[1] - vert0[1] ) + MTI->v[iface] * (vert2[1] - vert0[1] );
03551                   MTI->P[2] = vert0[2] + MTI->u[iface] * (vert1[2] - vert0[2] ) + MTI->v[iface] * (vert2[2] - vert0[2] );
03552                   /* find out which node is closest to P */
03553                   MTI->inodeminlocal = 0;
03554                   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]);
03555                   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]);
03556                   if (dii < MTI->d) {
03557                      MTI->d = dii;
03558                      MTI->inodeminlocal = 1;
03559                   }
03560                   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]);
03561                   if (dii < MTI->d) {
03562                      MTI->d = dii;
03563                      MTI->inodeminlocal = 2;
03564                   }
03565                   MTI->d = (float)sqrt((double)MTI->d);
03566                   ip = NP * iface + MTI->inodeminlocal;
03567                   MTI->inodemin = FaceSetList[ip];
03568                }
03569                if (disttest > tmax) {
03570                   tmax = disttest;
03571                   MTI->ifacemax = iface;
03572                }
03573             }
03574          }
03575       }
03576    #endif
03577    }/*iface */
03578    MTI->N_el = N_FaceSet;
03579    
03580    ++entry;
03581    N_FaceSet_Previous = N_FaceSet;
03582 
03583    SUMA_RETURN (MTI);
03584 }

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 3223 of file SUMA_MiscFunc.c.

References SUMA_Boolean, SUMA_ENTRY, SUMA_EPSILON, SUMA_MT_CROSS, SUMA_MT_DOT, SUMA_MT_SUB, SUMA_RETURN, and v.

Referenced by SUMA_BrushStrokeToNodeStroke(), SUMA_inNodeNeighb(), and SUMA_isVoxelIntersect_Triangle().

03224 {  
03225    static char FuncName[]={"SUMA_MT_isIntersect_Triangle"};
03226    double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
03227    double det,inv_det, u, v, t;
03228    double dir[3], dirn, orig[3];
03229    SUMA_Boolean hit = NOPE;
03230    
03231    SUMA_ENTRY;
03232    
03233    /* direction from two points */
03234    orig[0] = (double)P0[0];
03235    orig[1] = (double)P0[1];
03236    orig[2] = (double)P0[2];
03237    
03238    dir[0] = (double)P1[0] - orig[0];
03239    dir[1] = (double)P1[1] - orig[1];
03240    dir[2] = (double)P1[2] - orig[2];
03241    dirn = sqrt(dir[0]*dir[0]+dir[1]*dir[1]+dir[2]*dir[2]);
03242    dir[0] /= dirn;
03243    dir[1] /= dirn;
03244    dir[2] /= dirn;
03245 
03246    /* find vectors for two edges sharing vert0 */
03247    SUMA_MT_SUB(edge1, vert1, vert0);
03248    SUMA_MT_SUB(edge2, vert2, vert0);
03249 
03250    /* begin calculating determinant - also used to calculate U parameter */
03251    SUMA_MT_CROSS(pvec, dir, edge2);
03252 
03253    /* if determinant is near zero, ray lies in plane of triangle */
03254    det = SUMA_MT_DOT(edge1, pvec);
03255    
03256    hit = NOPE;
03257    
03258       if (det > -SUMA_EPSILON && det < SUMA_EPSILON) {
03259          /* no hit, will return below */
03260          hit = NOPE;
03261       } else {
03262          inv_det = 1.0 / det;
03263 
03264          /* calculate distance from vert0 to ray origin */
03265          SUMA_MT_SUB(tvec, orig, vert0);
03266 
03267          /* calculate U parameter and test bounds */
03268          u = SUMA_MT_DOT(tvec, pvec) * inv_det;
03269          if (u < 0.0 || u > 1.0) {
03270             /* no hit, will return below */
03271             hit = NOPE;
03272          } else {
03273             /* prepare to test V parameter */
03274             SUMA_MT_CROSS(qvec, tvec, edge1);
03275 
03276             /* calculate V parameter and test bounds */
03277             v = SUMA_MT_DOT(dir, qvec) * inv_det;
03278             if (v < 0.0 || u + v > 1.0) {
03279                 /* no hit, will return below */
03280                 hit = NOPE;
03281             } else {
03282                hit = YUP;
03283                
03284                if (iP) {
03285                   /* calculate t, ray intersects triangle */
03286                   t = SUMA_MT_DOT(edge2, qvec) * inv_det;         
03287 
03288                   /* calculate the location of the intersection (iP) in XYZ coords */
03289                   iP[0] = vert0[0] + u * (vert1[0] - vert0[0] ) + v * (vert2[0] - vert0[0] );
03290                   iP[1] = vert0[1] + u * (vert1[1] - vert0[1] ) + v * (vert2[1] - vert0[1] );
03291                   iP[2] = vert0[2] + u * (vert1[2] - vert0[2] ) + v * (vert2[2] - vert0[2] );
03292                   
03293                   if (d) {
03294                      /* find out which node is closest to P */
03295                      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]);
03296                      *closest_vert = 0;
03297                      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]);
03298                      if (d[1] < d[*closest_vert]) {
03299                         *closest_vert = 1;
03300                      }
03301                      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]);
03302                      if (d[2] < d[*closest_vert]) {
03303                         *closest_vert = 2;
03304                      }
03305                      d[0] = (float)sqrt((double)d[0]);
03306                      d[1] = (float)sqrt((double)d[1]);
03307                      d[2] = (float)sqrt((double)d[2]);
03308                   }
03309                }
03310 
03311             }
03312          }
03313       }
03314    
03315    SUMA_RETURN (hit);
03316 }

int SUMA_Next_Best_Seed SUMA_FACESET_FIRST_EDGE_NEIGHB   SFFN,
int *    visited,
int    N_FL
 

This function returns the best available seed, for use in SUMA_Take_A_Hike The first time you call the function, the seed is a triangle with three neighbors. The next time you call, the seed is a triangle that was visited by SUMA_Take_A_Hike and has preferably two neighbors left unvisited.

Definition at line 4136 of file SUMA_MiscFunc.c.

References SUMA_FACESET_FIRST_EDGE_NEIGHB::FirstNeighb, i, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb, seed, SUMA_ENTRY, and SUMA_RETURN.

04137 {
04138    static int entry = 0, seed=-1;
04139    int Found1 = -1, Found2 = -1, i, N_NotVisNeighb, itry;
04140    static char FuncName[]={"SUMA_Next_Best_Seed"};
04141    
04142    SUMA_ENTRY;
04143 
04144    if (!entry) { /* entry = 0 */
04145       for (i=0; i < N_FL; ++i) {
04146          if (SFFN->N_Neighb[i] == 3) {
04147             seed = i; ++entry; SUMA_RETURN(seed);
04148          }
04149          if (SFFN->N_Neighb[i] == 2) Found2 = i;
04150          if (SFFN->N_Neighb[i] == 1) Found1 = i;
04151       }   
04152             
04153       if (Found2 > 0) {
04154          ++entry;
04155          SUMA_RETURN (Found2);
04156       }
04157          
04158       if (Found1 > 0) {
04159          ++entry;
04160          SUMA_RETURN (Found1);
04161       }
04162       
04163       SUMA_RETURN (-1); /* No seeds found */      
04164    }/* entry = 0 */
04165    else {/* entry > 0 */
04166       for (i=0; i < N_FL; ++i) {
04167          if (visited[i]) { /* a candidate */
04168             /* count the number of unvisited neighbors */
04169             N_NotVisNeighb = 0;
04170             itry = 0;
04171             while (itry < SFFN->N_Neighb[i]) {
04172                if (!visited[SFFN->FirstNeighb[i][itry]]) ++N_NotVisNeighb;
04173                ++itry;
04174             }
04175             if (N_NotVisNeighb == 2) {
04176                seed = i; ++entry; SUMA_RETURN (seed);
04177             }
04178             if (N_NotVisNeighb == 1) {
04179                Found1 = i;
04180             }
04181          } /* a candidate */
04182       }
04183       if (Found1 > 0) {
04184          ++entry;
04185          SUMA_RETURN (Found1);
04186       }
04187       SUMA_RETURN (-1); /* No seeds found */   
04188    }/* entry > 0 */
04189 }

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 6353 of file SUMA_MiscFunc.c.

References i, strp, SUMA_calloc, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

Referenced by SUMA_RenderToPixMap().

06354 {/*SUMA_pad_str*/
06355     static char FuncName[]={"SUMA_pad_str"};
06356    int lo,i;
06357     char *strp , *buf1;
06358 
06359    SUMA_ENTRY;
06360 
06361     assert (str);
06362 
06363     lo = (int)strlen(str);
06364 
06365    buf1 = (char *)SUMA_calloc (pad_ln-lo+2,sizeof (char));
06366    strp = (char *)SUMA_calloc (pad_ln+lo+2,sizeof (char));
06367 
06368    for (i=0;i<pad_ln-lo;++i)
06369        {
06370           if (i == 0) sprintf (buf1,"%c",pad_val);
06371              else sprintf (buf1,"%s%c",buf1,pad_val);
06372 
06373        }
06374     if (opt == 0)
06375        sprintf (strp,"%s%s",buf1,str);
06376     else if (opt == 1)
06377        {
06378           sprintf (strp,"%s%s",str,buf1);
06379 
06380       }         
06381        else 
06382           {
06383              fprintf (SUMA_STDERR, "Error %s: Wrong opt paramter, only (0,1) allowed\n", FuncName);
06384              SUMA_free(strp);
06385             SUMA_free(buf1);
06386             SUMA_RETURN (NULL);
06387           }
06388 
06389     SUMA_free(buf1);
06390 
06391     SUMA_RETURN (strp);
06392 
06393 }/*SUMA_pad_str*/

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);
See also:
SUMA_POINT_AT_DISTANCE and SUMA_POINT_AT_DISTANCE_NORM macro

Definition at line 2083 of file SUMA_MiscFunc.c.

References flip(), i, LocalHead, p, q, SUMA_allocate2D(), SUMA_Boolean, SUMA_DOTP_VEC, SUMA_ENTRY, SUMA_RETURN, and SUMA_SL_Warn.

02084 {/*SUMA_Point_At_Distance*/
02085    static char FuncName[]={"SUMA_Point_At_Distance"}; 
02086    float bf, **P2, P1orig[3], Uorig[3];
02087    float m, n, p, q, D, A, B, C, epsi = 0.0001;
02088    int flip, i;
02089    SUMA_Boolean LocalHead = NOPE;
02090    
02091    SUMA_ENTRY;
02092 
02093    SUMA_SL_Warn ("useless piece of junk, use SUMA_POINT_AT_DISTANCE instead!");
02094    
02095    if (d == 0) {
02096       fprintf(SUMA_STDERR,"Error %s: d is 0. Not good, Not good at all.\n", FuncName);
02097       SUMA_RETURN (NULL);
02098    }
02099    
02100    if (LocalHead) {
02101       fprintf (SUMA_STDOUT,"%s: U %f, %f, %f, P1 %f %f %f, d %f\n", FuncName,\
02102          U[0], U[1], U[2], P1[0], P1[1], P1[2], d);
02103    }
02104          
02105    /* store initial values */
02106    P1orig[0] = P1[0];    
02107    P1orig[1] = P1[1]; 
02108    P1orig[2] = P1[2]; 
02109 
02110    Uorig[0] = U[0];
02111    Uorig[1] = U[1];
02112    Uorig[2] = U[2];
02113    
02114    /* normalize U such that U(0) = 1 */
02115    flip = 0;
02116    if (fabs(U[0]) < epsi) { /* must flip X with some other coordinate */
02117       if (fabs(U[1]) > epsi) {/*U[1] != 0; */
02118          U[0] = U[1]; U[1] = 0;
02119          bf = P1[0]; P1[0] = P1[1]; P1[1] = bf;
02120          flip = 1;
02121       } else {   /*U[1] = 0; */
02122          if (fabs(U[2]) > epsi) { /* U[2] != 0 */
02123             U[0] = U[2]; U[2] = 0;
02124             bf = P1[0]; P1[0] = P1[2]; P1[2] = bf;
02125             flip = 2;
02126          } else { /* U[2] = 0 */
02127             fprintf(SUMA_STDERR, "Error %s: 0 direction vector.\n", FuncName);
02128             SUMA_RETURN (NULL);
02129          }
02130       }/*U[1] = 0; */
02131    }/*U[0] = 0; */
02132 
02133    if (LocalHead) fprintf (SUMA_STDERR, "%s: flip = %d\n", FuncName, flip);
02134       
02135    if (LocalHead) fprintf (SUMA_STDERR, "%s: U original: %f, %f, %f\n", FuncName, U[0], U[1], U[2]);
02136    U[1] /= U[0];
02137    U[2] /= U[0];
02138    U[0] = 1.0; 
02139    if (LocalHead) fprintf (SUMA_STDERR, "%s: U normalized: %f, %f, %f\n", FuncName, U[0], U[1], U[2]);
02140    
02141    /* Now U is clean, calculate P2 */   
02142    m = U[1];
02143    n = U[2];
02144 
02145    q = P1[1] - m*P1[0];
02146    p = P1[2] - n*P1[0];
02147 
02148    if (LocalHead) fprintf (SUMA_STDERR, "%s: m=%f n=%f, p=%f, q=%f\n", FuncName, m, n, p, q);
02149 
02150    /* Now find P2 */
02151    A = (1 + n*n + m*m);
02152    B = -2 * P1[0] + 2 * m * (q - P1[1]) + 2 * n * (p - P1[2]);
02153    C = P1[0]*P1[0] + (q - P1[1])*(q - P1[1]) + (p - P1[2])*(p - P1[2]) - d*d;
02154 
02155    D = B*B - 4*A*C;
02156    
02157    if (LocalHead) fprintf (SUMA_STDERR, "%s: A=%f B=%f, C=%f, D=%f\n", FuncName, A, B, C, D);
02158    
02159    if (D < 0) {
02160       fprintf(SUMA_STDERR, "Error %s: Negative Delta: %f.\n"
02161                            "Input values were: \n"
02162                            "U :[%f %f %f]\n"
02163                            "P1:[%f %f %f]\n"
02164                            "d :[%f]\n"
02165                            , FuncName, D, Uorig[0], Uorig[1], Uorig[2], 
02166                            P1orig[0], P1orig[1], P1orig[2], d);
02167       SUMA_RETURN(NULL);
02168    }
02169 
02170    P2 = (float **)SUMA_allocate2D(2,3, sizeof(float));
02171    if (P2 == NULL) {
02172       fprintf(SUMA_STDERR, "Error %s: Could not allocate for 6 floats! What is this? What is the matter with you?!\n", FuncName);
02173       SUMA_RETURN (NULL);
02174    }
02175 
02176    P2[0][0] = (-B + sqrt(D)) / (2 *A);
02177    P2[1][0] = (-B - sqrt(D)) / (2 *A);
02178 
02179    P2[0][1] = m * P2[0][0] + q;
02180    P2[1][1] = m * P2[1][0] + q;
02181 
02182    P2[0][2] = n * P2[0][0] + p;
02183    P2[1][2] = n * P2[1][0] + p;
02184 
02185 
02186    /* if flipping was performed, undo it */
02187    if (flip == 1) {
02188     for (i=0; i < 2; ++i) {
02189        bf = P2[i][1];
02190        P2[i][1] = P2[i][0];
02191        P2[i][0] = bf;
02192       }
02193    } else if (flip == 2){
02194     for (i=0; i < 2; ++i) {
02195        bf = P2[i][2]; 
02196        P2[i][2] = P2[i][0];
02197        P2[i][0] = bf;
02198       }
02199    }   
02200 
02201    for (i=0; i < 3; ++i) {
02202       P1[i] = P1orig[i];
02203       U[i] = Uorig[i];
02204    }
02205 
02206    if (LocalHead) {
02207       fprintf(SUMA_STDOUT,"%s: P1 = %f, %f, %f\n  ", \
02208        FuncName, P1[0], P1[1], P1[2]);
02209       fprintf(SUMA_STDOUT,"%s: P2 = %f, %f, %f\n    %f, %f, %f\n", \
02210        FuncName, P2[0][0], P2[0][1], P2[0][2], P2[1][0], P2[1][1], P2[1][2]);
02211       fprintf(SUMA_STDOUT,"%s: U = %f, %f, %f\n  ", \
02212        FuncName, U[0], U[1], U[2]);
02213    }
02214 
02215    
02216    /* make sure 1st point is along the same direction */
02217    Uorig[0] = P2[0][0] - P1[0]; /* use Uorig, not needed anymore */
02218    Uorig[1] = P2[0][1] - P1[1];
02219    Uorig[2] = P2[0][2] - P1[2];
02220 
02221    SUMA_DOTP_VEC(Uorig, U, bf, 3, float, float)
02222    if (LocalHead) fprintf(SUMA_STDOUT,"%s: Dot product = %f\n", FuncName, bf);
02223    if (bf < 0) {
02224       if (LocalHead) fprintf(SUMA_STDOUT,"%s: Flipping at end...\n", FuncName);
02225       for (i=0; i< 3; ++i) {
02226          bf = P2[0][i];
02227          P2[0][i] = P2[1][i]; P2[1][i] = bf;
02228       }
02229    }
02230    
02231    if (LocalHead) {
02232       fprintf(SUMA_STDOUT,"%s: P2 = %f, %f, %f\n    %f, %f, %f\n", \
02233        FuncName, P2[0][0], P2[0][1], P2[0][2], P2[1][0], P2[1][1], P2[1][2]);
02234    }
02235 SUMA_RETURN (P2);
02236    
02237 }/*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 2420 of file SUMA_MiscFunc.c.

References i, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, SUMA_UNIT_VEC, xn, yn, and zn.

02421 {
02422    static char FuncName[]={"SUMA_Point_To_Line_Distance"};
02423    float U[3], Un, xn, yn, zn, dx, dy, dz;
02424    int i, id, ND;
02425    
02426    SUMA_ENTRY;
02427    
02428    ND = 3;
02429    if (N_points < 1) {
02430       fprintf(SUMA_STDERR,"Error %s: N_points is 0.\n",FuncName);
02431       SUMA_RETURN (NOPE);
02432    }
02433    
02434    SUMA_UNIT_VEC(P1, P2, U, Un);
02435    if (Un == 0) {
02436       fprintf(SUMA_STDERR,"Error %s: P1 and P2 are identical.\n",FuncName);
02437       SUMA_RETURN (NOPE);
02438    }
02439    
02440    
02441    
02442    /* calculate the distances and keep track of the minimum distance while you're at it */
02443    
02444    /*bad practice, only returned pointers are allocated for in functions */
02445    /*
02446    d2 = (float *)SUMA_calloc(N_points, sizeof(float)); */
02447    
02448    if (d2 == NULL) {
02449       fprintf(SUMA_STDERR,"Error %s: d2 not allocated for.\n",FuncName);
02450       SUMA_RETURN (NOPE);
02451    }
02452    
02453    
02454    /* do the first point to initialize d2min without an extra if statement */
02455     i = 0;
02456     xn = NodeList[0] - P1[0];
02457     yn = NodeList[1] - P1[1];
02458     zn = NodeList[2] - P1[2];
02459     
02460     dx = (U[1]*zn - yn*U[2]);
02461     dy = (U[0]*zn - xn*U[2]);
02462     dz = (U[0]*yn - xn*U[1]);
02463     
02464     d2[i] = dx*dx+dy*dy +dz*dz; /* save the sqrt for speed */
02465     *d2min = d2[i];
02466     *i2min = i;
02467     /* Now do the rest */
02468    for (i=1; i < N_points; ++i) {
02469       id = ND * i;
02470       xn = NodeList[id] - P1[0];
02471       yn = NodeList[id+1] - P1[1];
02472       zn = NodeList[id+2] - P1[2];
02473 
02474       dx = (U[1]*zn - yn*U[2]);
02475       dy = (U[0]*zn - xn*U[2]);
02476       dz = (U[0]*yn - xn*U[1]);
02477 
02478       d2[i] = dx*dx+dy*dy +dz*dz; /* save the sqrt for speed */
02479       if (d2[i] < *d2min) {
02480          *d2min = d2[i];
02481          *i2min = i;
02482       }
02483    }
02484    SUMA_RETURN (YUP);
02485 }

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 2510 of file SUMA_MiscFunc.c.

References i, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, xn, yn, and zn.

02511 {
02512    static char FuncName[]={"SUMA_Point_To_Point_Distance"};
02513    float xn, yn, zn;
02514    int i, id, ND;
02515    
02516    SUMA_ENTRY;
02517 
02518    ND = 3;
02519    if (N_points < 1) {
02520       fprintf(SUMA_STDERR,"Error %s: N_points is 0.\n",FuncName);
02521       SUMA_RETURN (NOPE);
02522    }
02523    
02524    
02525    /* calculate the distances and keep track of the minimum distance while you're at it */
02526    
02527    if (d2 == NULL) {
02528       fprintf(SUMA_STDERR,"Error %s: d2 not allocated for.\n",FuncName);
02529       SUMA_RETURN (NOPE);
02530    }
02531    
02532    
02533    /* do the first point to initialize d2min without an extra if statement */
02534     i = 0;
02535     xn = NodeList[0] - P1[0];
02536     yn = NodeList[1] - P1[1];
02537     zn = NodeList[2] - P1[2];
02538     
02539     d2[i] = xn*xn + yn*yn + zn*zn; /* save the sqrt for speed */
02540     *d2min = d2[i];
02541     *i2min = i;
02542     /* Now do the rest */
02543    for (i=1; i < N_points; ++i) {
02544       id = ND * i;
02545       xn = NodeList[id] - P1[0];
02546       yn = NodeList[id+1] - P1[1];
02547       zn = NodeList[id+2] - P1[2];
02548 
02549 
02550        d2[i] = xn*xn + yn*yn + zn*zn; /* save the sqrt for speed */
02551       if (d2[i] < *d2min) {
02552          *d2min = d2[i];
02553          *i2min = i;
02554       }
02555    }
02556    SUMA_RETURN (YUP);
02557 }

float* SUMA_PolySurf3 float *    NodeList,
int    N_Node,
int *    FaceSets,
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 5620 of file SUMA_MiscFunc.c.

References i, SUMA_allocate2D(), SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_free2D(), and SUMA_RETURN.

Referenced by SUMA_SurfaceMetrics_eng().

05621 {
05622    static char FuncName[]={"SUMA_PolySurf3"};
05623    float **V, *A, ax, ay, az, an;
05624    int i, ii, coord, kk, jj, id, ND, ip, NP;
05625    
05626    SUMA_ENTRY;
05627 
05628    ND = 3;
05629    NP = PolyDim;
05630    A = (float *) SUMA_calloc (N_FaceSet, sizeof(float));
05631    V = (float **) SUMA_allocate2D(PolyDim+2, 3, sizeof(float));
05632    
05633    if (A == NULL || V == NULL) {
05634       fprintf(SUMA_STDERR,"Error %s; Failed to allocate for A or V\n", FuncName);
05635       SUMA_RETURN (NULL);
05636    }
05637 
05638    for (i=0; i < N_FaceSet; ++i) {
05639       ip = NP * i;
05640       if (FaceNormList[ip] > 0) ax = FaceNormList[ip];
05641          else ax = -FaceNormList[ip];
05642       
05643       if (FaceNormList[ip+1] > 0) ay = FaceNormList[ip+1];
05644          else ay = -FaceNormList[ip+1];
05645       
05646       if (FaceNormList[ip+2] > 0) az = FaceNormList[ip+2];
05647          else az = -FaceNormList[ip+2];
05648    
05649    
05650       coord = 3;
05651       if (ax > ay) {
05652          if (ax > az) coord = 1;
05653       } else {
05654          if (ay > az) coord = 2;
05655       }
05656    
05657       for (ii=0; ii< PolyDim; ++ii) {
05658          ip = NP * i;
05659          id = ND * FaceSets[ip+ii];
05660          V[ii][0] = NodeList[id];
05661          V[ii][1] = NodeList[id+1];
05662          V[ii][2] = NodeList[id+2];
05663       }
05664       ii = PolyDim;
05665       V[ii][0] = V[0][0]; V[ii][1] = V[0][1]; V[ii][2] = V[0][2];
05666       ii = PolyDim + 1;
05667       V[ii][0] = V[1][0]; V[ii][1] = V[1][1]; V[ii][2] = V[1][2];
05668       
05669       /* compute area of 2D projection */
05670       jj = 2;
05671       kk = 0;
05672       for (ii=1; ii < PolyDim+1; ++ii) {
05673          switch (coord) {
05674             case 1:
05675                A[i] = A[i] + ( V[ii][1] * (V[jj][2] - V[kk][2]) );
05676                break;
05677             case 2:
05678                A[i] = A[i] + ( V[ii][0] * (V[jj][2] - V[kk][2]) );
05679                break;
05680             case 3:
05681                A[i] = A[i] + ( V[ii][0] * (V[jj][1] - V[kk][1]) );
05682                break;
05683          }
05684          
05685          ++jj;
05686          ++kk;
05687          
05688       }
05689       
05690       /* scale to get area before projection  */
05691       an = (float) sqrt(ax * ax + ay * ay + az * az);
05692       switch (coord) {
05693          case 1:
05694             A[i] = (A[i] * (an / (2*ax)));
05695             break;
05696          case 2:
05697             A[i] = (A[i] * (an / (2*ay)));
05698             break;
05699          case 3:
05700             A[i] = (A[i] * (an / (2*az)));
05701             break;
05702       }
05703       
05704       if (!SignedArea) {
05705          if (A[i] < 0) A[i] = -A[i];
05706       }
05707    } /* for i*/
05708    
05709    SUMA_free2D((char **)V, PolyDim+2);
05710    SUMA_RETURN (A);
05711 }

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 759 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

00760 {/*SUMA_Read_2Ddfile*/
00761    int ir, ic, ex;
00762    FILE*internal_file;
00763    static char FuncName[]={"SUMA_Read_2Ddfile"};
00764 
00765    SUMA_ENTRY;
00766 
00767    internal_file = fopen (f_name,"r");
00768    if (internal_file == NULL) {
00769       fprintf (SUMA_STDERR,"%s: \aCould not open %s \n",FuncName, f_name);
00770       SUMA_RETURN (-1);
00771    }
00772 
00773 
00774 
00775    ir = 0;
00776    while (ir < n_rows)
00777    {
00778        ic = 0;
00779       while (ic < n_cols)
00780          {
00781             ex = fscanf (internal_file,"%d",&x[ir][ic]);   
00782             if (ex == EOF)
00783                {
00784                   fprintf(stderr,"Error SUMA_Read_2Ddfile: Premature EOF\n");
00785                   fclose (internal_file);
00786                   SUMA_RETURN(ir);
00787                }
00788             ++ic;
00789          }
00790       ++ir;
00791    }
00792 
00793    fclose (internal_file);
00794    SUMA_RETURN (ir);      
00795       
00796 }/*SUMA_Read_2Ddfile*/

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

**

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 594 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_input().

00595 {/*SUMA_Read_2Dfile*/
00596    int ir=0, ic=0, ex;
00597    FILE*internal_file;
00598    static char FuncName[]={"SUMA_Read_2Dfile"};
00599 
00600    SUMA_ENTRY;
00601 
00602    internal_file = fopen (f_name,"r");
00603    if (internal_file == NULL) {
00604                           fprintf (SUMA_STDERR,"%s: \aCould not open %s \n",FuncName, f_name);
00605                           SUMA_RETURN (-1);
00606                           }
00607    ir = 0;
00608    while (ir < n_rows)
00609    {
00610        ic = 0;
00611       while (ic < n_cols)
00612          {
00613             ex = fscanf (internal_file,"%f",&x[ir][ic]);   
00614             if (ex == EOF)
00615                {
00616                   fprintf(stderr,"Error SUMA_Read_2Dfile: Premature EOF\n");
00617                   fclose (internal_file);
00618                   SUMA_RETURN (n_rows);
00619                }
00620             ++ic;
00621          }
00622       ++ir;
00623    }
00624 
00625    fclose (internal_file);
00626    SUMA_RETURN (ir);      
00627       
00628 }/*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 454 of file SUMA_MiscFunc.c.

References SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_Load_Surface_Object_eng().

00456 { /* pass a 0 to n_points if you want to read till EOF */
00457    int cnt=0,ex,dec;
00458    static char FuncName[]={"SUMA_Read_dfile"};
00459    FILE*internal_file;
00460 
00461    SUMA_ENTRY;
00462 
00463    internal_file = fopen (f_name,"r");
00464    if (internal_file == NULL) {
00465                           fprintf(SUMA_STDERR, "\aCould not open %s \n",f_name);
00466                           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00467                           exit (0);
00468                           }
00469    ex = fscanf (internal_file,"%d",&x[cnt]);                     
00470    while (ex != EOF)
00471    {
00472      ++cnt;
00473      /* NOT WORKING, RETURNS SIZEOF (FLOAT) .....
00474      if (sizeof(x) < cnt)
00475       {
00476         fprintf(SUMA_STDERR, "%d = sizeof(x)\n",sizeof(x));
00477         fprintf(SUMA_STDERR, "\nNot Enough Memory Allocated \n\a");
00478         fprintf(SUMA_STDERR, "Exiting @SUMA_Read_file function\n");
00479         exit (0);
00480       }
00481      ............................................ */
00482      ex = fscanf (internal_file,"%d",&x[cnt]);
00483 
00484      if ((n_points != 0) && (cnt == n_points)) ex = EOF;
00485    }
00486 
00487    if (cnt < n_points) 
00488       {
00489        fprintf(SUMA_STDERR, "\a\nAttempt to read %d points failed,\n",n_points);
00490        fprintf(SUMA_STDERR, " file contains %d points only.\n",cnt);
00491        do {
00492 
00493        fprintf(SUMA_STDERR, "End Execution (Yes (1) No (0) ? : ");
00494        ex=scanf ("%d",&dec);
00495        } while (ex != 1 || (dec != 1 && dec !=0));
00496        if (dec)
00497         {
00498           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00499       exit (0);
00500       }
00501       else fprintf(SUMA_STDERR, "\nContinuing execution with %d points\n",cnt);
00502 
00503       }
00504 
00505    fclose (internal_file);
00506    SUMA_RETURN (cnt);                            
00507 }

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

Definition at line 508 of file SUMA_MiscFunc.c.

References SUMA_ENTRY.

Referenced by SUMA_Load_Surface_Object_eng().

00510 { /* pass a 0 to n_points if you want to read till EOF */
00511    int cnt=0,ex,dec;
00512    FILE*internal_file;
00513    static char FuncName[]={"SUMA_Read_file"};
00514    
00515    SUMA_ENTRY;
00516 
00517    internal_file = fopen (f_name,"r");
00518    if (internal_file == NULL) {
00519                           fprintf(SUMA_STDERR, "\aCould not open %s \n",f_name);
00520                           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00521                           exit (0);
00522                           }
00523    ex = fscanf (internal_file,"%f",&x[cnt]);                     
00524    while (ex != EOF)
00525    {
00526      ++cnt;
00527      
00528      ex = fscanf (internal_file,"%f",&x[cnt]);
00529 
00530      if ((n_points != 0) && (cnt == n_points)) ex = EOF;
00531    }
00532 
00533    if (cnt < n_points) 
00534       {
00535        fprintf(SUMA_STDERR, "\a\nAttempt to read %d points failed,\n",n_points);
00536        fprintf(SUMA_STDERR, " file contains %d points only.\n",cnt);
00537        do {
00538 
00539        fprintf(SUMA_STDERR, "End Execution (Yes (1) No (0) ? : ");
00540        ex=scanf ("%d",&dec);
00541        } while (ex != 1 || (dec != 1 && dec !=0));
00542        if (dec)
00543         {
00544           fprintf(SUMA_STDERR, "Exiting @ SUMA_Read_file function\n");
00545               exit (0);
00546       }
00547       else fprintf(SUMA_STDERR, "\nContinuing execution with %d points\n",cnt);
00548 
00549       }
00550 
00551    fclose (internal_file);
00552    return (cnt);                            
00553 }

SUMA_IRGB* SUMA_Read_IRGB_file char *    f_name
 

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

Parameters:
f_name  (char *) filename
Returns:
irgb (SUMA_IRGB *) structure containing irgb data
See also:
SUMA_Create_IRGB , SUMA_Free_IRGB

Definition at line 692 of file SUMA_MiscFunc.c.

References SUMA_IRGB::b, far, SUMA_IRGB::g, i, SUMA_IRGB::i, MRI_FLOAT_PTR, mri_free(), mri_read_1D(), ncol, MRI_IMAGE::nx, MRI_IMAGE::ny, SUMA_IRGB::r, SUMA_Create_IRGB(), SUMA_ENTRY, SUMA_RETURN, SUMA_SL_Err, and SUMA_SLP_Err.

Referenced by SUMA_LoadColorPlaneFile().

00693 {
00694    int i=0, ncol = 0, nrow = 0;
00695    MRI_IMAGE *im = NULL;
00696    float *far=NULL;
00697    SUMA_IRGB *irgb=NULL;
00698    static char FuncName[]={"SUMA_Read_IRGB_file"};
00699 
00700    SUMA_ENTRY;
00701 
00702    im = mri_read_1D (f_name);
00703    
00704    if (!im) {
00705       SUMA_SLP_Err("Failed to read 1D file");
00706       SUMA_RETURN(NULL);
00707    }
00708    
00709    far = MRI_FLOAT_PTR(im);
00710    ncol = im->nx;
00711    nrow = im->ny;
00712    
00713    if (!ncol) {
00714       SUMA_SL_Err("Empty file");
00715       SUMA_RETURN(NULL);
00716    }
00717    if (nrow !=  4 ) {
00718       SUMA_SL_Err("File must have\n"
00719                   "4 columns.");
00720       mri_free(im); im = NULL;   /* done with that baby */
00721       SUMA_RETURN(NULL);
00722    }
00723   
00724    if (!(irgb = SUMA_Create_IRGB(ncol))) {
00725       fprintf (SUMA_STDERR,"%s: Failed to create irgb.\n",FuncName);
00726       SUMA_RETURN (NULL);
00727    }
00728    
00729    for (i=0; i < ncol; ++i) {
00730       irgb->i[i] = (int)far[i];
00731       irgb->r[i] = far[i+ncol];
00732       irgb->g[i] = far[i+2*ncol];
00733       irgb->b[i] = far[i+3*ncol];
00734    }   
00735    
00736    mri_free(im); im = NULL;
00737    
00738    SUMA_RETURN (irgb);      
00739       
00740 }

char SUMA_ReadCharStdin char    def,
int    case_sensitive,
char *    allowed
 

Definition at line 6396 of file SUMA_MiscFunc.c.

References cbuf, i, nc, SUMA_ENTRY, SUMA_IS_BLANK, and SUMA_RETURN.

Referenced by SUMA_StretchToFitLeCerveau().

06397 {
06398    static char FuncName[]={"SUMA_ReadCharStdin"};
06399    char str[10], *strback;
06400    char cbuf;
06401    int Done, i, nc;
06402    
06403    SUMA_ENTRY;
06404    
06405    do {
06406       Done = 1;
06407       /* fpurge (stdin); */ /* fpurge is not standard on all systems! */
06408       str[0] = def;
06409       strback = fgets(str, 2*sizeof(char), stdin);
06410       cbuf = str[0];
06411       if (SUMA_IS_BLANK(str[0])) {
06412          cbuf = def;
06413       }
06414 
06415       if (!case_sensitive) {
06416          if (cbuf >= 'A' && cbuf <= 'Z') cbuf = cbuf + 'a' - 'A';  
06417       }
06418       
06419       if (allowed && cbuf) {
06420          /* make sure that the character is allowed */
06421          nc = strlen(allowed);
06422          for (i=0; i<nc;++i) {
06423             if (cbuf == allowed[i]) SUMA_RETURN(cbuf); 
06424          }
06425          Done = 0;
06426          /* rewind */
06427          fprintf(stdout,"\abad input, try again: "); fflush(stdout);
06428       }
06429    } while (!Done);
06430    SUMA_RETURN(cbuf);
06431 }

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 6446 of file SUMA_MiscFunc.c.

References cbuf, i, LocalHead, strtod(), SUMA_Boolean, SUMA_ENTRY, SUMA_MAX_STRING_LENGTH, and SUMA_RETURN.

Referenced by SUMA_input().

06447 {   
06448    int i=0, nvr = 0;
06449    char *endp, *strtp, s[SUMA_MAX_STRING_LENGTH], cbuf;
06450    static char FuncName[]={"SUMA_ReadNumStdin"};
06451    SUMA_Boolean eos, LocalHead = NOPE;
06452    
06453    SUMA_ENTRY;
06454 
06455    fflush (stdin);
06456    
06457    while ((cbuf = getc(stdin)) != '\n' && i < SUMA_MAX_STRING_LENGTH-1) {
06458       if (cbuf == ',' || cbuf == '\t') {/* change , and tab  to space*/
06459          cbuf = ' ';
06460       }
06461          s[i] = cbuf;
06462          ++ i;
06463    }
06464    
06465    if (i == SUMA_MAX_STRING_LENGTH-1) {
06466       fprintf(SUMA_STDERR,"Error %s: No more than %d characters are allowed on stdin.\n", FuncName, SUMA_MAX_STRING_LENGTH-1);
06467       fflush(stdin);
06468       SUMA_RETURN(-1);
06469    }
06470    
06471    s[i] = '\0';
06472    
06473    if (!i) SUMA_RETURN(0);
06474    
06475    /* parse s */
06476    strtp = s;
06477    endp = NULL;
06478    nvr = 0;
06479    eos = NOPE;
06480    while (nvr < nv && !eos) {
06481       fv[nvr] = strtod(strtp, &endp);
06482       if (LocalHead) fprintf (SUMA_STDERR, "Local Debug %s: ERANGE: %d, EDOM %d, errno %d\n", FuncName, ERANGE, EDOM, errno); 
06483       
06484       if (endp == strtp) { 
06485          eos = YUP;
06486       } else {
06487          ++nvr;
06488          strtp = endp;
06489       }
06490    }
06491    
06492    if (eos && nvr < nv) {
06493       fprintf (SUMA_STDERR, "Warning %s: Expected to read %d elements, read only %d.\n", FuncName, nv, nvr);
06494    }
06495    
06496    SUMA_RETURN(nvr);
06497 }

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

Definition at line 221 of file SUMA_MiscFunc.c.

References realloc.

00222    {
00223       return (realloc(ptr, size));
00224    }

int* SUMA_reorder int *    y,
int *    isort,
int    N_isort
 

creates a reordered version of a vector yr = SUMA_reorder(y, isort, N_isort);

Parameters:
y  (int *) vector
isort  (int *) vector containing sorting order
N_isort  (int ) number of elements in isort
Returns:
yr (int *) reordered version of y where: yr[i] = y[isort[i]];

  • you should free yr with SUMA_free(yr) when done with it
  • obviously it's your business to ensure that isort[i] cannot be larger than then number of elements in y

Definition at line 6762 of file SUMA_MiscFunc.c.

References i, SUMA_calloc, SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_ROIv2dataset(), and SUMA_ROIv2Grpdataset().

06763 {
06764    static char FuncName[]={"SUMA_reorder"};
06765    int i = 0, *yr = NULL;
06766    
06767    SUMA_ENTRY;
06768    
06769    if (!y || !isort || N_isort <= 0) SUMA_RETURN(yr);
06770    
06771    yr = (int *)SUMA_calloc( N_isort, sizeof(int));
06772    if (!yr) SUMA_RETURN(yr);
06773    
06774    for (i=0; i<N_isort; ++i) yr[i] = y[isort[i]];
06775    
06776    SUMA_RETURN(yr);
06777 }

void SUMA_Show_Edge_List SUMA_EDGE_LIST   EL,
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 4274 of file SUMA_MiscFunc.c.

References SUMA_EDGE_LIST::EL, SUMA_EDGE_LIST::ELps, i, SUMA_EDGE_LIST::idcode_str, SUMA_EDGE_LIST::N_EL, SUMA_ENTRY, SUMA_RETURNe, and SUMA_EDGE_LIST::Tri_limb.

Referenced by SUMA_GetContour(), and SUMA_Make_Edge_List_eng().

04275 {
04276    static char FuncName[]={"SUMA_Show_Edge_List"};
04277    int i;
04278    
04279    SUMA_ENTRY;
04280    
04281    if (Out == NULL) Out = stdout;
04282    
04283    fprintf(Out,"\nEL contents:\n");
04284    if (EL->idcode_str) fprintf(Out,"IDcode: %s\n", EL->idcode_str);
04285    else fprintf(Out,"IDcode: NULL\n");
04286    
04287    fprintf(Out,"i-\t[EL[i][0] EL[i][1]]\t[ELps[i][0] ELps[i][1] ELps[i][2] ELps[i][3]]\n");
04288    for (i=0; i < EL->N_EL; ++i) {
04289       fprintf(Out,"%d-\t[%d %d]\t[%d %d %d %d]\n", 
04290                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]);
04291    
04292    }
04293    fprintf(Out,"\nTriLimb contents:\n");
04294    fprintf(Out,"ti-\t[Edge1 Edge2 Edge3]\n");
04295    for (i=0; i < EL->N_EL/3; ++i) { 
04296       fprintf(Out,"t%d-\t[%d %d %d]\n",
04297          i, EL->Tri_limb[i][0], EL->Tri_limb[i][1],EL->Tri_limb[i][2]);
04298    }
04299    
04300    SUMA_RETURNe;
04301 }

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 3590 of file SUMA_MiscFunc.c.

References SUMA_MT_INTERSECT_TRIANGLE::d, i, SUMA_MT_INTERSECT_TRIANGLE::ifacemax, SUMA_MT_INTERSECT_TRIANGLE::ifacemin, SUMA_MT_INTERSECT_TRIANGLE::inodemin, SUMA_MT_INTERSECT_TRIANGLE::inodeminlocal, SUMA_MT_INTERSECT_TRIANGLE::isHit, SUMA_MT_INTERSECT_TRIANGLE::N_el, SUMA_MT_INTERSECT_TRIANGLE::N_hits, SUMA_MT_INTERSECT_TRIANGLE::N_poshits, SUMA_MT_INTERSECT_TRIANGLE::P, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, SUMA_MT_INTERSECT_TRIANGLE::t, SUMA_MT_INTERSECT_TRIANGLE::u, and SUMA_MT_INTERSECT_TRIANGLE::v.

03591 {
03592    static char FuncName[]={"SUMA_Show_MT_intersect_triangle"};
03593    int MaxShow = 5, i,j;
03594    
03595    SUMA_ENTRY;
03596 
03597    if (Out == NULL) Out = stdout;
03598       
03599    if (MTI == NULL) {
03600       fprintf (Out, "NULL Surface Object Pointer\n");
03601       SUMA_RETURN(NOPE);
03602    }
03603    
03604    fprintf (Out,"\n---------------------------------\n");
03605    if (!MTI->N_el) {
03606       fprintf (Out,"Zero elements in structure\n");
03607       SUMA_RETURN (YUP);
03608    }
03609    
03610    if (MTI->isHit == NULL) {
03611       fprintf (SUMA_STDERR,"Error SUMA_Show_MT_intersect_triangle: isHit is NULL\n\n");
03612       SUMA_RETURN (NOPE);
03613    }
03614    else {
03615       if (MaxShow > MTI->N_el) MaxShow = MTI->N_el; 
03616       fprintf (Out, "Intersection results (showing first %d out of %d elements):\n", MaxShow, MTI->N_el);
03617       for (i=0; i < MaxShow; ++i)   {
03618          fprintf (Out, "\tisHit: %d t %f u %f v %f", MTI->isHit[i], MTI->t[i], MTI->u[i],MTI->v[i]);
03619       }
03620          fprintf (Out, "\n");
03621       
03622       if (MTI->N_hits) {
03623          fprintf (Out, "\n%d hits, (%d hists with positive distance).\n", MTI->N_hits, MTI->N_poshits);
03624          fprintf (Out, "Minimum Distance: %d t %f u %f v %f\n", \
03625                   MTI->ifacemin, MTI->t[MTI->ifacemin], MTI->u[MTI->ifacemin],MTI->v[MTI->ifacemin]);
03626          fprintf (Out, "Intersection point P at Minimum Distance FaceSet:\n%f, %f, %f\n", \
03627                   MTI->P[0], MTI->P[1], MTI->P[2]);
03628          fprintf (Out, "Closest node is number %d in Minimum Distance Faceset (%d in NodeList) at %f distance.\n",\
03629                   MTI->inodeminlocal, MTI->inodemin, MTI->d);                           
03630          fprintf (Out, "Maximum Distance: %d t %f u %f v %f\n\n", \
03631                   MTI->ifacemax, MTI->t[MTI->ifacemax], MTI->u[MTI->ifacemax],MTI->v[MTI->ifacemax]);
03632          fprintf (Out, "Intersection of ray with surface (showing first %d out of %d elements):\n", MaxShow, MTI->N_el);
03633          i = 0;
03634          j = 0;
03635          while (i< MTI->N_el && j < MTI->N_hits) {
03636             if (MTI->isHit[i]) {
03637                ++j;
03638                fprintf (Out, "\tisHit: %d t %f u %f v %f\n", MTI->isHit[i], MTI->t[i], MTI->u[i],MTI->v[i]);
03639             }
03640             ++i;
03641          }
03642          fprintf (Out, "\n");
03643       } else {
03644          fprintf (Out, "No Intersection of ray with surface\n");
03645       }
03646 
03647    }
03648    SUMA_RETURN (YUP);
03649 }

void SUMA_ShowMemTrace SUMA_MEMTRACE_STRUCT   Mem,
FILE *    Out
 

Definition at line 356 of file SUMA_MiscFunc.c.

References calloc, free, i, SUMA_MEMTRACE_STRUCT::N_alloc, SUMA_MEMTRACE_STRUCT::N_MaxPointers, SUMA_MEMTRACE_STRUCT::Pointers, SUMA_MEMTRACE_STRUCT::Size, SUMA_ENTRY, SUMA_RETURNe, SUMA_SL_Err, and SUMA_z_dqsort_nsc().

00357 {
00358    static char FuncName[]={"SUMA_ShowMemTrace"};
00359    int i, *isort = NULL, *mem_sz_sort = NULL, Tot;
00360    
00361    SUMA_ENTRY;
00362    
00363    #ifdef USE_SUMA_MALLOC
00364    SUMA_SL_Err("NO LONGER SUPPORTED");
00365    SUMA_RETURNe;
00366    if (!Out) Out = SUMA_STDERR;
00367    if (!Mem) {
00368       fprintf (Out,"\nNull struct. Nothing to show.\n");
00369       SUMA_RETURNe;
00370    }
00371    
00372    fprintf (Out,"\nShowing SUMA_MEMTRACE_STRUCT: %p\n", Mem);    
00373    fprintf (Out,"->N_alloc: %d allocated elements.\n", Mem->N_alloc);
00374    fprintf (Out,"->N_MaxPointers: %d\n", Mem->N_MaxPointers);
00375    
00376    /* sort the pointers by their sizes */
00377    /* make a copy of Mem->Size to keep it from getting modified then sort it.
00378    Do not use SUMA_calloc here because that'll increment N_alloc after space is allocated! */
00379    mem_sz_sort = (int *)calloc(Mem->N_alloc, sizeof(int));
00380    if (!mem_sz_sort) {
00381       fprintf (SUMA_STDERR, "Error %s: Could not allocate for mem_sz_sort.\n", FuncName);
00382       SUMA_RETURNe;
00383    }
00384    
00385    #if 1
00386    for (i=0; i < Mem->N_alloc; ++i) mem_sz_sort[i] = Mem->Size[i];
00387    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 */
00388    
00389    Tot = 0;
00390    for (i=0; i < Mem->N_alloc; ++i) {
00391       fprintf (Out,"->[%d]\tPointer %p\t %d bytes.\n", i, Mem->Pointers[isort[i]], Mem->Size[isort[i]]);
00392       Tot += Mem->Size[isort[i]];
00393    }
00394    #else
00395      
00396    Tot = 0;
00397    for (i=0; i < Mem->N_alloc; ++i) {
00398       fprintf (Out,"->[%d]\tPointer %p\t %d bytes.\n", i, Mem->Pointers[i], Mem->Size[i]);
00399       Tot += Mem->Size[i];
00400    }
00401    #endif
00402    
00403    fprintf (Out,"Total Memory Allocated %f Mbytes.\n", (float)Tot/1000000.0);
00404    if (mem_sz_sort) free(mem_sz_sort); /* mem_sz_sort should not be freed with SUMA_free */
00405    if (isort) free(isort); /* isort should not be freed with SUMA_free */
00406    
00407    #endif
00408    
00409    SUMA_RETURNe;
00410    
00411 }

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

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.
nr  (int) number of values per node in attr (for multiplexed vectors). So, if attr was R0G0Bo R1 G1 B1, ..., RnGnBn then nr = 3 Only row major multiplexing is allowed.
Returns:
attr_sm (float *) pointer to smoothed version of attr
See also:
SUMA_SmoothAttr_Neighb_Rec

Definition at line 5205 of file SUMA_MiscFunc.c.

References SUMA_NODE_FIRST_NEIGHB::FirstNeighb, SUMA_NODE_FIRST_NEIGHB::N_Neighb, SUMA_NODE_FIRST_NEIGHB::N_Node, SUMA_NODE_FIRST_NEIGHB::NodeId, nr, SUMA_calloc, SUMA_ENTRY, and SUMA_RETURN.

Referenced by SUMA_input(), SUMA_NN_GeomSmooth(), SUMA_SmoothAttr_Neighb_Rec(), and SUMA_SurfaceMetrics_eng().

05206 {
05207    static char FuncName[]={"SUMA_SmoothAttr_Neighb"};
05208    int ni, im, offs, j;
05209     
05210    SUMA_ENTRY;
05211 
05212    if (attr_sm && attr_sm == attr) {
05213       fprintf (SUMA_STDERR, "Error %s: attr and attr_sm point to the same location. BAD!\n",FuncName);
05214       SUMA_RETURN (NULL); 
05215    }
05216    if (fn == NULL) {
05217       fprintf (SUMA_STDERR, "Error %s: fn is null, nothing to do.\n",FuncName);
05218       SUMA_RETURN (NULL); 
05219    }
05220    if (nr*fn->N_Node != N_attr) {
05221       fprintf (SUMA_STDERR, "Error %s: N_attr (%d) must be equal to nr * fn->N_Node (%d * %d = %d).\n",FuncName, N_attr, nr, fn->N_Node, nr * fn->N_Node);
05222       SUMA_RETURN (NULL); 
05223    }
05224    
05225    attr_sm = (float *)attr_sm;
05226    if (attr_sm == NULL) {
05227       attr_sm = (float *)SUMA_calloc (N_attr, sizeof(float));
05228    }
05229    
05230    if (attr_sm == NULL)
05231    {
05232       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for returning variable.\n", FuncName);
05233       SUMA_RETURN (NULL);
05234    } 
05235    
05236    
05237    for (ni=0; ni < fn->N_Node; ++ni) { /* a counter for node index */
05238       /* make sure node id corresponds to ni. That is you have a full set of nodes 0..fn->N_Node */
05239       if (fn->NodeId[ni] != ni) {
05240          /* It's OK not to die here. This does occur in patches */
05241          /*fprintf (SUMA_STDERR, "Warning %s: fn does not seem to contain an explicit list of neighbors, from 0..N_attr. fn->NodeId[ni] = %d, ni = %d. Skipping node %d.\n", \
05242             FuncName, fn->NodeId[ni], ni, ni); */
05243          /*SUMA_free(attr_sm); 
05244          attr_sm = NULL;
05245          SUMA_RETURN (attr_sm);*/
05246          continue;
05247       }
05248       offs = nr * ni;
05249       for (im=0; im<nr; ++im) {
05250          attr_sm[offs+im] = attr[offs+im];
05251          for (j=0; j < fn->N_Neighb[ni]; ++j)
05252          {
05253             attr_sm[offs+im] += attr[nr*fn->FirstNeighb[ni][j]+im]; 
05254          }   
05255          attr_sm[offs+im] /= (fn->N_Neighb[ni]+1);
05256       }
05257    }
05258    
05259    SUMA_RETURN (attr_sm);   
05260 }

float* SUMA_SmoothAttr_Neighb_Rec float *    attr,
int    N_attr,
float *    attr_sm_orig,
SUMA_NODE_FIRST_NEIGHB   fn,
int    nr,
int    N_rep
 

float * SUMA_SmoothAttr_Neighb_Rec (float *attr, int N_attr, float *attr_sm_orig, SUMA_NODE_FIRST_NEIGHB *fn, int nr, int N_rep) A wrapper function to call SUMA_SmoothAttr_Neighb repeatedly See SUMA_SmoothAttr_Neighb for input and output options. The only additional option is N_Rec the number of repeated smoothing calls.

Definition at line 5272 of file SUMA_MiscFunc.c.

References i, LocalHead, nr, SUMA_Boolean, SUMA_ENTRY, SUMA_free, SUMA_RETURN, SUMA_SL_Err, and SUMA_SmoothAttr_Neighb().

Referenced by SUMA_Overlays_2_GLCOLAR4(), and SUMA_SurfaceMetrics_eng().

05274 {
05275    static char FuncName[]={"SUMA_SmoothAttr_Neighb"};
05276    int i;
05277    float *curr_attr=NULL, *attr_sm=NULL;
05278    SUMA_Boolean LocalHead = NOPE;
05279     
05280    SUMA_ENTRY;
05281 
05282    if (N_rep < 1) {
05283       SUMA_SL_Err("N_rep < 1");
05284       SUMA_RETURN(NULL);
05285    }
05286    
05287    if (N_rep == 1 && attr == attr_sm_orig) {
05288       SUMA_SL_Err("attr = attr_sm_orig && N_rep == 1. BAD.\n");
05289       SUMA_RETURN(NULL);
05290    }
05291    
05292    i = 1;
05293    curr_attr = attr; /* initialize with user's data */
05294    while (i < N_rep) {
05295       /* intermediary calls */
05296       attr_sm = SUMA_SmoothAttr_Neighb (curr_attr, N_attr, NULL, fn, nr);
05297       if (i > 1)  { /* second or more time in */
05298          /* free input to previous calculation */
05299          if (curr_attr) SUMA_free(curr_attr);
05300       }
05301       curr_attr = attr_sm; /* setup for next calculation */
05302       ++i;
05303    }      
05304    
05305    /* last call, honor the user's return pointer */
05306    attr_sm = SUMA_SmoothAttr_Neighb (curr_attr, N_attr, attr_sm_orig, fn, nr);
05307    
05308    /* free curr_attr if i > 1, i.e. it is not the user's original copy */
05309    if (i > 1) {
05310       if (curr_attr) SUMA_free(curr_attr);
05311    }
05312       
05313    SUMA_RETURN (attr_sm); 
05314 }

float* SUMA_Sph2Cart float *    sph,
int    Nval,
float *    center
 

Function to change a bunch of spherical coordinates to cartesian ones.

Parameters:
sph  (float *) Nval*3 [rho, theta(azimuth), phi(elevation)] spherical coords
Nval  (int) number of coord triplets
center  (float *) 3x1 XYZ of center (CARTESIAN). If NULL center is 0 0 0 center is ADDED to each coord triplet after xformation to cartesian
Returns:
coord (float *) Nval*3 XYZ coords
See also:
SUMA_SPH_2_CART

Definition at line 267 of file SUMA_MiscFunc.c.

References i, SUMA_ENTRY, SUMA_malloc, SUMA_RETURN, SUMA_SL_Crit, SUMA_SPH_2_CART, and v.

00268 {
00269    static char FuncName[]={"SUMA_Sph2Cart"};
00270    float v[3], *f;
00271    int i, i3;
00272    float *coord=NULL;
00273    
00274    SUMA_ENTRY;
00275    
00276    if (Nval <= 0) {
00277       SUMA_RETURN(NULL);
00278    }
00279    
00280    coord = (float *)SUMA_malloc(Nval*sizeof(float)*3);
00281    if (!coord) {
00282       SUMA_SL_Crit("Failed to allocate");
00283       SUMA_RETURN(NULL);
00284    }
00285    
00286    for (i=0; i<Nval; ++i) {
00287       i3 = 3*i;
00288       f = &(sph[i3]);
00289       SUMA_SPH_2_CART(f, v);
00290       
00291       if (center) {
00292          coord[i3+0] = v[0] + center[0]; 
00293          coord[i3+1] = v[1] + center[1]; 
00294          coord[i3+2] = v[2] + center[2]; 
00295       } else {
00296          coord[i3+0] = v[0]; 
00297          coord[i3+1] = v[1]; 
00298          coord[i3+2] = v[2]; 
00299       }
00300    
00301    }
00302    
00303    SUMA_RETURN(coord);
00304 }

int SUMA_suck_file char *    fname,
char **    fbuf
 

A function to suck in an ascii file Shamelessly stolen from Bob's suck_file.

See also:
SUMA_file_suck

Definition at line 6784 of file SUMA_MiscFunc.c.

References close(), fd, read(), SUMA_ENTRY, SUMA_free, SUMA_malloc, SUMA_RETURN, and THD_filesize().

Referenced by SUMA_OpenDX_Read().

06785 {
06786    static char FuncName[]={"SUMA_suck_file"};
06787    int  fd , ii ;
06788    unsigned long len; 
06789    char * buf ;
06790 
06791    SUMA_ENTRY;
06792    
06793    if( fname == NULL || fname[0] == '\0' || fbuf == NULL ) SUMA_RETURN(0) ;
06794 
06795    len = THD_filesize( fname ) ;
06796    if( len <= 0 ) SUMA_RETURN(0) ;
06797 
06798    buf = (char *) SUMA_malloc( sizeof(char) * (len+4) ) ;
06799    if( buf == NULL ) SUMA_RETURN(0) ;
06800 
06801    fd = open( fname , O_RDONLY ) ;
06802    if( fd < 0 ) SUMA_RETURN(0) ;
06803 
06804    ii = read( fd , buf , len ) ;
06805    close( fd ) ;
06806    if( ii <= 0 ){ SUMA_free(buf) ; SUMA_RETURN(0); }
06807    *fbuf = buf ; SUMA_RETURN(ii) ;
06808 }

SUMA_SURFACE_CURVATURE* SUMA_Surface_Curvature float *    NodeList,
int    N_Node,
float *    NodeNormList,
float *    A,
int    N_FaceSet,
SUMA_NODE_FIRST_NEIGHB   FN,
SUMA_EDGE_LIST   SEL
 

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 5746 of file SUMA_MiscFunc.c.

References c, SUMA_NODE_FIRST_NEIGHB::FirstNeighb, i, SUMA_SURFACE_CURVATURE::Kp1, SUMA_SURFACE_CURVATURE::Kp2, MAX_INCIDENT_TRI, SUMA_NODE_FIRST_NEIGHB::N_Neighb, SUMA_NODE_FIRST_NEIGHB::N_Neighb_max, SUMA_SURFACE_CURVATURE::N_Node, SUMA_SURFACE_CURVATURE::N_SkipNode, Ni, SUMA_allocate2D(), SUMA_Boolean, SUMA_calloc, SUMA_disp_mat(), SUMA_ENTRY, SUMA_free, SUMA_free2D(), SUMA_Free_SURFACE_CURVATURE(), SUMA_Get_Incident(), SUMA_Householder(), SUMA_malloc, SUMA_MULT_MAT, SUMA_PAUSE_PROMPT, SUMA_RETURN, SUMA_SUB_MAT, SUMA_TRANSP_MAT, SUMA_SURFACE_CURVATURE::T1, and SUMA_SURFACE_CURVATURE::T2.

Referenced by SUMA_input(), and SUMA_SurfaceMetrics_eng().

05747 { 
05748    static char FuncName[] = {"SUMA_Surface_Curvature"};
05749    int i, N_Neighb, j, ji, Incident[MAX_INCIDENT_TRI], N_Incident, kk, ii, id, ND; 
05750    float  Ntmp[3],  vi[3], vj[3], *Num, NumNorm, num, denum, sWij, T1e[3], T2e[3], mg, c, s;
05751    float **fa33, **fb33, **fc33, **Ni, **Nit, *Wij, *Kij, **Tij, **I, **Mi, **Q, **Qt, **fa22, **mMi, **mMir;
05752    SUMA_Boolean *SkipNode;
05753    SUMA_SURFACE_CURVATURE *SC;
05754    
05755    SUMA_ENTRY;
05756    
05757    if (!A || !NodeList || !NodeNormList || !FN || !SEL) {
05758       fprintf (SUMA_STDERR, "Error %s: One of your inputs is NULL.\n", FuncName);
05759       SUMA_RETURN(NULL);
05760    }
05761    
05762    SC = (SUMA_SURFACE_CURVATURE *)SUMA_malloc (sizeof(SUMA_SURFACE_CURVATURE));
05763    if (!SC) {
05764       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for SC.\n", FuncName);
05765       SUMA_RETURN(NULL);
05766    }
05767    
05768    Wij = (float *)SUMA_calloc (FN->N_Neighb_max, sizeof(float));
05769    Kij = (float *)SUMA_calloc (FN->N_Neighb_max, sizeof(float));
05770    Num = (float *)SUMA_calloc (3, sizeof(float));
05771    SkipNode = (SUMA_Boolean *) SUMA_calloc (N_Node, sizeof(SUMA_Boolean));
05772    mMi = (float **) SUMA_allocate2D (2,2, sizeof(float));
05773    mMir =(float **) SUMA_allocate2D (2,2, sizeof(float));
05774    fa22 =(float **) SUMA_allocate2D (2,2, sizeof(float));
05775    Tij = (float **) SUMA_allocate2D (FN->N_Neighb_max, 3, sizeof(float));
05776    Ni =  (float **) SUMA_allocate2D (3, 1, sizeof(float));
05777    Nit = (float **) SUMA_allocate2D (1, 3, sizeof(float));
05778    fa33 =(float **) SUMA_allocate2D (3, 3, sizeof(float));
05779    fb33 =(float **) SUMA_allocate2D (3, 3, sizeof(float));
05780    fc33 =(float **) SUMA_allocate2D (3, 3, sizeof(float));
05781    I =   (float **) SUMA_allocate2D (3, 3, sizeof(float));
05782    Q =   (float **) SUMA_allocate2D (3, 3, sizeof(float));
05783    Qt =  (float **) SUMA_allocate2D (3, 3, sizeof(float));
05784    Mi =  (float **) SUMA_allocate2D (3, 3, sizeof(float));
05785    SC->T1 = (float **) SUMA_allocate2D (N_Node, 3, sizeof(float));
05786    SC->T2 = (float **) SUMA_allocate2D (N_Node, 3, sizeof(float));
05787    SC->Kp1 =(float *)SUMA_calloc (N_Node, sizeof(float));
05788    SC->Kp2 =(float *)SUMA_calloc (N_Node, sizeof(float));
05789 
05790    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) {
05791       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for Wij, Kij, Tij.\n", FuncName);
05792       if (Wij) SUMA_free(Wij);
05793       if (Kij) SUMA_free(Kij);
05794       if (Num) SUMA_free(Num);
05795       if (SkipNode) SUMA_free(SkipNode);
05796       if (mMi) SUMA_free2D((char **)mMi, 2);
05797       if (mMir) SUMA_free2D((char **)mMir, 2);
05798       if (fa22) SUMA_free2D((char **)fa22, 2);
05799       if (Tij) SUMA_free2D((char **)Tij, FN->N_Neighb_max);
05800       if (Ni) SUMA_free2D((char **)Ni, 3);
05801       if (Nit) SUMA_free2D((char **)Nit, 1);
05802       if (fa33) SUMA_free2D((char **)fa33, 3);
05803       if (fb33) SUMA_free2D((char **)fb33, 3);
05804       if (I) SUMA_free2D((char **)I, 3);
05805       if (Q) SUMA_free2D((char **)Q, 3);
05806       if (Qt) SUMA_free2D((char **)Qt, 3);
05807       if (Mi) SUMA_free2D((char **)Mi, 3);
05808       if (SC) SUMA_Free_SURFACE_CURVATURE (SC);      
05809       SUMA_RETURN(NULL);
05810    }
05811 
05812    /* 3x3 identity matrix */
05813    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;
05814    
05815    /* initialize SC */
05816    SC->N_SkipNode = 0;
05817    SC->N_Node = N_Node;
05818    
05819    fprintf (SUMA_STDERR, "%s: Beginning curvature computations:\n", FuncName);
05820    
05821    ND = 3;
05822    SC->N_SkipNode = 0;
05823    for (i=0; i < N_Node; ++i) { /* for i */
05824       #ifdef DBG_1
05825          if (!(i%10000)) {
05826             fprintf (SUMA_STDERR, "%s: [%d]/[%d] %.2f/100%% completed\n", FuncName, i, N_Node, (float)i / N_Node * 100);
05827          }
05828       #endif
05829       SkipNode[i] = NOPE;
05830       /* sanity copies */
05831       N_Neighb = FN->N_Neighb[i];
05832       id = ND * i;
05833       Ni[0][0] = NodeNormList[id]; Ni[1][0] = NodeNormList[id+1]; Ni[2][0] = NodeNormList[id+2]; /* Normal vector at i*/
05834       Nit[0][0] = NodeNormList[id]; Nit[0][1] = NodeNormList[id+1]; Nit[0][2] = NodeNormList[id+2]; /* transpose of Ni */ 
05835       vi[0] = NodeList[id]; vi[1] = NodeList[id+1]; vi[2] = NodeList[id+2];  /* node coordinate vector */ 
05836       #ifdef DBG_2
05837          fprintf (SUMA_STDERR, "%s: Looping over neighbors, i = %d\n", FuncName, i);
05838       #endif
05839       j=0;
05840       sWij = 0.0;
05841       while (j < N_Neighb) {
05842          ji = FN->FirstNeighb[i][j]; /* index of the jth first neighbor of i */
05843          id = ND * ji;
05844          vj[0] = NodeList[id]; vj[1] = NodeList[id+1]; vj[2] = NodeList[id+2];  /* node coordinate vector at jth neighbor */
05845          
05846          /* calculate Tij */
05847          #ifdef DBG_2
05848             fprintf (SUMA_STDERR, "%s: Mat Op j=%d\n", FuncName, j);
05849          #endif
05850          
05851          /* fa33 = Ni*Ni' */
05852          SUMA_MULT_MAT(Ni,Nit,fa33,3,1,3,float,float,float); 
05853          
05854          /* fb33 = I - fa33 */
05855          SUMA_SUB_MAT(I, fa33, fb33, 3, 3, float, float, float); 
05856 
05857          /* fa33 = vi - vj (only 1st column is meaningful)*/
05858          fa33[0][0] = vi[0] - vj[0];  fa33[1][0] = vi[1] - vj[1]; fa33[2][0] = vi[2] - vj[2];
05859          
05860          /* Num = fc33 = (I - Ni*Ni') * (vi - vj) (only 1st column in fc33 is meaningful)*/
05861          SUMA_MULT_MAT(fb33, fa33, fc33, 3, 3, 1, float, float, float);
05862          Num[0] = fc33[0][0]; Num[1] = fc33[1][0]; Num[2] = fc33[2][0];
05863 
05864          /* Calculate Tij at this j, a 3x1 vector unit length normalized projection projection of vj-vi onto the plane perp. to Ni */
05865          NumNorm = (float)sqrt(Num[0]*Num[0] + Num[1]*Num[1] + Num[2]*Num[2]);
05866          if (NumNorm == 0) {
05867             fprintf (SUMA_STDERR, "Warning %s: NumNorm = 0 for node %d.\n", FuncName, i); 
05868             SkipNode[i] = YUP;
05869             SC->N_SkipNode++;
05870             break;
05871          }
05872          
05873          Tij[j][0] = Num[0] / NumNorm; 
05874          Tij[j][1] = Num[1] / NumNorm; 
05875          Tij[j][2] = Num[2] / NumNorm;
05876          
05877          #ifdef DBG_2
05878             fprintf(SUMA_STDOUT,"%s: i,j, ji =%d,%d, %d Ni = %f %f %f\n Tij(%d,:) = %f %f %f.\n", \
05879                FuncName, i, j, ji,Ni[0][0], Ni[1][0], Ni[2][0], j, Tij[j][0], Tij[j][1], Tij[j][2]);
05880          #endif
05881           
05882          /* calculate Kij(j) the directional curvature along ij*/
05883          /* fa33 = (vj - vi) (only 1st column is meaningful)*/
05884          fa33[0][0] = (vj[0] - vi[0]);  fa33[1][0] = (vj[1] - vi[1]); fa33[2][0] = (vj[2] - vi[2]);
05885          /* Num = fb33 = Ni' * fa33 (only 1st value in fb33 is meaningful)*/
05886          SUMA_MULT_MAT(Nit, fa33, fb33, 1, 3, 1, float, float, float);
05887          num = fb33[0][0]; 
05888          /* denum = sum((vj - vi)^2) */
05889          denum = fa33[0][0] * fa33[0][0] + fa33[1][0] * fa33[1][0]+ fa33[2][0] * fa33[2][0]; 
05890          
05891          Kij[j] = 2 * num / denum;
05892          #ifdef DBG_2
05893             fprintf(SUMA_STDOUT,"%s: Kij[%d] = %f\n", FuncName, j, Kij[j]);
05894          #endif
05895          
05896          /* calculate the weights for integration, Wij */
05897             /* find the incident triangles */
05898             if (!SUMA_Get_Incident(i, ji, SEL, Incident, &N_Incident, 1))
05899             {
05900                fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
05901                if (Wij) SUMA_free(Wij);
05902                if (Kij) SUMA_free(Kij);
05903                if (Num) SUMA_free(Num);
05904                if (SkipNode) SUMA_free(SkipNode);
05905                if (mMi) SUMA_free2D((char **)mMi, 2);
05906                if (mMir) SUMA_free2D((char **)mMir, 2);
05907                if (fa22) SUMA_free2D((char **)fa22, 2);
05908                if (Tij) SUMA_free2D((char **)Tij, FN->N_Neighb_max);
05909                if (Ni) SUMA_free2D((char **)Ni, 3);
05910                if (Nit) SUMA_free2D((char **)Nit, 1);
05911                if (fa33) SUMA_free2D((char **)fa33, 3);
05912                if (fb33) SUMA_free2D((char **)fb33, 3);
05913                if (I) SUMA_free2D((char **)I, 3);
05914                if (Q) SUMA_free2D((char **)Q, 3);
05915                if (Qt) SUMA_free2D((char **)Qt, 3);
05916                if (Mi) SUMA_free2D((char **)Mi, 3);
05917                if (SC) SUMA_Free_SURFACE_CURVATURE (SC);      
05918                SUMA_RETURN(NULL);
05919             }
05920 
05921             #ifdef DBG_2
05922                fprintf (SUMA_STDERR,"%s: Incidents ...\n", FuncName);
05923                for (kk=0; kk < N_Incident; ++kk) {
05924                   fprintf (SUMA_STDERR,"\t %d", Incident[kk]);
05925                }
05926                fprintf (SUMA_STDERR,"\n");
05927             #endif
05928 
05929             if (N_Incident != 2 && N_Incident != 1)
05930             {
05931                fprintf (SUMA_STDERR,"Warning %s: Unexpected N_Incident = %d at i,j = %d,%d\n", FuncName, N_Incident, i, j);
05932                SkipNode[i] = YUP;
05933                ++SC->N_SkipNode;
05934                break;
05935             }
05936             Wij[j] = 0.0; 
05937             for (ii=0; ii < N_Incident; ++ii) {
05938                Wij[j] = Wij[j] + fabs(A[Incident[ii]]);
05939             }
05940             sWij += Wij[j];
05941             if (Wij[j] == 0.0) {
05942                fprintf (SUMA_STDERR,"Warning %s: Null Wij[%d] at i,j=%d,%d\n", FuncName, j, i, j);
05943                SkipNode[i] = YUP;
05944                ++SC->N_SkipNode;
05945                break; 
05946             }
05947          
05948          ++j;
05949          
05950       }/* while j*/
05951       if (!SkipNode[i]) {
05952             /* make the sum of the weights be equal to 1*/
05953             #ifdef DBG_2   
05954                fprintf (SUMA_STDERR,"%s: Wij:\n", FuncName);
05955             #endif
05956             for (ii=0; ii < N_Neighb; ++ii) {
05957                Wij[ii] /= sWij; 
05958                /*   fprintf (SUMA_STDERR,"Wij[%d]=%f\t", ii, Wij[ii]);*/
05959             }
05960             #ifdef DBG_2   
05961                fprintf (SUMA_STDERR,"\n");
05962             #endif
05963             /* calculate Mi */
05964             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;
05965             for (j=0; j < N_Neighb; ++j) {
05966                /* calculate fc33 = Tij(j,:)' * Tij(j,:) transpose on Tij is flipped from equation because Tij(j,:) should be a column vector */
05967                 fa33[0][0] = Tij[j][0]; fa33[1][0] = Tij[j][1]; fa33[2][0] = Tij[j][2];
05968                fb33[0][0] = Tij[j][0]; fb33[0][1] = Tij[j][1]; fb33[0][2] = Tij[j][2];
05969                SUMA_MULT_MAT (fa33, fb33, fc33, 3, 1, 3, float, float, float);
05970                
05971                for (ii=0; ii < 3; ++ii) {
05972                   for (kk=0; kk < 3; ++kk) {
05973                      Mi[ii][kk] = Mi[ii][kk] + Wij[j] * Kij[j] * fc33[ii][kk];
05974                   }
05975                }
05976             }
05977             #ifdef DBG_2   
05978                SUMA_disp_mat (Mi, 3, 3, 1);
05979             #endif
05980             /* calculate Householder of Ni */
05981             Ntmp[0] = Ni[0][0]; Ntmp[1] = Ni[1][0]; Ntmp[2] = Ni[2][0];
05982             if (!SUMA_Householder(Ntmp, Q)) {
05983                fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Householder for node %d.\n ", FuncName, i);
05984                mg = 0.0;
05985                SkipNode[i] = YUP;
05986                SC->N_SkipNode++;
05987             } else {
05988                T1e[0] = Q[0][1]; T1e[1] = Q[1][1]; T1e[2] = Q[2][1];
05989                T2e[0] = Q[0][2]; T2e[1] = Q[1][2]; T2e[2] = Q[2][2];  /* T tilda 1, T tilda2 */
05990                SUMA_TRANSP_MAT (Q, Qt, 3, 3, float, float);
05991                #ifdef DBG_2   
05992                   SUMA_disp_mat (Q, 3, 3, 1);
05993                   SUMA_disp_mat (Qt, 3, 3, 1);
05994                #endif
05995                
05996                /* Mi (aka fb33) = Q' * Mi * Q; Mi should become a 3x3 with 2x2  non zero minor in lower right */
05997                SUMA_MULT_MAT (Qt, Mi, fa33, 3, 3, 3, float, float, float);
05998                SUMA_MULT_MAT (fa33, Q, Mi, 3, 3, 3, float, float, float);
05999                #ifdef DBG_2   
06000                   SUMA_disp_mat (Mi, 3, 3, 1);
06001                #endif
06002                mMi[0][0] = Mi[1][1]; mMi[0][1] = Mi[1][2];
06003                mMi[1][0] = Mi[2][1]; mMi[1][1] = Mi[2][2]; 
06004                
06005                /*compute c ( = cos(theta) ) & s ( = sin(theta) )from the Givens rotation to null out the bottom left element of the non zero minor mMi*/
06006                mg = sqrt(mMi[0][0]*mMi[0][0] + mMi[1][0]*mMi[1][0]);
06007                c = mMi[0][0] / mg;
06008                s = mMi[1][0] / mg;
06009                /* rotate mMi */
06010                fa22[0][0] =  c; fa22[0][1] = s; 
06011                fa22[1][0] = -s; fa22[1][1] = c; 
06012                SUMA_MULT_MAT(fa22, mMi, mMir, 2, 2, 2, float, float, float);
06013                #ifdef DBG_2   
06014                   fprintf (SUMA_STDERR,"%s: mg = %f, c = %f, s = %f\n", FuncName,  mg, c, s);
06015                #endif   
06016                /* calculate the principal directions */
06017                SC->T1[i][0] = c * T1e[0] - s * T2e[0];               
06018                SC->T1[i][1] = c * T1e[1] - s * T2e[1];               
06019                SC->T1[i][2] = c * T1e[2] - s * T2e[2];   
06020                            
06021                SC->T2[i][0] = s * T1e[0] + c * T2e[0];               
06022                SC->T2[i][1] = s * T1e[1] + c * T2e[1];               
06023                SC->T2[i][2] = s * T1e[2] + c * T2e[2];   
06024                
06025                /* calculate the principal curvatures and mean curvatures etc ... */
06026                SC->Kp1[i] = 3 * mMir[0][0] - mMir[1][1];
06027                SC->Kp2[i] = 3 * mMir[1][1] - mMir[0][0];
06028                #ifdef DBG_2   
06029                   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);
06030                #endif   
06031             }
06032             
06033          #ifdef DBG_3
06034             SUMA_PAUSE_PROMPT("Done with node, waiting to move to next");
06035          #endif
06036          
06037       } /* not skipped (yet)*/
06038       if (SkipNode[i]) {
06039          SC->T1[i][0] = SC->T1[i][1] = SC->T1[i][2] = 0.0;
06040          SC->T2[i][0] = SC->T2[i][1] = SC->T2[i][2] = 0.0;
06041          SC->Kp1[i] = SC->Kp2[i] = 0.0;
06042       }
06043    }/* for i */
06044 
06045    /* write out the results to a file (debugging only)*/
06046    {
06047       FILE *fid;
06048       fprintf(SUMA_STDOUT,"%s: Writing Kp1 & Kp2 to Curvs_c.txt ...", FuncName);
06049       fid = fopen("Curvs_c.txt","w");
06050       for (ii=0; ii < SC->N_Node; ++ii) {
06051          /*fprintf(fid,"%f %f\n", (SC->Kp1[ii]+SC->Kp2[ii])/2, SC->Kp1[ii]*SC->Kp2[ii]);*/
06052          fprintf(fid,"%f %f\n", SC->Kp1[ii], SC->Kp2[ii]);
06053       }
06054       fclose (fid);
06055       
06056       fprintf(SUMA_STDOUT,"%s: Done.\n", FuncName);
06057    }
06058    
06059    /* free the left overs */
06060    if (Wij) SUMA_free(Wij);
06061    if (Kij) SUMA_free(Kij);
06062    if (Num) SUMA_free(Num);
06063    if (SkipNode) SUMA_free(SkipNode);
06064    if (mMi) SUMA_free2D((char **)mMi, 2);
06065    if (mMir) SUMA_free2D((char **)mMir, 2);
06066    if (fa22) SUMA_free2D((char **)fa22, 2);
06067    if (Tij) SUMA_free2D((char **)Tij, FN->N_Neighb_max);
06068    if (Ni) SUMA_free2D((char **)Ni, 3);
06069    if (Nit) SUMA_free2D((char **)Nit, 1);
06070    if (fa33) SUMA_free2D((char **)fa33, 3);
06071    if (fb33) SUMA_free2D((char **)fb33, 3);
06072    if (I) SUMA_free2D((char **)I, 3);
06073    if (Q) SUMA_free2D((char **)Q, 3);
06074    if (Qt) SUMA_free2D((char **)Qt, 3);
06075    if (Mi) SUMA_free2D((char **)Mi, 3);
06076    
06077    fprintf (SUMA_STDERR, "%s: Done with curvature computations.\n", FuncName);
06078 
06079    SUMA_RETURN (SC);
06080 }

SUMA_TAKE_A_HIKE SUMA_Take_A_Hike SUMA_FACESET_FIRST_EDGE_NEIGHB   SFFN,
int *    visited,
int *    N_visited,
int *    Consistent,
int *    FL,
int    N_FL,
int    seed
 

This function starts at one triangle and proceeds from edge to edge without going through the same triangle twice. The very first time you call the function, the seed is at a triangle that has not been visited yet. The next calls require that the seed triangle is a visited one. It is very unlikely to visit all triangles with one seed. So, the function needs to be called multiple times with different seeds and because of that, it is very slow. When a triangle is visited, it's winding order is compared the the precursor triangle. If need be, the order is corrected.

See also:
SUMA_Next_Best_Seed , SUMA_isConsistent

Definition at line 4203 of file SUMA_MiscFunc.c.

References SUMA_FACESET_FIRST_EDGE_NEIGHB::FirstNeighb, SUMA_FACESET_FIRST_EDGE_NEIGHB::N_Neighb, seed, SUMA_BAD_SEED, SUMA_ENTRY, SUMA_isConsistent(), SUMA_NO_MORE_TO_VISIT, SUMA_NO_NEIGHB, SUMA_RETURN, SUMA_TAKE_A_HIKE, and SUMA_VISITED_ALL.

04204 {
04205    static char FuncName[]={"SUMA_Take_A_Hike"};
04206    int NotFound, itry, curface, nxtface, ipcur, ipnxt, NP;
04207    static int entry=0;
04208 
04209    SUMA_ENTRY;
04210    NP = 3;
04211    curface = seed;
04212    if (!visited[curface]) { /* a new visit this should only happen on the first call */
04213       if (!entry) {
04214          *N_visited += 1;
04215          visited[curface] = 1;
04216          Consistent[curface] = 1;
04217          /*fprintf (SUMA_STDERR, "%s: visited %d\n", FuncName, curface);*/
04218       }else {
04219          fprintf (SUMA_STDERR, "Error %s: You should not send unvisited seeds, except at the very first call.\n", FuncName);
04220          SUMA_RETURN (SUMA_BAD_SEED);
04221       }
04222    }
04223    if (SFFN->N_Neighb[curface] == 0) {
04224       SUMA_RETURN (SUMA_NO_NEIGHB);
04225    }
04226    ++entry;
04227 
04228    while (*N_visited <= N_FL) {
04229       /* try the neighbors */
04230       itry = 0; /* index into neighbors */
04231       NotFound = 1; /* now new unvisited neighbor found */
04232       do {
04233          nxtface = SFFN->FirstNeighb[curface][itry];
04234          if (visited[nxtface]) {
04235             /* already visited try another neighbor */
04236             ++itry;
04237          }else {
04238             if (SFFN->N_Neighb[nxtface] == 1) {
04239                /* that's a loner, do it and continue with the neighbors */
04240                /*fprintf (SUMA_STDERR, "%s: LONER!\n", FuncName);*/
04241                visited[nxtface] = 1;
04242                Consistent[nxtface] = SUMA_isConsistent (&(FL[curface*NP]), &(FL[nxtface*NP]));
04243                /*fprintf (SUMA_STDERR, "%s: visited %d\n", FuncName, nxtface);*/
04244                *N_visited = *N_visited+1;
04245                ++itry;
04246             } else {
04247                /* that's a good one to follow */
04248                Consistent[nxtface] = SUMA_isConsistent (&(FL[curface*NP]), &(FL[nxtface*NP]));
04249                visited[nxtface] = 1;
04250                curface = nxtface;
04251                /*fprintf (SUMA_STDERR, "%s: visited %d\n", FuncName, curface);*/
04252                *N_visited = *N_visited+1;
04253                NotFound = 0;
04254                itry = 100; 
04255             }
04256          }
04257       } while (itry < SFFN->N_Neighb[curface]) ;
04258 
04259       if (NotFound) { /* no more useful neighbors on this walk, get outa here */
04260          /*fprintf (SUMA_STDERR, "%s:  N_visited = %d, N_tot = %d\n", FuncName, *N_visited, N_FL);*/
04261          SUMA_RETURN (SUMA_NO_MORE_TO_VISIT);
04262       }
04263 
04264    }
04265    
04266    SUMA_RETURN (SUMA_VISITED_ALL);
04267 }

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 5510 of file SUMA_MiscFunc.c.

References i, n0, n1, n2, SUMA_Boolean, and SUMA_RETURN.

Referenced by SUMA_SurfNorm().

05511 {
05512    static char FuncName[]={"SUMA_TriNorm"};
05513    int i;
05514    float d1[3], d2[3], d;
05515    
05516    for (i=0; i<3; ++i) {
05517          d1[i] = n0[i] - n1[i];
05518          d2[i] = n1[i] - n2[i];
05519    }
05520    norm[0] = d1[1]*d2[2] - d1[2]*d2[1];
05521    norm[1] = d1[2]*d2[0] - d1[0]*d2[2];
05522    norm[2] = d1[0]*d2[1] - d1[1]*d2[0];  
05523    
05524    d = sqrt(norm[0] * norm[0] + norm[1] * norm[1] + norm[2] * norm[2]);
05525    
05526    if (d==0.0) {
05527       norm[0] = norm[1] = norm[2] = 1.0;
05528       SUMA_RETURN (NOPE);
05529    }else {
05530       for (i=0; i<3; ++i) norm[i] /= d;
05531       SUMA_RETURN (YUP);
05532    }
05533 }

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 5547 of file SUMA_MiscFunc.c.

References i, n0, n1, n2, SUMA_ENTRY, SUMA_MT_CROSS, SUMA_MT_SUB, SUMA_NORM, and SUMA_RETURN.

Referenced by SUMA_SurfaceMetrics_eng().

05548 {
05549    static char FuncName[]={"SUMA_TriSurf3"};
05550    float dv[3], dw[3], cross[3], A; 
05551    int i, ii, coord, kk, jj;
05552    
05553    SUMA_ENTRY;
05554    
05555    SUMA_MT_SUB (dv, n1, n0);
05556    SUMA_MT_SUB (dw, n2, n0);
05557    SUMA_MT_CROSS(cross,dv,dw);
05558    SUMA_NORM(A, cross);
05559    A *= 0.5;
05560    
05561    SUMA_RETURN (A); 
05562 }

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 5576 of file SUMA_MiscFunc.c.

References a, i, n0, n1, n2, SUMA_calloc, SUMA_ENTRY, SUMA_RETURN, and SUMA_TRI_AREA.

Referenced by SUMA_SurfaceMetrics_eng().

05577 {
05578    static char FuncName[]={"SUMA_TriSurf3v"};
05579    float *A = NULL, *n0, *n1, *n2, a;
05580    int i, i3;
05581 
05582    SUMA_ENTRY;
05583    
05584    A = (float *) SUMA_calloc (N_FaceSet, sizeof(float));
05585    if (A == NULL ) {
05586       fprintf(SUMA_STDERR,"Error %s; Failed to allocate for A \n", FuncName);
05587       SUMA_RETURN (NULL);
05588    }  
05589    
05590    for (i=0;  i<N_FaceSet; ++i) {
05591       i3 = 3*i;
05592       n0 = &(NodeList[3*FaceSets[i3]]);
05593       n1 = &(NodeList[3*FaceSets[i3+1]]);
05594       n2 = &(NodeList[3*FaceSets[i3+2]]);
05595       SUMA_TRI_AREA( n0, n1, n2, A[i]); 
05596       /* A[i] = SUMA_TriSurf3 (n0, n1, n2); */
05597    }
05598    
05599    SUMA_RETURN (A);
05600 }

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

Definition at line 6615 of file SUMA_MiscFunc.c.

References LocalHead, SUMA_Boolean, SUMA_calloc, SUMA_compare_int(), SUMA_COPY_VEC, SUMA_ENTRY, SUMA_free, and SUMA_RETURN.

Referenced by SUMA_1DROI_to_DrawnROI(), and SUMA_NodesInROI().

06616 {/*SUMA_UniqueInt*/
06617    int *xtmp, *xunq, k ,*x;
06618    SUMA_Boolean LocalHead = NOPE;
06619    static char FuncName[]={"SUMA_UniqueInt"};
06620 
06621    SUMA_ENTRY;
06622    *kunq = 0;
06623 
06624    if (!xsz)
06625     {
06626       SUMA_RETURN(NULL);
06627    }
06628    if (!Sorted)
06629     {/* must sort y , put in a new location so that y is not disturbed*/
06630       x = (int *)SUMA_calloc(xsz, sizeof(int));
06631       if (!x)
06632          {
06633             fprintf (SUMA_STDERR,"Error %s: Failed to allocate for x.", FuncName);
06634             SUMA_RETURN (NULL);
06635          }
06636       for (k=0; k < xsz; ++k)
06637          x[k] = y[k];
06638       qsort(x,xsz,sizeof(int), (int(*) (const void *, const void *)) SUMA_compare_int);
06639    }
06640    else
06641       x = y;
06642 
06643    if (!xsz)   /* Nothing sent ! */
06644     SUMA_RETURN (NULL);
06645 
06646    xtmp = (int *) SUMA_calloc(xsz,sizeof(int));
06647    if (xtmp == NULL)
06648     {
06649       fprintf (SUMA_STDERR,"Error %s: Could not allocate memory", FuncName);
06650       SUMA_RETURN (NULL);
06651    }
06652 
06653    *kunq = 0;
06654    xtmp[0] = x[0];
06655    for (k=1;k<xsz;++k)
06656     {
06657       if ((x[k] != x[k - 1]))
06658          {
06659             ++*kunq;
06660             xtmp[*kunq] = x[k];   
06661          }
06662    }
06663    ++*kunq;
06664    
06665    
06666    /* get rid of extra space allocated */
06667    xunq = (int *) SUMA_calloc(*kunq,sizeof(int));
06668    SUMA_COPY_VEC(xtmp,xunq,*kunq,int,int);
06669 
06670    SUMA_free(xtmp); 
06671 
06672    if (!Sorted)
06673       SUMA_free (x);
06674 
06675    SUMA_RETURN (xunq);
06676 }/*SUMA_UniqueInt*/

int* SUMA_UniqueInt_ind int *    ys,
int    N_y,
int *    kunq,
int **    iup
 

In addition to returning the unique set of values, The function creates a vector of indices specifying which values in y were retained.

yu = SUMA_UniqueInt_ind (y, N_y, N_yu, Sorted, iu);

Parameters:
y  (int *) SORTED input vector
N_y  (int) number of elements in y
N_yu  (int *) to contain number of elements in yu
iu  (int **) to contain pointer to vector containing indices into y of the values retained in yu
See also:
SUMA_UniqueInt_ind , SUMA_z_dqsort
-Make sure y is sorted ahead of time -remember to free yu and *iu after you are done with them

Definition at line 6698 of file SUMA_MiscFunc.c.

References LocalHead, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_realloc, SUMA_RETURN, and ys.

Referenced by SUMA_ROIv2dataset(), and SUMA_ROIv2Grpdataset().

06699 {/*SUMA_UniqueInt*/
06700    int *yu=NULL, k ,*iu=NULL;
06701    SUMA_Boolean LocalHead = NOPE;
06702    static char FuncName[]={"SUMA_UniqueInt_ind"};
06703 
06704    SUMA_ENTRY;
06705    
06706    *kunq = 0;
06707 
06708    if (!N_y)
06709     {
06710       SUMA_RETURN(NULL);
06711    }
06712 
06713    if (!N_y)   /* Nothing sent ! */
06714     SUMA_RETURN (NULL);
06715 
06716    yu = (int *) SUMA_calloc(N_y,sizeof(int));
06717    iu = (int *) SUMA_calloc(N_y,sizeof(int));
06718    if (!yu || !iu)
06719     {
06720       fprintf (SUMA_STDERR,"Error %s: Could not allocate memory", FuncName);
06721       SUMA_RETURN (NULL);
06722    }
06723 
06724    *kunq = 0;
06725    yu[0] = ys[0];
06726    iu[0] = 0;
06727    for (k=1;k<N_y;++k)
06728     {
06729       if ((ys[k] != ys[k - 1]))
06730          {
06731             ++*kunq;
06732             yu[*kunq] = ys[k];   
06733             iu[*kunq] = k;
06734          }
06735    }
06736    ++*kunq;
06737    
06738    
06739    /* get rid of extra space allocated */
06740    yu = (int *) SUMA_realloc(yu, *kunq*sizeof(int));
06741    iu = (int *) SUMA_realloc(iu, *kunq*sizeof(int));
06742 
06743    *iup = iu;
06744    SUMA_RETURN (yu);
06745 }/*SUMA_UniqueInt_ind*/

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

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
IOtrace  (int) this function is called a lot, set IOtrace to 1 if you want IOtracing to be enabled (if 1 then the function will trace if DBG_trace is not 0)
Returns:
Tri index of triangle containing n1, n2 and n3 -1 if no such triangle was found

Definition at line 3881 of file SUMA_MiscFunc.c.

References i, n1, n2, SUMA_Boolean, SUMA_ENTRY, SUMA_Get_Incident(), and SUMA_RETURN.

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

03882 {
03883    static char FuncName[]={"SUMA_whichTri"};
03884    int IncTri_E1[100], IncTri_E2[100], N_IncTri_E1 = 0, N_IncTri_E2 = 0, i, j, Tri= -1;
03885    SUMA_Boolean Found = NOPE;
03886    
03887    if (IOtrace) SUMA_ENTRY;
03888    
03889    Tri = -1;
03890    /* find incident triangles to n1-n2 edge */
03891    if (!SUMA_Get_Incident(n1, n2, EL, IncTri_E1, &N_IncTri_E1, IOtrace)) {
03892       fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
03893    } else if (!SUMA_Get_Incident(n1, n3, EL, IncTri_E2, &N_IncTri_E2, IOtrace)) {
03894       /* find incident triangles to n1-n3 edge */
03895       fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_Get_Incident.\n", FuncName);
03896    } else if (N_IncTri_E1 > 99 || N_IncTri_E2 > 99 ) {
03897       /* check that we did not go overboard */
03898       fprintf (SUMA_STDERR,"Error %s: Exceeded preallocated space.\n", FuncName);
03899    } else {
03900       /* find triangle incident to both edges */
03901       i=0;
03902       Found = NOPE;
03903       while (i < N_IncTri_E1 && !Found) {
03904          j = 0;
03905          while (j < N_IncTri_E2 && !Found) {
03906             if (IncTri_E2[j] == IncTri_E1[i]) { 
03907                Found = YUP;
03908                Tri = IncTri_E2[j];
03909             }
03910             ++j;
03911          }
03912          ++i;
03913       }
03914    }
03915    if (IOtrace) { SUMA_RETURN (Tri); }
03916    else return(Tri);
03917 }

int* SUMA_z_doubqsort double *    x,
int    nx
 

Definition at line 2710 of file SUMA_MiscFunc.c.

References compare_SUMA_Z_QSORT_DOUBLE(), SUMA_Z_QSORT_DOUBLE::Index, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_RETURN, and SUMA_Z_QSORT_DOUBLE::x.

Referenced by SUMA_dPercRange(), and SUMA_LoadPrepInVol().

02711 {/*SUMA_z_qsort*/
02712    static char FuncName[]={"SUMA_z_doubqsort"}; 
02713    int *I, k;
02714    SUMA_Z_QSORT_DOUBLE *Z_Q_doubStrct;
02715    
02716    SUMA_ENTRY;
02717 
02718    /* allocate for the structure */
02719    Z_Q_doubStrct = (SUMA_Z_QSORT_DOUBLE *) SUMA_calloc(nx, sizeof (SUMA_Z_QSORT_DOUBLE));
02720    I = (int *) SUMA_calloc (nx, sizeof(int));
02721 
02722    if (!Z_Q_doubStrct || !I)
02723       {
02724          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02725          SUMA_RETURN (NULL);
02726       }
02727 
02728    for (k=0; k < nx; ++k) /* copy the data into a structure */
02729       {
02730          Z_Q_doubStrct[k].x = x[k];
02731          Z_Q_doubStrct[k].Index = k;
02732       }
02733 
02734    /* sort the structure by it's field value */
02735    qsort(Z_Q_doubStrct, nx, sizeof(SUMA_Z_QSORT_DOUBLE), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_DOUBLE);
02736 
02737    /* recover the index table */
02738    for (k=0; k < nx; ++k) /* copy the data into a structure */
02739       {
02740          x[k] = Z_Q_doubStrct[k].x;
02741          I[k] = Z_Q_doubStrct[k].Index;
02742       }
02743 
02744    /* free the structure */
02745    SUMA_free(Z_Q_doubStrct);
02746 
02747    /* return */
02748    SUMA_RETURN (I);
02749 
02750 
02751 }/*SUMA_z_doubqsort*/

int* SUMA_z_dqsort int *    x,
int    nx
 

Definition at line 2753 of file SUMA_MiscFunc.c.

References compare_SUMA_Z_QSORT_INT(), SUMA_Z_QSORT_INT::Index, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_RETURN, and SUMA_Z_QSORT_INT::x.

Referenced by SUMA_DrawnROI_to_1DDrawROI(), SUMA_OpenDrawnROI_1D(), SUMA_Overlays_2_GLCOLAR4(), SUMA_read1D(), SUMA_ROIv2dataset(), SUMA_ROIv2Grpdataset(), and SUMA_ShowOffset_Info().

02754 {/*SUMA_z_dqsort*/
02755    static char FuncName[]={"SUMA_z_dqsort"}; 
02756    int *I, k;
02757    SUMA_Z_QSORT_INT *Z_Q_iStrct;
02758    
02759    SUMA_ENTRY;
02760 
02761    /* allocate for the structure
02762  */
02763    Z_Q_iStrct = (SUMA_Z_QSORT_INT *) SUMA_calloc(nx, sizeof (SUMA_Z_QSORT_INT));
02764    I = (int *) SUMA_calloc (nx,sizeof(int));
02765 
02766    if (!Z_Q_iStrct || !I)
02767       {
02768          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02769          SUMA_RETURN (NULL);
02770       }
02771 
02772    for (k=0; k < nx; ++k) /* copy the data into a structure */
02773       {
02774          Z_Q_iStrct[k].x = x[k];
02775          Z_Q_iStrct[k].Index = k;
02776       }
02777 
02778    /* sort the structure by it's field value */
02779    qsort(Z_Q_iStrct, nx, sizeof(SUMA_Z_QSORT_INT), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_INT);
02780 
02781    /* recover the index table */
02782    for (k=0; k < nx; ++k) /* copy the data into a structure */
02783       {
02784          x[k] = Z_Q_iStrct[k].x;
02785          I[k] = Z_Q_iStrct[k].Index;
02786       }
02787 
02788    /* free the structure */
02789    SUMA_free(Z_Q_iStrct);
02790 
02791    /* return */
02792    SUMA_RETURN (I);
02793 
02794       
02795 }/*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 2800 of file SUMA_MiscFunc.c.

References calloc, compare_SUMA_Z_QSORT_INT(), free, SUMA_Z_QSORT_INT::Index, SUMA_ENTRY, SUMA_RETURN, and SUMA_Z_QSORT_INT::x.

Referenced by SUMA_ShowMemTrace().

02801 {/*SUMA_z_dqsort_nsc*/
02802    static char FuncName[]={"SUMA_z_dqsort_nsc"}; 
02803    int *I, k;
02804    SUMA_Z_QSORT_INT *Z_Q_iStrct;
02805    
02806    SUMA_ENTRY;
02807 
02808    /* allocate for the structure
02809  */
02810    Z_Q_iStrct = (SUMA_Z_QSORT_INT *) calloc(nx, sizeof (SUMA_Z_QSORT_INT));
02811    I = (int *) calloc (nx,sizeof(int));
02812 
02813    if (!Z_Q_iStrct || !I)
02814       {
02815          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02816          SUMA_RETURN (NULL);
02817       }
02818 
02819    for (k=0; k < nx; ++k) /* copy the data into a structure */
02820       {
02821          Z_Q_iStrct[k].x = x[k];
02822          Z_Q_iStrct[k].Index = k;
02823       }
02824 
02825    /* sort the structure by it's field value */
02826    qsort(Z_Q_iStrct, nx, sizeof(SUMA_Z_QSORT_INT), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_INT);
02827 
02828    /* recover the index table */
02829    for (k=0; k < nx; ++k) /* copy the data into a structure */
02830       {
02831          x[k] = Z_Q_iStrct[k].x;
02832          I[k] = Z_Q_iStrct[k].Index;
02833       }
02834 
02835    /* free the structure */
02836    free(Z_Q_iStrct);
02837 
02838    /* return */
02839    SUMA_RETURN (I);
02840 
02841       
02842 }/*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 2667 of file SUMA_MiscFunc.c.

References compare_SUMA_Z_QSORT_FLOAT(), SUMA_Z_QSORT_FLOAT::Index, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_RETURN, and SUMA_Z_QSORT_FLOAT::x.

Referenced by SUMA_MapSurface(), SUMA_PercRange(), and SUMA_SphereQuality().

02668 {/*SUMA_z_qsort*/
02669    static char FuncName[]={"SUMA_z_qsort"}; 
02670    int *I, k;
02671    SUMA_Z_QSORT_FLOAT *Z_Q_fStrct;
02672    
02673    SUMA_ENTRY;
02674 
02675    /* allocate for the structure */
02676    Z_Q_fStrct = (SUMA_Z_QSORT_FLOAT *) SUMA_calloc(nx, sizeof (SUMA_Z_QSORT_FLOAT));
02677    I = (int *) SUMA_calloc (nx, sizeof(int));
02678 
02679    if (!Z_Q_fStrct || !I)
02680       {
02681          fprintf(SUMA_STDERR,"Error %s: Allocation problem.\n",FuncName);
02682          SUMA_RETURN (NULL);
02683       }
02684 
02685    for (k=0; k < nx; ++k) /* copy the data into a structure */
02686       {
02687          Z_Q_fStrct[k].x = x[k];
02688          Z_Q_fStrct[k].Index = k;
02689       }
02690 
02691    /* sort the structure by it's field value */
02692    qsort(Z_Q_fStrct, nx, sizeof(SUMA_Z_QSORT_FLOAT), (int(*) (const void *, const void *)) compare_SUMA_Z_QSORT_FLOAT);
02693 
02694    /* recover the index table */
02695    for (k=0; k < nx; ++k) /* copy the data into a structure */
02696       {
02697          x[k] = Z_Q_fStrct[k].x;
02698          I[k] = Z_Q_fStrct[k].Index;
02699       }
02700 
02701    /* free the structure */
02702    SUMA_free(Z_Q_fStrct);
02703 
02704    /* return */
02705    SUMA_RETURN (I);
02706 
02707 
02708 }/*SUMA_z_qsort*/

Variable Documentation

SUMA_CommonFields* SUMAg_CF  
 

Global pointer to structure containing info common to all viewers

Definition at line 3 of file SUMA_MiscFunc.c.

 

Powered by Plone

This site conforms to the following standards: