Doxygen Source Code Documentation
SUMA_SurfNorm.c File Reference
#include "SUMA_suma.h"
Go to the source code of this file.
Functions | |
SUMA_SURF_NORM | SUMA_SurfNorm (float *NodeList, int N_NodeList, int *FaceSetList, int N_FaceSetList) |
SUMA_MEMBER_FACE_SETS * | SUMA_MemberFaceSets (int Nind, int *FaceSetList, int nFr, int FaceDim, char *ownerid) |
SUMA_Boolean | SUMA_Free_MemberFaceSets (SUMA_MEMBER_FACE_SETS *MF) |
Variables | |
SUMA_CommonFields * | SUMAg_CF |
Function Documentation
|
|
** File : SUMA_MemberFaceSets.c
Usage : RetStruct = SUMA_MemberFaceSets (int Nind, int * FaceSetList, int nFace, int FaceSetDim); Input paramters :
Support :
and Nind is: 7 Then RetStruct.NodeMemberOfFaceSet is: -1 0 0 ( Node 0 is not used in FaceSetList ) 0 2 -1 (Node 1 is used in Facesets 0 & 2 ) 1 -1 0 (Node 2 is used in Faceset 1) 2 -1 0 (Node 3 is used in Faceset 2) 0 1 -1 (Node 4 is used in Facesets 0 & 1) -1 0 0 (Node 5 in not used in FaceSetList) 0 1 2 (Node 6 is used in all Facesets) and RetStruct.N_Memb is: 0 2 1 1 2 0 3 Side effects : To free RetStruct, use: if (RetStruct.NodeMemberOfFaceSet) SUMA_free2D((char **)RetStruct.NodeMemberOfFaceSet, Nind); if (RetStruct.N_Memb) SUMA_free(RetStruct.N_Memb); if (RetStruct) SUMA_free(RetStrct); Definition at line 303 of file SUMA_SurfNorm.c. References i, SUMA_MEMBER_FACE_SETS::idcode_str, SUMA_MEMBER_FACE_SETS::LinkedPtrType, SUMA_MEMBER_FACE_SETS::N_links, SUMA_MEMBER_FACE_SETS::N_Memb, SUMA_MEMBER_FACE_SETS::N_Memb_max, SUMA_MEMBER_FACE_SETS::Nnode, SUMA_MEMBER_FACE_SETS::NodeMemberOfFaceSet, SUMA_MEMBER_FACE_SETS::owner_id, SUMA_allocate2D(), SUMA_calloc, SUMA_ENTRY, SUMA_free2D(), SUMA_LINKED_MEMB_FACE_TYPE, SUMA_malloc, SUMA_MAX_MEMBER_FACE_SETS, SUMA_NEW_ID, and SUMA_RETURN. Referenced by main(), SUMA_CreateIcosahedron(), and SUMA_SurfaceMetrics_eng().
00304 {/*SUMA_MemberFaceSets*/ 00305 static char FuncName[]={"SUMA_MemberFaceSets"}; 00306 SUMA_MEMBER_FACE_SETS *RetStrct; 00307 int **tmpMember; 00308 int i, inode, iface, ip , NP; 00309 00310 SUMA_ENTRY; 00311 00312 NP = FaceDim; 00313 RetStrct = (SUMA_MEMBER_FACE_SETS *)SUMA_malloc(sizeof(SUMA_MEMBER_FACE_SETS)); 00314 RetStrct->idcode_str = NULL; 00315 SUMA_NEW_ID(RetStrct->idcode_str, NULL); 00316 RetStrct->N_links = 0; 00317 if (ownerid) sprintf(RetStrct->owner_id, "%s", ownerid); 00318 else RetStrct->owner_id[0] = '\0'; 00319 RetStrct->LinkedPtrType = SUMA_LINKED_MEMB_FACE_TYPE; 00320 00321 RetStrct->N_Memb_max = RetStrct->Nnode = 0; 00322 RetStrct->N_Memb = NULL; 00323 RetStrct->NodeMemberOfFaceSet = NULL; 00324 00325 /* Allocate return variables */ 00326 tmpMember = (int **) SUMA_allocate2D (Nind, SUMA_MAX_MEMBER_FACE_SETS ,sizeof(int)); 00327 RetStrct->N_Memb = (int *) SUMA_calloc (Nind, sizeof(int)); 00328 00329 if (!tmpMember || !RetStrct->N_Memb) 00330 { 00331 fprintf (SUMA_STDERR,"Error %s: Failed to allocate for tmpMember or RetStrct->N_Memb\n", FuncName); 00332 SUMA_RETURN (RetStrct); 00333 } 00334 00335 /* loop through all facesets and tag nodes that make up FaceSets*/ 00336 for (iface=0; iface<nFr; ++iface) {/*iface*/ 00337 i = 0; 00338 ip = NP * iface; 00339 do { 00340 inode = FaceSetList[ip + i]; 00341 if (inode > Nind) { 00342 fprintf (SUMA_STDERR,"Error %s: FaceSetList contains node indices >= Nind\n", FuncName); 00343 SUMA_RETURN (RetStrct); 00344 } 00345 tmpMember[inode][RetStrct->N_Memb[inode]] = iface; 00346 ++RetStrct->N_Memb[inode]; 00347 if (RetStrct->N_Memb[inode] >= SUMA_MAX_MEMBER_FACE_SETS) { 00348 fprintf (SUMA_STDERR,"Error %s: Node %d is member of (%d FaceSets) more than SUMA_MAX_MEMBER_FACE_SETS (%d)\n",\ 00349 FuncName, inode, RetStrct->N_Memb[inode], SUMA_MAX_MEMBER_FACE_SETS); 00350 SUMA_RETURN (RetStrct); 00351 } 00352 if (RetStrct->N_Memb[inode] > RetStrct->N_Memb_max) RetStrct->N_Memb_max = RetStrct->N_Memb[inode]; 00353 ++i; 00354 } while (i < FaceDim); 00355 } 00356 00357 /*allocate just enough for returning variables */ 00358 RetStrct->NodeMemberOfFaceSet = (int **) SUMA_allocate2D (Nind, RetStrct->N_Memb_max ,sizeof(int)); 00359 if (!RetStrct->NodeMemberOfFaceSet) 00360 { 00361 fprintf(SUMA_STDERR,"Error %s: Failed to allocate for RetStrct->NodeMemberOfFaceSet\n", FuncName); 00362 SUMA_RETURN (RetStrct); 00363 } 00364 00365 /* loop through all nodes, cp results into RetStrct->NodeMemberOfFaceSet and seal with -1 */ 00366 for (inode = 0; inode < Nind; ++inode) { 00367 i = 0; 00368 while (i < RetStrct->N_Memb[inode]) { 00369 RetStrct->NodeMemberOfFaceSet[inode][i] = tmpMember[inode][i]; 00370 ++i; 00371 } 00372 /*seal with -1 */ 00373 if (RetStrct->N_Memb[inode] < RetStrct->N_Memb_max) RetStrct->NodeMemberOfFaceSet[inode][i] = -1; 00374 } 00375 00376 /* Clean up time */ 00377 if (tmpMember) SUMA_free2D((char **)tmpMember, Nind); 00378 00379 RetStrct->Nnode = Nind; 00380 SUMA_RETURN (RetStrct); 00381 00382 }/*SUMA_MemberFaceSets*/ |
|
** File : SUMA_SurfNorm.c
Usage : RetStrct = SUMA_SurfNorm (NodeList, N_NodeList, FaceSetList, N_FaceSetList ); Input paramters :
------------------- ## * Here, Node I will have its normal biased towards the direction of N2 and N3 ## * | because node I is part of two triangles from one side and one triangle in ## N1 * | each of the other 2 sides. ## * | ## I * N3 | ------------------ * | |## |######| | ## N4 | * | ## | N2 * | ## | * | ## | * | ## | * ------------------ Definition at line 87 of file SUMA_SurfNorm.c. References SUMA_SURF_NORM::FaceNormList, i, LocalHead, SUMA_SURF_NORM::N_Face, SUMA_SURF_NORM::N_Node, SUMA_SURF_NORM::NodeNormList, SUMA_alloc_problem(), SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_error_message(), SUMA_free, SUMA_LH, SUMA_RETURN, SUMA_SL_Warn, and SUMA_TriNorm(). Referenced by main(), SUMA_Cmap_To_SO(), SUMA_Cmap_To_SO_old(), SUMA_CreateIcosahedron(), SUMA_Pattie_Volume(), and SUMA_PrepSO_GeomProp_GL().
00088 {/*SUMA_SurfNorm*/ 00089 static char stmp[200], FuncName[]={"SUMA_SurfNorm"}; 00090 float d1[3], d2[3], d, nrm; 00091 SUMA_SURF_NORM RetStrct; 00092 int *Index, *N_Memb, i, j, maxind, NotMember, id, id2, ND, ip, NP; 00093 SUMA_Boolean LocalHead = NOPE; 00094 00095 SUMA_ENTRY; 00096 00097 ND = 3; 00098 NP = 3; 00099 RetStrct.N_Node = N_NodeList; /* redundant, but practical for clean up outside the function */ 00100 RetStrct.N_Face = N_FaceSetList; 00101 00102 /* allocate space */ 00103 if (LocalHead) fprintf(SUMA_STDERR,"%s: %d %d\n", FuncName, N_NodeList, N_FaceSetList); 00104 RetStrct.FaceNormList = (float *)SUMA_calloc (N_FaceSetList * NP, sizeof(float)); 00105 RetStrct.NodeNormList = (float *)SUMA_calloc (N_NodeList * ND, sizeof(float)); 00106 Index = (int *)SUMA_calloc (N_NodeList, sizeof(int)); 00107 N_Memb = (int *)SUMA_calloc (N_NodeList, sizeof(int)); 00108 if (!RetStrct.FaceNormList || !RetStrct.NodeNormList || !Index || !N_Memb) 00109 { 00110 SUMA_alloc_problem (FuncName); 00111 SUMA_RETURN (RetStrct); 00112 } 00113 00114 /* calculate and normalize triangle normals */ 00115 maxind = N_NodeList -1; 00116 for (i=0; i < N_FaceSetList; i++) { 00117 ip = NP * i; 00118 for (j=0; j < 3; j++) { 00119 d1[j] = NodeList[(ND*FaceSetList[ip])+j] - NodeList[(ND*FaceSetList[ip+1])+j]; 00120 d2[j] = NodeList[(ND*FaceSetList[ip+1])+j] - NodeList[(ND*FaceSetList[ip+2])+j]; 00121 } 00122 RetStrct.FaceNormList[ip] = d1[1]*d2[2] - d1[2]*d2[1]; 00123 RetStrct.FaceNormList[ip+1] = d1[2]*d2[0] - d1[0]*d2[2]; 00124 RetStrct.FaceNormList[ip+2] = d1[0]*d2[1] - d1[1]*d2[0]; 00125 d = sqrt(RetStrct.FaceNormList[ip]*RetStrct.FaceNormList[ip]+RetStrct.FaceNormList[ip+1]*RetStrct.FaceNormList[ip+1]+RetStrct.FaceNormList[ip+2]*RetStrct.FaceNormList[ip+2]); 00126 if (d == 0.0) { 00127 /* I used to return here with a nasty message, but it seems that FreeSurfer surfaces contain such conditions 00128 So, now I just set the normal to 1.0 in that case */ 00129 /*SUMA_error_message (FuncName,"Zero length vector, returning",1); 00130 if (RetStrct.FaceNormList) SUMA_free(RetStrct.FaceNormList); 00131 if (RetStrct.NodeNormList) SUMA_free(RetStrct.NodeNormList); 00132 if (Index) SUMA_free(Index); 00133 if (N_Memb) SUMA_free(N_Memb); 00134 SUMA_RETURN (RetStrct);*/ 00135 RetStrct.FaceNormList[ip] = 1.0; 00136 RetStrct.FaceNormList[ip+1] = 1.0; 00137 RetStrct.FaceNormList[ip+2] = 1.0; 00138 00139 } else { 00140 RetStrct.FaceNormList[ip] /= d; 00141 RetStrct.FaceNormList[ip+1] /= d; 00142 RetStrct.FaceNormList[ip+2] /= d; 00143 } 00144 00145 #if 0 00146 /* a test for the function SUMA_TriNorm */ 00147 { 00148 float test_norm[3]; 00149 SUMA_TriNorm (&(NodeList[(ND*FaceSetList[ip])]), &(NodeList[(ND*FaceSetList[ip+1])]), &(NodeList[(ND*FaceSetList[ip+2])]), test_norm); 00150 if (test_norm[0] != RetStrct.FaceNormList[ip] || test_norm[1] != RetStrct.FaceNormList[ip+1] || test_norm[2] != RetStrct.FaceNormList[ip+2]) { 00151 fprintf (SUMA_STDERR, "Error %s: Test of SUMA_TriNorm failed, difference in norms. Exiting.\n", FuncName); 00152 exit(1); 00153 } 00154 fprintf (SUMA_STDERR,"."); 00155 } 00156 00157 #endif 00158 00159 /*each node making up the FaceSet will get its normal vector updated*/ 00160 if (FaceSetList[ip] > maxind || FaceSetList[ip+1] > maxind || FaceSetList[ip+2] > maxind) { 00161 SUMA_error_message (FuncName,"FaceSetList contains indices >= N_NodeList",1); 00162 if (RetStrct.FaceNormList) SUMA_free(RetStrct.FaceNormList); 00163 if (RetStrct.NodeNormList) SUMA_free(RetStrct.NodeNormList); 00164 if (Index) SUMA_free(Index); 00165 if (N_Memb) SUMA_free(N_Memb); 00166 SUMA_RETURN (RetStrct); 00167 } 00168 00169 00170 id2 = ND * FaceSetList[ip]; 00171 RetStrct.NodeNormList[id2] += RetStrct.FaceNormList[ip]; 00172 RetStrct.NodeNormList[id2+1] += RetStrct.FaceNormList[ip+1]; 00173 RetStrct.NodeNormList[id2+2] += RetStrct.FaceNormList[ip+2]; 00174 ++N_Memb[FaceSetList[ip]]; 00175 id2 = ND * FaceSetList[ip+1]; 00176 RetStrct.NodeNormList[id2] += RetStrct.FaceNormList[ip]; 00177 RetStrct.NodeNormList[id2+1] += RetStrct.FaceNormList[ip+1]; 00178 RetStrct.NodeNormList[id2+2] += RetStrct.FaceNormList[ip+2]; 00179 ++N_Memb[FaceSetList[ip+1]]; 00180 id2 = ND * FaceSetList[ip+2]; 00181 RetStrct.NodeNormList[id2] += RetStrct.FaceNormList[ip]; 00182 RetStrct.NodeNormList[id2+1] += RetStrct.FaceNormList[ip+1]; 00183 RetStrct.NodeNormList[id2+2] += RetStrct.FaceNormList[ip+2]; 00184 ++N_Memb[FaceSetList[ip+2]]; 00185 } 00186 SUMA_LH("Normalizing"); 00187 /*Now normalize NodeNormList*/ 00188 NotMember = 0; 00189 for (i=0; i<N_NodeList; ++i) 00190 { 00191 id = ND * i; 00192 if (N_Memb[i]) 00193 { 00194 /* fprintf(SUMA_STDERR,"%s: Node %d, Normal (pre scale) %f %f %f\n", FuncName, i, RetStrct.NodeNormList[id], RetStrct.NodeNormList[id+1], RetStrct.NodeNormList[id+2]); */ 00195 RetStrct.NodeNormList[id] /= N_Memb[i]; 00196 RetStrct.NodeNormList[id+1] /= N_Memb[i]; 00197 RetStrct.NodeNormList[id+2] /= N_Memb[i]; 00198 /* normalize */ 00199 nrm = sqrt(RetStrct.NodeNormList[id]*RetStrct.NodeNormList[id] + RetStrct.NodeNormList[id+1]*RetStrct.NodeNormList[id+1] + RetStrct.NodeNormList[id+2]*RetStrct.NodeNormList[id+2]); 00200 if (nrm) { /* at times nrm is 0. This happened once on a flat surface that was not consistently wound. Nodes that were 00201 members of two triangles of opposed normals ended up with a normal (and nrm) of 0 */ 00202 RetStrct.NodeNormList[id] /= nrm; 00203 RetStrct.NodeNormList[id+1] /= nrm; 00204 RetStrct.NodeNormList[id+2] /= nrm; 00205 } 00206 00207 /* fprintf(SUMA_STDERR,"%s: Node %d, N_Memb[i] = %d, nrm = %f\n", FuncName, i, N_Memb[i], nrm); */ 00208 } 00209 else 00210 { 00211 ++NotMember; 00212 /* 00213 For some patches (Free Surfer's) such conditions are frequent, spitting out that message becomes old too quick */ 00214 /* 00215 fprintf(stdout,"\n%s Warning: Node %d is not a member of any FaceSets, returning unit vector as normal.\n", FuncName, i); 00216 */ 00217 RetStrct.NodeNormList[id] = RetStrct.NodeNormList[id+1] = RetStrct.NodeNormList[id+2] = 1.0; 00218 } 00219 } 00220 if (NotMember) { 00221 sprintf (stmp, "(IGNORE for surface patches\n" 00222 "%d nodes (%f%% of total) are\n" 00223 "not members of any FaceSets.\n" 00224 "Their normals are set to the\n" 00225 "unit vector.\n", NotMember, (float)NotMember/(float)N_NodeList*100.0); 00226 SUMA_SL_Warn(stmp); 00227 } 00228 00229 if (N_Memb) SUMA_free(N_Memb); 00230 if (Index) SUMA_free(Index); 00231 SUMA_RETURN (RetStrct); 00232 }/*SUMA_SurfNorm*/ |
Variable Documentation
|
Global pointer to structure containing info common to all viewers Definition at line 22 of file SUMA_SurfNorm.c. |