Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Dynlift/unfolding_subdivisions.adb, Revision 1.1.1.1
1.1 maekawa 1: with Integer_Support_Functions; use Integer_Support_Functions;
2: with Flatten_Mixed_Subdivisions; use Flatten_Mixed_Subdivisions;
3:
4: package body Unfolding_Subdivisions is
5:
6: function Different_Normals ( mixsub : Mixed_Subdivision ) return List is
7:
8: tmp : Mixed_Subdivision := mixsub;
9: res,res_last : List;
10:
11: begin
12: while not Is_Null(tmp) loop
13: Append_Diff(res,res_last,Head_Of(tmp).nor.all);
14: tmp := Tail_Of(tmp);
15: end loop;
16: return res;
17: end Different_Normals;
18:
19: function Extract ( normal : Vector; mixsub : Mixed_Subdivision )
20: return Mixed_Subdivision is
21:
22: tmp : Mixed_Subdivision := mixsub;
23: res,res_last : Mixed_Subdivision;
24:
25: begin
26: while not Is_Null(tmp) loop
27: declare
28: mic : Mixed_Cell := Head_Of(tmp);
29: begin
30: if mic.nor.all = normal
31: then Append(res,res_last,mic);
32: end if;
33: end;
34: tmp := Tail_Of(tmp);
35: end loop;
36: return res;
37: end Extract;
38:
39: function Merge_Same_Normal ( mixsub : Mixed_Subdivision )
40: return Mixed_Cell is
41:
42: -- DESCRIPTION :
43: -- All cells with the same inner normal will be put in one cell,
44: -- that will be contained in the mixed subdivision on return.
45:
46: -- REQUIRED :
47: -- not Is_Null(mixsub) and all mixed cells have the same inner normal.
48:
49: tmp : Mixed_Subdivision;
50: resmic,mic : Mixed_Cell;
51:
52: begin
53: mic := Head_Of(mixsub);
54: resmic.nor := new Standard_Integer_Vectors.Vector'(mic.nor.all);
55: resmic.pts := new Array_of_Lists'(mic.pts.all);
56: tmp := Tail_Of(mixsub);
57: while not Is_Null(tmp) loop
58: mic := Head_Of(tmp);
59: declare
60: last : List;
61: begin
62: for k in mic.pts'range loop
63: last := resmic.pts(k);
64: while not Is_Null(Tail_Of(last)) loop
65: last := Tail_Of(last);
66: end loop;
67: Deep_Concat_Diff(resmic.pts(k),last,mic.pts(k));
68: end loop;
69: end;
70: tmp := Tail_Of(tmp);
71: end loop;
72: return resmic;
73: end Merge_Same_Normal;
74:
75: function Merge_Same_Normal ( mixsub : Mixed_Subdivision )
76: return Mixed_Subdivision is
77:
78: -- REQUIRED :
79: -- not Is_Null(mixsub) and all mixed cells have the same inner normal.
80:
81: resmic : Mixed_Cell := Merge_Same_Normal(mixsub);
82: ressub : Mixed_Subdivision;
83:
84: begin
85: Construct(resmic,ressub);
86: return ressub;
87: end Merge_Same_Normal;
88:
89: function Merge ( mixsub : Mixed_Subdivision ) return Mixed_Subdivision is
90:
91: -- NOTE :
92: -- Cells with an unique normal are simply taken over in the result,
93: -- cells with the same normal are merged, hereby the refinement of these
94: -- cells is destroyed. Though, one could do better...
95:
96: begin
97: if Is_Null(mixsub)
98: then return mixsub;
99: else
100: declare
101: tmp : Mixed_Subdivision := mixsub;
102: res,res_last : Mixed_Subdivision;
103: mic : Mixed_Cell;
104: begin
105: while not Is_Null(tmp) loop
106: mic := Head_Of(tmp);
107: if not Is_In(res,mic.nor.all)
108: then
109: if not Is_In(Tail_Of(tmp),mic.nor.all)
110: then Append(res,res_last,mic);
111: else declare
112: tmpmic : Mixed_Subdivision := Extract(mic.nor.all,tmp);
113: bigmic : Mixed_Cell := Merge_Same_Normal(tmpmic);
114: begin
115: Append(res,res_last,bigmic);
116: end;
117: end if;
118: end if;
119: tmp := Tail_Of(tmp);
120: end loop;
121: return res;
122: end;
123: end if;
124: end Merge;
125:
126: function Relift ( l : List; point : Vector ) return List is
127:
128: tmp,res : List;
129: pt : Link_to_Vector;
130:
131: begin
132: Copy(l,res);
133: tmp := res;
134: while not Is_Null(tmp) loop
135: pt := Head_Of(tmp);
136: if pt.all = point
137: then pt(pt'last) := 1;
138: else pt(pt'last) := 0;
139: end if;
140: Set_Head(tmp,pt);
141: tmp := Tail_Of(tmp);
142: end loop;
143: return res;
144: end Relift;
145:
146: function Relift ( pts : Array_of_Lists; point : Vector )
147: return Array_of_Lists is
148:
149: res : Array_of_Lists(pts'range);
150:
151: begin
152: for i in pts'range loop
153: res(i) := Relift(pts(i),point);
154: end loop;
155: return res;
156: end Relift;
157:
158: function Relift ( mic : Mixed_Cell; point : Vector ) return Mixed_Cell is
159:
160: res : Mixed_Cell;
161:
162: begin
163: res.pts := new Array_of_Lists'(Relift(mic.pts.all,point));
164: res.nor := new Standard_Integer_Vectors.Vector'(point'range => 0);
165: Compute_Inner_Normal(res);
166: return res;
167: end Relift;
168:
169: function Relift ( mixsub : Mixed_Subdivision; point : Vector )
170: return Mixed_Subdivision is
171:
172: tmp,res,res_last : Mixed_Subdivision;
173:
174: begin
175: tmp := mixsub;
176: while not Is_Null(tmp) loop
177: Append(res,res_last,Relift(Head_Of(tmp),point));
178: tmp := Tail_Of(tmp);
179: end loop;
180: return res;
181: end Relift;
182:
183: function Is_In_Point ( pt : Link_to_Vector; l : List ) return boolean is
184:
185: -- DESCRIPTION :
186: -- Returns true if the first n coordinates of pt belong to l.
187:
188: tmp : List := l;
189: lpt : Link_to_Vector;
190:
191: begin
192: while not Is_Null(tmp) loop
193: lpt := Head_Of(tmp);
194: if lpt(lpt'first..lpt'last-1) = pt(pt'first..pt'last-1)
195: then return true;
196: else tmp := Tail_Of(tmp);
197: end if;
198: end loop;
199: return false;
200: end Is_In_Point;
201:
202: function Different_Points ( l1,l2 : List ) return natural is
203:
204: -- DESCRIPTION :
205: -- Return the number of different points of the list l2 w.r.t. l1.
206:
207: res : natural := 0;
208: tmp : List := l2;
209:
210: begin
211: while not Is_Null(tmp) loop
212: if not Is_In_Point(Head_Of(tmp),l1)
213: then res := res + 1;
214: end if;
215: tmp := Tail_Of(tmp);
216: end loop;
217: return res;
218: end Different_Points;
219:
220: function Different_Points ( l1,l2 : List ) return List is
221:
222: -- DESCRIPTION :
223: -- Return the list of different points of the list l2 w.r.t. l1.
224:
225: res,res_last : List;
226: tmp : List := l2;
227:
228: begin
229: while not Is_Null(tmp) loop
230: if not Is_In_Point(Head_Of(tmp),l1)
231: then Append(res,res_last,Head_Of(tmp).all);
232: end if;
233: tmp := Tail_Of(tmp);
234: end loop;
235: return res;
236: end Different_Points;
237:
238: function Different_Points ( pts : Array_of_Lists; mic : Mixed_Cell )
239: return natural is
240:
241: -- DESCRIPTION :
242: -- Return the number of different points of the cell mic w.r.t. pts.
243:
244: res : natural := 0;
245:
246: begin
247: for i in pts'range loop
248: res := res + Different_Points(pts(i),mic.pts(i));
249: end loop;
250: return res;
251: end Different_Points;
252:
253: function Different_Points ( pts : Array_of_Lists; mic : Mixed_Cell )
254: return Array_of_Lists is
255:
256: -- DESCRIPTION :
257: -- Return the different points of the cell mic w.r.t. pts.
258:
259: res : Array_of_Lists(pts'range);
260:
261: begin
262: for i in pts'range loop
263: res(i) := Different_Points(pts(i),mic.pts(i));
264: end loop;
265: return res;
266: end Different_Points;
267:
268: procedure Add ( l : in out List; pts : in List ) is
269:
270: -- DESCRIPTION :
271: -- Adds the points in pts to l.
272:
273: tmp : List := pts;
274: pt : Link_to_Vector;
275:
276: begin
277: while not Is_Null(tmp) loop
278: pt := Head_Of(tmp);
279: declare
280: npt : Link_to_Vector := new Vector'(pt.all);
281: begin
282: Construct(npt,l);
283: end;
284: tmp := Tail_Of(tmp);
285: end loop;
286: end Add;
287:
288: procedure Add ( l : in out Array_of_Lists; pts : in Array_of_Lists ) is
289:
290: -- DESCRIPTION :
291: -- Adds the points in pts to l.
292:
293: begin
294: for i in l'range loop
295: Add(l(i),pts(i));
296: end loop;
297: end Add;
298:
299: procedure Put_Next_to_Front ( mixsub : in out Mixed_Subdivision;
300: pts : in Array_of_Lists ) is
301:
302: -- DESCRIPTION :
303: -- Selects the next mixed cell to be processed, and puts in front
304: -- of the list of cells mixsub.
305:
306: mic1 : Mixed_Cell := Head_Of(mixsub);
307: min1 : natural := Different_Points(pts,mic1);
308: tmp : Mixed_Subdivision := Tail_Of(mixsub);
309: min : natural;
310: mic : Mixed_Cell;
311:
312: begin
313: while not Is_Null(tmp) loop
314: mic := Head_Of(tmp);
315: min := Different_Points(pts,mic);
316: if min < min1
317: then min1 := min;
318: Set_Head(mixsub,mic);
319: Set_Head(tmp,mic1);
320: end if;
321: tmp := Tail_Of(tmp);
322: end loop;
323: end Put_Next_to_Front;
324:
325: procedure Relift ( l : in out List; ref : in List ) is
326:
327: -- DESCRIPTION :
328: -- Gives all points in l, which belong to ref, lifting value 1.
329:
330: tmp : List := l;
331: pt : Link_to_Vector;
332:
333: begin
334: while not Is_Null(tmp) loop
335: pt := Head_Of(tmp);
336: if Is_In(ref,pt)
337: then pt(pt'last) := 1;
338: else pt(pt'last) := 0;
339: end if;
340: Set_Head(tmp,pt);
341: tmp := Tail_Of(tmp);
342: end loop;
343: end Relift;
344:
345: procedure Relift ( l : in out List ) is
346:
347: -- DESCRIPTION :
348: -- Gives all points lifting value 1.
349:
350: tmp : List := l;
351: pt : Link_to_Vector;
352:
353: begin
354: while not Is_Null(tmp) loop
355: pt := Head_Of(tmp);
356: pt(pt'last) := 1;
357: Set_Head(tmp,pt);
358: tmp := Tail_Of(tmp);
359: end loop;
360: end Relift;
361:
362: procedure Relift ( l : in out Array_of_Lists; ref : in Array_of_Lists ) is
363:
364: -- DESCRIPTION :
365: -- Gives all points in l, which belong to ref, lifting value 1.
366:
367: begin
368: for i in l'range loop
369: Relift(l(i),ref(i));
370: end loop;
371: end Relift;
372:
373: procedure Relift ( l : in out Array_of_Lists ) is
374:
375: -- DESCRIPTION :
376: -- Gives all points lifting value 1.
377:
378: begin
379: for i in l'range loop
380: Relift(l(i));
381: end loop;
382: end Relift;
383:
384: procedure Relift ( mic : in out Mixed_Cell; pts : in out Array_of_Lists ) is
385:
386: -- DESCRIPTION :
387: -- Gives the points in mic, which belong to pts lifting 1,
388: -- and computes the new inner normal.
389:
390: begin
391: Relift(mic.pts.all,pts);
392: Relift(pts);
393: end Relift;
394:
395: procedure Orientate_Inner_Normal
396: ( mic : in out Mixed_Cell; pts : in Array_of_Lists ) is
397:
398: -- DESCRIPTION :
399: -- Orientates the normal of mic w.r.t. the points in pts.
400:
401: done : boolean := false;
402:
403: begin
404: for i in pts'range loop
405: if Minimal_Support(mic.pts(i),mic.nor.all)
406: > Minimal_Support(pts(i),mic.nor.all)
407: then Min(mic.nor);
408: done := true;
409: end if;
410: exit when done;
411: end loop;
412: end Orientate_Inner_Normal;
413:
414: procedure Unfolding ( mixsub : in out Mixed_Subdivision ) is
415:
416: tmp : Mixed_Subdivision;
417:
418: begin
419: if not Is_Null(mixsub)
420: then
421: declare
422: mic : Mixed_Cell := Head_Of(mixsub);
423: pts : Array_of_Lists(mic.pts'range);
424: begin
425: Flatten(mic);
426: Copy(mic.pts.all,pts);
427: Process(mic,pts);
428: tmp := Tail_Of(mixsub);
429: while not Is_Null(tmp) loop
430: Put_Next_to_Front(tmp,pts);
431: mic := Head_Of(tmp);
432: declare
433: newpts : Array_of_Lists(pts'range);
434: begin
435: newpts := Different_Points(pts,mic);
436: Relift(mic,newpts);
437: Compute_Inner_Normal(mic);
438: -- Orientate_Inner_Normal(mic,pts);
439: Process(mic,newpts);
440: Add(pts,newpts);
441: Deep_Clear(newpts);
442: end;
443: tmp := Tail_Of(tmp);
444: end loop;
445: end;
446: end if;
447: end Unfolding;
448:
449: end Unfolding_Subdivisions;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>