Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Dynlift/dynamic_mixed_subdivisions.adb, Revision 1.1.1.1
1.1 maekawa 1: with Standard_Integer_VecVecs; use Standard_Integer_VecVecs;
2: with Transforming_Integer_Vector_Lists; use Transforming_Integer_Vector_Lists;
3: with Initial_Mixed_Cell;
4: with Vertices,Simplices; use Vertices,Simplices;
5: with Global_Dynamic_Triangulation; use Global_Dynamic_Triangulation;
6: with Integer_Lifting_Utilities; use Integer_Lifting_Utilities;
7: with Dynamic_Lifting_Functions; use Dynamic_Lifting_Functions;
8: with Flatten_Mixed_Subdivisions; use Flatten_Mixed_Subdivisions;
9: with Enumerate_Faces_of_Polytope; use Enumerate_Faces_of_Polytope;
10: with Common_Faces_of_Polytope; use Common_Faces_of_Polytope;
11: with Integer_Pruning_Methods; use Integer_Pruning_Methods;
12: with Mixed_Volume_Computation; use Mixed_Volume_Computation;
13: with Contributions_to_Mixed_Volume; use Contributions_to_Mixed_Volume;
14:
15: package body Dynamic_Mixed_Subdivisions is
16:
17: -- UTILITIES :
18:
19: function Is_Empty ( points : Array_of_Lists ) return boolean is
20: begin
21: for i in points'range loop
22: if not Is_Null(points(i))
23: then return false;
24: end if;
25: end loop;
26: return true;
27: end Is_Empty;
28:
29: function First_Non_Empty ( points : Array_of_Lists ) return integer is
30:
31: -- DESCRIPTION :
32: -- Returns the index of the first non empty set in the points.
33:
34: res : integer := points'first - 1;
35:
36: begin
37: for i in points'range loop
38: if not Is_Null(points(i))
39: then res := i;
40: end if;
41: exit when res >= points'first;
42: end loop;
43: return res;
44: end First_Non_Empty;
45:
46: function Is_In ( fs : Face_Structure; point : vector ) return boolean is
47: begin
48: if Is_Null(fs.t)
49: then return Is_In(fs.l,point);
50: else return Is_In(fs.t,point);
51: end if;
52: end Is_In;
53:
54: -- procedure put ( n : in natural; fs : in Face_Structure ) is
55: -- begin
56: -- put_line("The list of lifted points : "); put(fs.l);
57: -- put_line("The list of k-faces : "); put(fs.f);
58: -- put_line("The triangulation : "); put(n,fs.t);
59: -- end put;
60:
61: -- procedure put ( n : in natural; fs : in Face_Structures ) is
62: -- begin
63: -- for i in fs'range loop
64: -- put("face structure for component "); put(i,1);
65: -- put_line(" :");
66: -- put(n,fs(i));
67: -- end loop;
68: -- end put;
69:
70: -- FLATTENING :
71:
72: procedure Flatten ( points : in out VecVec ) is
73:
74: pt : Link_to_Vector;
75:
76: begin
77: for i in points'range loop
78: pt := points(i);
79: if pt(pt'last) /= 0
80: then pt(pt'last) := 0;
81: end if;
82: end loop;
83: end Flatten;
84:
85: procedure Flatten ( f : in out Face ) is
86: begin
87: Flatten(f.all);
88: end Flatten;
89:
90: procedure Flatten ( fs : in out Faces ) is
91:
92: tmp : Faces := fs;
93: f : Face;
94:
95: begin
96: while not Is_Null(tmp) loop
97: f := Head_Of(tmp);
98: Flatten(f);
99: Set_Head(tmp,f);
100: tmp := Tail_Of(tmp);
101: end loop;
102: end Flatten;
103:
104: procedure Flatten ( fs : in out Face_Structure ) is
105: begin
106: Flatten(fs.l); Flatten(fs.t); Flatten(fs.f);
107: end Flatten;
108:
109: procedure Flatten ( fs : in out Face_Structures ) is
110: begin
111: for i in fs'range loop
112: Flatten(fs(i));
113: end loop;
114: end Flatten;
115:
116: -- ZERO CONTRIBUTION :
117:
118: function Extract_Facet ( n : natural; s : Simplex ) return Face is
119:
120: ver : constant VecVec := Simplices.Vertices(s);
121: res : Face := new VecVec(ver'range);
122:
123: begin
124: for i in res'range loop
125: res(i) := new Standard_Integer_Vectors.Vector'(ver(i)(1..n));
126: end loop;
127: return res;
128: end Extract_Facet;
129:
130: function Extract_Facets ( n : natural; t : Triangulation; x : Vector )
131: return Faces is
132:
133: -- DESCRIPTION :
134: -- Returns the list of facets in t that all contain x.
135: -- The facets are given in their original coordinates.
136:
137: -- REQUIRED : x is lifted, i.e., x'length = n+1.
138:
139: tmp : Triangulation := t;
140: res,res_last : Faces;
141:
142: begin
143: while not Is_Null(tmp) loop
144: declare
145: s : Simplex := Head_Of(tmp);
146: begin
147: if Is_Vertex(s,x)
148: then Append(res,res_last,Extract_Facet(n,s));
149: end if;
150: end;
151: tmp := Tail_Of(tmp);
152: end loop;
153: return res;
154: end Extract_Facets;
155:
156: function Zero_Contribution ( n : natural; fs : Face_Structures;
157: x : Vector; i : natural ) return boolean is
158:
159: -- DESCRIPTION :
160: -- Returns true if the point x does not contribute to the mixed volume
161: -- when considered to the ith component of the already lifted points.
162:
163: -- REQUIRED : x'length = n+1, n = dimension before lifting.
164:
165: res : boolean := false;
166: supp : Array_of_Lists(fs'range);
167:
168: begin
169: for j in supp'range loop
170: supp(j) := Reduce(fs(j).l,n+1);
171: end loop;
172: if Length_Of(fs(i).t) > 1
173: then declare
174: facets : Faces := Extract_Facets(n,fs(i).t,x);
175: begin
176: res := Simple_Zero_Contribution(supp,facets,x(1..n),i);
177: end;
178: else res := Simple_Zero_Contribution(supp,x(1..n),i);
179: end if;
180: Deep_Clear(supp);
181: return res;
182: end Zero_Contribution;
183:
184: -- INITIALIZATION :
185:
186: procedure Initialize
187: ( n : in natural; mix : in Vector; points : in Array_of_Lists;
188: mixsub : in out Mixed_Subdivision;
189: fs : in out Face_Structures; rest : in out Array_of_Lists;
190: done : in out boolean ) is
191:
192: -- DESCRIPTION :
193: -- Performs initialization of the dynamic lifting algorithm.
194:
195: -- ON ENTRY :
196: -- n length of the vectors in points;
197: -- mix type of mixture;
198: -- mixsub mixed subdivision of the lifted points;
199: -- fs face structures of the lifted points.
200:
201: -- ON RETURN :
202: -- mixsub if empty on entry, then it contains the initial mixed
203: -- cell, in case the problem is nondegenerate;
204: -- rest rest of point list to be processed;
205: -- done if true, then either the mixed volume equals zero,
206: -- or there are no more points to process.
207:
208: null_points : Array_of_Lists(points'range);
209:
210: begin
211: if Is_Null(mixsub)
212: then -- compute an initial mixed cell
213: declare
214: mic : Mixed_Cell;
215: begin
216: Initial_Mixed_Cell(n,mix,points,mic,rest);
217: if Mixed_Volume(n,mix,mic) > 0 -- check on degeneracy
218: then
219: -- initialize the mixed subdivision :
220: Construct(mic,mixsub);
221: -- initialize the face structures :
222: for i in mic.pts'range loop
223: declare
224: tmp : List := mic.pts(i);
225: fc : Face;
226: begin
227: while not Is_Null(tmp) loop
228: Append(fs(i).l,fs(i).last,Head_Of(tmp).all);
229: tmp := Tail_of(tmp);
230: end loop;
231: fc := new VecVec'(Shallow_Create(mic.pts(i)));
232: Construct(fc,fs(i).f);
233: end;
234: end loop;
235: if mix'last = mix'first
236: then declare
237: v : constant VecVec := Shallow_Create(fs(fs'first).l);
238: s : Simplex := Create(v);
239: begin
240: fs(fs'first).t := Create(s);
241: end;
242: end if;
243: done := Is_Empty(rest);
244: else -- degenerate problem => mixed volume = 0
245: rest := null_points; done := true;
246: end if;
247: end;
248: else
249: rest := points;
250: done := Is_Empty(rest);
251: end if;
252: end Initialize;
253:
254: function Initial_Triangulation
255: ( n : in natural; l : in List; point : in Link_to_Vector )
256: return Triangulation is
257:
258: -- DESCRIPTION :
259: -- Given a list of lifted points with Length_Of(l) >= n and another
260: -- lifted point, a nonempty triangulation will be returned, when the
261: -- volume of \conv(l U {point}) > 0.
262:
263: res : Triangulation;
264: del,span : List;
265: delpoint : Link_to_Vector := new vector(1..n);
266:
267: function Deflate ( lifted : in List ) return List is
268:
269: -- DESCRIPTION :
270: -- Discards the lifting value of the points in the list l.
271:
272: res,res_last : List;
273: tmp : List := lifted;
274: pt : Link_to_Vector;
275:
276: begin
277: while not Is_Null(tmp) loop
278: pt := Head_Of(tmp);
279: declare
280: dpt : Link_to_Vector := new vector(1..n);
281: begin
282: dpt.all := pt(dpt'range);
283: Append(res,res_last,dpt);
284: end;
285: tmp := Tail_Of(tmp);
286: end loop;
287: return res;
288: end Deflate;
289:
290: function Lift ( pt,liftpt : Link_to_Vector; lifted : List )
291: return Link_to_Vector is
292:
293: -- DESCRIPTION :
294: -- Compares the value of pt with that of liftpt and
295: -- looks up the lifting value of the point pt in the list lifted.
296: -- The lifted point will be returned.
297:
298: -- REQUIRED :
299: -- Either the point pt should be equal to Deflate(liftpt)
300: -- or it should belong to Deflate(lifted).
301:
302: tmp : List := lifted;
303: res : Link_to_Vector;
304:
305: begin
306: if pt.all = liftpt(pt'range)
307: then return liftpt;
308: else while not Is_Null(tmp) loop
309: res := Head_Of(tmp);
310: if pt.all = res(pt'range)
311: then return res;
312: else tmp := Tail_Of(tmp);
313: end if;
314: end loop;
315: return res;
316: end if;
317: end Lift;
318:
319: begin
320: del := Deflate(l);
321: delpoint.all := point(delpoint'range);
322: Construct(delpoint,del);
323: span := Extremal_Points(n,del);
324: if Length_Of(span) = n+1
325: then
326: declare
327: verpts : VecVec(1..n+1);
328: tmp : List := span;
329: pt : Link_to_Vector;
330: s : Simplex;
331: begin
332: for i in verpts'range loop
333: verpts(i) := Lift(Head_Of(tmp),point,l);
334: tmp := Tail_Of(tmp);
335: end loop;
336: s := Create(verpts);
337: res := Create(s);
338: tmp := l;
339: while not Is_Null(tmp) loop
340: pt := Head_Of(tmp);
341: if not Is_In(span,pt)
342: then Update(res,pt);
343: end if;
344: tmp := Tail_Of(tmp);
345: end loop;
346: end;
347: end if;
348: Clear(del); Clear(span); Clear(delpoint);
349: return res;
350: end Initial_Triangulation;
351:
352: -- CHOOSE NEXT POINT :
353:
354: procedure Next_Point
355: ( n : in natural; points : in out Array_of_Lists;
356: order : in boolean;
357: index : in out integer; point : out Link_to_Vector ) is
358:
359: -- DESCRIPTION :
360: -- Chooses a point out of the lists of points.
361:
362: -- ON ENTRY :
363: -- n length of the elements in the point lists;
364: -- points nonempty lists of points;
365: -- order if true, then the first element out of the next first
366: -- nonempty list will be chosen;
367: -- index indicates component where not Is_Null(points(index)).
368:
369: -- ON RETURN :
370: -- points lists of points with the point removed;
371: -- index points to the next nonempty list,
372: -- if index < points'first, then Is_Empty(points);
373: -- point the next point to be processed.
374:
375: newindex : integer := points'first-1;
376: pt : Link_to_Vector;
377:
378: begin
379: if order
380: then pt := Head_Of(points(index));
381: else pt := Max_Extreme(points(index),n,-3,3);
382: Swap_to_Front(points(index),pt);
383: end if;
384: points(index) := Tail_Of(points(index));
385: for i in (index+1)..points'last loop
386: if not Is_Null(points(i))
387: then newindex := i;
388: end if;
389: exit when newindex >= points'first;
390: end loop;
391: if newindex < points'first
392: then for i in points'first..index loop
393: if not Is_Null(points(i))
394: then newindex := i;
395: end if;
396: exit when newindex >= points'first;
397: end loop;
398: end if;
399: index := newindex;
400: point := pt;
401: end Next_Point;
402:
403: -- UPDATE ROUTINES :
404:
405: procedure Merge ( mic : in out Mixed_Cell;
406: mixsub : in out Mixed_Subdivision ) is
407:
408: tmp : Mixed_Subdivision := mixsub;
409: done : boolean := false;
410:
411: begin
412: while not Is_Null(tmp) loop
413: declare
414: mic1 : Mixed_Cell := Head_Of(tmp);
415: last : List;
416: begin
417: if Equal(mic.nor,mic1.nor)
418: then for k in mic1.pts'range loop
419: last := mic1.pts(k);
420: while not Is_Null(Tail_Of(last)) loop
421: last := Tail_Of(last);
422: end loop;
423: Deep_Concat_Diff(mic.pts(k),mic1.pts(k),last);
424: end loop;
425: done := true;
426: else tmp := Tail_Of(tmp);
427: end if;
428: end;
429: exit when done;
430: end loop;
431: if done
432: then Deep_Clear(mic);
433: else Construct(mic,mixsub);
434: end if;
435: end Merge;
436:
437: procedure Merge ( cells : in Mixed_Subdivision;
438: mixsub : in out Mixed_Subdivision ) is
439:
440: tmp : Mixed_Subdivision := cells;
441:
442: begin
443: while not Is_Null(tmp) loop
444: declare
445: mic : Mixed_Cell := Head_Of(tmp);
446: begin
447: Merge(mic,mixsub);
448: end;
449: tmp := Tail_Of(tmp);
450: end loop;
451: end Merge;
452:
453: procedure Compute_New_Faces
454: ( fs : in out Face_Structure; k,n : in natural;
455: point : in out Link_to_Vector; newfs : out Faces ) is
456:
457: -- DESCRIPTION :
458: -- Given a point, the new faces will be computed and returned.
459:
460: -- ON ENTRY :
461: -- fs a face structure;
462: -- k dimension of the faces to generate;
463: -- n dimension without the lifting;
464: -- point point that has to be in all the faces.
465:
466: -- ON RETURN :
467: -- fs face structure with updated triangulation,
468: -- the new faces are not added, also the list is not updated;
469: -- point lifted conservatively w.r.t. fs.t;
470: -- newfs k-faces, which all contain the given point.
471:
472: res,res_last : Faces;
473:
474: procedure Append ( fc : in VecVec ) is
475:
476: f : Face;
477:
478: begin
479: f := new VecVec'(fc);
480: Append(res,res_last,f);
481: end Append;
482: procedure EnumLis is new Enumerate_Lower_Faces_in_List(Append);
483: procedure EnumTri is new Enumerate_Faces_in_Triangulation(Append);
484:
485: begin
486: -- COMPUTE THE NEW FACES AND UPDATE fs :
487: if Is_Null(fs.t)
488: then
489: if Length_Of(fs.l) >= n
490: then
491: fs.t := Initial_Triangulation(n,fs.l,point);
492: if Is_Null(fs.t)
493: then EnumLis(fs.l,point,k);
494: else EnumTri(fs.t,point,k);
495: end if;
496: else
497: EnumLis(fs.l,point,k);
498: end if;
499: else
500: declare
501: newt : Triangulation;
502: begin
503: point(point'last) := Lift_to_Place(fs.t,point.all);
504: Update(fs.t,point,newt);
505: Enumtri(newt,point,k);
506: end;
507: end if;
508: Append(fs.l,fs.last,point);
509: newfs := res;
510: end Compute_New_Faces;
511:
512: procedure Swap ( index : in natural; points : in out Array_of_Lists ) is
513:
514: -- DESCRIPTION :
515: -- Swaps the first component of points with the component index.
516:
517: tmp : List := points(index);
518:
519: begin
520: points(index) := points(points'first);
521: points(points'first) := tmp;
522: end Swap;
523:
524: procedure Swap ( index : in natural; mixsub : in out Mixed_Subdivision ) is
525:
526: -- DESCRIPTION :
527: -- Swaps the first component of each cell with the component index.
528:
529: tmp : Mixed_Subdivision := mixsub;
530:
531: begin
532: while not Is_Null(tmp) loop
533: declare
534: mic : Mixed_Cell := Head_Of(tmp);
535: begin
536: Swap(index,mic.pts.all);
537: -- Set_Head(tmp,mic);
538: end;
539: tmp := Tail_Of(tmp);
540: end loop;
541: end Swap;
542:
543: procedure Create_Cells
544: ( index,n : in natural; mix : in Vector;
545: afs : in Array_of_Faces; lif : in Array_of_Lists;
546: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector;
547: mixsub : out Mixed_Subdivision ) is
548:
549: -- DESCRIPTION :
550: -- Creates a mixed subdivision by considering the faces
551: -- of component index first.
552:
553: res : Mixed_Subdivision;
554: wrkmix : Vector(mix'range) := mix;
555: wrkafs : Array_of_Faces(afs'range) := afs;
556: wrklif : Array_of_Lists(lif'range) := lif;
557:
558: begin
559: wrkmix(wrkmix'first) := mix(index); wrkmix(index) := mix(mix'first);
560: wrkafs(wrkafs'first) := afs(index); wrkafs(index) := afs(afs'first);
561: wrklif(wrklif'first) := lif(index); wrklif(index) := lif(lif'first);
562: Create_CS(n,wrkmix,wrkafs,wrklif,nbsucc,nbfail,res);
563: Swap(index,res);
564: mixsub := res;
565: end Create_Cells;
566:
567: procedure Compute_New_Cells
568: ( n : in natural; mix : in Vector; mic : in Mixed_Cell;
569: afs : in Array_of_Faces; index : in integer;
570: lifted : in Array_of_Lists; mixsub : out Mixed_Subdivision;
571: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
572:
573: -- DESCRIPTION :
574: -- Computes the new cells by considering a given mixed cell with
575: -- a tuple of faces.
576:
577: -- ON ENTRY :
578: -- n dimension before lifting;
579: -- mix type of mixture;
580: -- mic a given mixed cell;
581: -- afs type of faces;
582: -- index component where new faces are computed for;
583: -- lifted tuple of lifted points;
584: -- nbsucc number of succesful tests of face-face combinations;
585: -- nbfail number of unsuccesful tests of face-face combinations.
586:
587: -- ON RETURN :
588: -- mixsub the new mixed cells;
589: -- nbsucc updated number of succesful tests;
590: -- nbfail updated number of unsuccesful tests;
591:
592: res,res2 : Mixed_Subdivision;
593: neiafs : Array_of_Faces(afs'range);
594:
595: begin
596: neiafs(index) := Neighboring_Faces(mic,afs(index),index);
597: if not Is_Null(neiafs(index))
598: then
599: for i in neiafs'range loop
600: if i /= index
601: then neiafs(i) := Neighboring_Faces(mic,afs(i),i);
602: end if;
603: end loop;
604: if index /= 1
605: then Create_Cells(index,n,mix,neiafs,lifted,nbsucc,nbfail,res);
606: else Create_CS(n,mix,neiafs,lifted,nbsucc,nbfail,res);
607: end if;
608: for i in neiafs'range loop
609: if i /= index
610: then Shallow_Clear(neiafs(i));
611: end if;
612: end loop;
613: end if;
614: Shallow_Clear(neiafs(index));
615: res2 := Create(lifted,res); -- test on normals
616: Shallow_Clear(res);
617: mixsub := res2;
618: end Compute_New_Cells;
619:
620: procedure Compute_New_Cells
621: ( n : in natural; mix : in Vector;
622: mixsub : in Mixed_Subdivision; index : in integer;
623: newfaces : in Faces; fs : in Face_Structures;
624: newcells : out Mixed_Subdivision;
625: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
626:
627: res : Mixed_Subdivision;
628: afs : Array_of_Faces(fs'range);
629: lifted : Array_of_Lists(fs'range);
630:
631: begin
632: -- CREATE NEW CELLS ONLY WITH THE NEW FACES :
633: for i in afs'range loop
634: if i = index
635: then afs(index) := newfaces;
636: else afs(i) := fs(i).f;
637: end if;
638: lifted(i) := fs(i).l;
639: end loop;
640: if not Is_Null(fs(index).t)
641: then
642: -- ENUMERATE ALL CELLS IN mixsub :
643: declare
644: tmp : Mixed_Subdivision := mixsub;
645: begin
646: while not Is_Null(tmp) loop
647: declare
648: newcells2 : Mixed_Subdivision;
649: begin
650: Compute_New_Cells(n,mix,Head_Of(tmp),afs,index,lifted,
651: newcells2,nbsucc,nbfail);
652: Merge(newcells2,res); Shallow_Clear(newcells2);
653: end;
654: tmp := Tail_Of(tmp);
655: end loop;
656: end;
657: else
658: -- COMPUTE ALL NEW CELLS AT ONCE :
659: declare
660: res2 : Mixed_Subdivision;
661: begin
662: if index /= 1
663: then Create_Cells(index,n,mix,afs,lifted,nbsucc,nbfail,res2);
664: else Create_CS(n,mix,afs,lifted,nbsucc,nbfail,res2);
665: end if;
666: res := Create(lifted,res2);
667: Shallow_Clear(res2);
668: end;
669: end if;
670: newcells := res;
671: end Compute_New_Cells;
672:
673: -- BASIC VERSION : WITHOUT OUTPUT GENERICS :
674:
675: procedure Dynamic_Lifting
676: ( n : in natural; mix : in Vector;
677: points : in Array_of_Lists;
678: order,inter,conmv : in boolean; maxli : in natural;
679: mixsub : in out Mixed_Subdivision;
680: fs : in out Face_Structures;
681: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
682:
683: rest,inner : Array_of_Lists(points'range);
684: index,newindex : integer;
685: finished : boolean := false;
686: pt : Link_to_Vector;
687: nexli : natural := 1;
688:
689: begin
690: Initialize(n,mix,points,mixsub,fs,rest,finished);
691: if not finished
692: then
693: index := First_Non_Empty(rest); newindex := index;
694: while not finished loop -- ITERATE UNTIL NO MORE POINTS :
695: Next_Point(n,rest,order,newindex,pt);
696: declare
697: point : Link_to_Vector := new vector(pt'first..pt'last+1);
698: newfa : Faces;
699: newcells : Mixed_Subdivision;
700: begin -- LIFT THE POINT CONSERVATIVELY :
701: point(pt'range) := pt.all;
702: point(point'last) := 1;
703: if inter and then Is_In(fs(index),point.all)
704: then
705: Clear(point); Construct(pt,inner(index));
706: else
707: nexli := Conservative_Lifting(mixsub,index,point.all);
708: if (maxli > 0) and then nexli > maxli
709: then Flatten(mixsub); Flatten(fs);
710: nexli := 1;
711: end if;
712: point(point'last) := nexli;
713: -- COMPUTE NEW FACES AND NEW CELLS :
714: Compute_New_Faces(fs(index),mix(index),n,point,newfa);
715: if not conmv or else not Zero_Contribution(n,fs,point.all,index)
716: then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,
717: newcells,nbsucc,nbfail);
718: -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
719: Construct(newcells,mixsub); Shallow_Clear(newcells);
720: end if;
721: Construct(fs(index).f,newfa); Shallow_Clear(newfa);
722: end if;
723: end;
724: index := newindex;
725: finished := (index < rest'first);
726: end loop;
727: end if;
728: if inter -- lift out the interior points
729: then for i in inner'range loop
730: Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
731: Shallow_Clear(inner(i));
732: end loop;
733: end if;
734: exception
735: when numeric_error -- probably due to a too high lifting
736: => Flatten(mixsub); Flatten(fs);
737: Dynamic_Lifting(n,mix,rest,order,inter,conmv,maxli,mixsub,fs,
738: nbsucc,nbfail);
739: end Dynamic_Lifting;
740:
741: -- EXTENDED VERSIONS : WITH OUTPUT GENERICS :
742:
743: procedure Dynamic_Lifting_with_Flat
744: ( n : in natural; mix : in Vector; points : in Array_of_Lists;
745: order,inter,conmv : in boolean; maxli : in natural;
746: mixsub : in out Mixed_Subdivision;
747: fs : in out Face_Structures;
748: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
749:
750: rest,inner : Array_of_Lists(points'range);
751: index,newindex : integer;
752: finished : boolean := false;
753: pt : Link_to_Vector;
754: nexli : natural := 1;
755:
756: begin
757: Initialize(n,mix,points,mixsub,fs,rest,finished);
758: if not finished
759: then
760: index := First_Non_Empty(rest); newindex := index;
761: while not finished loop -- ITERATE UNTIL NO MORE POINTS :
762: Next_Point(n,rest,order,newindex,pt);
763: declare
764: point : Link_to_Vector := new vector(pt'first..pt'last+1);
765: newfa : Faces;
766: newcells : Mixed_Subdivision;
767: begin -- LIFT THE POINT CONSERVATIVELY :
768: point(pt'range) := pt.all;
769: point(point'last) := 1;
770: if inter and then Is_In(fs(index),point.all)
771: then
772: Clear(point); Construct(pt,inner(index));
773: else
774: nexli := Conservative_Lifting(mixsub,index,point.all);
775: if (maxli > 0) and then nexli > maxli
776: then Before_Flattening(mixsub,fs);
777: Flatten(mixsub); Flatten(fs);
778: nexli := 1;
779: end if;
780: point(point'last) := nexli;
781: -- COMPUTE NEW FACES AND NEW CELLS :
782: Compute_New_Faces(fs(index),mix(index),n,point,newfa);
783: if not conmv or else not Zero_Contribution(n,fs,point.all,index)
784: then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,
785: newcells,nbsucc,nbfail);
786: -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
787: Construct(newcells,mixsub); Shallow_Clear(newcells);
788: end if;
789: Construct(fs(index).f,newfa); Shallow_Clear(newfa);
790: end if;
791: end;
792: index := newindex;
793: finished := (index < rest'first);
794: end loop;
795: end if;
796: if inter -- lift out the interior points
797: then for i in inner'range loop
798: Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
799: Shallow_Clear(inner(i));
800: end loop;
801: end if;
802: exception
803: when numeric_error -- probably due to a too high lifting
804: => Before_Flattening(mixsub,fs);
805: Flatten(mixsub); Flatten(fs);
806: Dynamic_Lifting_with_Flat(n,mix,rest,order,inter,conmv,maxli,mixsub,
807: fs,nbsucc,nbfail);
808: end Dynamic_Lifting_with_Flat;
809:
810: procedure Dynamic_Lifting_with_New
811: ( n : in natural; mix : in Vector; points : in Array_of_Lists;
812: order,inter,conmv : in boolean; maxli : in natural;
813: mixsub : in out Mixed_Subdivision;
814: fs : in out Face_Structures;
815: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
816:
817: rest,inner : Array_of_Lists(points'range);
818: index,newindex : integer;
819: finished : boolean := false;
820: pt : Link_to_Vector;
821: nexli : natural := 1;
822:
823: begin
824: Initialize(n,mix,points,mixsub,fs,rest,finished);
825: Process_New_Cells(mixsub,0,Head_Of(fs(fs'last).last).all);
826: if not finished
827: then
828: index := First_Non_Empty(rest); newindex := index;
829: while not finished loop -- ITERATE UNTIL NO MORE POINTS :
830: Next_Point(n,rest,order,newindex,pt);
831: declare
832: point : Link_to_Vector := new vector(pt'first..pt'last+1);
833: newfa : Faces;
834: newcells : Mixed_Subdivision;
835: begin -- LIFT THE POINT CONSERVATIVELY :
836: point(pt'range) := pt.all;
837: point(point'last) := 1;
838: if inter and then Is_In(fs(index),point.all)
839: then
840: Clear(point); Construct(pt,inner(index));
841: else
842: nexli := Conservative_Lifting(mixsub,index,point.all);
843: if (maxli > 0) and then nexli > maxli
844: then Flatten(mixsub); Flatten(fs);
845: nexli := 1;
846: end if;
847: point(point'last) := nexli;
848: -- COMPUTE NEW FACES AND NEW CELLS :
849: Compute_New_Faces(fs(index),mix(index),n,point,newfa);
850: if not conmv or else not Zero_Contribution(n,fs,point.all,index)
851: then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,newcells,
852: nbsucc,nbfail);
853: Process_New_Cells(newcells,index,point.all);
854: -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
855: Construct(newcells,mixsub); Shallow_Clear(newcells);
856: end if;
857: Construct(fs(index).f,newfa); Shallow_Clear(newfa);
858: end if;
859: end;
860: index := newindex;
861: finished := (index < rest'first);
862: end loop;
863: end if;
864: if inter -- lift out the interior points
865: then for i in inner'range loop
866: Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
867: Shallow_Clear(inner(i));
868: end loop;
869: end if;
870: exception
871: when numeric_error -- probably due to a too high lifting
872: => Flatten(mixsub); Flatten(fs);
873: Dynamic_Lifting_with_New(n,mix,rest,order,inter,conmv,maxli,mixsub,fs,
874: nbsucc,nbfail);
875: end Dynamic_Lifting_with_New;
876:
877: procedure Dynamic_Lifting_with_Flat_and_New
878: ( n : in natural; mix : in Vector; points : in Array_of_Lists;
879: order,inter,conmv : in boolean; maxli : in natural;
880: mixsub : in out Mixed_Subdivision;
881: fs : in out Face_Structures;
882: nbsucc,nbfail : in out Standard_Floating_Vectors.Vector ) is
883:
884: rest,inner : Array_of_Lists(points'range);
885: index,newindex : integer;
886: finished : boolean := false;
887: pt : Link_to_Vector;
888: nexli : natural := 1;
889:
890: begin
891: Initialize(n,mix,points,mixsub,fs,rest,finished);
892: Process_New_Cells(mixsub,0,Head_Of(fs(fs'last).last).all);
893: if not finished
894: then
895: index := First_Non_Empty(rest); newindex := index;
896: while not finished loop -- ITERATE UNTIL NO MORE POINTS
897: Next_Point(n,rest,order,newindex,pt);
898: declare
899: point : Link_to_Vector := new vector(pt'first..pt'last+1);
900: newfa : Faces;
901: newcells : Mixed_Subdivision;
902: begin -- LIFT THE POINT CONSERVATIVELY :
903: point(pt'range) := pt.all;
904: point(point'last) := 1;
905: if inter and then Is_In(fs(index),point.all)
906: then
907: Clear(point); Construct(pt,inner(index));
908: else
909: nexli := Conservative_Lifting(mixsub,index,point.all);
910: if (maxli > 0) and then nexli > maxli
911: then Before_Flattening(mixsub,fs);
912: Flatten(mixsub); Flatten(fs);
913: nexli := 1;
914: end if;
915: point(point'last) := nexli;
916: -- COMPUTE NEW FACES AND NEW CELLS :
917: Compute_New_Faces(fs(index),mix(index),n,point,newfa);
918: if not conmv or else not Zero_Contribution(n,fs,point.all,index)
919: then Compute_New_Cells(n,mix,mixsub,index,newfa,fs,newcells,
920: nbsucc,nbfail);
921: Process_New_Cells(newcells,index,point.all);
922: -- UPDATE THE MIXED SUBDIVISION AND THE FACE STRUCTURES :
923: Construct(newcells,mixsub); Shallow_Clear(newcells);
924: end if;
925: Construct(fs(index).f,newfa); Shallow_Clear(newfa);
926: end if;
927: end;
928: index := newindex;
929: finished := (index < rest'first);
930: end loop;
931: end if;
932: if inter -- lift out the interior points
933: then for i in inner'range loop
934: Constant_Lifting(inner(i),nexli,fs(i).l,fs(i).last);
935: Shallow_Clear(inner(i));
936: end loop;
937: end if;
938: exception
939: when numeric_error -- probably due to a too high lifting
940: => Before_Flattening(mixsub,fs);
941: Flatten(mixsub); Flatten(fs);
942: Dynamic_Lifting_with_Flat_and_New
943: (n,mix,rest,order,inter,conmv,maxli,mixsub,fs,nbsucc,nbfail);
944: end Dynamic_Lifting_with_Flat_and_New;
945:
946: end Dynamic_Mixed_Subdivisions;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>