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