7f9007e1a45dba67a26d3d6b0f486076637fb326
[occt.git] / src / BRepFill / BRepFill_Evolved.cxx
1 // Created on: 1994-10-03
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Bisector_Bisec.hxx>
19 #include <Bisector_BisecAna.hxx>
20 #include <Bnd_Box2d.hxx>
21 #include <BndLib_Add2dCurve.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRep_Tool.hxx>
24 #include <BRepAdaptor_Curve.hxx>
25 #include <BRepAlgo_FaceRestrictor.hxx>
26 #include <BRepAlgo_Loop.hxx>
27 #include <BRepClass3d_SolidClassifier.hxx>
28 #include <BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape.hxx>
29 #include <BRepFill_DataMapOfNodeDataMapOfShapeShape.hxx>
30 #include <BRepFill_DataMapOfShapeDataMapOfShapeListOfShape.hxx>
31 #include <BRepFill_DataMapOfShapeSequenceOfPnt.hxx>
32 #include <BRepFill_DataMapOfShapeSequenceOfReal.hxx>
33 #include <BRepFill_Evolved.hxx>
34 #include <BRepFill_OffsetAncestors.hxx>
35 #include <BRepFill_OffsetWire.hxx>
36 #include <BRepFill_Pipe.hxx>
37 #include <BRepFill_TrimSurfaceTool.hxx>
38 #include <BRepLib.hxx>
39 #include <BRepLib_FindSurface.hxx>
40 #include <BRepLib_MakeEdge.hxx>
41 #include <BRepLib_MakeFace.hxx>
42 #include <BRepLib_MakeVertex.hxx>
43 #include <BRepLib_MakeWire.hxx>
44 #include <BRepLProp.hxx>
45 #include <BRepMAT2d_BisectingLocus.hxx>
46 #include <BRepMAT2d_Explorer.hxx>
47 #include <BRepMAT2d_LinkTopoBilo.hxx>
48 #include <BRepSweep_Prism.hxx>
49 #include <BRepSweep_Revol.hxx>
50 #include <BRepTools.hxx>
51 #include <BRepTools_Modifier.hxx>
52 #include <BRepTools_Quilt.hxx>
53 #include <BRepTools_TrsfModification.hxx>
54 #include <BRepTools_WireExplorer.hxx>
55 #include <Geom2d_CartesianPoint.hxx>
56 #include <Geom2d_Circle.hxx>
57 #include <Geom2d_Curve.hxx>
58 #include <Geom2d_Geometry.hxx>
59 #include <Geom2d_Line.hxx>
60 #include <Geom2d_TrimmedCurve.hxx>
61 #include <Geom2dAdaptor_Curve.hxx>
62 #include <Geom2dAPI_ExtremaCurveCurve.hxx>
63 #include <Geom2dInt_GInter.hxx>
64 #include <Geom_Curve.hxx>
65 #include <Geom_Line.hxx>
66 #include <Geom_Plane.hxx>
67 #include <Geom_RectangularTrimmedSurface.hxx>
68 #include <Geom_Surface.hxx>
69 #include <Geom_TrimmedCurve.hxx>
70 #include <GeomAPI.hxx>
71 #include <GeomProjLib.hxx>
72 #include <gp.hxx>
73 #include <gp_Ax1.hxx>
74 #include <gp_Ax3.hxx>
75 #include <gp_Circ2d.hxx>
76 #include <gp_Dir.hxx>
77 #include <gp_Pln.hxx>
78 #include <gp_Pnt.hxx>
79 #include <gp_Pnt2d.hxx>
80 #include <gp_Trsf.hxx>
81 #include <gp_Vec.hxx>
82 #include <gp_Vec2d.hxx>
83 #include <IntRes2d_IntersectionPoint.hxx>
84 #include <MAT2d_CutCurve.hxx>
85 #include <MAT_Arc.hxx>
86 #include <MAT_BasicElt.hxx>
87 #include <MAT_Graph.hxx>
88 #include <MAT_Node.hxx>
89 #include <MAT_Side.hxx>
90 #include <Precision.hxx>
91 #include <Standard_ConstructionError.hxx>
92 #include <Standard_NoSuchObject.hxx>
93 #include <Standard_NotImplemented.hxx>
94 #include <TColgp_SequenceOfPnt.hxx>
95 #include <TColStd_SequenceOfReal.hxx>
96 #include <TopAbs.hxx>
97 #include <TopExp.hxx>
98 #include <TopExp_Explorer.hxx>
99 #include <TopLoc_Location.hxx>
100 #include <TopoDS.hxx>
101 #include <TopoDS_Compound.hxx>
102 #include <TopoDS_Edge.hxx>
103 #include <TopoDS_Face.hxx>
104 #include <TopoDS_Iterator.hxx>
105 #include <TopoDS_Shape.hxx>
106 #include <TopoDS_Solid.hxx>
107 #include <TopoDS_Vertex.hxx>
108 #include <TopoDS_Wire.hxx>
109 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
110 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
111 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
112 #include <TopTools_DataMapOfShapeShape.hxx>
113 #include <TopTools_ListIteratorOfListOfShape.hxx>
114 #include <TopTools_SequenceOfShape.hxx>
115
116 //#define DRAW
117 #ifdef DRAW
118 #include <DBRep.hxx>
119 #include <DrawTrSurf.hxx>
120 #include <stdio.h>
121 static Standard_Boolean AffichGeom = Standard_False;
122 static Standard_Boolean AffichEdge = Standard_False;
123 static Standard_Integer NbFACES       = 0;
124 static Standard_Integer NbTRIMFACES   = 0;
125 static Standard_Integer NbVEVOS       = 0;
126 static Standard_Integer NbPROFILS     = 0;
127 static Standard_Integer NbEDGES       = 0;
128 #endif
129
130 static Standard_Real BRepFill_Confusion() 
131 {
132   Standard_Real Tol = 1.e-6;
133   return Tol;
134 }
135
136 static const TopoDS_Wire PutProfilAt (const TopoDS_Wire&     ProfRef,
137   const gp_Ax3&          AxeRef,
138   const TopoDS_Edge&     E,
139   const TopoDS_Face&     F,
140   const Standard_Boolean AtStart);
141
142 static void TrimFace(const TopoDS_Face&              Face,
143   TopTools_SequenceOfShape& TheEdges,
144   TopTools_SequenceOfShape& S);
145
146 static void TrimEdge (const TopoDS_Edge&              Edge,
147   const TopTools_SequenceOfShape& TheEdgesControle,
148   TopTools_SequenceOfShape& TheVer,
149   TColStd_SequenceOfReal&   ThePar,
150   TopTools_SequenceOfShape& S);
151
152 static TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge&     E,
153   const TopoDS_Face&     F);
154
155 static Standard_Integer PosOnFace (Standard_Real d1,
156   Standard_Real d2,
157   Standard_Real d3);
158
159 static void ComputeIntervals (const TopTools_SequenceOfShape& VonF,
160   const TopTools_SequenceOfShape& VOnL,
161   const TColgp_SequenceOfPnt&     ParOnF,
162   const TColgp_SequenceOfPnt&     ParOnL,
163   const BRepFill_TrimSurfaceTool& Trim,
164   const Handle(Geom2d_Curve)&     Bis,
165   const TopoDS_Vertex&            VS,
166   const TopoDS_Vertex&            VE,
167   TColStd_SequenceOfReal&   FirstPar,
168   TColStd_SequenceOfReal&   LastPar,
169   TopTools_SequenceOfShape& FirstV,
170   TopTools_SequenceOfShape& LastV );    
171
172 static Standard_Real    DistanceToOZ (const TopoDS_Vertex& V);
173
174 static Standard_Real    Altitud (const TopoDS_Vertex& V);
175
176 static Standard_Boolean DoubleOrNotInFace (const TopTools_SequenceOfShape& EC,
177   const TopoDS_Vertex&            V);
178
179 static void SimpleExpression (const Bisector_Bisec&        B, 
180   Handle(Geom2d_Curve)&  Bis);
181
182 static TopAbs_Orientation Relative (const TopoDS_Wire&   W1,
183   const TopoDS_Wire&   W2,
184   const TopoDS_Vertex& V,
185   Standard_Boolean&    Commun);
186
187 static void CutEdge (const TopoDS_Edge& E, 
188   const TopoDS_Face& F,TopTools_ListOfShape& Cuts);
189
190 static void CutEdgeProf (const TopoDS_Edge&                  E,
191   const Handle(Geom_Plane)&           Plane,
192   const Handle(Geom2d_Line)&          Line,
193   TopTools_ListOfShape&         Cuts,
194   TopTools_DataMapOfShapeShape& MapVerRefMoved);
195
196 static Standard_Integer VertexFromNode 
197   (const Handle(MAT_Node)&                          aNode, 
198   const TopoDS_Edge&                               E, 
199   const TopoDS_Vertex&                             VF, 
200   const TopoDS_Vertex&                             VL,
201   BRepFill_DataMapOfNodeDataMapOfShapeShape& MapNodeVertex,
202   TopoDS_Vertex&                             VS);
203
204 //=======================================================================
205 //function : EdgeVertices
206 //purpose  : 
207 //=======================================================================
208
209 static void EdgeVertices (const TopoDS_Edge&   E,
210   TopoDS_Vertex& V1, 
211   TopoDS_Vertex& V2)
212 {
213   if (E.Orientation() == TopAbs_REVERSED) {
214     TopExp::Vertices(E,V2,V1);
215   }
216   else {
217     TopExp::Vertices(E,V1,V2);
218   }
219 }
220
221 //=======================================================================
222 //function : BRepFill_Evolved
223 //purpose  : 
224 //=======================================================================
225
226 BRepFill_Evolved::BRepFill_Evolved() 
227   :
228 myIsDone   (Standard_False),
229   mySpineType(Standard_True)
230 {
231 }
232
233
234 //=======================================================================
235 //function : BRepFill_Evolved
236 //purpose  : 
237 //=======================================================================
238
239 BRepFill_Evolved::BRepFill_Evolved(const TopoDS_Wire&      Spine, 
240   const TopoDS_Wire&      Profile,
241   const gp_Ax3&           AxeProf,
242   const GeomAbs_JoinType  Join,
243   const Standard_Boolean  Solid)
244
245   : myIsDone(Standard_False)
246 {
247   Perform( Spine, Profile, AxeProf, Join, Solid);
248 }
249
250
251 //=======================================================================
252 //function : BRepFill_Evolved
253 //purpose  : 
254 //=======================================================================
255
256 BRepFill_Evolved::BRepFill_Evolved(const TopoDS_Face&     Spine, 
257   const TopoDS_Wire&     Profile,
258   const gp_Ax3&          AxeProf,
259   const GeomAbs_JoinType Join,
260   const Standard_Boolean Solid)
261   : myIsDone(Standard_False)
262 {
263   Perform( Spine, Profile, AxeProf, Join, Solid);
264 }
265
266 //=======================================================================
267 //function : IsVertical
268 //purpose  : 
269 //=======================================================================
270
271 static Standard_Boolean IsVertical(const TopoDS_Edge& E) 
272 {
273   TopoDS_Vertex V1,V2;
274   TopExp::Vertices(E,V1,V2);
275   gp_Pnt P1 = BRep_Tool::Pnt(V1);
276   gp_Pnt P2 = BRep_Tool::Pnt(V2);
277
278   if ( Abs(P1.Y() - P2.Y()) < BRepFill_Confusion()) {
279     // It is a Line ?
280     TopLoc_Location Loc;
281     Standard_Real f,l;
282     Handle(Geom_Curve) GC = BRep_Tool::Curve(E,Loc,f,l);
283     if ( GC->DynamicType() == STANDARD_TYPE(Geom_Line))
284       return Standard_True;
285   }
286   return Standard_False;
287 }
288
289 //=======================================================================
290 //function : IsPlanar
291 //purpose  : 
292 //=======================================================================
293
294 static Standard_Boolean IsPlanar(const TopoDS_Edge& E) 
295 {
296   TopoDS_Vertex V1,V2;
297   TopExp::Vertices(E,V1,V2);
298   gp_Pnt P1 = BRep_Tool::Pnt(V1);
299   gp_Pnt P2 = BRep_Tool::Pnt(V2);
300
301   if ( Abs(P1.Z() - P2.Z()) < BRepFill_Confusion()) {
302     // It is a Line ?
303     TopLoc_Location Loc;
304     Standard_Real f,l;
305     Handle(Geom_Curve) GC = BRep_Tool::Curve(E,Loc,f,l);
306     if ( GC->DynamicType() == STANDARD_TYPE(Geom_Line))
307       return Standard_True;
308   }
309   return Standard_False;
310
311 }
312
313 //=======================================================================
314 //function : Side
315 //purpose  : determine the position of the profil correspondingly to plane XOZ.
316 //           Return 1 : MAT_Left.
317 //           Return 2 : MAT_Left and Planar.
318 //           Return 3 : MAT_Left and Vertical.
319 //           Return 4 : MAT_Right.
320 //           Return 5 : MAT_Right and Planar.
321 //           Return 6 : MAT_Right and Vertical.
322 //=======================================================================
323
324 static Standard_Integer Side(const TopoDS_Wire&  Profil,
325   const Standard_Real Tol)
326 {
327   TopoDS_Vertex    V1,V2;
328   // Rem : it is enough to test the first edge of the Wire.
329   //       ( Correctly cut in PrepareProfil)
330   TopExp_Explorer Explo(Profil,TopAbs_EDGE);
331
332   Standard_Integer TheSide;
333   const TopoDS_Edge& E = TopoDS::Edge(Explo.Current());
334
335   TopExp::Vertices(E,V1,V2);
336   gp_Pnt P1 = BRep_Tool::Pnt(V1);
337   gp_Pnt P2 = BRep_Tool::Pnt(V2);
338
339   if ( P1.Y() < -Tol || P2.Y() < -Tol)  TheSide = 4;
340   else                                  TheSide = 1;
341   if      (IsVertical(E)) TheSide+=2;
342   else if (IsPlanar(E))   TheSide++;
343   return TheSide;
344 }
345
346
347 //=======================================================================
348 //function : Perform
349 //purpose  : 
350 //=======================================================================
351
352 void BRepFill_Evolved::Perform(const TopoDS_Wire&      Spine, 
353   const TopoDS_Wire&      Profile,
354   const gp_Ax3&           AxeProf,
355   const GeomAbs_JoinType  Join,
356   const Standard_Boolean  Solid)
357 {
358   mySpineType = Standard_False;
359   TopoDS_Face aFace = BRepLib_MakeFace(Spine,Standard_True);
360   PrivatePerform( aFace, Profile, AxeProf, Join, Solid);
361 }
362
363 //=======================================================================
364 //function : Perform
365 //purpose  : 
366 //=======================================================================
367
368 void BRepFill_Evolved::Perform(const TopoDS_Face&      Spine, 
369   const TopoDS_Wire&      Profile,
370   const gp_Ax3&           AxeProf,
371   const GeomAbs_JoinType  Join,
372   const Standard_Boolean  Solid)
373 {
374   mySpineType = Standard_True;
375   PrivatePerform( Spine, Profile, AxeProf, Join, Solid);
376 }
377
378 //=======================================================================
379 //function : PrivatePerform
380 //purpose  : 
381 //=======================================================================
382
383 void BRepFill_Evolved::PrivatePerform(const TopoDS_Face&     Spine, 
384   const TopoDS_Wire&     Profile,
385   const gp_Ax3&          AxeProf,
386   const GeomAbs_JoinType Join,
387   const Standard_Boolean Solid)
388 {
389   TopoDS_Shape aLocalShape = Spine.Oriented(TopAbs_FORWARD);
390   mySpine    = TopoDS::Face(aLocalShape);
391   //  mySpine    = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD));
392   aLocalShape = Profile.Oriented(TopAbs_FORWARD);
393   myProfile  = TopoDS::Wire(aLocalShape);
394   //  myProfile  = TopoDS::Wire(Profile.Oriented(TopAbs_FORWARD));
395   myJoinType = Join;
396   myMap.Clear();
397
398   if (myJoinType > GeomAbs_Arc)  {
399     Standard_NotImplemented::Raise();
400   }
401
402   TopTools_ListOfShape               WorkProf;
403   TopoDS_Face                        WorkSpine;
404   TopTools_ListIteratorOfListOfShape WPIte;
405
406   //-------------------------------------------------------------------
407   // Positioning of mySpine and myProfil in the workspace.
408   //-------------------------------------------------------------------
409   TopLoc_Location LSpine   = FindLocation(mySpine);
410   gp_Trsf T;
411   T.SetTransformation(AxeProf);
412   TopLoc_Location LProfile  (T);
413   TopLoc_Location InitLS = mySpine  .Location();
414   TopLoc_Location InitLP = myProfile.Location();
415   TransformInitWork(LSpine,LProfile);
416
417   //------------------------------------------------------------------
418   // projection of the profile and cut of the spine.
419   //------------------------------------------------------------------
420   TopTools_DataMapOfShapeShape MapProf, MapSpine;
421
422   PrepareProfile(WorkProf , MapProf);  
423   PrepareSpine  (WorkSpine, MapSpine);
424
425   Standard_Real    Tol       = BRepFill_Confusion();
426   Standard_Boolean YaLeft    = Standard_False;
427   Standard_Boolean YaRight   = Standard_False;  
428   TopoDS_Wire      SP;
429
430   for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {
431     SP = TopoDS::Wire(WPIte.Value());
432     if ( Side(SP,Tol) < 4) YaLeft  = Standard_True;
433     else                   YaRight = Standard_True;
434     if (YaLeft && YaRight) break;
435   }
436
437   TopoDS_Face              Face;
438   BRepMAT2d_BisectingLocus Locus;
439
440   //----------------------------------------------------------
441   // Initialisation of cut volevo.
442   // For each part of the profile create a volevo added to CutVevo
443   //----------------------------------------------------------
444   BRepFill_Evolved       CutVevo;
445   TopoDS_Wire            WP;
446   BRep_Builder           BB;
447   BRepTools_WireExplorer WExp;
448
449   BB.MakeWire(WP);
450
451   for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {     
452     for (WExp.Init(TopoDS::Wire(WPIte.Value())); WExp.More(); WExp.Next()) {
453       BB.Add(WP,WExp.Current());
454     }
455   }
456   CutVevo.SetWork(WorkSpine,WP);
457
458   BRepTools_Quilt  Glue;
459   Standard_Integer CSide;
460
461   //---------------------------------
462   // Construction of vevos to the left.
463   //---------------------------------
464   if (YaLeft) {
465     //-----------------------------------------------------
466     // Calculate the map of bisector locations at the left.  
467     // and links Topology -> base elements of the map.
468     //-----------------------------------------------------
469     BRepMAT2d_Explorer Exp(WorkSpine);
470     Locus.Compute(Exp,1,MAT_Left);
471     BRepMAT2d_LinkTopoBilo Link(Exp,Locus);
472
473     for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {    
474       SP    = TopoDS::Wire(WPIte.Value());
475       CSide = Side(SP,Tol);     
476       //-----------------------------------------------
477       // Construction and adding of elementary volevo.
478       //-----------------------------------------------
479       BRepFill_Evolved Vevo;
480       if ( CSide == 1) { 
481         Vevo.ElementaryPerform (WorkSpine, SP, Locus, Link, Join);
482       }
483       else if (CSide == 2) {
484         Vevo.PlanarPerform (WorkSpine, SP, Locus, Link, Join);
485       }
486       else if (CSide == 3) {
487         Vevo.VerticalPerform (WorkSpine, SP, Locus, Link, Join);
488       }
489       CutVevo.Add (Vevo, SP, Glue);
490     }
491   }
492
493   //---------------------------------
494   // Construction of vevos to the right.
495   //---------------------------------
496   if (YaRight) {
497     //-----------------------------------
498     // Decomposition of the face into wires.
499     //-----------------------------------
500     TopExp_Explorer SpineExp (WorkSpine, TopAbs_WIRE);
501     for ( ; SpineExp.More(); SpineExp.Next()) {
502       //----------------------------------------------
503       // Calculate the map to the right of the current wire.
504       //----------------------------------------------
505       BRepLib_MakeFace B(gp_Pln(0.,0.,1.,0.));
506       TopoDS_Shape aLocalShapeRev = SpineExp.Current().Reversed();
507       B.Add(TopoDS::Wire(aLocalShapeRev));
508       //      B.Add(TopoDS::Wire(SpineExp.Current().Reversed()));
509       Face = B.Face();
510       BRepMAT2d_Explorer Exp(Face);
511       Locus.Compute(Exp,1,MAT_Left);
512       BRepMAT2d_LinkTopoBilo Link(Exp,Locus);
513
514       for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {
515         SP = TopoDS::Wire(WPIte.Value());
516         CSide = Side(SP,Tol);   
517         //-----------------------------------------------
518         // Construction and adding of an elementary volevo
519         //-----------------------------------------------
520         BRepFill_Evolved Vevo;
521         if ( CSide == 4) { 
522           Vevo.ElementaryPerform (Face, SP, Locus, Link, Join);
523         }
524         else if (CSide == 5) {
525           Vevo.PlanarPerform (Face, SP, Locus, Link, Join);
526         }
527         else if (CSide == 6) {
528           Vevo.VerticalPerform (Face, SP, Locus, Link, Join);
529         }
530         CutVevo.Add (Vevo, SP, Glue);
531       }      
532     }
533   }
534
535   if (Solid) CutVevo.AddTopAndBottom(Glue);
536
537   //-------------------------------------------------------------------------
538   // Gluing of regularites on parallel edges generate4d by vertices of the 
539   // cut of the profile.
540   //-------------------------------------------------------------------------
541   CutVevo.ContinuityOnOffsetEdge(WorkProf);
542
543   //-----------------------------------------------------------------
544   // construction of the shape via the quilt, ie:
545   // - sharing of topologies of elementary added volevos.
546   // - Orientation of faces correspondingly to each other.
547   //-----------------------------------------------------------------
548   TopoDS_Shape& SCV = CutVevo.ChangeShape();
549   SCV = Glue.Shells();
550   //------------------------------------------------------------------------
551   // Transfer of the map of generated elements and of the shape of Cutvevo 
552   // in myMap and repositioning in the initial space.
553   //------------------------------------------------------------------------
554   Transfert (CutVevo, MapProf, MapSpine, LSpine.Inverted(), InitLS, InitLP);
555
556   //Orientation of the solid.
557   if (Solid) MakeSolid();
558
559   //  modified by NIZHNY-EAP Mon Jan 24 11:26:48 2000 ___BEGIN___
560   BRepLib::UpdateTolerances(myShape,Standard_False);
561   //  modified by NIZHNY-EAP Mon Jan 24 11:26:50 2000 ___END___
562   myIsDone = Standard_True;
563 }
564
565
566
567 //=======================================================================
568 //function : IsInversed
569 //purpose  : 
570 //=======================================================================
571
572 static void IsInversed(const TopoDS_Shape& S,
573   const TopoDS_Edge&  E1,
574   const TopoDS_Edge&  E2,
575   Standard_Boolean*   Inverse)
576 {  
577
578   Inverse[0] = Inverse[1] = 0;
579   if (S.ShapeType() != TopAbs_EDGE) return;
580
581   gp_Pnt P;
582   gp_Vec DS,DC1,DC2 ;
583   BRepAdaptor_Curve CS(TopoDS::Edge(S));
584   if (S.Orientation() == TopAbs_FORWARD) {
585     CS.D1(CS.FirstParameter(),P,DS);
586   }
587   else {
588     CS.D1(CS.LastParameter(),P,DS);
589     DS.Reverse();
590   }
591
592
593   if (!BRep_Tool::Degenerated(E1)) {
594     BRepAdaptor_Curve C1(TopoDS::Edge(E1));
595     if (E1.Orientation() == TopAbs_FORWARD) {
596       C1.D1(C1.FirstParameter(),P,DC1);
597     }
598     else {
599       C1.D1(C1.LastParameter(),P,DC1);
600       DC1.Reverse();
601     }
602     Inverse[0] = (DS.Dot(DC1) < 0.);
603   }
604   else Inverse[0] = 1;
605
606   if (!BRep_Tool::Degenerated(E2)) {
607     BRepAdaptor_Curve C2(TopoDS::Edge(E2));
608     if (E2.Orientation() == TopAbs_FORWARD) {
609       C2.D1(C2.FirstParameter(),P,DC2);
610     }
611     else {
612       C2.D1(C2.LastParameter(),P,DC2);
613       DC2.Reverse();
614     }
615     Inverse[1] = (DS.Dot(DC2) < 0.);
616   }
617   else Inverse[1] = 1;
618 }
619
620 //=======================================================================
621 //function : SetWork
622 //purpose  : 
623 //=======================================================================
624
625 void BRepFill_Evolved::SetWork(const TopoDS_Face& Sp,
626   const TopoDS_Wire& Pr)
627 {
628   mySpine   = Sp;
629   myProfile = Pr;
630 }
631
632 //=======================================================================
633 //function : ConcaveSide
634 //purpose  : Determine if the pipes were at the side of the 
635 //           concavity. In this case they can be closed.
636 //           WARNING: Not finished. Done only for circles.
637 //=======================================================================
638
639 static Standard_Boolean ConcaveSide(const TopoDS_Shape& S,
640   const TopoDS_Face&  F)
641 {
642
643   if (S.ShapeType() == TopAbs_VERTEX) return Standard_False;
644
645   if (S.ShapeType() == TopAbs_EDGE) {
646     Standard_Real f,l;
647     Handle(Geom2d_Curve) G2d = 
648       BRep_Tool::CurveOnSurface(TopoDS::Edge(S),F,f,l);
649     Handle(Geom2d_Curve) G2dOC;
650
651     Geom2dAdaptor_Curve  AC(G2d,f,l);
652     if ( AC.GetType() == GeomAbs_Circle) {
653       Standard_Boolean Direct = AC.Circle().IsDirect();
654       if (S.Orientation() == TopAbs_REVERSED) Direct = (!Direct);
655       return Direct;
656     }
657   }
658   return Standard_False;
659 }
660
661 //=======================================================================
662 //function : ElementaryPerform
663 //purpose  : 
664 //=======================================================================
665
666 void BRepFill_Evolved::ElementaryPerform (const TopoDS_Face&              Sp,
667   const TopoDS_Wire&              Pr,
668   const BRepMAT2d_BisectingLocus& Locus,
669   BRepMAT2d_LinkTopoBilo&   Link,
670   const GeomAbs_JoinType          /*Join*/)
671 {
672
673 #ifdef DRAW
674   if (AffichEdge) {       
675     char name[100];
676     sprintf(name,"PROFIL_%d",++NbPROFILS);      
677     DBRep::Set(name,Pr);
678   }
679 #endif
680   TopoDS_Shape aLocalShape = Sp.Oriented(TopAbs_FORWARD);
681   mySpine   = TopoDS::Face(aLocalShape);
682   //  mySpine   = TopoDS::Face(Sp.Oriented(TopAbs_FORWARD));
683   myProfile = Pr;
684   myMap.Clear();
685
686   BRep_Builder myBuilder;
687   myBuilder.MakeCompound(TopoDS::Compound(myShape));
688
689   //---------------------------------------------------------------------
690   // MapNodeVertex : associate to each node of the map (key1) and
691   //                 to each element of the profile (key2) a vertex (item).
692   // MapBis        : a set of edges or vertexes (item) generated by
693   //                 a bisectrice on a face or an edge (key) of 
694   //                 tubes or revolutions.
695   // MapVerPar     : Map of parameters of vertices on parallel edges 
696   //                 the list contained in MapVerPar (E) corresponds  
697   //                 to parameters on E of vertices contained in  MapBis(E);
698   // MapBS         : links BasicElt of the map => Topology of the spine.
699   //---------------------------------------------------------------------
700
701
702   BRepFill_DataMapOfNodeDataMapOfShapeShape MapNodeVertex; 
703   TopTools_DataMapOfShapeSequenceOfShape    MapBis;  
704   BRepFill_DataMapOfShapeSequenceOfReal     MapVerPar;
705
706   TopTools_DataMapOfShapeShape              EmptyMap;
707   TopTools_SequenceOfShape                  EmptySeq;
708   TopTools_ListOfShape                      EmptyList;
709   TColStd_SequenceOfReal                    EmptySeqOfReal;
710
711   // mark of the profile.
712   gp_Ax3 AxeRef(gp_Pnt(0.,0.,0.),
713     gp_Dir(0.,0.,1.),
714     gp_Dir(1.,0.,0.));  
715
716   //---------------------------------------------------------------
717   // Construction of revolutions and tubes.
718   //---------------------------------------------------------------
719   BRepTools_WireExplorer ProfExp;
720   TopExp_Explorer        FaceExp;
721   BRepTools_WireExplorer WireExp;
722
723   for (FaceExp.Init(mySpine,TopAbs_WIRE); FaceExp.More(); FaceExp.Next()){
724
725     for (WireExp.Init(TopoDS::Wire(FaceExp.Current())); WireExp.More(); 
726       WireExp.Next()) {
727
728         TopoDS_Edge   CurrentEdge = WireExp.Current();
729         TopoDS_Vertex VFirst,VLast;
730         EdgeVertices(CurrentEdge,VFirst,VLast);
731
732         for (Link.Init(VLast); Link.More(); Link.Next()) {
733           //----------------------------.
734           //Construction of a Revolution
735           //----------------------------.
736           MakeRevol (CurrentEdge, VLast, AxeRef);
737         }
738
739         for (Link.Init(CurrentEdge); Link.More(); Link.Next()) {
740           //------------------------.
741           //Construction of a Tube
742           //-------------------------
743           MakePipe (CurrentEdge, AxeRef);
744         }
745     }
746   }
747
748 #ifdef DRAW
749   if (AffichEdge) {
750     cout << " End Construction of geometric primitives"<<endl;
751   }
752 #endif
753
754   //---------------------------------------------------
755   // Construction of edges associated to bissectrices.
756   //---------------------------------------------------
757   Handle(MAT_Arc)        CurrentArc;
758   Handle(Geom2d_Curve)   Bis, PCurve1, PCurve2 ;
759   Handle(Geom_Curve)     CBis;
760   Standard_Boolean       Reverse;
761   TopoDS_Edge            CurrentEdge;
762   TopoDS_Shape           S       [2];
763   TopoDS_Face            F       [2];
764   TopoDS_Edge            E       [4];
765   TopLoc_Location        L;
766   Standard_Integer       k;
767
768   for (Standard_Integer i = 1; i <= Locus.Graph()->NumberOfArcs(); i++) {
769     CurrentArc = Locus.Graph()->Arc(i);
770     SimpleExpression(Locus.GeomBis(CurrentArc,Reverse), Bis); 
771
772     //------------------------------------------------------------------
773     // Return elements of the spine corresponding to separate basicElts.
774     //------------------------------------------------------------------
775     S [0] = Link.GeneratingShape(CurrentArc->FirstElement());
776     S [1] = Link.GeneratingShape(CurrentArc->SecondElement());
777
778     Standard_Boolean Concave0 = ConcaveSide(S[0],mySpine);
779     Standard_Boolean Concave1 = ConcaveSide(S[1],mySpine);
780
781     TopTools_SequenceOfShape VOnF,VOnL;
782     TColgp_SequenceOfPnt     ParOnF,ParOnL;
783
784     TopTools_DataMapOfShapeSequenceOfShape MapSeqVer;
785     BRepFill_DataMapOfShapeSequenceOfPnt   MapSeqPar;
786
787     Standard_Integer vv = 0;
788     for(ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()) {
789       vv++;
790       //-----------------------------------------------
791       // Return two faces separated by the bissectrice.
792       //-----------------------------------------------
793       F [0] = TopoDS::Face(myMap(S[0])(ProfExp.Current()).First());
794       F [1] = TopoDS::Face(myMap(S[1])(ProfExp.Current()).First());
795
796       //------------------------------------
797       // Return parallel edges on each face.
798       //------------------------------------
799       TopoDS_Vertex VF,VL;
800
801       EdgeVertices(ProfExp.Current(),VF,VL);
802
803       E [0] = TopoDS::Edge(myMap(S[0])(VF).First());
804       E [1] = TopoDS::Edge(myMap(S[0])(VL).First());
805       E [2] = TopoDS::Edge(myMap(S[1])(VF).First());
806       E [3] = TopoDS::Edge(myMap(S[1])(VL).First());
807
808       Standard_Boolean Inv0[2];
809       Standard_Boolean Inv1[2];
810
811       Inv0[0] = Inv0[1] = Inv1[0]= Inv1[1] = 0;
812       if (Concave0) IsInversed(S[0],E[0],E[1],Inv0);
813       if (Concave1) IsInversed(S[1],E[2],E[3],Inv1);
814
815       //---------------------------------------------
816       // Construction of geometries.
817       //---------------------------------------------
818       BRepFill_TrimSurfaceTool Trim (Bis,F[0],F[1],
819         E[0],E[2],Inv0[0],Inv1[0]);
820       //-----------------------------------------------------------
821       //Construction of vertices corresponding to the node of the map
822       //-----------------------------------------------------------
823       TopoDS_Vertex VS,VE;
824       Handle(MAT_Node) Node1, Node2;
825
826       if (Reverse) {
827         Node1 = CurrentArc->SecondNode();
828         Node2 = CurrentArc->FirstNode();
829       }
830       else  {
831         Node1 = CurrentArc->FirstNode();
832         Node2 = CurrentArc->SecondNode();
833       }
834       //--------------------------------------------------------
835       // Particular case when the node is on a vertex of the spine.
836       //--------------------------------------------------------
837       if (Node1->OnBasicElt()) {
838         if (S[0].ShapeType() == TopAbs_VERTEX) {
839           Node1 = CurrentArc->FirstElement()->StartArc()->FirstNode();
840         }
841         else if (S[1].ShapeType() == TopAbs_VERTEX) {
842           Node1 = CurrentArc->SecondElement()->StartArc()->FirstNode();
843         }
844       } 
845       // End of particular case.
846
847       Standard_Integer 
848         StartOnF  = VertexFromNode(Node1, 
849         TopoDS::Edge(ProfExp.Current()), 
850         VF, VL ,
851         MapNodeVertex,VS);
852
853       Standard_Integer 
854         EndOnF    = VertexFromNode(Node2, 
855         TopoDS::Edge(ProfExp.Current()), 
856         VF, VL ,
857         MapNodeVertex,VE);
858
859       //-----------------------------------------------------------
860       // Construction of vertices on edges parallel to the spine.
861       //-----------------------------------------------------------
862       if (!MapSeqVer.IsBound(VF)) {
863         if (Inv0 [0] || Inv1 [0]) {
864           ParOnF.Clear();
865           VOnF  .Clear();
866         }
867         else {
868           Trim.IntersectWith(E [0], E [2], ParOnF);
869           VOnF  .Clear();
870           for (Standard_Integer s = 1; s <= ParOnF.Length(); s++) {
871             TopoDS_Vertex VC;
872             myBuilder.MakeVertex (VC);
873             VOnF.Append(VC);
874           }
875           if (StartOnF == 1) {
876             VOnF  .SetValue(1,VS);
877           }
878           if (EndOnF == 1) {      
879             VOnF  .SetValue(ParOnF.Length(),VE);
880           }
881         }
882       }
883       else {
884         ParOnF = MapSeqPar(VF);
885         VOnF   = MapSeqVer(VF);
886       }
887
888       if (!MapSeqVer.IsBound(VL)) {
889         if (Inv0 [1] || Inv1 [1]) {
890           ParOnL.Clear();
891           VOnL  .Clear();
892         }
893         else {
894           Trim.IntersectWith(E [1], E [3], ParOnL);
895           VOnL.Clear();
896           for (Standard_Integer s = 1; s <= ParOnL.Length(); s++) {     
897             TopoDS_Vertex VC;
898             myBuilder.MakeVertex (VC); 
899             VOnL.Append(VC);
900           }
901           if (StartOnF == 3) {
902             VOnL  .SetValue(1,VS);
903           }
904           if (EndOnF == 3)   {
905             VOnL  .SetValue(ParOnL.Length(),VE);
906           }
907         }
908       }
909       else {
910         ParOnL = MapSeqPar(VL);
911         VOnL   = MapSeqVer(VL);
912       }
913
914       //------------------------------------------------------
915       // Test if the Bissectrice is not projected on the face
916       //------------------------------------------------------
917       if ((StartOnF == 0) && (EndOnF == 0) && 
918         VOnL.IsEmpty() && VOnF.IsEmpty())
919         // No trace of the bisectrice on the face.
920         continue;
921
922       if ((StartOnF == 0) && (EndOnF == 0) && 
923         (VOnL.Length() + VOnF.Length() == 1)) 
924         // the first or last node of the arc is on the edge
925         // but the arc is not on the face. 
926         continue; 
927
928       //---------------------------------------------------------
929       // determine the intervals of the bissectrice that are
930       // projected on F[0] and F[1].
931       //---------------------------------------------------------
932       TColStd_SequenceOfReal     LastPar,FirstPar;
933       TopTools_SequenceOfShape   FirstV,LastV;
934
935       ComputeIntervals (VOnF,VOnL,ParOnF,ParOnL,Trim,Bis,
936         VS,VE,FirstPar,LastPar,FirstV,LastV);
937
938       for (Standard_Integer Ti =  1; Ti <= FirstPar.Length(); Ti++) {
939         TopoDS_Vertex V1 = TopoDS::Vertex(FirstV.Value(Ti));
940         TopoDS_Vertex V2 = TopoDS::Vertex(LastV .Value(Ti));
941
942         GeomAbs_Shape Continuity;
943
944         Trim.Project(FirstPar.Value(Ti),LastPar.Value(Ti),
945           CBis,PCurve1,PCurve2,Continuity);
946
947         //-------------------------------------
948         // Coding of the edge.
949         //-------------------------------------
950         myBuilder.MakeEdge(CurrentEdge, CBis, 
951           BRepFill_Confusion());
952
953         myBuilder.UpdateVertex(V1,CBis->Value(CBis->FirstParameter()),
954           BRepFill_Confusion()); 
955         myBuilder.UpdateVertex(V2,CBis->Value(CBis->LastParameter()),
956           BRepFill_Confusion());
957
958         myBuilder.Add(CurrentEdge,V1.Oriented(TopAbs_FORWARD));
959         myBuilder.Add(CurrentEdge,V2.Oriented(TopAbs_REVERSED));
960
961         myBuilder.Range(CurrentEdge,
962           CBis->FirstParameter(),
963           CBis->LastParameter());
964         myBuilder.UpdateEdge(CurrentEdge,PCurve1,F[0],BRepFill_Confusion());
965         myBuilder.UpdateEdge(CurrentEdge,PCurve2,F[1],BRepFill_Confusion());
966
967         myBuilder.Continuity(CurrentEdge,F[0],F[1],Continuity);
968
969 #ifdef DRAW
970         if (AffichEdge) {
971           char name[100];
972           sprintf(name,"ARCEDGE_%d_%d_%d",i,vv,Ti);     
973           DBRep::Set(name,CurrentEdge);
974         }
975 #endif
976         //-------------------------------------------
977         // Storage of the edge for each of faces.
978         //-------------------------------------------
979         for (k = 0; k <= 1;k++) {
980           if (!MapBis.IsBound(F[k])) {
981             MapBis.Bind(F[k],EmptySeq);
982           }
983         }
984         //---------------------------------------------------------------
985         // orientation of the edge depends on the direction of the skin.
986         // skin => same orientation E[0] , inverted orientation E[2]
987         // if contreskin it is inverted.
988         //--------------------------------------------------------------
989         E[0].Orientation(OriEdgeInFace(E[0],F[0]));
990         E[2].Orientation(OriEdgeInFace(E[2],F[1]));
991
992         if (DistanceToOZ(VF) < DistanceToOZ(VL)  ) { 
993           // Skin
994           MapBis(F[0]).Append(CurrentEdge.Oriented  (E[0].Orientation()));
995           CurrentEdge.Orientation(TopAbs::Complement(E[2].Orientation()));
996           MapBis(F[1]).Append(CurrentEdge);
997         }
998         else {
999           //Contreskin
1000           MapBis(F[1]).Append(CurrentEdge.Oriented  (E[2].Orientation()));
1001           CurrentEdge.Orientation(TopAbs::Complement(E[0].Orientation()));
1002           MapBis(F[0]).Append(CurrentEdge);
1003         }
1004       }
1005
1006       //----------------------------------------------
1007       // Storage of vertices on parallel edges.
1008       // fill MapBis and MapVerPar.
1009       // VOnF for E[0] and E[2].
1010       // VOnL for E[1] and E[3].
1011       //----------------------------------------------
1012       for (k = 0; k <= 2; k = k+2) {
1013         if ( !MapSeqVer.IsBound(VF)) {
1014           if (!VOnF.IsEmpty()) {
1015             if (!MapBis.IsBound(E[k])) {
1016               MapBis   .Bind(E[k],EmptySeq);
1017               MapVerPar.Bind(E[k],EmptySeqOfReal);
1018             } 
1019             for (Standard_Integer ii = 1; ii <= VOnF.Length(); ii++) {
1020               MapBis (E[k]).Append(VOnF.Value(ii));
1021               if (k == 0) MapVerPar (E[k]).Append(ParOnF.Value(ii).Y());
1022               else        MapVerPar (E[k]).Append(ParOnF.Value(ii).Z());
1023             }
1024           }
1025         }
1026       }
1027
1028       for (k = 1; k <= 3; k = k+2) {
1029         if ( !MapSeqVer.IsBound(VL)) {
1030           if (!VOnL.IsEmpty()) {
1031             if (!MapBis.IsBound(E[k])) {
1032               MapBis   .Bind(E[k],EmptySeq);
1033               MapVerPar.Bind(E[k],EmptySeqOfReal);
1034             }
1035             for (Standard_Integer ii = 1; ii <= VOnL.Length(); ii++) {
1036               MapBis(E[k]).Append(VOnL.Value(ii));
1037               if (k == 1) MapVerPar (E[k]).Append(ParOnL.Value(ii).Y());
1038               else        MapVerPar (E[k]).Append(ParOnL.Value(ii).Z());
1039             }
1040           }
1041         }
1042       }
1043
1044       //----------------------------------------------------------------
1045       // Edge [1] of the current face will be Edge [0] of the next face.
1046       // => copy of VonL in VonF. To avoid creating the same vertices twice.
1047       //-----------------------------------------------------------------
1048
1049       MapSeqPar.Bind(VF,ParOnF);
1050       MapSeqVer.Bind(VF,VOnF);
1051       MapSeqPar.Bind(VL,ParOnL);
1052       MapSeqVer.Bind(VL,VOnL);
1053
1054     }
1055   }
1056
1057 #ifdef DRAW
1058   if (AffichEdge) {
1059     cout << " End of Construction of edges and vertices on bissectrices"<<endl;
1060   }
1061 #endif
1062
1063   //----------------------------------
1064   // Construction of parallel edges.
1065   //----------------------------------
1066   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape ite1;
1067   TopoDS_Shape           CurrentProf,PrecProf;
1068   TopoDS_Face            CurrentFace;
1069   TopoDS_Shape           CurrentSpine;
1070   TopoDS_Vertex          VCF,VCL;
1071
1072   for (ite1.Initialize(myMap); ite1.More(); ite1.Next()) {
1073     CurrentSpine = ite1.Key();
1074
1075     for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){      
1076       CurrentProf = ProfExp.Current();
1077       EdgeVertices(TopoDS::Edge(CurrentProf),VCF,VCL);
1078       CurrentEdge  = TopoDS::Edge(myMap(CurrentSpine)(VCF).First());
1079
1080       //-------------------------------------------------------------
1081       //RQ : Current Edge is oriented relatively to the face (oriented forward)
1082       //     generated by edge CurrentProf .
1083       //-------------------------------------------------------------
1084       if (MapBis.IsBound(CurrentEdge)) {
1085
1086         //--------------------------------------------------------
1087         // Find if one of two faces connected to the edge
1088         // belongs to volevo. The edges on this face serve
1089         // to eliminate certain vertices that can appear twice
1090         // on the parallel edge. These Vertices corespond to the
1091         // nodes of the map.
1092         //---------------------------------------------------------
1093         TopoDS_Shape     FaceControle;
1094         Standard_Boolean YaFace = Standard_True;
1095
1096         FaceControle = myMap(CurrentSpine)(CurrentProf).First();
1097         if (!MapBis.IsBound(FaceControle)){
1098           YaFace = Standard_False;
1099           if (!PrecProf.IsNull()) {
1100             FaceControle = myMap(CurrentSpine)(PrecProf).First();
1101             if (MapBis.IsBound(FaceControle)){
1102               YaFace = Standard_True;
1103             }
1104           }
1105         }
1106
1107         if (YaFace) {
1108           //------------------------------------------------------------
1109           // No connected face in the volevo => no parallel edge.
1110           //------------------------------------------------------------
1111           TopTools_SequenceOfShape aSeqOfShape;
1112           TrimEdge (CurrentEdge,
1113             MapBis   (FaceControle), 
1114             MapBis   (CurrentEdge) ,  
1115             MapVerPar(CurrentEdge) , aSeqOfShape);
1116
1117           for ( k = 1; k <= aSeqOfShape.Length(); k++) {
1118             myMap(CurrentSpine)(VCF).Append(aSeqOfShape.Value(k));
1119
1120 #ifdef DRAW         
1121             if (AffichEdge) {
1122               char name[100];
1123               sprintf(name,"PAREDGE_%d_%d",++NbEDGES,k);        
1124               DBRep::Set(name,aSeqOfShape.Value(k));
1125             }
1126 #endif      
1127           }
1128         }
1129       }
1130       PrecProf = CurrentProf;
1131     }
1132
1133     //------------------------------------------------------------
1134     // Construction of the parallel edge from the last vertex of myProfile.
1135     //------------------------------------------------------------
1136     CurrentEdge  = TopoDS::Edge(myMap(CurrentSpine)(VCL).First());
1137
1138     if (MapBis.IsBound(CurrentEdge)) {
1139       Standard_Boolean YaFace = Standard_True;
1140       TopoDS_Shape     FaceControle;
1141
1142       FaceControle = myMap(CurrentSpine)(CurrentProf).First();
1143       if (!MapBis.IsBound(FaceControle)){
1144         YaFace = Standard_False;
1145       }
1146       // the number of element of the list allows to know
1147       // if the edges have already been done (closed profile) .
1148       if (YaFace && myMap(CurrentSpine)(VCL).Extent()<= 1) {
1149         TopTools_SequenceOfShape aSeqOfShape;
1150         TrimEdge (CurrentEdge, 
1151           MapBis   (FaceControle), 
1152           MapBis   (CurrentEdge) , 
1153           MapVerPar(CurrentEdge) , aSeqOfShape);
1154
1155         for ( k = 1; k <= aSeqOfShape.Length(); k++) {
1156           myMap(CurrentSpine)(VCL).Append(aSeqOfShape.Value(k));
1157
1158 #ifdef DRAW         
1159           if (AffichEdge) {       
1160             char name[100];
1161             sprintf(name,"PAREDGE_%d_%d",++NbEDGES,k);  
1162             DBRep::Set(name,aSeqOfShape.Value(k));
1163           }
1164 #endif
1165         }
1166       }
1167     }
1168   }
1169
1170 #ifdef DRAW
1171   if (AffichEdge) {
1172     cout <<" End Construction of parallel edges "<<endl;
1173   }
1174 #endif
1175
1176   //-------------------------------------------------------------------
1177   // Cut faces by edges.
1178   //-------------------------------------------------------------------
1179   for (ite1.Initialize(myMap); ite1.More(); ite1.Next()) {
1180     CurrentSpine = ite1.Key();
1181
1182     for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){
1183       CurrentProf = ProfExp.Current();
1184       CurrentFace = TopoDS::Face(myMap(CurrentSpine)(CurrentProf).First());
1185       myMap(CurrentSpine)(CurrentProf).Clear();
1186
1187       if (MapBis.IsBound(CurrentFace)) {
1188         //----------------------------------------------------------
1189         // If the face does not contain edges that can limit it
1190         // it does not appear in volevo.
1191         // cut of face by edges can generate many faces.
1192         //
1193         // Add edges generated on the edges parallel to the set
1194         // of edges that limit the face.
1195         //
1196         //------------------------------------------------------------
1197         EdgeVertices(TopoDS::Edge(CurrentProf),VCF,VCL);
1198
1199         TopTools_ListIteratorOfListOfShape itl;
1200         const TopTools_ListOfShape& LF = myMap(CurrentSpine)(VCF);
1201
1202         TopAbs_Orientation Ori = OriEdgeInFace(TopoDS::Edge(LF.First()),
1203           CurrentFace);
1204         for (itl.Initialize(LF), itl.Next(); itl.More(); itl.Next()) {
1205           TopoDS_Edge RE = TopoDS::Edge(itl.Value());
1206           MapBis(CurrentFace).Append(RE.Oriented(Ori));
1207         }
1208         const TopTools_ListOfShape& LL = myMap(CurrentSpine)(VCL);        
1209         Ori = OriEdgeInFace(TopoDS::Edge(LL.First()),CurrentFace);
1210         for (itl.Initialize(LL), itl.Next() ; itl.More(); itl.Next()) {  
1211           TopoDS_Edge RE = TopoDS::Edge(itl.Value());
1212           MapBis(CurrentFace).Append(RE.Oriented(Ori));
1213         }
1214
1215         //Cut of the face.
1216         TopTools_SequenceOfShape  aSeqOfShape;
1217
1218         TrimFace (CurrentFace, MapBis(CurrentFace), aSeqOfShape);
1219
1220         for (Standard_Integer ii = 1; ii <= aSeqOfShape.Length(); ii++) {
1221           myBuilder.Add (myShape, aSeqOfShape.Value(ii));
1222           myMap(CurrentSpine)(CurrentProf).Append(aSeqOfShape.Value(ii));
1223         }
1224       }
1225     }
1226     //-----------------------------------------------------------------
1227     // Removal of first edge (edge of origin) from lists of myMap 
1228     // corresponding to vertices of the profile.
1229     //-----------------------------------------------------------------
1230     TopExp_Explorer Explo(myProfile,TopAbs_VERTEX);
1231     TopTools_MapOfShape vmap;
1232
1233     for ( ; Explo.More(); Explo.Next()){
1234       if (vmap.Add(Explo.Current())) {
1235         myMap(CurrentSpine)(Explo.Current()).RemoveFirst();
1236       }
1237     }
1238   }      
1239   myIsDone = Standard_True;
1240
1241 #ifdef DRAW  
1242   if (AffichEdge) {       
1243     cout <<" End of construction of an elementary volevo."<<endl;           
1244     char name[100];
1245     sprintf(name,"VEVO_%d",++NbVEVOS);  
1246     DBRep::Set(name,myShape);
1247   }
1248 #endif
1249 }
1250
1251 //=======================================================================
1252 //function : PlanarPerform
1253 //purpose  : 
1254 //=======================================================================
1255
1256 void BRepFill_Evolved::PlanarPerform (const TopoDS_Face&              Sp,
1257   const TopoDS_Wire&              Pr,
1258   const BRepMAT2d_BisectingLocus& Locus,
1259   BRepMAT2d_LinkTopoBilo&   Link,
1260   const GeomAbs_JoinType          Join)
1261 {
1262   TopoDS_Shape aLocalShapeOriented = Sp.Oriented(TopAbs_FORWARD);
1263   mySpine   = TopoDS::Face(aLocalShapeOriented);
1264   //  mySpine   = TopoDS::Face(Sp.Oriented(TopAbs_FORWARD));
1265   myProfile = Pr;
1266   myMap.Clear();
1267
1268   BRep_Builder B;
1269   B.MakeCompound(TopoDS::Compound(myShape));
1270
1271   BRepTools_WireExplorer             ProfExp;
1272   TopExp_Explorer                    Exp,exp1,exp2;
1273   TopTools_DataMapOfShapeListOfShape EmptyMap;
1274   TopTools_ListOfShape               EmptyList;
1275   TopTools_DataMapOfShapeShape       MapVP;
1276   BRepFill_OffsetWire                Paral;
1277
1278   for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){
1279     const TopoDS_Edge& E = ProfExp.Current();
1280     BRepAlgo_FaceRestrictor FR;
1281     BRepFill_OffsetAncestors OffAnc;
1282
1283     TopoDS_Vertex V[2];
1284     EdgeVertices(E,V[0],V[1]);
1285     Standard_Real Alt = Altitud(V[0]);
1286     Standard_Real Offset[2];
1287     Offset[0] = DistanceToOZ(V[0]);
1288     Offset[1] = DistanceToOZ(V[1]);
1289     Standard_Boolean IsMinV1 = ( Offset[0] < Offset[1]);
1290
1291     for (Standard_Integer i = 0; i <= 1; i++) {
1292       if (!MapVP.IsBound(V[i])) {
1293         //------------------------------------------------
1294         // Calculate parallel lines corresponding to vertices.
1295         //------------------------------------------------
1296         Paral.PerformWithBiLo(mySpine,Offset[i],Locus,Link,Join,Alt);
1297         OffAnc.Perform(Paral);
1298         MapVP.Bind(V[i],Paral.Shape());
1299
1300         //-----------------------------
1301         // Update myMap (.)(V[i])
1302         //-----------------------------
1303         for (Exp.Init(Paral.Shape(),TopAbs_EDGE);
1304           Exp.More();
1305           Exp.Next()) {
1306             const TopoDS_Edge& WC = TopoDS::Edge(Exp.Current());
1307             const TopoDS_Shape& GS = OffAnc.Ancestor(WC);
1308             if ( !myMap.IsBound(GS)) 
1309               myMap.Bind(GS, EmptyMap);
1310             if ( !myMap(GS).IsBound(V[i]))
1311               myMap(GS).Bind(V[i],Paral.GeneratedShapes(GS));
1312         }
1313       }
1314       TopoDS_Shape Rest = MapVP(V[i]);
1315
1316       Standard_Boolean ToReverse = Standard_False;
1317       if ( ( IsMinV1 && (i==1)) || (!IsMinV1 && (i==0)) )
1318         ToReverse = Standard_True;
1319
1320       if (!Rest.IsNull()) {
1321         if (Rest.ShapeType() == TopAbs_WIRE) {
1322           if ( ToReverse){
1323             TopoDS_Shape aLocalShape  = Rest.Reversed();
1324             TopoDS_Wire aWire = TopoDS::Wire(aLocalShape);
1325             FR.Add(aWire);
1326           }       
1327           else
1328             FR.Add(TopoDS::Wire(Rest));
1329         }
1330         else {
1331           for (Exp.Init(Rest,TopAbs_WIRE);Exp.More();Exp.Next()) {
1332             TopoDS_Wire WCop = TopoDS::Wire(Exp.Current());
1333             if ( ToReverse){
1334               TopoDS_Shape aLocalShape = WCop.Reversed();
1335               TopoDS_Wire bWire =   TopoDS::Wire(aLocalShape);
1336               //              TopoDS_Wire bWire =   TopoDS::Wire(WCop.Reversed());
1337               FR.Add(bWire);
1338             }       
1339             else
1340               FR.Add(WCop);
1341           }
1342         }
1343       }
1344     }
1345 #ifdef DRAW  
1346     if (AffichEdge) {     
1347       TopTools_DataMapIteratorOfDataMapOfShapeShape it(MapVP);
1348       Standard_Integer k = 0;
1349       for (; it.More(); it.Next()) {
1350         char name[100];
1351         sprintf(name,"PARALI_%d",++k);  
1352         DBRep::Set(name,it.Value());
1353       }
1354     }
1355 #endif
1356
1357     //----------------------------------------------------
1358     // Construction of faces limited by parallels.
1359     // - set to the height of the support face.
1360     //----------------------------------------------------
1361     gp_Trsf T; T.SetTranslation(gp_Vec(0,0,Alt));
1362     TopLoc_Location LT(T);
1363     TopoDS_Shape aLocalShape = mySpine.Moved(LT);
1364     FR.Init(TopoDS::Face(aLocalShape));
1365     //    FR.Init(TopoDS::Face(mySpine.Moved(LT)));
1366     FR.Perform();
1367
1368     for ( ;FR.More(); FR.Next()) {
1369       const TopoDS_Face& F = FR.Current();
1370       B.Add(myShape,F);
1371       //---------------------------------------
1372       // Update myMap(.)(E)
1373       //---------------------------------------
1374       for ( Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1375         const TopoDS_Edge& CE = TopoDS::Edge(Exp.Current());
1376         if (OffAnc.HasAncestor(CE)) {
1377           const TopoDS_Shape& InitE = OffAnc.Ancestor(CE);
1378           if ( !myMap.IsBound(InitE)) 
1379             myMap.Bind(InitE, EmptyMap);
1380           if ( !myMap(InitE).IsBound(E))
1381             myMap(InitE).Bind(E,EmptyList);
1382           myMap(InitE)(E).Append(F);
1383         }
1384       }
1385     }
1386   }  // End loop on profile.
1387 }
1388
1389
1390 //=======================================================================
1391 //function : VerticalPerform
1392 //purpose  : 
1393 //=======================================================================
1394
1395 void BRepFill_Evolved::VerticalPerform (const TopoDS_Face&              Sp,
1396   const TopoDS_Wire&              Pr,
1397   const BRepMAT2d_BisectingLocus& Locus,
1398   BRepMAT2d_LinkTopoBilo&   Link,
1399   const GeomAbs_JoinType          Join)
1400 {
1401   TopoDS_Shape aLocalShape = Sp.Oriented(TopAbs_FORWARD);
1402   mySpine   = TopoDS::Face(aLocalShape);
1403   //  mySpine   = TopoDS::Face(Sp.Oriented(TopAbs_FORWARD));
1404   myProfile = Pr;
1405   myMap.Clear();
1406
1407   BRep_Builder B;
1408   B.MakeCompound(TopoDS::Compound(myShape));
1409
1410   BRepTools_WireExplorer   ProfExp;
1411   TopExp_Explorer          Exp;
1412   BRepFill_OffsetWire      Paral;
1413   BRepFill_OffsetAncestors OffAnc;
1414   TopoDS_Vertex            V1,V2;
1415
1416   Standard_Boolean First = Standard_True;
1417   TopoDS_Shape     Base;
1418   TopTools_DataMapOfShapeListOfShape  EmptyMap;
1419
1420   for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){
1421     const TopoDS_Edge& E = ProfExp.Current();
1422     EdgeVertices(E,V1,V2);
1423     Standard_Real Alt1 = Altitud(V1);
1424     Standard_Real Alt2 = Altitud(V2);
1425
1426     if (First) {
1427       Standard_Real Offset = DistanceToOZ(V1);
1428       if (Abs(Offset) < BRepFill_Confusion()) {
1429         Offset = 0.;
1430       }
1431       Paral.PerformWithBiLo(mySpine,Offset,Locus,Link,Join,Alt1);   
1432       OffAnc.Perform(Paral);
1433       Base = Paral.Shape();
1434
1435       // MAJ myMap
1436       for (Exp.Init(Base,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1437         const TopoDS_Edge&  anEdge = TopoDS::Edge(Exp.Current());
1438         const TopoDS_Shape& AE =  OffAnc.Ancestor(anEdge);
1439         if (!myMap.IsBound(AE)) {
1440           myMap.Bind(AE,EmptyMap);
1441         }
1442         if (!myMap(AE).IsBound(V1)) {
1443           TopTools_ListOfShape L;
1444           myMap(AE).Bind(V1,L);
1445         }
1446         myMap(AE)(V1).Append(anEdge);
1447       }
1448       First = Standard_False;
1449     }
1450
1451
1452 #ifdef DRAW  
1453     if (AffichEdge) {     
1454       char name[100];
1455       sprintf(name,"PARALI_%d",++NbVEVOS);      
1456       DBRep::Set(name,Base);
1457     }
1458 #endif
1459
1460     BRepSweep_Prism PS(Base,gp_Vec(0,0,Alt2 - Alt1),Standard_False);
1461 #ifdef DRAW  
1462     if (AffichEdge) {     
1463       char name[100];
1464       sprintf(name,"PRISM_%d",NbVEVOS); 
1465       DBRep::Set(name,PS.Shape());
1466     }
1467 #endif
1468
1469     Base = PS.LastShape();
1470
1471     for (Exp.Init(PS.Shape(),TopAbs_FACE); Exp.More(); Exp.Next()) {
1472       B.Add(myShape,Exp.Current());
1473     }
1474
1475     // MAJ myMap
1476     BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape 
1477       it(myMap);
1478
1479     for (; it.More(); it.Next()) {
1480       const TopTools_ListOfShape& LOF = it.Value()(V1);
1481       TopTools_ListIteratorOfListOfShape itLOF(LOF);
1482       if (!myMap(it.Key()).IsBound(V2)) {
1483         TopTools_ListOfShape L;
1484         myMap(it.Key()).Bind(V2,L);
1485       }
1486
1487       if (!myMap(it.Key()).IsBound(E)) {
1488         TopTools_ListOfShape L;
1489         myMap(it.Key()).Bind(E,L);
1490       }
1491
1492       for (; itLOF.More(); itLOF.Next()) {
1493         const TopoDS_Shape& OS = itLOF.Value();
1494         myMap(it.Key())(V2).Append(PS.LastShape(OS));
1495         myMap(it.Key())(E).Append(PS.Shape(OS));
1496       }
1497     }
1498   }
1499 }
1500
1501 //=======================================================================
1502 //function : Bubble
1503 //purpose  : Order the sequence of points by growing x. 
1504 //=======================================================================
1505
1506 static void Bubble(TColStd_SequenceOfReal& Seq) 
1507 {
1508   Standard_Boolean Invert = Standard_True;
1509   Standard_Integer NbPoints = Seq.Length();
1510
1511   while (Invert) {
1512     Invert = Standard_False;
1513     for ( Standard_Integer i = 1; i < NbPoints; i++) {
1514       if ( Seq.Value(i+1) < Seq.Value(i)) {
1515         Seq.Exchange(i,i+1);
1516         Invert = Standard_True;
1517       }
1518     }
1519   }
1520 }
1521
1522
1523 //=======================================================================
1524 //function : PrepareProfile
1525 //purpose  : - Projection of the profile on the working plane.
1526 //           - Cut of the profile at the extrema of distance from profile to axis Oz.
1527 //           - Isolate vertical and horizontal parts.
1528 //           - Reconstruction of wires starting from cut edges.
1529 //           New wires stored in <WorkProf> are always at the same 
1530 //           side of axis OZ or mixed with it.
1531 //=======================================================================
1532
1533 void BRepFill_Evolved::PrepareProfile(TopTools_ListOfShape&         WorkProf, 
1534   TopTools_DataMapOfShapeShape& MapProf  ) 
1535   const 
1536 {
1537   // Supposedly the profile is located so that the only transformation 
1538   // to be carried out is a projection on plane yOz.
1539
1540   // initialise the projection Plane and the Line to evaluate the extrema.
1541   Handle(Geom_Plane) Plane = new Geom_Plane(gp_Ax3(gp::YOZ()));
1542   Handle(Geom2d_Line) Line = new Geom2d_Line(gp::OY2d());
1543
1544   // Map initial vertex -> projected vertex.
1545   TopTools_DataMapOfShapeShape MapVerRefMoved;
1546
1547   TopoDS_Vertex V1,V2,VRef1,VRef2;
1548   TopoDS_Wire   W;
1549   BRep_Builder  B;
1550   TopTools_ListOfShape WP;
1551   B.MakeWire(W);
1552   WP.Append(W);
1553
1554   BRepTools_WireExplorer Exp(myProfile) ;
1555
1556   while (Exp.More()) {
1557     TopTools_ListOfShape Cuts;
1558     Standard_Boolean     NewWire = Standard_False;
1559     const TopoDS_Edge&   E = TopoDS::Edge(Exp.Current());
1560
1561     // Cut of the edge.
1562     CutEdgeProf (E ,Plane ,Line ,Cuts ,MapVerRefMoved);
1563
1564     EdgeVertices(E,VRef1,VRef2);
1565
1566     if ( Cuts.IsEmpty()) { 
1567       // Neither extrema nor intersections nor vertices on the axis.
1568       B.Add(W,E);
1569       MapProf.Bind(E,E);
1570     }
1571     else {
1572       while (!Cuts.IsEmpty()) {
1573         const TopoDS_Edge& NE = TopoDS::Edge(Cuts.First());
1574         MapProf.Bind(NE,E);
1575         EdgeVertices(NE,V1,V2);
1576         if (!MapProf.IsBound(V1)) MapProf.Bind(V1,E);
1577         if (!MapProf.IsBound(V2)) MapProf.Bind(V2,E);
1578
1579         B.Add(W,NE);
1580         Cuts.RemoveFirst();
1581
1582         if (DistanceToOZ(V2) < BRepFill_Confusion() &&
1583           DistanceToOZ(V1) > BRepFill_Confusion()) {
1584             // NE ends on axis OZ => new wire
1585             if (Cuts.IsEmpty()) {
1586               // last part of the current edge
1587               // If it is not the last edge of myProfile 
1588               // create a new wire.
1589               NewWire = Standard_True;
1590             }
1591             else {
1592               // New wire.
1593               B.MakeWire(W);
1594               WP.Append(W);
1595             }
1596         }
1597       }
1598     }
1599     Exp.Next();
1600     if (Exp.More() && NewWire) {
1601       B.MakeWire(W);
1602       WP.Append(W);
1603     }
1604   }
1605
1606   // In the list of Wires, find edges generating plane or vertical vevo.
1607   TopTools_ListIteratorOfListOfShape ite;
1608   TopoDS_Wire CurW,NW;
1609   TopExp_Explorer EW;
1610
1611
1612   for (ite.Initialize(WP); ite.More(); ite.Next()) {
1613     CurW = TopoDS::Wire(ite.Value());
1614     Standard_Boolean YaModif = Standard_False;
1615     for (EW.Init(CurW,TopAbs_EDGE); EW.More(); EW.Next()) {
1616       const TopoDS_Edge& EE = TopoDS::Edge(EW.Current());
1617       if (IsVertical(EE) || IsPlanar(EE)) {
1618         YaModif = Standard_True;
1619         break;
1620       }
1621     }
1622
1623     if (YaModif) {
1624       //Status = 0 for the begining
1625       //         3 vertical
1626       //         2 horizontal
1627       //         1 other
1628       Standard_Integer Status = 0; 
1629
1630       for (EW.Init(CurW,TopAbs_EDGE); EW.More(); EW.Next()) {
1631         const TopoDS_Edge& EE = TopoDS::Edge(EW.Current());
1632         if (IsVertical(EE)) {
1633           if (Status != 3) {
1634             B.MakeWire(NW);
1635             WorkProf.Append(NW);
1636             Status = 3;
1637           }
1638         }
1639         else if (IsPlanar(EE)) {
1640           if (Status != 2) {
1641             B.MakeWire(NW);
1642             WorkProf.Append(NW);
1643             Status = 2;
1644           }
1645         }
1646         else if ( Status != 1) {
1647           B.MakeWire(NW);
1648           WorkProf.Append(NW);
1649           Status = 1;
1650         }
1651         B.Add(NW,EE);
1652       }
1653     }
1654     else {
1655       WorkProf.Append(CurW);
1656     }
1657   }
1658
1659   //connect vertices modified in MapProf;
1660   TopTools_DataMapIteratorOfDataMapOfShapeShape gilbert(MapVerRefMoved);
1661   for ( ;gilbert.More() ;gilbert.Next()) {
1662     MapProf.Bind(gilbert.Value(),gilbert.Key());
1663   }
1664 }
1665
1666
1667 //=======================================================================
1668 //function : PrepareSpine
1669 //purpose  : 
1670 //=======================================================================
1671
1672 void BRepFill_Evolved::PrepareSpine(TopoDS_Face&                 WorkSpine, 
1673   TopTools_DataMapOfShapeShape& MapSpine) 
1674   const
1675 {
1676   BRep_Builder      B;
1677   TopTools_ListOfShape Cuts;
1678   TopTools_ListIteratorOfListOfShape IteCuts;
1679   TopoDS_Vertex V1,V2;
1680
1681   TopLoc_Location L;
1682   const Handle(Geom_Surface)& S    = BRep_Tool::Surface  (mySpine,L);
1683   Standard_Real               TolF = BRep_Tool::Tolerance(mySpine);
1684   B.MakeFace(WorkSpine,S,L,TolF);
1685
1686   for (TopoDS_Iterator IteF(mySpine) ; IteF.More(); IteF.Next()) {
1687
1688     TopoDS_Wire NW;
1689     B.MakeWire (NW);
1690     Standard_Boolean IsClosed = IteF.Value().Closed();
1691
1692     for (TopoDS_Iterator IteW(IteF.Value()); IteW.More(); IteW.Next()) {
1693
1694       TopoDS_Edge E = TopoDS::Edge(IteW.Value());
1695       EdgeVertices(E,V1,V2);
1696       MapSpine.Bind(V1,V1);
1697       MapSpine.Bind(V2,V2);
1698       Cuts.Clear();
1699
1700       // Cut
1701       CutEdge (E, mySpine, Cuts);
1702
1703       if (Cuts.IsEmpty()) {
1704         B.Add(NW,E);
1705         MapSpine.Bind(E,E);
1706       }
1707       else {    
1708         for (IteCuts.Initialize(Cuts); IteCuts.More(); IteCuts.Next()) {
1709           const TopoDS_Edge& NE = TopoDS::Edge(IteCuts.Value());
1710           B.Add(NW,NE);
1711           MapSpine.Bind(NE,E);
1712           EdgeVertices(NE,V1,V2);
1713           if (!MapSpine.IsBound(V1)) MapSpine.Bind(V1,E);
1714           if (!MapSpine.IsBound(V2)) MapSpine.Bind(V2,E);
1715         }
1716       }
1717     }
1718     NW.Closed(IsClosed);
1719     B.Add(WorkSpine, NW);
1720   }
1721
1722   // Construct curves 3D of the spine
1723   BRepLib::BuildCurves3d(WorkSpine);
1724
1725 #ifdef DRAW
1726   if (AffichEdge) {
1727     char name[100];
1728     sprintf(name,"workspine");  
1729     DBRep::Set(name,WorkSpine);
1730   }
1731 #endif 
1732
1733 }
1734 //=======================================================================
1735 //function : GeneratedShapes
1736 //purpose  : 
1737 //=======================================================================
1738
1739 const TopoDS_Shape&  BRepFill_Evolved::Top() const 
1740 {
1741   return myTop;
1742 }
1743
1744 //=======================================================================
1745 //function : GeneratedShapes
1746 //purpose  : 
1747 //=======================================================================
1748
1749 const TopoDS_Shape&  BRepFill_Evolved::Bottom() const 
1750 {
1751   return myBottom;
1752 }
1753
1754 //=======================================================================
1755 //function : GeneratedShapes
1756 //purpose  : 
1757 //=======================================================================
1758
1759 const TopTools_ListOfShape&  BRepFill_Evolved::GeneratedShapes ( 
1760   const TopoDS_Shape& SpineShape,
1761   const TopoDS_Shape& ProfShape )
1762   const 
1763 {
1764   if (myMap            .IsBound(SpineShape) &&
1765     myMap(SpineShape).IsBound(ProfShape)     ) {
1766       return myMap(SpineShape)(ProfShape);
1767   }
1768   else {
1769     static TopTools_ListOfShape Empty;
1770     return Empty;
1771   }
1772 }
1773
1774 //=======================================================================
1775 //function : Generated
1776 //purpose  : 
1777 //=================================================================== ====
1778
1779 BRepFill_DataMapOfShapeDataMapOfShapeListOfShape& BRepFill_Evolved::Generated()
1780 {
1781   return myMap;
1782 }
1783
1784 //=======================================================================
1785 //function : Compare
1786 //purpose  : 
1787 //=======================================================================
1788
1789 static TopAbs_Orientation Compare (const TopoDS_Edge& E1,
1790   const TopoDS_Edge& E2) 
1791 {
1792   TopAbs_Orientation OO = TopAbs_FORWARD;
1793   TopoDS_Vertex V1[2],V2[2];
1794   TopExp::Vertices (E1,V1[0],V1[1]);
1795   TopExp::Vertices (E2,V2[0],V2[1]);
1796   gp_Pnt P1 = BRep_Tool::Pnt(V1[0]);
1797   gp_Pnt P2 =BRep_Tool::Pnt(V2[0]);
1798   gp_Pnt P3 =BRep_Tool::Pnt(V2[1]);
1799   if (P1.Distance(P3) < P1.Distance(P2)) OO = TopAbs_REVERSED; 
1800
1801   return OO;
1802 }
1803
1804 //=======================================================================
1805 //function : Add
1806 //purpose  : 
1807 //=======================================================================
1808
1809 void BRepFill_Evolved::Add(      BRepFill_Evolved& Vevo, 
1810   const TopoDS_Wire&      Prof,
1811   BRepTools_Quilt&  Glue)               
1812
1813 {  
1814   BRepFill_DataMapOfShapeDataMapOfShapeListOfShape& MapVevo = Vevo.Generated();
1815   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape                  iteP;
1816   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape    iteS;
1817   TopoDS_Shape CurrentSpine, CurrentProf;
1818
1819   if (Vevo.Shape().IsNull()) return;
1820
1821   //-------------------------------------------------
1822   // Find wires common to <me> and <Vevo>.
1823   //-------------------------------------------------
1824
1825   TopExp_Explorer ExProf;
1826   for (ExProf.Init(Prof,TopAbs_VERTEX); ExProf.More(); ExProf.Next()) {
1827     const TopoDS_Shape& VV = ExProf.Current();
1828     //---------------------------------------------------------------
1829     // Parse edges generated by VV in myMap if they existent 
1830     // and Bind in Glue
1831     //---------------------------------------------------------------
1832
1833     //------------------------------------------------- -------------
1834     // Note: the curves of of reinforced edges are in the same direction
1835     //          if one remains on the same edge.
1836     //          if one passes from left to the right they are inverted.
1837     //------------------------------------------------- -------------
1838     Standard_Boolean   Commun = Standard_False;
1839     Relative(myProfile,Prof,
1840       TopoDS::Vertex(VV),
1841       Commun);
1842
1843     if (Commun) {
1844       for (iteS.Initialize(myMap); iteS.More(); iteS.Next()) {
1845         const TopoDS_Shape& SP = iteS.Key();
1846         if (iteS.Value().IsBound(VV) && 
1847           MapVevo.IsBound(SP) && MapVevo(SP).IsBound(VV)) {
1848
1849             const TopTools_ListOfShape& MyList   = myMap(SP)(VV);
1850             const TopTools_ListOfShape& VevoList = Vevo.GeneratedShapes(SP,VV);
1851             TopTools_ListIteratorOfListOfShape MyIte  (MyList);
1852             TopTools_ListIteratorOfListOfShape VevoIte(VevoList);
1853             for (; MyIte.More(); MyIte.Next(), VevoIte.Next()) {
1854               const TopoDS_Edge& ME = TopoDS::Edge(MyIte  .Value());
1855               const TopoDS_Edge& VE = TopoDS::Edge(VevoIte.Value());
1856               TopAbs_Orientation OG = Compare(ME,VE);
1857               TopoDS_Shape aLocalShape  = VE.Oriented (TopAbs_FORWARD);
1858               TopoDS_Shape aLocalShape2 = ME.Oriented (OG);
1859               Glue.Bind(TopoDS::Edge(aLocalShape),TopoDS::Edge(aLocalShape2));
1860               //            Glue.Bind(TopoDS::Edge(VE.Oriented (TopAbs_FORWARD)),
1861               //                      TopoDS::Edge(ME.Oriented (OG)));
1862             }
1863         }
1864       }
1865     }
1866   }
1867   Glue.Add(Vevo.Shape());
1868
1869   //----------------------------------------------------------
1870   // Add map of elements generate in Vevo in myMap.
1871   //----------------------------------------------------------
1872   TopTools_DataMapOfShapeListOfShape        EmptyMap;
1873   TopTools_ListOfShape                      EmptyList;
1874
1875   for (iteS.Initialize(MapVevo); iteS.More() ; iteS.Next()) {
1876     CurrentSpine = iteS.Key();
1877     for (iteP.Initialize(MapVevo(CurrentSpine)); iteP.More(); iteP.Next()) {
1878       CurrentProf  = iteP.Key();
1879       if (!myMap.IsBound(CurrentSpine)) {
1880         //------------------------------------------------
1881         // The element of spine is not yet present .
1882         // => previous profile not on the border.
1883         //-------------------------------------------------
1884         myMap.Bind(CurrentSpine,EmptyMap);
1885       }
1886       if (!myMap(CurrentSpine).IsBound(CurrentProf)) {
1887         myMap(CurrentSpine).Bind(CurrentProf,EmptyList);      
1888         const TopTools_ListOfShape& GenShapes 
1889           = MapVevo (CurrentSpine)(CurrentProf);
1890         TopTools_ListIteratorOfListOfShape itl (GenShapes);
1891         for (; itl.More(); itl.Next()) {
1892           // during Glue.Add the shared shapes are recreated.
1893           if (Glue.IsCopied(itl.Value())) 
1894             myMap(CurrentSpine)(CurrentProf).Append(Glue.Copy(itl.Value()));
1895           else
1896             myMap(CurrentSpine)(CurrentProf).Append(itl.Value());
1897         }
1898       }
1899     }
1900   }
1901 }
1902
1903 //=======================================================================
1904 //function : ChangeShape
1905 //purpose  : 
1906 //=======================================================================
1907
1908 TopoDS_Shape&  BRepFill_Evolved::ChangeShape()
1909 {
1910   return myShape;
1911 }
1912
1913 //=======================================================================
1914 //function : Transfert
1915 //purpose  : 
1916 //=======================================================================
1917
1918 void BRepFill_Evolved::Transfert(      BRepFill_Evolved&             Vevo, 
1919   const TopTools_DataMapOfShapeShape& MapProf, 
1920   const TopTools_DataMapOfShapeShape& MapSpine,
1921   const TopLoc_Location&              LS,
1922   const TopLoc_Location&              InitLS,
1923   const TopLoc_Location&              InitLP)
1924 {  
1925   //----------------------------------------------------------------
1926   // Transfer the shape from Vevo in myShape and Reposition shapes.
1927   //----------------------------------------------------------------
1928   myShape = Vevo.Shape();
1929   mySpine  .Location(InitLS); 
1930   myProfile.Location(InitLP);
1931   myShape  .Move    (LS);
1932
1933   //
1934   // Expecting for better, the Same Parameter is forced here 
1935   //  ( Pb Sameparameter between YaPlanar and Tuyaux 
1936   //
1937   BRep_Builder B;
1938   TopExp_Explorer ex(myShape,TopAbs_EDGE);
1939   while (ex.More()) {
1940     B.SameRange(TopoDS::Edge(ex.Current()), Standard_False);
1941     B.SameParameter(TopoDS::Edge(ex.Current()), Standard_False);
1942     BRepLib::SameParameter(TopoDS::Edge(ex.Current()));
1943     ex.Next();
1944   }
1945
1946
1947   //--------------------------------------------------------------
1948   // Transfer of myMap of Vevo into myMap.
1949   //--------------------------------------------------------------
1950   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape iteS;
1951   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape               iteP; 
1952   TopTools_DataMapOfShapeListOfShape EmptyMap;
1953   TopTools_ListOfShape               EmptyList;
1954   TopoDS_Shape                       InitialSpine, InitialProf;
1955
1956   BRepFill_DataMapOfShapeDataMapOfShapeListOfShape& MapVevo 
1957     = Vevo.Generated();
1958
1959   for (iteS.Initialize(MapVevo); iteS.More(); iteS.Next()) {
1960     InitialSpine = MapSpine(iteS.Key());
1961     InitialSpine.Move(LS);
1962
1963     for (iteP.Initialize(MapVevo(iteS.Key())); iteP.More(); iteP.Next()) {
1964       InitialProf  = MapProf (iteP.Key());
1965       InitialProf.Location(InitLP);
1966
1967       TopTools_ListOfShape& GenShapes = 
1968         MapVevo.ChangeFind(iteS.Key()).ChangeFind(iteP.Key());
1969
1970       TopTools_ListIteratorOfListOfShape itl;
1971       for (itl.Initialize(GenShapes); itl.More(); itl.Next()) {
1972         itl.Value().Move(LS);
1973       }
1974
1975       if (!myMap.IsBound(InitialSpine)) {
1976         myMap.Bind(InitialSpine,EmptyMap);
1977       }
1978
1979       if (!myMap(InitialSpine).IsBound(InitialProf)) {
1980         myMap(InitialSpine).Bind(InitialProf,EmptyList);
1981       }
1982       myMap(InitialSpine)(InitialProf).Append(GenShapes);
1983     }
1984   }
1985   //--------------------------------------------------------------
1986   // Transfer of Top and Bottom of Vevo in myTop and myBottom.
1987   //--------------------------------------------------------------
1988   myTop    = Vevo.Top()   ; myTop.Move(LS);
1989   myBottom = Vevo.Bottom(); myBottom.Move(LS);
1990 }
1991
1992 //=======================================================================
1993 //function : IsDone
1994 //purpose  : 
1995 //=======================================================================
1996
1997 Standard_Boolean BRepFill_Evolved::IsDone() const 
1998 {
1999   return myIsDone;
2000 }
2001
2002 //=======================================================================
2003 //function : Shape
2004 //purpose  : 
2005 //=======================================================================
2006
2007 const TopoDS_Shape& BRepFill_Evolved::Shape() const 
2008 {
2009   return myShape;
2010 }
2011
2012 //=======================================================================
2013 //function : JoinType
2014 //purpose  : 
2015 //=======================================================================
2016
2017 GeomAbs_JoinType BRepFill_Evolved::JoinType() const 
2018 {
2019   return myJoinType;
2020 }
2021
2022 //=======================================================================
2023 //function : AddTopAndBottom
2024 //purpose  : 
2025 //=======================================================================
2026
2027 void BRepFill_Evolved::AddTopAndBottom(BRepTools_Quilt& Glue)
2028 {  
2029   //  return first and last vertex of the profile.
2030   TopoDS_Vertex V[2];
2031   TopExp::Vertices (myProfile,V[0],V[1]);
2032   if (V[0].IsSame(V[1])) return;
2033
2034   TopTools_ListIteratorOfListOfShape itL;
2035   Standard_Boolean ToReverse=Standard_False;
2036   for (Standard_Integer i = 0; i<=1; i++) {
2037
2038     BRepAlgo_Loop Loop;
2039     // Construction of supports.
2040     gp_Pln S (0.,0.,1.,- Altitud(V[i]));
2041     TopoDS_Face F = BRepLib_MakeFace(S);
2042     Loop.Init(F);
2043
2044     TopExp_Explorer     ExpSpine(mySpine,TopAbs_EDGE);
2045     TopTools_MapOfShape View;
2046
2047     for (; ExpSpine.More(); ExpSpine.Next()) {
2048       const TopoDS_Edge& ES = TopoDS::Edge(ExpSpine.Current());
2049       const TopTools_ListOfShape& L = GeneratedShapes(ES,V[i]);
2050       Standard_Boolean ComputeOrientation = 0;
2051
2052       for (itL.Initialize(L); itL.More(); itL.Next()) {
2053         const TopoDS_Edge& E = TopoDS::Edge(itL.Value());
2054
2055         if (!ComputeOrientation) {
2056           BRepAdaptor_Curve C1(ES);
2057           BRepAdaptor_Curve C2(E);
2058           Standard_Real f,l,fs,ls;
2059           BRep_Tool::Range(E ,f ,l);
2060           BRep_Tool::Range(ES,fs,ls);
2061           Standard_Real u  = 0.3*f  + 0.7*l;
2062           Standard_Real us = 0.3*fs + 0.7*ls;
2063           gp_Pnt P;
2064           gp_Vec V1,V2;
2065           C1.D1(us,P,V1); C2.D1(u,P,V2);
2066           ToReverse = (V1.Dot(V2) < 0.);
2067           ComputeOrientation = 1;
2068         }
2069
2070         TopAbs_Orientation Or = ES.Orientation();
2071         if (ToReverse) Or = TopAbs::Reverse(Or);
2072         TopoDS_Shape aLocalShape = E.Oriented(Or);
2073         Loop.AddConstEdge(TopoDS::Edge(aLocalShape));
2074         //      Loop.AddConstEdge(TopoDS::Edge(E.Oriented(Or)));
2075       }
2076     }
2077
2078     gp_Pnt PV = BRep_Tool::Pnt(V[i]);
2079     Standard_Boolean IsOut = PV.Y() < 0;
2080
2081     for (ExpSpine.Init(mySpine,TopAbs_VERTEX); ExpSpine.More(); ExpSpine.Next()) {
2082       const TopoDS_Vertex& ES = TopoDS::Vertex(ExpSpine.Current());
2083       if (View.Add(ES)) {
2084         const TopTools_ListOfShape& L = GeneratedShapes(ES,V[i]);
2085         for (itL.Initialize(L); itL.More(); itL.Next()) {
2086           const TopoDS_Edge& E = TopoDS::Edge(itL.Value());
2087           if (!BRep_Tool::Degenerated(E)){
2088             // the center of circle (ie vertex) is IN the cap if vertex IsOut
2089             //                                    OUT                   !IsOut
2090             BRepAdaptor_Curve C(E);
2091             Standard_Real f,l;
2092             BRep_Tool::Range(E,f,l);
2093             Standard_Real u = 0.3*f + 0.7*l;
2094             gp_Pnt P = BRep_Tool::Pnt(ES);
2095             gp_Pnt PC;
2096             gp_Vec VC;
2097             C.D1(u,PC,VC);
2098             gp_Vec aPPC(P,PC);
2099             gp_Vec Prod = aPPC.Crossed(VC);
2100             if (IsOut) {
2101               ToReverse = Prod.Z() < 0.;
2102             }
2103             else { 
2104               ToReverse = Prod.Z() > 0.;
2105             }
2106             TopAbs_Orientation Or = TopAbs_FORWARD;
2107             if (ToReverse)     Or = TopAbs_REVERSED;
2108             TopoDS_Shape aLocalShape = E.Oriented(Or);
2109             Loop.AddConstEdge(TopoDS::Edge(aLocalShape));
2110             //      Loop.AddConstEdge(TopoDS::Edge(E.Oriented(Or)));
2111           }
2112         }
2113       }
2114     }
2115
2116     Loop.Perform();
2117     Loop.WiresToFaces();
2118     const TopTools_ListOfShape& L = Loop.NewFaces();
2119     TopTools_ListIteratorOfListOfShape anIterL(L);
2120
2121     // Maj of myTop and myBottom for the history
2122     // and addition of constructed faces.
2123     TopoDS_Compound  Bouchon;
2124     BRep_Builder     B;
2125     B.MakeCompound(Bouchon);
2126     Standard_Integer j = 0;
2127
2128     for (anIterL.Initialize(L); anIterL.More(); anIterL.Next()) {
2129       j++;
2130       Glue.Add(anIterL.Value());
2131       if (j ==1 && i == 0) myTop    = anIterL.Value();
2132       if (j ==1 && i == 1) myBottom = anIterL.Value();
2133       B.Add(Bouchon,anIterL.Value());
2134     }
2135     if (i == 0 && j > 1) myTop    = Bouchon;
2136     if (i == 1 && j > 1) myBottom = Bouchon;
2137   }
2138 }
2139
2140 //================================================================== =====
2141 //function : MakePipe
2142 //purpose  : 
2143 //=======================================================================
2144
2145 void BRepFill_Evolved::MakeSolid()
2146 {
2147
2148   TopExp_Explorer  exp(myShape,TopAbs_SHELL);
2149   Standard_Integer ish=0;
2150   TopoDS_Compound  Res;
2151   TopoDS_Solid     Sol;
2152   BRep_Builder     B;
2153   B.MakeCompound(Res);
2154
2155   for (; exp.More(); exp.Next()) {
2156     TopoDS_Shape Sh = exp.Current();
2157     B.MakeSolid(Sol);
2158     B.Add(Sol,Sh);
2159     BRepClass3d_SolidClassifier SC(Sol);
2160     SC.PerformInfinitePoint(BRepFill_Confusion());
2161     if (SC.State() == TopAbs_IN) {
2162       B.MakeSolid(Sol);
2163       B.Add(Sol,Sh.Reversed());
2164     }
2165     B.Add(Res,Sol);
2166     ish++;
2167   }
2168   if (ish == 1) { myShape = Sol;}
2169   else          { myShape = Res;}
2170
2171 }
2172
2173 //=======================================================================
2174 //function : MakePipe
2175 //purpose  : 
2176 //=======================================================================
2177
2178 void BRepFill_Evolved::MakePipe(const TopoDS_Edge& SE,
2179   const gp_Ax3&      AxeRef)
2180 {  
2181   BRepTools_WireExplorer ProfExp;
2182   TopExp_Explorer        FaceExp;
2183
2184   gp_Trsf trsf;
2185   if (Side(myProfile,BRepFill_Confusion()) > 3) { // side right 
2186     trsf.SetRotation(gp::OZ(),M_PI);
2187   }
2188   TopLoc_Location DumLoc (trsf);
2189   TopoDS_Shape aLocalShape = myProfile.Moved(DumLoc);
2190   TopoDS_Wire DummyProf = 
2191     PutProfilAt (TopoDS::Wire(aLocalShape),
2192     AxeRef,SE,
2193     mySpine,Standard_True);
2194   //  TopoDS_Wire DummyProf = 
2195   //    PutProfilAt (TopoDS::Wire(myProfile.Moved(DumLoc)),
2196   //             AxeRef,SE,
2197   //             mySpine,Standard_True);
2198
2199   // Copy of the profile to avoid the accumulation of 
2200   // locations on the Edges of myProfile!
2201
2202   Handle(BRepTools_TrsfModification) TrsfMod 
2203     = new BRepTools_TrsfModification(gp_Trsf());
2204   BRepTools_Modifier Modif(DummyProf,TrsfMod);
2205
2206   TopoDS_Wire GenProf = TopoDS::Wire(Modif.ModifiedShape(DummyProf));
2207
2208 #ifdef DRAW
2209   if (AffichGeom) {
2210     char name[100];
2211     sprintf(name,"EVOLBASE_%d",++NbFACES);
2212     DBRep::Set(name,SE);
2213     sprintf(name,"EVOLPROF_%d",NbFACES);
2214     DBRep::Set(name,GenProf);
2215   }
2216 #endif
2217
2218   BRepFill_Pipe Pipe(BRepLib_MakeWire(SE), GenProf);    
2219   //BRepFill_Pipe Pipe = BRepFill_Pipe(BRepLib_MakeWire(SE),GenProf);   
2220
2221 #ifdef DRAW
2222   if (AffichGeom) {
2223     char name[100];
2224     sprintf(name,"EVOL_%d",++NbFACES);
2225     DBRep::Set(name,Pipe.Shape());
2226   }
2227 #endif
2228   //---------------------------------------------
2229   // Arrangement of Tubes in myMap.
2230   //---------------------------------------------
2231
2232   BRepTools_WireExplorer GenProfExp;
2233   TopTools_ListOfShape   L;
2234   TopoDS_Vertex          VF,VL,VFG,VLG;
2235   Standard_Boolean       FirstVertex = Standard_True;
2236   TopTools_DataMapOfShapeListOfShape  P;
2237
2238   myMap.Bind(SE,P);
2239
2240   for (ProfExp.Init(myProfile),GenProfExp.Init(GenProf);
2241     ProfExp.More();
2242     ProfExp.Next(),GenProfExp.Next()) {
2243
2244       EdgeVertices(ProfExp   .Current(),VF ,VL);
2245       EdgeVertices(GenProfExp.Current(),VFG,VLG);
2246
2247       if (FirstVertex) {
2248         myMap(SE).Bind(VF,L);
2249         myMap(SE)(VF).Append(Pipe.Edge(SE,VFG)); 
2250         FirstVertex = Standard_False;
2251       }
2252       myMap(SE).Bind(VL,L);
2253       myMap(SE)(VL).Append(Pipe.Edge(SE,VLG));
2254       myMap(SE).Bind(ProfExp.Current(),L);
2255       myMap(SE)(ProfExp.Current()).Append
2256         (Pipe.Face(SE,GenProfExp.Current()));
2257   }
2258 }
2259
2260
2261 //=======================================================================
2262 //function : MakeRevol
2263 //purpose  : 
2264 //=======================================================================
2265
2266 void BRepFill_Evolved::MakeRevol(const TopoDS_Edge&   SE,
2267   const TopoDS_Vertex& VLast,
2268   const gp_Ax3&        AxeRef)
2269 {  
2270   BRepTools_WireExplorer ProfExp;
2271   TopExp_Explorer        FaceExp;
2272
2273   gp_Trsf trsf;
2274   if (Side(myProfile,BRepFill_Confusion()) > 3) { // side right 
2275     trsf.SetRotation(gp::OZ(),M_PI);
2276   }
2277   TopLoc_Location DumLoc (trsf);
2278   TopoDS_Shape aLocalShape = myProfile.Moved(DumLoc);
2279   TopoDS_Wire GenProf = 
2280     PutProfilAt (TopoDS::Wire(aLocalShape),
2281     AxeRef,SE,
2282     mySpine,Standard_False);
2283   //  TopoDS_Wire GenProf = 
2284   //    PutProfilAt (TopoDS::Wire(myProfile.Moved(DumLoc)),
2285   //             AxeRef,SE,
2286   //             mySpine,Standard_False);
2287
2288   gp_Ax1 AxeRev( BRep_Tool::Pnt(VLast), -gp::DZ());  
2289
2290   // Position of the sewing on the edge of the spine
2291   // so that the bissectrices didn't cross the sewings.
2292   gp_Trsf dummy;
2293   dummy.SetRotation(AxeRev, 1.5*M_PI);
2294   TopLoc_Location DummyLoc(dummy);
2295   GenProf.Move(DummyLoc);
2296
2297   BRepSweep_Revol Rev(GenProf,AxeRev,Standard_True);
2298
2299 #ifdef DRAW  
2300   if (AffichGeom) {
2301     char name[100];
2302     sprintf(name,"EVOLBASE_%d",++NbFACES);
2303     DrawTrSurf::Set(name,new Geom_Line(AxeRev));
2304     //    DrawTrSurf::Set(name,new Geom_Line(AxeRev));
2305     sprintf(name,"EVOLPROF_%d",NbFACES);
2306     DBRep::Set(name,GenProf);
2307
2308     sprintf(name,"EVOL_%d",NbFACES);
2309     DBRep::Set(name,Rev.Shape());
2310   }
2311 #endif
2312   //--------------------------------------------
2313   // Arrangement of revolutions in myMap.
2314   //---------------------------------------------
2315   BRepTools_WireExplorer GenProfExp;
2316   TopTools_ListOfShape   L;
2317   TopoDS_Vertex          VF,VL,VFG,VLG;
2318   Standard_Boolean       FirstVertex = Standard_True;
2319   TopTools_DataMapOfShapeListOfShape  R;
2320
2321   myMap.Bind(VLast,R);
2322
2323   for (ProfExp.Init(myProfile),GenProfExp.Init(GenProf);
2324     ProfExp.More();
2325     ProfExp.Next(),GenProfExp.Next()) {
2326
2327       EdgeVertices(ProfExp   .Current(),VF ,VL);
2328       EdgeVertices(GenProfExp.Current(),VFG,VLG);
2329
2330       TopAbs_Orientation Or = GenProfExp.Current().Orientation();
2331
2332       if (FirstVertex) {
2333         myMap(VLast).Bind(VF,L);
2334         const TopoDS_Shape& RV = Rev.Shape(VFG);
2335         //      TopAbs_Orientation OO = TopAbs::Compose(RV.Orientation(),Or);
2336         TopAbs_Orientation OO = RV.Orientation();
2337         myMap(VLast)(VF).Append(RV.Oriented(OO));
2338         FirstVertex = Standard_False;
2339       }
2340       myMap(VLast).Bind(ProfExp.Current(),L);   
2341       const TopoDS_Shape& RF = Rev.Shape(GenProfExp.Current());
2342       TopAbs_Orientation  OO = TopAbs::Compose(RF.Orientation(),Or);
2343
2344       myMap(VLast)(ProfExp.Current()).Append(RF.Oriented(OO));
2345       myMap(VLast).Bind(VL,L);
2346       const TopoDS_Shape& RV = Rev.Shape(VLG);
2347       //    OO = TopAbs::Compose(RV.Orientation(),Or);
2348       OO = RV.Orientation();
2349       myMap(VLast)(VL).Append(RV.Oriented(OO));
2350   }
2351 }
2352
2353 //=======================================================================
2354 //function : FindLocation
2355 //purpose  : 
2356 //=======================================================================
2357
2358 TopLoc_Location BRepFill_Evolved::FindLocation(const TopoDS_Face& Face)
2359   const 
2360 {
2361   TopLoc_Location L;
2362   Handle(Geom_Surface) S;
2363   S = BRep_Tool::Surface(Face, L);
2364
2365   if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
2366     BRepLib_FindSurface FS( Face, -1, Standard_True);
2367     if ( FS.Found()) {
2368       S = FS.Surface();
2369       L = FS.Location();
2370     }
2371     else
2372       Standard_NoSuchObject::Raise
2373       ("BRepFill_Evolved : The Face is not planar");
2374   }
2375
2376   if (!L.IsIdentity())
2377     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
2378
2379   Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(S);
2380   gp_Ax3 Axis = P->Position();
2381
2382   gp_Trsf T;
2383   gp_Ax3 AxeRef(gp_Pnt(0.,0.,0.),
2384     gp_Dir(0.,0.,1.),
2385     gp_Dir(1.,0.,0.));  
2386   T.SetTransformation(AxeRef,Axis);
2387
2388   return TopLoc_Location(T);
2389 }
2390
2391
2392 //=======================================================================
2393 //function : TransformInitWork
2394 //purpose  : 
2395 //=======================================================================
2396
2397 void BRepFill_Evolved::TransformInitWork(const TopLoc_Location& LS,
2398   const TopLoc_Location& LP)
2399 {
2400   mySpine.Move  (LS);
2401   myProfile.Move(LP);
2402
2403 #ifdef DRAW
2404   if (AffichEdge) {
2405     char name[100];
2406     sprintf(name,"movedspine");
2407     TopoDS_Face SL = mySpine;
2408     DBRep::Set(name,SL);    
2409     sprintf(name,"movedprofile");
2410     TopoDS_Wire PL = myProfile;
2411     DBRep::Set(name,PL);
2412   }
2413 #endif  
2414 }
2415
2416
2417 //=======================================================================
2418 //function : ContinuityOnOffsetEdge
2419 //purpose  : Coding of regularities on edges parallel to CutVevo
2420 //           common to left and right parts of volevo.
2421 //=======================================================================
2422 void  BRepFill_Evolved::ContinuityOnOffsetEdge (const TopTools_ListOfShape&) 
2423 {
2424   BRepTools_WireExplorer WExp ; 
2425   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape iteS;
2426   TopoDS_Vertex          VF,VL,V;
2427   TopoDS_Edge            PrecE,CurE,FirstE;
2428   BRep_Builder           B;
2429
2430
2431   WExp.Init(myProfile);
2432   FirstE = WExp.Current();
2433   PrecE  = FirstE;
2434   EdgeVertices (FirstE, VF, V);
2435   if (WExp.More()) WExp.Next();
2436
2437   for (; WExp.More(); WExp.Next()) {
2438     CurE = WExp.Current();
2439     V    = WExp.CurrentVertex();
2440
2441     if (DistanceToOZ(V) <= BRepFill_Confusion()) {
2442       // the regularities are already coded on the edges of elementary volevos
2443       Standard_Real     U1 = BRep_Tool::Parameter(V,CurE);
2444       Standard_Real     U2 = BRep_Tool::Parameter(V,PrecE);
2445       BRepAdaptor_Curve Curve1(CurE);
2446       BRepAdaptor_Curve Curve2(PrecE);
2447       GeomAbs_Shape     Continuity = BRepLProp::Continuity(Curve1,Curve2,U1,U2);
2448
2449       if (Continuity >=1) {
2450         //-----------------------------------------------------
2451         //Code continuity for all edges generated by V.
2452         //-----------------------------------------------------
2453         for (iteS.Initialize(myMap); iteS.More(); iteS.Next()) {
2454           const TopoDS_Shape& SP = iteS.Key(); 
2455           if (myMap (SP).IsBound(V) 
2456             && myMap (SP).IsBound(CurE) &&  myMap (SP).IsBound(PrecE)){
2457               if (!myMap(SP)(V)    .IsEmpty() &&
2458                 !myMap(SP)(CurE) .IsEmpty() &&
2459                 !myMap(SP)(PrecE).IsEmpty()   ) 
2460                 B.Continuity (TopoDS::Edge(myMap(SP)(V)    .First()),
2461                 TopoDS::Face(myMap(SP)(CurE) .First()),
2462                 TopoDS::Face(myMap(SP)(PrecE).First()),
2463                 Continuity);
2464           }
2465         }
2466       }
2467     }
2468     PrecE = CurE;
2469   }
2470
2471   EdgeVertices (PrecE, V, VL);
2472
2473   if (VF.IsSame(VL)) {
2474     //Closed profile.
2475     Standard_Real     U1 = BRep_Tool::Parameter(VF,CurE);
2476     Standard_Real     U2 = BRep_Tool::Parameter(VF,FirstE);
2477     BRepAdaptor_Curve Curve1(CurE);
2478     BRepAdaptor_Curve Curve2(FirstE);
2479     GeomAbs_Shape     Continuity = BRepLProp::Continuity(Curve1,Curve2,U1,U2);
2480
2481     if (Continuity >=1) {
2482       //---------------------------------------------
2483       //Code continuity for all edges generated by V.
2484       //---------------------------------------------
2485       for (iteS.Initialize(myMap); iteS.More(); iteS.Next()) {
2486         const TopoDS_Shape& SP = iteS.Key(); 
2487         if (myMap (SP).IsBound(VF) 
2488           && myMap (SP).IsBound(CurE) &&  myMap (SP).IsBound(FirstE)){
2489             if (!myMap(SP)(VF)    .IsEmpty() &&
2490               !myMap(SP)(CurE)  .IsEmpty() &&
2491               !myMap(SP)(FirstE).IsEmpty()   ) 
2492               B.Continuity (TopoDS::Edge(myMap(SP)(VF)    .First()),
2493               TopoDS::Face(myMap(SP)(CurE)  .First()),
2494               TopoDS::Face(myMap(SP)(FirstE).First()),
2495               Continuity);
2496         }
2497       }
2498     }
2499   }
2500 }
2501
2502 //=======================================================================
2503 //function : AddDegeneratedEdge
2504 //purpose  : degenerated edges can be missing in some face
2505 //           the missing degenerated edges have vertices corresponding  
2506 //           to node of the map.
2507 //           Now it is enough to compare points UV of vertices
2508 //           on edges with a certain tolerance.
2509 //=======================================================================
2510
2511 static void AddDegeneratedEdge(TopoDS_Face& F,
2512   TopoDS_Wire& W) 
2513 {
2514   TopLoc_Location      L;
2515   Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2516   if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2517     Handle(Geom_Surface) SB = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
2518     if (SB->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2519       return;
2520     }
2521   }
2522
2523   if (S->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2524     return;
2525   }
2526
2527
2528   BRep_Builder         B;
2529   Standard_Real        TolConf = 1.e-4;
2530
2531   Standard_Boolean Change = Standard_True;
2532
2533   while (Change) {
2534     Change = Standard_False;
2535     BRepTools_WireExplorer WE(W,F);
2536     gp_Pnt2d PF,PrevP,P1,P2;
2537     TopoDS_Vertex VF,V1,V2;
2538
2539     for (; WE.More(); WE.Next()) {
2540       const TopoDS_Edge& CE = WE.Current();
2541       EdgeVertices (CE,V1,V2);
2542       if (CE.Orientation() == TopAbs_REVERSED)
2543         BRep_Tool::UVPoints(CE, F, P2, P1);
2544       else 
2545         BRep_Tool::UVPoints(CE, F, P1, P2);
2546       if (VF.IsNull()) {
2547         VF = V1;
2548         PF = P1;
2549       }
2550       else {
2551         if (!P1.IsEqual(PrevP,TolConf)) {
2552           // degenerated edge to be inserted.
2553           Change = Standard_True;
2554           gp_Vec2d V(PrevP,P1);
2555           Handle(Geom2d_Line) C2d = new Geom2d_Line(PrevP,gp_Dir2d(V));
2556           Standard_Real f = 0, l = PrevP.Distance(P1);
2557           Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(C2d,f,l);
2558           TopoDS_Edge NE = BRepLib_MakeEdge(C2d,S);
2559           B.Degenerated(NE,Standard_True);
2560           B.Add(NE,V1.Oriented(TopAbs_FORWARD));
2561           B.Add(NE,V1.Oriented(TopAbs_REVERSED));
2562           B.Range(NE,f,l);
2563           B.Add(W,NE);
2564           break;
2565         }
2566       }
2567       PrevP = P2;
2568     }
2569     if (!Change && VF.IsSame(V2)) {  // closed
2570       if (!PF.IsEqual(P2,TolConf)) {
2571         // Degenerated edge to be inserted.
2572         Change = Standard_True;
2573         gp_Vec2d V(P2,PF);
2574         Handle(Geom2d_Line) C2d = new Geom2d_Line(P2,gp_Dir2d(V));
2575         Standard_Real f = 0, l = P2.Distance(PF);
2576         Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(C2d,f,l);
2577         TopoDS_Edge NE = BRepLib_MakeEdge(C2d,S);
2578         B.Degenerated(NE,Standard_True);
2579         B.Add(NE,VF.Oriented(TopAbs_FORWARD));
2580         B.Add(NE,VF.Oriented(TopAbs_REVERSED));
2581         B.Range(NE,f,l);
2582         B.Add(W,NE);
2583       }
2584     }
2585   }
2586 }
2587
2588 //=======================================================================
2589 //function : TrimFace
2590 //purpose  : 
2591 //=======================================================================
2592
2593 void TrimFace(const TopoDS_Face&              Face,
2594   TopTools_SequenceOfShape& TheEdges,
2595   TopTools_SequenceOfShape& S)
2596 {
2597
2598 #ifdef DRAW
2599   Standard_Integer NB = TheEdges.Length();
2600   if ( AffichEdge) {
2601     char name[100];
2602     cout << " TrimFace " << ++NbTRIMFACES;
2603     cout << " : " << NB << " edges within the restriction" << endl;
2604     for ( Standard_Integer j = 1; j <= NB; j++) {
2605       sprintf(name,"TRIMEDGE_%d_%d",NbTRIMFACES,j);
2606       DBRep::Set(name,TopoDS::Edge(TheEdges.Value(j)));
2607     }
2608   }
2609 #endif
2610
2611
2612   //--------------------------------------
2613   // Creation of wires limiting faces.
2614   //--------------------------------------
2615   BRep_Builder             TheBuilder;
2616
2617   Standard_Integer NbEdges;
2618   Standard_Boolean NewWire  = Standard_True;
2619   Standard_Boolean AddEdge  = Standard_False;
2620   TopoDS_Wire      GoodWire;
2621
2622
2623   while ( !TheEdges.IsEmpty()) {
2624
2625     BRepLib_MakeWire MWire(TopoDS::Edge(TheEdges.First()));
2626     GoodWire = MWire.Wire();
2627     TheEdges.Remove(1);
2628     NbEdges = TheEdges.Length();
2629     NewWire = Standard_False;
2630
2631     while (!NewWire) {
2632       AddEdge  = Standard_False;
2633
2634       for ( Standard_Integer i = 1; i <= NbEdges && !AddEdge; i++) {
2635         const TopoDS_Edge& E = TopoDS::Edge(TheEdges.Value(i));
2636         if ( BRep_Tool::Degenerated(E)) {
2637           TheEdges.Remove(i);
2638           AddEdge = Standard_True;
2639           NbEdges = TheEdges.Length();
2640           GoodWire = MWire.Wire();
2641         }
2642         else {
2643           MWire.Add(E);
2644           if ( MWire.Error() == BRepLib_WireDone) {
2645             // the connection is successful 
2646             // it is removed from the sequence and one restarts from the beginning.
2647             TheEdges.Remove(i);
2648             AddEdge = Standard_True;
2649             NbEdges = TheEdges.Length();
2650             GoodWire = MWire.Wire();
2651           }
2652         }
2653       }
2654       NewWire = (!AddEdge);
2655     }
2656     TopoDS_Shape aLocalShape = Face.EmptyCopied();
2657     TopoDS_Face FaceCut = TopoDS::Face(aLocalShape);
2658     //    TopoDS_Face FaceCut = TopoDS::Face(Face.EmptyCopied());
2659     FaceCut.Orientation(TopAbs_FORWARD);
2660     BRepTools::Update  (FaceCut);
2661     AddDegeneratedEdge (FaceCut,GoodWire);
2662     TheBuilder.Add     (FaceCut,GoodWire);
2663     FaceCut.Orientation(Face.Orientation());
2664     S.Append(FaceCut);
2665   }
2666 }
2667
2668
2669
2670 //=======================================================================
2671 //function : PutProfilAt
2672 //purpose  : 
2673 //=======================================================================
2674
2675 const TopoDS_Wire PutProfilAt (const TopoDS_Wire&     ProfRef,
2676   const gp_Ax3&          AxeRef, 
2677   const TopoDS_Edge&     E,
2678   const TopoDS_Face&     F,
2679   const Standard_Boolean AtStart)
2680 {       
2681   gp_Vec2d             D1;
2682   gp_Pnt2d             P;
2683   TopoDS_Wire          Prof;
2684   Handle(Geom2d_Curve) C2d;
2685   Standard_Real        First,Last;
2686
2687   C2d = BRep_Tool::CurveOnSurface(E,F,First,Last);
2688   if (C2d.IsNull()) {
2689     Standard_ConstructionError::Raise("ConstructionError in PutProfilAt"); 
2690   }
2691
2692   if (E.Orientation() == TopAbs_REVERSED) {
2693     if (!AtStart) C2d->D1(First,P,D1);else C2d->D1(Last,P,D1);
2694     D1.Reverse();
2695   }
2696   else {
2697     if (!AtStart) C2d->D1(Last,P,D1) ;else C2d->D1(First,P,D1); 
2698   }
2699   gp_Pnt P3d(P.X() ,P.Y() ,0.);
2700   gp_Vec V3d(D1.X(),D1.Y(),0.);
2701
2702   gp_Ax3  Ax( P3d, gp::DZ(), V3d);
2703   gp_Trsf Trans;
2704   Trans.SetTransformation(Ax,AxeRef);
2705   TopoDS_Shape aLocalShape = ProfRef.Moved(TopLoc_Location(Trans));
2706   Prof = TopoDS::Wire(aLocalShape);
2707   //  Prof = TopoDS::Wire(ProfRef.Moved(TopLoc_Location(Trans)));
2708   return Prof;
2709 }
2710
2711
2712 //=======================================================================
2713 //function : TrimEdge
2714 //purpose  : 
2715 //=======================================================================
2716
2717 void TrimEdge (const TopoDS_Edge&        Edge,
2718   const TopTools_SequenceOfShape& TheEdgesControle,
2719   TopTools_SequenceOfShape& TheVer,
2720   TColStd_SequenceOfReal&   ThePar,
2721   TopTools_SequenceOfShape& S)
2722 {
2723   Standard_Boolean         Change = Standard_True;
2724   BRep_Builder             TheBuilder;
2725   S.Clear();
2726   //------------------------------------------------------------
2727   // Parse two sequences depending on the parameter on the edge.
2728   //------------------------------------------------------------
2729   while (Change) {
2730     Change = Standard_False;
2731     for (Standard_Integer i = 1; i < ThePar.Length(); i++) {
2732       if (ThePar.Value(i) > ThePar.Value(i+1)) {
2733         ThePar.Exchange(i,i+1);
2734         TheVer.Exchange(i,i+1);
2735         Change = Standard_True;
2736       }
2737     }
2738   }
2739
2740   //----------------------------------------------------------
2741   // If a vertex is not in the proofing point, it is removed.
2742   //----------------------------------------------------------
2743   if (!BRep_Tool::Degenerated(Edge)) {
2744     for (Standard_Integer k = 1; k <= TheVer.Length(); k ++) {
2745       if ( DoubleOrNotInFace (TheEdgesControle,
2746         TopoDS::Vertex(TheVer.Value(k)))) {
2747           TheVer.Remove(k);
2748           ThePar.Remove(k);
2749           k--;
2750       }
2751     }
2752   }
2753
2754   //-------------------------------------------------------------------
2755   // Processing of double vertices for non-degenerated edges.
2756   // If a vertex_double appears twice in the edges of control, 
2757   // the vertex is eliminated .
2758   // otherwise its only representation is preserved.
2759   //-------------------------------------------------------------------
2760   if (!BRep_Tool::Degenerated(Edge)) {
2761     for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
2762       if (TheVer.Value(k).IsSame(TheVer.Value(k+1))) {
2763         TheVer.Remove(k+1);
2764         ThePar.Remove(k+1);
2765         if ( DoubleOrNotInFace (TheEdgesControle,
2766           TopoDS::Vertex(TheVer.Value(k)))) {
2767             TheVer.Remove(k);
2768             ThePar.Remove(k);
2769             //    k--;
2770         }
2771         k--;
2772       }
2773     }
2774   }
2775
2776   //-----------------------------------------------------------
2777   // Creation of edges.
2778   // the number of vertices should be even. The edges to be created leave  
2779   // from a vertex with uneven index i to vertex i+1;
2780   //-----------------------------------------------------------
2781   for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) {
2782     TopoDS_Shape aLocalShape = Edge.EmptyCopied();
2783     TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
2784     //    TopoDS_Edge NewEdge = TopoDS::Edge(Edge.EmptyCopied());
2785
2786     if (NewEdge.Orientation() == TopAbs_REVERSED) {
2787       TheBuilder.Add  (NewEdge,TheVer.Value(k)  .Oriented(TopAbs_REVERSED));
2788       TheBuilder.Add  (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD));
2789     }
2790     else {      
2791       TheBuilder.Add  (NewEdge,TheVer.Value(k)  .Oriented(TopAbs_FORWARD));
2792       TheBuilder.Add  (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED));
2793     }
2794     TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1));
2795     //  modified by NIZHNY-EAP Wed Dec 22 12:09:48 1999 ___BEGIN___
2796     BRepLib::UpdateTolerances(NewEdge,Standard_False);
2797     //  modified by NIZHNY-EAP Wed Dec 22 13:34:19 1999 ___END___
2798     S.Append(NewEdge);
2799   }
2800
2801
2802 //=======================================================================
2803 //function : ComputeIntervals
2804 //purpose  : 
2805 //=======================================================================
2806
2807 void ComputeIntervals (const TopTools_SequenceOfShape& VOnF,
2808   const TopTools_SequenceOfShape& VOnL,
2809   const TColgp_SequenceOfPnt&     ParOnF,
2810   const TColgp_SequenceOfPnt&     ParOnL,
2811   const BRepFill_TrimSurfaceTool& Trim,
2812   const Handle(Geom2d_Curve)&     Bis,
2813   const TopoDS_Vertex&            VS,
2814   const TopoDS_Vertex&            VE,
2815   TColStd_SequenceOfReal&   FirstPar,
2816   TColStd_SequenceOfReal&   LastPar,
2817   TopTools_SequenceOfShape& FirstV,
2818   TopTools_SequenceOfShape& LastV )
2819 {
2820   Standard_Integer IOnF    = 1,IOnL = 1;
2821   Standard_Real    U1 = 0.,U2;
2822   TopoDS_Shape     V1,V2;
2823
2824   if (!VS.IsNull()) {
2825     U1  = Bis->FirstParameter();
2826     V1  = VS;
2827   }
2828   while ( IOnF <= VOnF.Length() || IOnL <= VOnL.Length()) {
2829     //---------------------------------------------------------
2830     // Return the smallest parameter on the bissectrice
2831     // correponding to the current positions IOnF,IOnL.
2832     //---------------------------------------------------------
2833     if ( IOnL > VOnL.Length() ||
2834       (IOnF <= VOnF.Length() &&
2835       ParOnF.Value(IOnF).X() < ParOnL.Value(IOnL).X())) {
2836
2837         U2 = ParOnF.Value(IOnF).X();
2838         V2 = VOnF  .Value(IOnF);
2839         IOnF++;
2840     }     
2841     else{
2842       U2 = ParOnL.Value(IOnL).X();
2843       V2 = VOnL  .Value(IOnL);
2844       IOnL++;
2845     }
2846     //---------------------------------------------------------------------
2847     // When V2 and V1 are different the medium point P of the 
2848     // interval is tested compared to the face. If P is in the face the interval
2849     // is valid.
2850     //--------------------------------------------------------------------- 
2851     if (!V1.IsNull() && !V2.IsSame(V1)) {
2852       gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
2853       if (Trim.IsOnFace(P)) {
2854         FirstPar.Append(U1); LastPar .Append(U2);
2855         FirstV.  Append(V1); LastV   .Append(V2);
2856       }
2857     }
2858     U1 = U2;
2859     V1 = V2;
2860   }  
2861
2862   if (!VE.IsNull()) {
2863     U2 = Bis->LastParameter();
2864     V2 = VE;
2865     if (!V2.IsSame(V1)) {
2866       gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
2867       if (Trim.IsOnFace(P)) {
2868         FirstPar.Append(U1); LastPar .Append(U2);
2869         FirstV.Append  (V1);   LastV .Append(V2);
2870       }
2871     }
2872   }
2873
2874 }
2875
2876 //=======================================================================
2877 //function : Relative
2878 //purpose  : Commun is true if two wires have V in common
2879 //           return FORWARD if the wires near the vertex are at 
2880 //           the same side. otherwise REVERSED.
2881 //=======================================================================
2882 static TopAbs_Orientation Relative (const TopoDS_Wire&   W1,
2883   const TopoDS_Wire&   W2,
2884   const TopoDS_Vertex& V,
2885   Standard_Boolean&    Commun)
2886 {
2887   TopExp_Explorer Exp;
2888   TopoDS_Edge     E1,E2;
2889   TopoDS_Vertex   V1,V2;
2890
2891   for (Exp.Init(W1,TopAbs_EDGE); Exp.More(); Exp.Next()) {
2892     const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
2893     TopExp::Vertices(E,V1,V2);
2894     if (V1.IsSame(V) || V2.IsSame(V)) {
2895       E1 = E;
2896       break;
2897     }
2898   }
2899   for (Exp.Init(W2,TopAbs_EDGE); Exp.More(); Exp.Next()) {
2900     const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
2901     TopExp::Vertices(E,V1,V2);
2902     if (V1.IsSame(V) || V2.IsSame(V)) {
2903       E2 = E;
2904       break;
2905     }
2906   }
2907
2908   if (E1.IsNull() || E2.IsNull()) {
2909     Commun = Standard_False;
2910     return TopAbs_FORWARD;
2911   }
2912   Commun = Standard_True;
2913
2914   TopoDS_Wire WW1 = BRepLib_MakeWire(E1);
2915   TopoDS_Wire WW2 = BRepLib_MakeWire(E2);
2916   Standard_Real Tol = BRepFill_Confusion();
2917   if (Side(WW1,Tol) < 4 && Side(WW2,Tol) < 4) // two to the left
2918     return TopAbs_FORWARD;
2919   if (Side(WW1,Tol) > 4 && Side(WW2,Tol) > 4) // two to the right
2920     return TopAbs_FORWARD;
2921
2922   return TopAbs_REVERSED;
2923 }
2924 //=======================================================================
2925 //function : OriEdgeInFace
2926 //purpose  : 
2927 //=======================================================================
2928
2929 TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge& E,
2930   const TopoDS_Face& F )
2931
2932 {
2933   TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
2934
2935   for (; Exp.More() ;Exp.Next()) {
2936     if (Exp.Current().IsSame(E)) {
2937       return Exp.Current().Orientation();
2938     }
2939   }
2940   Standard_ConstructionError::Raise("BRepFill_Evolved::OriEdgeInFace");
2941   return E.Orientation();
2942 }
2943
2944
2945
2946 //=======================================================================
2947 //function : IsOnFace
2948 //purpose  : Return the position of the point defined by d1
2949 //           in the face defined by d2 d3.
2950 //           
2951 //           0 : the point is out of the face.
2952 //           1 : the point is on edge corresponding to d2.
2953 //           2 : the point is inside the face.
2954 //           3 : the point is on edge corresponding to d3.
2955 //=======================================================================
2956
2957 Standard_Integer  PosOnFace (Standard_Real d1,
2958   Standard_Real d2,
2959   Standard_Real d3)
2960 {
2961   if (Abs(d1 - d2) <= BRepFill_Confusion())
2962     return 1;
2963   if (Abs(d1 - d3) <= BRepFill_Confusion())
2964     return 3;
2965
2966   if (d2 < d3) { 
2967     if (d1 > (d2 + BRepFill_Confusion()) && 
2968       d1 < (d3 - BRepFill_Confusion())    ) 
2969       return 2;
2970   }
2971   else {
2972     if (d1 > (d3 + BRepFill_Confusion()) && 
2973       d1 < (d2 - BRepFill_Confusion())   ) 
2974       return 2;
2975   }
2976   return 0;
2977 }
2978
2979 //=======================================================================
2980 //function : DoubleOrNotInFace
2981 //purpose  : Return True if V appears zero or two times in the sequence
2982 //           of edges EC 
2983 //=======================================================================
2984
2985 Standard_Boolean DoubleOrNotInFace(const TopTools_SequenceOfShape& EC,
2986   const TopoDS_Vertex&            V)
2987 {
2988   Standard_Boolean Vu = Standard_False;
2989
2990   for (Standard_Integer i = 1; i <= EC.Length(); i++) {
2991     TopoDS_Vertex V1,V2;
2992     TopExp::Vertices(TopoDS::Edge(EC.Value(i)),V1,V2);
2993     if (V1.IsSame(V)) {
2994       if  (Vu) return Standard_True;
2995       else       Vu = Standard_True;
2996     }
2997     if (V2.IsSame(V)) {
2998       if  (Vu) return Standard_True;
2999       else       Vu = Standard_True;
3000     }
3001   }
3002   if (Vu) return Standard_False;
3003   else    return Standard_True;   
3004 }
3005
3006
3007 //=======================================================================
3008 //function : DistanceToOZ
3009 //purpose  : 
3010 //=======================================================================
3011
3012 Standard_Real DistanceToOZ (const TopoDS_Vertex& V) 
3013 {
3014   gp_Pnt PV3d = BRep_Tool::Pnt(V);
3015   return Abs(PV3d.Y()); 
3016 }
3017
3018 //=======================================================================
3019 //function : Altitud
3020 //purpose  : 
3021 //=======================================================================
3022
3023 Standard_Real Altitud (const TopoDS_Vertex& V) 
3024 {
3025   gp_Pnt PV3d = BRep_Tool::Pnt(V);
3026   return PV3d.Z(); 
3027 }
3028
3029 //=======================================================================
3030 //function : SimpleExpression 
3031 //purpose  : 
3032 //=======================================================================
3033
3034 void SimpleExpression (const Bisector_Bisec&  B, 
3035   Handle(Geom2d_Curve)&  Bis)
3036 {
3037   Bis = B.Value();
3038
3039   Handle(Standard_Type) BT = Bis->DynamicType();
3040   if (BT == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
3041     Handle(Geom2d_TrimmedCurve) TrBis 
3042       = Handle(Geom2d_TrimmedCurve)::DownCast(Bis);
3043     Handle(Geom2d_Curve) BasBis = TrBis->BasisCurve();
3044     BT = BasBis->DynamicType();
3045     if (BT == STANDARD_TYPE(Bisector_BisecAna)) {
3046       Bis = Handle(Bisector_BisecAna)::DownCast(BasBis)->Geom2dCurve();
3047       Bis = new Geom2d_TrimmedCurve (Bis,
3048         TrBis->FirstParameter(),
3049         TrBis->LastParameter());
3050     }
3051   }
3052 }
3053
3054 //=======================================================================
3055 //function : CutEdgeProf
3056 //purpose  : Projection and Cut of an edge at extrema of distance to axis OZ.
3057 //=======================================================================
3058
3059 void CutEdgeProf (const TopoDS_Edge&                  E,
3060   const Handle(Geom_Plane)&           Plane,
3061   const Handle(Geom2d_Line)&          Line,
3062   TopTools_ListOfShape&         Cuts,
3063   TopTools_DataMapOfShapeShape& MapVerRefMoved)
3064
3065   Cuts.Clear();
3066
3067   Standard_Real             f,l;
3068   Handle(Geom_Curve)        C;
3069   Handle(Geom_TrimmedCurve) CT;
3070   Handle(Geom2d_Curve)      C2d;
3071   TopLoc_Location           L;
3072
3073   // Return the curve associated to each Edge
3074   C  = BRep_Tool::Curve(E,L,f,l);
3075   CT = new Geom_TrimmedCurve(C,f,l);
3076   CT->Transform(L.Transformation());
3077
3078   // project it in the plane and return the associated PCurve 
3079   gp_Dir Normal = Plane->Pln().Axis().Direction();
3080   C = 
3081     Handle(Geom_Curve)::DownCast(GeomProjLib::ProjectOnPlane(CT,Plane,
3082     Normal,
3083     Standard_False));
3084   C2d = GeomProjLib::Curve2d(C,Plane);
3085
3086   // Calculate the extrema with the straight line
3087   TColStd_SequenceOfReal Seq;
3088
3089   Standard_Real U1 = -Precision::Infinite();
3090   Standard_Real U2 =  Precision::Infinite();
3091   f= C2d->FirstParameter();
3092   l= C2d->LastParameter();
3093
3094   Bnd_Box2d B;
3095   Geom2dAdaptor_Curve AC2d(C2d);
3096   BndLib_Add2dCurve::Add(AC2d,BRepFill_Confusion(),B);
3097   Standard_Real xmin,xmax;
3098   B.Get(xmin,U1,xmax,U2);
3099
3100   //  modified by NIZHNY-EAP Wed Feb  2 16:32:37 2000 ___BEGIN___
3101   // no sense if C2 is normal to Line or really is a point
3102   if (U1 != U2) {
3103     Geom2dAPI_ExtremaCurveCurve Extrema(Line,C2d,U1-1.,U2+1.,f,l);
3104
3105     Standard_Integer i, Nb = Extrema.NbExtrema();
3106     for ( i = 1; i <= Nb; i++) {
3107       Extrema.Parameters(i,U1,U2);
3108       Seq.Append(U2);
3109     }
3110   }
3111   //  modified by NIZHNY-EAP Wed Feb  2 16:33:05 2000 ___END___
3112
3113   // On calcule les intersection avec Oy.
3114   Geom2dAdaptor_Curve ALine(Line);
3115   Standard_Real Tol = Precision::Intersection();
3116   Standard_Real TolC = 0.;
3117
3118   Geom2dInt_GInter Intersector(ALine,AC2d,TolC,Tol);
3119   Standard_Integer i, Nb = Intersector.NbPoints();
3120
3121   for ( i = 1; i <= Nb; i++) {
3122     Seq.Append(Intersector.Point(i).ParamOnSecond());
3123   }
3124
3125   // Compute the new edges.
3126   BRep_Builder Builder;
3127   TopoDS_Vertex VV,Vf,Vl,VRf,VRl;
3128   TopExp::Vertices(E,VRf,VRl);
3129
3130   if (!MapVerRefMoved.IsBound(VRf)) {
3131     Builder.MakeVertex(Vf,C->Value(f),BRep_Tool::Tolerance(VRf));
3132     MapVerRefMoved.Bind(VRf,Vf);
3133   }
3134   else {
3135     Vf = TopoDS::Vertex(MapVerRefMoved(VRf));
3136   }
3137
3138   if (!MapVerRefMoved.IsBound(VRl)) {
3139     Builder.MakeVertex(Vl,C->Value(l),BRep_Tool::Tolerance(VRl));
3140     MapVerRefMoved.Bind(VRl,Vl);
3141   }
3142   else {
3143     Vl = TopoDS::Vertex(MapVerRefMoved(VRl));
3144   }
3145
3146   if ( !Seq.IsEmpty()) {
3147
3148     Bubble(Seq);
3149
3150     Standard_Boolean Empty = Standard_False;
3151
3152     Standard_Real CurParam = f;
3153     Standard_Real Param;
3154
3155     while ( !Empty) {
3156       Param = Seq.First();
3157       Seq.Remove(1);
3158       Empty = Seq.IsEmpty();
3159       if (Abs( Param - CurParam) > BRepFill_Confusion() &&
3160         Abs( Param - l)        > BRepFill_Confusion() ) {
3161
3162           VV = BRepLib_MakeVertex( C->Value(Param));
3163
3164           TopoDS_Edge EE = BRepLib_MakeEdge(C,Vf,VV);
3165           EE.Orientation(E.Orientation());
3166           if ( EE.Orientation() == TopAbs_FORWARD)
3167             Cuts.Append(EE);
3168           else
3169             Cuts.Prepend(EE);
3170
3171           // reinitialize 
3172           CurParam = Param;
3173           Vf = VV;
3174       }
3175     }
3176   }
3177
3178   TopoDS_Edge EE = BRepLib_MakeEdge(C,Vf,Vl);
3179   EE.Orientation(E.Orientation());
3180   if ( EE.Orientation() == TopAbs_FORWARD)
3181     Cuts.Append(EE);
3182   else
3183     Cuts.Prepend(EE);
3184 }
3185
3186 //=======================================================================
3187 //function : CutEdge
3188 //purpose  : Cut an edge at thw extrema of curves and at points of inflexion.
3189 //           Closed circles are also cut in two.
3190 //           If <Cuts> are empty the edge is not modified.
3191 //           The first and the last vertex of the original edge 
3192 //           belong to the first and last parts respectively.
3193 //=======================================================================
3194 void CutEdge (const TopoDS_Edge& E, 
3195   const TopoDS_Face& F,
3196   TopTools_ListOfShape& Cuts)
3197 {
3198   Cuts.Clear();
3199   MAT2d_CutCurve              Cuter;
3200   Standard_Real               f,l; 
3201   Handle(Geom2d_Curve)        C2d;
3202   Handle(Geom2d_TrimmedCurve) CT2d;
3203
3204   TopoDS_Vertex V1,V2,VF,VL;
3205   TopExp::Vertices (E,V1,V2);
3206   BRep_Builder B;
3207
3208   C2d  = BRep_Tool::CurveOnSurface (E,F,f,l);
3209   CT2d = new Geom2d_TrimmedCurve(C2d,f,l);
3210
3211   if (CT2d->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Circle)) &&
3212     BRep_Tool::IsClosed(E)) {
3213       //---------------------------
3214       // Cut closed circle.
3215       //---------------------------
3216       Standard_Real m1 = (2*f +   l)/3.;
3217       Standard_Real m2 = (  f + 2*l)/3.;
3218       gp_Pnt2d P1 = CT2d->Value(m1);
3219       gp_Pnt2d P2 = CT2d->Value(m2);
3220
3221       TopoDS_Vertex VL1 = BRepLib_MakeVertex(gp_Pnt(P1.X(), P1.Y(), 0.));
3222       TopoDS_Vertex VL2 = BRepLib_MakeVertex(gp_Pnt(P2.X(), P2.Y(), 0.));
3223       TopoDS_Shape aLocalShape1 = E.EmptyCopied();
3224       TopoDS_Shape aLocalShape2 = E.EmptyCopied();
3225       TopoDS_Shape aLocalShape3 = E.EmptyCopied();
3226       TopoDS_Edge FE = TopoDS::Edge(aLocalShape1);    
3227       TopoDS_Edge ME = TopoDS::Edge(aLocalShape2);    
3228       TopoDS_Edge LE = TopoDS::Edge(aLocalShape3);
3229       //    TopoDS_Edge FE = TopoDS::Edge(E.EmptyCopied());    
3230       //   TopoDS_Edge ME = TopoDS::Edge(E.EmptyCopied());    
3231       //    TopoDS_Edge LE = TopoDS::Edge(E.EmptyCopied());
3232
3233       FE.Orientation(TopAbs_FORWARD);
3234       ME.Orientation(TopAbs_FORWARD);
3235       LE.Orientation(TopAbs_FORWARD );
3236
3237       B.Add  (FE,V1);
3238       B.Add  (FE,VL1.Oriented(TopAbs_REVERSED));
3239       B.Range(FE, f, m1);    
3240
3241       B.Add  (ME,VL1.Oriented(TopAbs_FORWARD));
3242       B.Add  (ME,VL2.Oriented(TopAbs_REVERSED));
3243       B.Range(ME, m1, m2);    
3244
3245       B.Add  (LE,VL2.Oriented(TopAbs_FORWARD));
3246       B.Add  (LE,V2);
3247       B.Range(LE, m2, l);
3248
3249       Cuts.Append(FE.Oriented(E.Orientation()));
3250       Cuts.Append(ME.Oriented(E.Orientation()));
3251       Cuts.Append(LE.Oriented(E.Orientation()));
3252       //--------
3253       // Return.
3254       //--------
3255       return;
3256   }
3257
3258   //-------------------------
3259   // Cut of the curve.
3260   //-------------------------
3261   Cuter.Perform(CT2d);
3262
3263   if (Cuter.UnModified()) {
3264     //-----------------------------
3265     // edge not modified => return.
3266     //-----------------------------
3267     return;
3268   }
3269   else {
3270     //------------------------
3271     // Creation of cut edges.
3272     //------------------------
3273     VF = V1;
3274
3275     for ( Standard_Integer k = 1; k <= Cuter.NbCurves(); k++) {
3276       Handle(Geom2d_TrimmedCurve)CC = Cuter.Value(k);
3277       if (k == Cuter.NbCurves()) {VL = V2;}
3278       else { 
3279         gp_Pnt2d P = CC->Value(CC->LastParameter());
3280         VL = BRepLib_MakeVertex(gp_Pnt(P.X(), P.Y(), 0.));
3281       }
3282       TopoDS_Shape aLocalShape = E.EmptyCopied();
3283       TopoDS_Edge NE = TopoDS::Edge(aLocalShape);
3284       //      TopoDS_Edge NE = TopoDS::Edge(E.EmptyCopied());
3285       NE.Orientation(TopAbs_FORWARD);
3286       B.Add  (NE,VF.Oriented(TopAbs_FORWARD));
3287       B.Add  (NE,VL.Oriented(TopAbs_REVERSED));      
3288       B.Range(NE,CC->FirstParameter(),CC->LastParameter());
3289       Cuts.Append(NE.Oriented(E.Orientation()));
3290       VF = VL;
3291     }
3292   }
3293 }
3294
3295 //=======================================================================
3296 //function : VertexFromNode
3297 //purpose  : Test if the position of aNode correspondingly to the distance to OZ
3298 //           of vertices VF and VL. returns Status.
3299 //           if Status is different from 0 Returned
3300 //           the vertex corresponding to aNode is created.
3301 //=======================================================================
3302
3303 Standard_Integer VertexFromNode
3304   (const Handle(MAT_Node)&                          aNode, 
3305   const TopoDS_Edge&                                E, 
3306   const TopoDS_Vertex&                              VF, 
3307   const TopoDS_Vertex&                              VL,
3308   BRepFill_DataMapOfNodeDataMapOfShapeShape&  MapNodeVertex,
3309   TopoDS_Vertex&                              VN)
3310 {      
3311   TopoDS_Shape                 ShapeOnNode;
3312   TopTools_DataMapOfShapeShape EmptyMap;
3313   Standard_Integer             Status = 0;
3314   BRep_Builder                 B;
3315
3316   if (!aNode->Infinite()) {
3317     Status    = PosOnFace(aNode->Distance(),
3318       DistanceToOZ(VF) , DistanceToOZ(VL));
3319   }
3320   if      (Status == 2) ShapeOnNode = E;
3321   else if (Status == 1) ShapeOnNode = VF;
3322   else if (Status == 3) ShapeOnNode = VL;
3323
3324   if (!ShapeOnNode.IsNull()) {
3325     //-------------------------------------------------
3326     // the vertex will correspond to a node of the map
3327     //-------------------------------------------------
3328     if (MapNodeVertex.IsBound(aNode) &&
3329       MapNodeVertex(aNode).IsBound(ShapeOnNode)) {
3330         VN = TopoDS::Vertex
3331           (MapNodeVertex(aNode)(ShapeOnNode));
3332     }
3333     else { 
3334       B.MakeVertex (VN);
3335       if (!MapNodeVertex.IsBound(aNode)) {
3336         MapNodeVertex.Bind(aNode,EmptyMap);
3337       }
3338       MapNodeVertex(aNode).Bind(ShapeOnNode,VN);
3339     }
3340   }
3341   return Status;
3342 }
3343