File: simply_connected.cmd

package info (click to toggle)
evolver 2.70+ds-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 17,148 kB
  • sloc: ansic: 127,395; makefile: 209; sh: 98
file content (258 lines) | stat: -rw-r--r-- 7,152 bytes parent folder | download | duplicates (2)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// simply_connected.cmd

// Surface Evolver command to find seams for splitting a multiply-connected
// surface into a simply connected surface.  Meant for setting up Bonnet
// rotations of triply-periodic minimal surfaces.

define vertex attribute sc_vmark integer 
define edge attribute sc_emark integer 
define facet attribute sc_fmark integer
define vertex attribute sc_vdistance integer
define edge attribute sc_edistance integer
define facet attribute sc_fdistance integer

sc_startf := 0
sc_startv := 0

mark_distances := {

  local changes,current_distance,unmarked_edges,unmarked_vertices;

  // sanity checks
  if max(edge,valence) > 2 then
  { printf "mark_simply_connected error: there are edges with valence > 2.\n";
    abort;
  };
  
set facet color white;
set edge color black;

  // starting vertex  
  if not valid_element(vertex[sc_startv]) then  // find a starting facet
    foreach vertex vv do 
    { sc_startv := vv.id;
      break;
    };


  // initialize
  set vertex sc_vdistance -1;
  set edge sc_edistance -1;
  set facet sc_fdistance -1;
  foreach vertex[sc_startv].facet ff do
  {
    ff.sc_fdistance := 1;
    set ff.vertex sc_vdistance 1;
    set ff.edge sc_edistance 1;
  };
  vertex[sc_startv].sc_vdistance := 0;

  current_distance := 1;

  // sweep with increasing distance, adding further facets that are
  // edge neighbors as long as Euler sum is ok.
  do
  { 
    changes := 0;
    foreach edge ee where valence == 2 and 
      ee.sc_edistance == current_distance and
        (ee.facet[1].sc_fdistance*ee.facet[2].sc_fdistance < 0) do
    { foreach ee.facet fff where fff.sc_fdistance == -1 do
      { // add facet
        fff.sc_fdistance := current_distance + 1;
        set fff.edges.sc_edistance current_distance + 1 where sc_edistance < 0;
        set fff.vertices.sc_vdistance current_distance + 1 where sc_vdistance < 0;
        changes += 1;
fff.color := (current_distance imod 14) + 1;
      }
    };
    current_distance += 1;
printf "distance %d\n",current_distance;
  } while changes;


}

// old version calculates its own distances, but those can be messed
// up by the simply-connected mechanism.
mark_simply_connected_old := {

  local changes,current_distance,unmarked_edges,unmarked_vertices;

  // sanity checks
  if max(edge,valence) > 2 then
  { printf "mark_simply_connected error: there are edges with valence > 2.\n";
    abort;
  };
  
set facet color white;
set edge color black;

  // starting vertex  
  if not valid_element(vertex[sc_startv]) then  // find a starting facet
    foreach vertex vv do 
    { sc_startv := vv.id;
      break;
    };


  // initialize
  set vertex sc_vmark -1;
  set edge sc_emark -1;
  set facet sc_fmark -1;
  set facet sc_fdistance -1;
  foreach vertex[sc_startv].facet ff do
  {
    ff.sc_fdistance := 1;
    set ff.vertex sc_vmark 1;
    set ff.edge sc_emark 1;
  };
  current_distance := 1;

  // sweep with increasing distance, adding further facets that are
  // edge neighbors as long as Euler sum is ok.
  do
  { changes := 0;
    foreach facet ff where sc_fdistance == current_distance do
    { foreach ff.edge ee where valence == 2 and 
          (ee.facet[1].sc_fdistance*ee.facet[2].sc_fdistance < 0) do
      { foreach ee.facet fff where fff.sc_fdistance == -1 do
        { local unmarked_edges,unmarked_vertices;
          unmarked_edges := sum(fff.edge, sc_emark < 0);
          unmarked_vertices := sum(fff.vertex, sc_vmark < 0);
          if unmarked_vertices - unmarked_edges + 1 == 0 then
          { // add facet
            fff.sc_fdistance := current_distance + 1;
            set fff.edges.sc_emark current_distance + 1 where sc_emark < 0;
            set fff.vertices.sc_vmark current_distance + 1 where sc_vmark < 0;
            changes += 1;
fff.color := (current_distance imod 14) + 1;
          }
        }

      }
    };
    current_distance += 1;
printf "distance %d\n",current_distance;
  } while changes;

  // distance numbers for the open band facets
  set facet sc_fmark (sc_fdistance > 0);
  do
  { changes := 0;
    foreach facet ff where sc_fmark == 0 do
    { local newdist;
      newdist := min(ff.edge ee where sc_emark > 0, sc_emark);
      if newdist > 0 and ((newdist < ff.sc_fdistance) or (ff.sc_fdistance < 0))
      then
      { ff.sc_fdistance := newdist + 1;
        set ff.edge sc_emark newdist + 1;
ff.color := (newdist imod 14) + 1;
        changes += 1;
      };
    };
printf "changes %d\n",changes;
  } while changes;



set edge ee color white where valence==2 and 
 ee.facet[1].sc_fdistance == ee.facet[2].sc_fdistance
 and max(ee.facet, sc_fmark==0);

set edge ee color green where valence==2 and 
   abs(ee.facet[1].sc_fdistance-ee.facet[2].sc_fdistance)==2
     and max(ee.facet, sc_fmark==0);
} 




  


  
  
mark_simply_connected := {

  local max_dist;

  // assuming mark_distances has already been run.

  // sanity checks
  if max(edge,valence) > 2 then
  { printf "mark_simply_connected error: there are edges with valence > 2.\n";
    abort;
  };
  
set facet color white;
set edge color black;

  max_dist := max(facet,sc_fdistance);

  // starting vertex  
  if not valid_element(vertex[sc_startv]) then  // find a starting facet
    foreach vertex vv do 
    { sc_startv := vv.id;
      break;
    };


  // initialize
  set vertex sc_vmark -1;
  set edge sc_emark -1;
  set facet sc_fmark -1;
  foreach vertex[sc_startv].facet ff do
  {
    ff.sc_fmark := 1;
    set ff.vertex sc_vmark 1;
    set ff.edge sc_emark 1;
    ff.color := 2;
  };

  // sweep with increasing distance, adding further facets that are
  // edge neighbors as long as Euler sum is ok.
  do
  { changes := 0;
    current_distance := 1;
    for ( current_distance := 1 ; current_distance <= max_dist ; 
              current_distance += 1 )
    { 
      foreach edge ee where sc_emark > 0 and valence == 2 and 
          sc_edistance == current_distance do

// make it so only go UP in distance!

      { foreach ee.facet fff where fff.sc_fmark == -1
          and fff.sc_fdistance > current_distance do
        { unmarked_edges := sum(fff.edge, sc_emark < 0);
          unmarked_vertices := sum(fff.vertex, sc_vmark < 0);
          if unmarked_vertices - unmarked_edges + 1 == 0 then
          { // add facet
            fff.sc_fmark := 1;
            set fff.edges.sc_emark 1;
            set fff.vertices.sc_vmark 1;
            changes += 1;
            fff.color := (current_distance imod 14) + 1;
          }
        }

      };
printf "distance %d\n",current_distance;
    }

  } while changes;


set edge ee color white where valence==2 and 
 ee.facet[1].sc_fdistance == ee.facet[2].sc_fdistance
 and max(ee.facet, sc_fmark==0);

set edge ee color green where valence==2 and 
   abs(ee.facet[1].sc_fdistance-ee.facet[2].sc_fdistance)==2
     and max(ee.facet, sc_fmark==0);
} 

// end simply_connected.cmd

// Usage: mark_simply_connected