// unseam.cmd // Splits a surface along marked edges. // Programmer: Ken Brakke, brakke@susqu.edu www.susqu.edu/brakke define edge attribute unseam_mark integer unseam := { local facet2, doomed_facet, midvertex, fix_status, oldcoord, nextedge; local oldedge, oldfacet, oldvertex, nextvertex, nextfacet; // Check assumptions if space_dimension != 3 then { errprintf "The 'unseam' command must be run in three-dimensional space.\n"; abort; }; if surface_dimension == 1 then { errprintf "The 'unseam' command is not meant for the string model.\n"; abort; }; if simplex_representation then { errprintf "The 'unseam' command is not meant for the simplex model.\n"; abort; }; if lagrange_order >= 2 then { errprintf "The 'unseam' command is meant for the linear model, not quadratic or Lagrange.\n"; abort; }; foreach edge ee where unseam_mark do { // Make sure valence is 2 if ee.valence != 2 then { errprintf "unseam: valence of marked edge %d is not 2. Aborting.\n",ee.id; abort; }; }; foreach edge ee where unseam_mark do { // Split edge while keeping same endpoints, by refining one facet // and dissolving part next to marked edge and deleting one edge. facet2 := ee.facet[2].id; refine ee.facet[1]; foreach ee.facet ff where ff.id != facet2 do { doomed_facet := ff.id; break; }; foreach facet[doomed_facet].vertex vv where vv.id != ee.vertex[1].id and vv.id != ee.vertex[2].id do { midvertex := vv.id; break; }; dissolve facet[doomed_facet]; fix_status := ee.vertex[1].fixed; fix ee.vertex[1]; delete ee.vertex[1].edge eee where eee.vertex[2].id == midvertex; if not fix_status then unfix ee.vertex[1]; }; return; // Now have to pop vertices that have two gaps foreach vertex vv where sum(vv.edge,valence==1) >= 4 and sum(vv.edge,unseam_mark) > 0 do while sum(vv.edge,valence==1) > 2 do { define oldcoord real[3]; oldcoord := vv.__x; // pick one valence 1 edge and propagate deletable edges foreach vv.edge ee where valence==1 do { nextedge := ee.id; break; }; oldedge := 0; oldfacet := 0; oldvertex := 0; while nextedge do { refine edge[nextedge]; // nextedge should be tail half nextvertex := edge[nextedge].vertex[2].id; if oldfacet then { delete vertex[nextvertex].edge ee where ee.vertex[2].id == oldvertex; if valid_element(edge[nextedge]) then oldedge := nextedge; } else oldedge := nextedge; if edge[oldedge].valence == 0 then break; oldvertex := edge[oldedge].vertex[2].id; nextfacet := edge[oldedge].facet[1].id; nextedge := 0; foreach facet[nextfacet].edge eee where eee.vertex[2].id == vv.id do { nextedge := -eee.id; break; }; }; } } // End unseam.cmd /* Usage: set edge unseam_mark (boolean for those edges you want to split) unseam */