int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SampBias"}; int N_Spec = -1; int i; SUMA_SurfaceObject *SO = NULL; SUMA_SurfSpecFile *Spec; SUMA_GENERIC_ARGV_PARSE *ps=NULL; void *SO_name = NULL; SUMA_DSET *dset=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_KUBATEST_OPTIONS Opt; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-i;-spec;-sv;-s;-o;"); SUMA_SampBias_ParseInput (argv, argc, &Opt, ps); if (argc < 4) { SUMA_S_Err("Too few arguments"); exit (0); } /* read surface */ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } SUMA_LH("Loading surface..."); SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], Opt.debug); if (!SO) { fprintf (SUMA_STDERR,"Error %s:\n" "Failed to find surface\n" "in spec file. \n", FuncName ); exit(1); } if (!(dset = calcWithOffsets(SO, &Opt))) { SUMA_S_Err("Failed to calc ratios"); exit(1); } if (!SUMA_AddNgrHist(dset->ngr, "SampBias", argc, argv)) { SUMA_S_Err("Failed to add history"); } if (Opt.prefix) { char *cc = SUMA_WriteDset_s(Opt.prefix, dset, SUMA_NO_DSET_FORMAT, 1,1); if (cc) SUMA_free(cc); } SUMA_LH("clean up"); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (Opt.outfile) SUMA_free(Opt.outfile); if (Opt.histnote) SUMA_free(Opt.histnote); if (Opt.prefix) SUMA_free(Opt.prefix); if (Opt.segdo) SUMA_free(Opt.segdo); if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free SpecFields"); } SUMA_free(Spec); Spec = NULL; if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (!SUMA_Free_CommonFields(SUMAg_CF)) { SUMA_SL_Err("SUMAg_CF Cleanup Failed!");} SUMA_RETURN(0); }
int main (int argc,char *argv[]) { /* Main */ static char FuncName[]= {"SurfQual"}; char *OutName = NULL, ext[5], *prefix = NULL, *shist=NULL; SUMA_SURFQUAL_OPTIONS *Opt; int SO_read = -1; int i, cnt, trouble, consistent = -1, eu = -1, nsi = -1, N_Spec=0; SUMA_SurfaceObject *SO = NULL; SUMA_SurfSpecFile *Spec=NULL; void *SO_name = NULL; SUMA_Boolean DoConv = NOPE, DoSphQ = NOPE, DoSelfInt = NOPE; int N_bad_nodes, N_bad_facesets; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;"); /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = SUMA_SurfQual_ParseInput (argv, argc, ps); if (argc < 2) { SUMA_S_Err("Too few options"); usage_SUMA_SurfQual(ps, 0); exit (1); } /* read all surfaces */ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec > 1 ) { SUMA_S_Err( "Mike, you cannot mix -spec with -i or -t options " "for specifying surfaces."); exit(1); } if (Spec->N_Surfs < 1) { SUMA_S_Err("No surfaces"); exit(1); } if (Opt->self_intersect) DoSelfInt = YUP; DoConv = NOPE; DoSphQ = NOPE; if (Opt->surftype) { if (!strcmp(Opt->surftype, "-sphere")) { DoSphQ = YUP; } else { /* Don't complain anymore, maybe winding checking is all users need */ } } for (i=0; i < Spec->N_Surfs; ++i) {/* loop to read in surfaces */ /* now identify surface needed */ if (!(SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, i, ps->sv[0], 0))) { SUMA_S_Err("Failed to load surface .\n"); exit(1); } fprintf(SUMA_STDERR,"\nReport for Surface %s\n", SO->Label); /* do the quality thing based on the Opt->surftype */ if (!Opt->out_prefix) prefix = SUMA_copy_string(SO->Label); else prefix = SUMA_copy_string (Opt->out_prefix); /* check the winding */ if (!SUMA_MakeConsistent (SO->FaceSetList, SO->N_FaceSet, SO->EL, 0, &trouble)) { SUMA_S_Warn( "Failed to make sure surface's mesh is consistently wound.\n" "You should fix the mesh.\n"); consistent = 0; } { int iii=0, isbad=0, ht0; int *badedge=(int*)SUMA_calloc(SO->N_Node, sizeof(int)); /* check on troubled edges */ while (iii < SO->EL->N_EL) { ht0 = SO->EL->ELps[iii][1]; /* make sure edge is not part of three triangles, if it is,skip it*/ if (SO->EL->ELps[iii][2] > 2) { ++iii; fprintf( SUMA_STDERR, "%s: Bad edge (#%d: %d--%d), \n" " part of more than 2 triangles, skip it\n", FuncName, i, SO->EL->EL[iii][0], SO->EL->EL[iii][1]); ++badedge[SO->EL->EL[iii][0]]; ++badedge[SO->EL->EL[iii][1]]; isbad = 1; continue; } ++iii; } if (isbad) { if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_replace_string ( prefix, "_BadEdgeNodes.1D.dset", ext, 0); } else { OutName = SUMA_append_string (prefix, "_BadEdgeNodes.1D.dset"); } SUMA_WRITE_ARRAY_1D(badedge,SO->N_Node,1,OutName); if (OutName) SUMA_free(OutName); OutName = NULL; } SUMA_free(badedge); badedge = NULL; } if (DoConv) { float *Cx = NULL; if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_replace_string (prefix, "_Conv_detail.1D.dset", ext, 0); } else { OutName = SUMA_append_string (prefix, "_Conv_detail.1D.dset"); } Cx = SUMA_Convexity_Engine ( SO->NodeList, SO->N_Node, SO->NodeNormList, SO->FN, OutName, NULL); if (Cx) SUMA_free(Cx); Cx = NULL; if (OutName) SUMA_free(OutName); OutName = NULL; } if (DoSphQ) { if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_string (prefix, ext); } else { OutName = SUMA_copy_string (prefix); } shist = SUMA_HistString (NULL, argc, argv, NULL); SUMA_SphereQuality (SO, OutName, shist, &N_bad_nodes, &N_bad_facesets); if (shist) SUMA_free(shist); shist = NULL; if (OutName) SUMA_free(OutName); OutName = NULL; } if (trouble) { /* put winding problem here to make it visible */ fprintf (SUMA_STDERR,"\n"); SUMA_S_Warn( "Mesh is not consistent, use ConvertSurface's -make_consistent \n" "option to fix the problem before proceeding further.\n" "Other results reported by this and other programs\n" "may be incorrect if mesh is not consistently wound.\n" ); consistent = 0; } else { consistent = 1; fprintf (SUMA_STDERR,"\n"); fprintf (SUMA_STDERR,"Surface is consistently wound\n"); } { SUMA_EULER_SO(SO, eu); fprintf (SUMA_STDERR,"\n"); fprintf(SUMA_STDERR,"Surface Euler Characteristic is: %d\n", eu); } if ((SO->EL->min_N_Hosts == 1 || SO->EL->max_N_Hosts == 1)) { fprintf (SUMA_STDERR,"\n"); fprintf(SUMA_STDERR, "Warning %s:\n" " Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SO->EL->min_N_Hosts, SO->EL->max_N_Hosts); fprintf( SUMA_STDERR, " You have edges that form a border in the surface.\n"); } if (SO->EL->min_N_Hosts == 2 && SO->EL->max_N_Hosts == 2) { fprintf (SUMA_STDERR,"\n"); fprintf(SUMA_STDERR,"Surface is closed and is a 2-manifold."); } if (SO->EL->min_N_Hosts > 2 || SO->EL->max_N_Hosts > 2) { fprintf (SUMA_STDERR,"\n"); fprintf( SUMA_STDERR, "Warning %s:\n" "Min/Max number of edge hosting triangles: [%d/%d] \n", FuncName, SO->EL->min_N_Hosts, SO->EL->max_N_Hosts); fprintf(SUMA_STDERR, "Warning %s:\n" " You have edges that belong to more than two triangles.\n" " Bad for analysis assuming surface is a 2-manifold.\n", FuncName); if (1) { int iii=0; fprintf( SUMA_STDERR, " These edges are formed by the following nodes:\n"); for (iii = 0; iii < SO->EL->N_EL; ++iii) { if (SO->EL->ELps[iii][2] > 2) fprintf (SUMA_STDERR, " %d: Edge [%d %d] shared by %d triangles.\n", iii+1, SO->EL->EL[iii][0], SO->EL->EL[iii][1] , SO->EL->ELps[iii][2] ); } } } if (DoSelfInt) { int iii; FILE *fout=NULL; byte *report = (byte *)SUMA_calloc(SO->N_Node, sizeof(byte)); if (!report) { SUMA_SL_Crit("Failed to allocate for report"); report = NULL; } fprintf( SUMA_STDERR, "\n\nChecking for intersections...:\n"); nsi = SUMA_isSelfIntersect(SO, 500, report); if (nsi) { fprintf( SUMA_STDERR, " Surface is self intersecting.\n" "%d segments were found to intersect the surface.\n", nsi); if (nsi >= 500) { fprintf( SUMA_STDERR, " It is possible that you have additional segments" " intersecting the surface.\n"); } if (report) { if (Spec->N_Surfs > 1) { sprintf(ext,"_%c", 65+i); OutName = SUMA_append_replace_string ( prefix, "_IntersNodes.1D.dset", ext, 0); } else { OutName = SUMA_append_string (prefix, "_IntersNodes.1D.dset"); } fout = fopen(OutName, "w"); if (fout) { fprintf(fout, "#List of nodes that are part of segments which intersect " "the surface\n" "#%s\n" "#A total of %d segments (search limit is 500) were found to " "intersect the surface.\n" "#Col.1 : Node index\n" "#Col.2 : Dummy flag, always 1\n", SUMA_CHECK_NULL_STR(SO->Label), nsi ); for (iii=0; iii<SO->N_Node; ++iii) if (report[iii]) fprintf(fout, "%d\t1\n", iii); fclose(fout); fout = NULL; } else { SUMA_SL_Err("Failed to open file for output."); } if (OutName) SUMA_free(OutName); } } else { fprintf(SUMA_STDERR, " Surface is not self intersecting.\n"); } if (report) SUMA_free(report); report = NULL; } fprintf (SUMA_STDERR,"\n"); if (Opt->DoSum) { /* do not change syntax, scripts depend on this */ fprintf(stdout,"Summary for %s:\n", SO->Label); fprintf(stdout,"Euler_Charac. %d\n", eu); fprintf(stdout,"Consistent_Winding %d\n", consistent); if (DoSphQ) { fprintf(stdout,"Folding_Triangles %d\n", N_bad_facesets); fprintf(stdout,"Sketchy_nodes %d\n", N_bad_nodes); } if (DoSelfInt) fprintf(stdout,"Self_Intersections %d\n", nsi); fprintf(stdout,"\n"); } } SUMA_LH("clean up"); if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free spec fields"); } SUMA_free(Spec); Spec = NULL; if (prefix) SUMA_free(prefix); prefix = NULL; if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); SUMA_RETURN(0); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SurfMatch"}; SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_SurfSpecFile *Spec = NULL; int N_Spec=0, N_inmask; byte *cmask=NULL; SUMA_SurfaceObject *SO = NULL, *SOr=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;"); if (argc < 2) { usage_SurfMatch(ps, 0); exit (1); } Opt = SUMA_SurfMatch_ParseInput (argv, argc, ps); if (Opt->debug > 2) LocalHead = YUP; /* check on inputs */ if (ps->s_N_surfnames + ps->i_N_surfnames + ps->t_N_surfnames != 2) { SUMA_S_Err("Must have two surfaces"); exit(1); } Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec != 1) { SUMA_S_Err("Multiple spec at input."); exit(1); } SOr = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], 1); if (!SOr) { fprintf (SUMA_STDERR,"Error %s:\n" "Failed to find surface\n" "in spec file. \n", FuncName ); exit(1); } if (Opt->efrac>0.0) { SUMA_SurfaceObject *SOrr=NULL; if (!(SOrr = SUMA_Mesh_Resample_nodes(SOr, Opt->efrac))) { SUMA_S_Errv("Failed to resample initial mesh at %f\n",Opt->efrac); exit(1); } SUMA_Free_Surface_Object(SOr); SOr=SOrr; SOrr=NULL; SUMA_SurfaceMetrics_eng(SOr, "EdgeList|MemberFace", NULL, 0, SUMAg_CF->DsetList); if (!SOr->Label && !(SUMA_SurfaceFileName(SOr, NOPE))) { SOr->Label = SUMA_copy_string("Le_Remaille"); } } SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, 1, ps->sv[0], 1); if (Opt->flt1 != 1.0) { SUMA_LHv("Masking out nodes deeper than %f mm", Opt->flt1); N_inmask = SUMA_NodeDepth(SO->NodeList, SO->N_Node, prjdir, NULL, Opt->flt1, &cmask, NULL); } else { N_inmask = SO->N_Node; } SUMA_S_Notev("Have Reference %s %d nodes, input %s, %d nodes (%d in mask)\n", SOr->Label, SOr->N_Node, SO->Label, SO->N_Node, N_inmask); if (Opt->b1) { Opt->s = SUMA_append_replace_string(Opt->s,"City", " ; ", 1); } SUMA_AlignCoords(SO->NodeList, SO->N_Node, cmask, 1, SOr, Opt->s); /* write surface */ if (!SUMA_Save_Surface_Object_Wrap (Opt->out_prefix, NULL, SO, SUMA_FT_NOT_SPECIFIED, SUMA_FF_NOT_SPECIFIED, NULL)) { SUMA_S_Err("Failed to write surface of whole head"); exit (1); } if (SOr) SUMA_Free_Surface_Object(SOr); SOr = NULL; if (SO) SUMA_Free_Surface_Object(SO); SO = NULL; if (cmask) SUMA_free(cmask); cmask=NULL; if (ps) SUMA_FreeGenericArgParse(ps); ps = NULL; if (N_Spec) { int k=0; for (k=0; k<N_Spec; ++k) { if (!SUMA_FreeSpecFields(&(Spec[k]))) { SUMA_S_Err("Failed to free spec fields"); } } SUMA_free(Spec); Spec = NULL; N_Spec = 0; } if (Opt) Opt = SUMA_Free_Generic_Prog_Options_Struct(Opt); if (!SUMA_Free_CommonFields(SUMAg_CF)) SUMA_error_message(FuncName,"SUMAg_CF Cleanup Failed!",1); exit(0); }
int main (int argc,char *argv[]) {/* Main */ static char FuncName[]={"SurfPatch"}; SUMA_GETPATCH_OPTIONS *Opt; char *ppref=NULL, ext[5]; float *far=NULL; MRI_IMAGE *im = NULL; int SO_read = -1; int *NodePatch=NULL, N_NodePatch=-1, *FaceSetList=NULL , N_FaceSet = -1, N_Node = -1, N_Spec=0; int i, inodeoff=-1, ilabeloff=-1, nvec, ncol, cnt; SUMA_SurfaceObject *SO = NULL; SUMA_PATCH *ptch = NULL; SUMA_SurfSpecFile *Spec; SUMA_INDEXING_ORDER d_order; void *SO_name = NULL; SUMA_Boolean exists = NOPE; SUMA_SO_File_Type typetmp; SUMA_SurfaceObject *SOnew = NULL; float *NodeList = NULL; SUMA_GENERIC_ARGV_PARSE *ps=NULL; SUMA_Boolean LocalHead = NOPE; SUMA_STANDALONE_INIT; SUMA_mainENTRY; ps = SUMA_Parse_IO_Args(argc, argv, "-i;-t;-spec;-s;-sv;"); /* Allocate space for DO structure */ SUMAg_DOv = SUMA_Alloc_DisplayObject_Struct (SUMA_MAX_DISPLAYABLE_OBJECTS); Opt = SUMA_GetPatch_ParseInput (argv, argc, ps); if (argc < 2) { SUMA_S_Err("Too few options"); usage_SUMA_getPatch(ps, 0); exit (1); } /* read all surfaces */ Spec = SUMA_IO_args_2_spec(ps, &N_Spec); if (N_Spec == 0) { SUMA_S_Err("No surfaces found."); exit(1); } if (N_Spec > 1 ) { SUMA_S_Err( "Mike, you cannot mix -spec with -i or -t options " "for specifying surfaces."); exit(1); } if (Spec->N_Surfs < 1) { SUMA_S_Err("No surfaces"); exit(1); } if (Opt->DoVol && Spec->N_Surfs != 2) { SUMA_S_Errv("Must specify 2 and only 2 surfaces with -vol options\n" "Have %d from the command line\n",Spec->N_Surfs); exit(1); } if (Opt->oType != SUMA_FT_NOT_SPECIFIED && !Opt->VolOnly) { for (i=0; i < Spec->N_Surfs; ++i) { if (Spec->N_Surfs > 1) { sprintf(ext, "_%c", 65+i); ppref = SUMA_append_string(Opt->out_prefix, ext); } else { ppref = SUMA_copy_string(Opt->out_prefix); } SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, Opt->oType, &exists); if (exists && !THD_ok_overwrite()) { fprintf(SUMA_STDERR, "Error %s:\nOutput file(s) %s* on disk.\n" "Will not overwrite.\n", FuncName, ppref); exit(1); } if (ppref) SUMA_free(ppref); ppref = NULL; if (SO_name) SUMA_free(SO_name); SO_name = NULL; } } /* read in the file containing the node information */ im = mri_read_1D (Opt->in_name); if (!im) { SUMA_S_Errv("Failed to read 1D file '%s'\n", Opt->in_name); exit(1); } far = MRI_FLOAT_PTR(im); nvec = im->nx; ncol = im->ny; if (Opt->nodecol >= ncol || Opt->labelcol >= ncol) { fprintf(SUMA_STDERR, "\n" "Error %s: Input file has a total of %d columns.\n" "One or both user-specified node (%d) and \n" "label (%d) columns are too high. Maximum usable\n" "column index is %d.\n" , FuncName, ncol, Opt->nodecol, Opt->labelcol, ncol -1 ); exit(1); } d_order = SUMA_COLUMN_MAJOR; if (!nvec) { SUMA_SL_Err("Empty file"); exit(1); } /* form the node vector */ NodePatch = (int *)SUMA_malloc(sizeof(int)*nvec); if (!NodePatch) { SUMA_SL_Crit("Failed to allocate."); exit(1); } inodeoff = Opt->nodecol*nvec; if (Opt->labelcol < 0) { /* all listed nodes */ for (i=0; i<nvec; ++i) { NodePatch[i] = far[i+inodeoff]; } N_NodePatch = nvec; } else { ilabeloff = Opt->labelcol*nvec; if (Opt->thislabel < 0) { /* all nodes with non zero labels */ cnt = 0; for (i=0; i<nvec; ++i) { if (far[i+ilabeloff]) { NodePatch[cnt] = far[i+inodeoff]; ++cnt; } } N_NodePatch = cnt; } else { /* select labels */ cnt = 0; for (i=0; i<nvec; ++i) { if (far[i+ilabeloff] == Opt->thislabel) { NodePatch[cnt] = far[i+inodeoff]; ++cnt; } } N_NodePatch = cnt; } NodePatch = (int *) SUMA_realloc(NodePatch , sizeof(int)*N_NodePatch); } /* done with im, free it */ mri_free(im); im = NULL; if (Opt->DoVol) { SUMA_SurfaceObject *SO1 = SUMA_Load_Spec_Surf_with_Metrics(Spec, 0, ps->sv[0], 0); SUMA_SurfaceObject *SO2 = SUMA_Load_Spec_Surf_with_Metrics(Spec, 1, ps->sv[0], 0); double Vol = 0.0; SUMA_SurfaceObject *SOp = SUMA_Alloc_SurfObject_Struct(1); byte *adj_N=NULL; if (Opt->adjust_contour) adj_N = SUMA_calloc(SO1->N_Node, sizeof(byte)); if (!SO1 || !SO2) { SUMA_SL_Err("Failed to load surfaces."); exit(1); } /* a chunk used to test SUMA_Pattie_Volume */ Vol = SUMA_Pattie_Volume(SO1, SO2, NodePatch, N_NodePatch, SOp, Opt->minhits, Opt->FixBowTie, Opt->adjust_contour, adj_N, Opt->verb); fprintf (SUMA_STDOUT,"Volume = %f\n", fabs(Vol)); if (Opt->out_volprefix) { if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SOp->FileType = Opt->oType; if (Opt->flip) { if (Opt->verb > 1) SUMA_S_Note("Flipping stitched surf's triangles\n"); SUMA_FlipSOTriangles (SOp); } if (!(SUMA_Save_Surface_Object_Wrap ( Opt->out_volprefix, NULL, SOp, SUMA_PLY, SUMA_ASCII, NULL))) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); } if (Opt->adjust_contour && adj_N) { Opt->out_volprefix = SUMA_append_replace_string(Opt->out_volprefix, ".adjneighb","",1); ppref = SUMA_Extension(Opt->out_volprefix, ".1D.dset", NOPE); SUMA_WRITE_IND_ARRAY_1D(adj_N, NULL, SO1->N_Node, 1, ppref); SUMA_free(ppref); ppref=NULL; } } if (SOp) SUMA_Free_Surface_Object(SOp); SOp = NULL; } if (!Opt->VolOnly) { FaceSetList = NULL; N_FaceSet = -1; for (i=0; i < Spec->N_Surfs; ++i) {/* loop to read in surfaces */ /* now identify surface needed */ if (!(SO = SUMA_Load_Spec_Surf_with_Metrics(Spec, i, ps->sv[0], 0))) { SUMA_S_Err("Failed to load surface .\n"); exit(1); } if (SO->aSO) { /* otherwise, when you reset the number of FaceSets for example, and you still write in GIFTI, the old contents of aSO will prevail */ SO->aSO = SUMA_FreeAfniSurfaceObject(SO->aSO); } /* extract the patch */ ptch = SUMA_getPatch (NodePatch, N_NodePatch, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, SO->MF, Opt->minhits, Opt->FixBowTie, (!i && !Opt->DoVol)); /* verbose only for first patch, and if no volume computation was required This is to keep the warnings to a minimum*/ if (!ptch) { SUMA_SL_Err("Failed to form patch."); exit(1); } if (LocalHead) SUMA_ShowPatch(ptch, NULL); /* Now create a surface with that patch */ if (Spec->N_Surfs > 1) { sprintf(ext, "_%c", 65+i); ppref = SUMA_append_string(Opt->out_prefix, ext); } else { ppref = SUMA_copy_string(Opt->out_prefix); } /* save the original type */ typetmp = SO->FileType; if (Opt->oType != SUMA_FT_NOT_SPECIFIED) SO->FileType = Opt->oType; SO_name = SUMA_Prefix2SurfaceName(ppref, NULL, NULL, SO->FileType, &exists); if (ppref) SUMA_free(ppref); ppref = NULL; /* save the original pointers to the facesets and their number */ FaceSetList = SO->FaceSetList; N_FaceSet = SO->N_FaceSet; NodeList = SO->NodeList; N_Node = SO->N_Node; /* replace with Patch */ SO->FaceSetList = ptch->FaceSetList; SO->N_FaceSet = ptch->N_FaceSet; if (Opt->Do_p2s) { if (LocalHead) fprintf (SUMA_STDERR, "%s: Changing patch to surface...\n", FuncName); SOnew = SUMA_Patch2Surf(SO->NodeList, SO->N_Node, SO->FaceSetList, SO->N_FaceSet, 3); if (!SOnew) { SUMA_S_Err("Failed to change patch to surface."); exit(1); } SO->FaceSetList = SOnew->FaceSetList; SO->N_FaceSet = SOnew->N_FaceSet; SO->N_Node = SOnew->N_Node; SO->NodeList = SOnew->NodeList; } if (SO->N_FaceSet <= 0) { SUMA_S_Warn("The patch is empty.\n" " Non existing surface not written to disk.\n"); } else { /* Is the gain wanted? */ if (Opt->coordgain) { SUMA_SL_Note("Applying coord gain to surface nodes!"); for (cnt=0; cnt < SO->NodeDim*SO->N_Node; ++cnt) SO->NodeList[cnt] *= Opt->coordgain; } if (Opt->flip) { if (Opt->verb > 1) SUMA_S_Note("Flipping triangles\n"); SUMA_FlipTriangles (SO->FaceSetList, SO->N_FaceSet); SUMA_RECOMPUTE_NORMALS(SO); } if (!SUMA_Save_Surface_Object (SO_name, SO, SO->FileType, SUMA_ASCII, NULL)) { fprintf (SUMA_STDERR, "Error %s: Failed to write surface object.\n", FuncName); exit (1); } } /* bring SO back to shape */ SO->FileType = typetmp; SO->FaceSetList = FaceSetList; FaceSetList = NULL; SO->N_FaceSet = N_FaceSet; N_FaceSet = -1; SO->NodeList = NodeList; NodeList = NULL; SO->N_Node = N_Node; N_Node = -1; if (SO_name) SUMA_free(SO_name); SO_name = NULL; if (ptch) SUMA_freePatch(ptch); ptch = NULL; if (SOnew) SUMA_Free_Surface_Object(SOnew); SOnew = NULL; /* get rid of old surface object */ } } SUMA_LH("clean up"); if (!SUMA_FreeSpecFields(Spec)) { SUMA_S_Err("Failed to free spec fields"); } SUMA_free(Spec); Spec = NULL; if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL; if (Opt->out_volprefix) SUMA_free(Opt->out_volprefix); Opt->out_volprefix = NULL; if (Opt) SUMA_free(Opt); if (!SUMA_Free_Displayable_Object_Vect (SUMAg_DOv, SUMAg_N_DOv)) { SUMA_SL_Err("DO Cleanup Failed!"); } if (!SUMA_Free_CommonFields(SUMAg_CF)) { SUMA_SL_Err("SUMAg_CF Cleanup Failed!"); } SUMA_RETURN(0); }