1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
// 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
*/
|