File: offn.cmd

package info (click to toggle)
evolver 2.70%2Bds-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 17,148 kB
  • sloc: ansic: 127,395; makefile: 209; sh: 98
file content (95 lines) | stat: -rw-r--r-- 2,954 bytes parent folder | download | duplicates (3)
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
// offn.cmd
// Surface Evolver command to print Geomview OFF file with virtual vertices to 
// separate films meeting at triple lines, permitting
// local normal calculation for smoothing.

// Usage: offn >>> "filename.off"

// Algorithm: Goes through facets, and for each vertex on a facet
// compares the facet normal to existing virtual vertex normal. If
// none is close enough, a new virtual vertex is created.

// Limits: Assumes no more than 6 virtual vertices are needed at a vertex.

define vertex attribute vircount integer // number of virtual vertices at vertex
define vertex attribute virlist  real[6] // ID's of virtual vertices
define vertex attribute virnorm  real[18] // virtual normals
define facet attribute virvertex integer[3]

cosine_cutoff := 0.8 // criterion for matching normals

makevir := { 
   local  nx,ny,nz,norm,kk,vn,cosang;

   offn_virnum := 0;
   set vertex vircount 0;
   foreach facet ff where show and color >= 0 do
   { nx := ff.x; ny := ff.y; nz := ff.z;
     norm := sqrt(nx^2 + ny^2 + nz^2);
     nx := nx/norm; ny := ny/norm; nz := nz/norm;
     kk := 1; // which facet vertex
     foreach ff.vertex vv do
     { vn := 1;
       while ( vn <= vv.vircount ) do
       { cosang := nx*vv.virnorm[3*vn-2] + ny*vv.virnorm[3*vn-1] 
                     + nz*vv.virnorm[3*vn];
         if ( abs(cosang) >= cosine_cutoff ) then break;
         vn := vn+1;
       };
       if ( vn > vv.vircount ) then
       { vv.vircount := vv.vircount + 1;
         if ( vv.vircount > 6 ) then
         { printf"Too many virtual vertices at vertex %g facet %g\n",vv.id,ff.id;
           return;
         };
         vv.virlist[vv.vircount] := offn_virnum;
         ff.virvertex[kk] := offn_virnum;
         offn_virnum := offn_virnum + 1;
         vv.virnorm[3*vn-2] := nx;
         vv.virnorm[3*vn-1] := ny;
         vv.virnorm[3*vn] := nz;
       }
       else ff.virvertex[kk] := vv.virlist[vn];
       kk := kk+1;
     }
   }
}

flist := { 
  foreach facet ff where show and color >= 0 do 
  { printf "3 %g %g %g\n",ff.virvertex[1],ff.virvertex[2],ff.virvertex[3];
  }
}
printvir := {
   local vn;

   offn_virnum := 0;
   foreach facet ff do
   { foreach ff.vertex vv do
     { vn := 1;
       while ( vn <= vv.vircount ) do
       { if ( offn_virnum == vv.virlist[vn] ) then
         { printf "%f %f %f\n",vv.x,vv.y,vv.z; // add to output vertex list
           offn_virnum := offn_virnum + 1;
           break;
         };
         vn := vn+1;
       };
     }
   }
}

offn := {  makevir;
           printf "OFF\n%g %g %g\n",offn_virnum,
              sum(facet,show and color >= 0),
              sum(edge,show and color >= 0);
           printvir;
           flist
        }

/* Usage:
    Set cosine_cutoff (default 0.8) for detection of ridges.
    Set facet "show" criterion, if desired. Then
     offn >>> "filename.off"
*/