Annotation of OpenXM_contrib/PHC/Ada/Root_Counts/Dynlift/dynamic_mixed_subdivisions.adb, Revision 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>