Integration of OCCT 6.5.0 from SVN
[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 pour 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 la position du profil par rapport au plan 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 : il suffit de tester sur le premier edge du Wire.
336   //       ( Correctement decoupe dans 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   // Positionnement de mySpine et de myProfil dans le repere de travail.
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 du profil et decoupe du 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 du volevo decoupe.
449   // Pour chaque portion du profile on cree en volevo qui est
450   // additionner a CutVevo
451   //----------------------------------------------------------
452   BRepFill_Evolved       CutVevo;
453   TopoDS_Wire            WP;
454   BRep_Builder           BB;
455   BRepTools_WireExplorer WExp;
456
457   BB.MakeWire(WP);
458
459   for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {     
460     for (WExp.Init(TopoDS::Wire(WPIte.Value())); WExp.More(); WExp.Next()) {
461       BB.Add(WP,WExp.Current());
462     }
463   }
464   CutVevo.SetWork(WorkSpine,WP);
465
466   BRepTools_Quilt  Glue;
467   Standard_Integer CSide;
468   
469   //---------------------------------
470   // Construction des vevos a gauche.
471   //---------------------------------
472   if (YaLeft) {
473     //-----------------------------------------------------
474     // Calcul de la carte des lieux bissecteurs a gauche.  
475     // et des Liens Topologie -> elements de base de la carte.
476     //-----------------------------------------------------
477     BRepMAT2d_Explorer Exp(WorkSpine);
478     Locus.Compute(Exp,1,MAT_Left);
479     BRepMAT2d_LinkTopoBilo Link(Exp,Locus);
480
481     for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {    
482       SP    = TopoDS::Wire(WPIte.Value());
483       CSide = Side(SP,Tol);     
484       //-----------------------------------------------
485       // Construction et ajout d un volevo elementaire.
486       //-----------------------------------------------
487       BRepFill_Evolved Vevo;
488       if ( CSide == 1) { 
489         Vevo.ElementaryPerform (WorkSpine, SP, Locus, Link, Join);
490       }
491       else if (CSide == 2) {
492         Vevo.PlanarPerform (WorkSpine, SP, Locus, Link, Join);
493       }
494       else if (CSide == 3) {
495         Vevo.VerticalPerform (WorkSpine, SP, Locus, Link, Join);
496       }
497       CutVevo.Add (Vevo, SP, Glue);
498     }
499   }
500
501   //---------------------------------
502   // Construction des vevos a droite.
503   //---------------------------------
504   if (YaRight) {
505     //-----------------------------------
506     // Decomposition de la face en wires.
507     //-----------------------------------
508     TopExp_Explorer SpineExp (WorkSpine, TopAbs_WIRE);
509     for ( ; SpineExp.More(); SpineExp.Next()) {
510       //----------------------------------------------
511       // Calcul de la carte a droite du wire courant.
512       //----------------------------------------------
513       BRepLib_MakeFace B(gp_Pln(0.,0.,1.,0.));
514       TopoDS_Shape aLocalShape = SpineExp.Current().Reversed();
515       B.Add(TopoDS::Wire(aLocalShape));
516 //      B.Add(TopoDS::Wire(SpineExp.Current().Reversed()));
517       Face = B.Face();
518       BRepMAT2d_Explorer Exp(Face);
519       Locus.Compute(Exp,1,MAT_Left);
520       BRepMAT2d_LinkTopoBilo Link(Exp,Locus);
521       
522       for (WPIte.Initialize(WorkProf); WPIte.More(); WPIte.Next()) {
523         SP = TopoDS::Wire(WPIte.Value());
524         CSide = Side(SP,Tol);   
525         //-----------------------------------------------
526         // Construction et ajout d un volevo elementaire.
527         //-----------------------------------------------
528         BRepFill_Evolved Vevo;
529         if ( CSide == 4) { 
530           Vevo.ElementaryPerform (Face, SP, Locus, Link, Join);
531         }
532         else if (CSide == 5) {
533           Vevo.PlanarPerform (Face, SP, Locus, Link, Join);
534         }
535         else if (CSide == 6) {
536           Vevo.VerticalPerform (Face, SP, Locus, Link, Join);
537         }
538         CutVevo.Add (Vevo, SP, Glue);
539       }      
540     }
541   }
542
543   if (Solid) CutVevo.AddTopAndBottom(Glue);
544
545   //-------------------------------------------------------------------------
546   // Codage des regularites sur les edges paralleles generes par les vertex
547   // de la decoupe du profil.
548   //-------------------------------------------------------------------------
549   CutVevo.ContinuityOnOffsetEdge(WorkProf);
550
551   //-----------------------------------------------------------------
552   // construction du shape via le quilt, ie:
553   // - partage des topologies des volevos elementaires additionnes.
554   // - Orientation des faces les unes par rapport aux autres.
555   //-----------------------------------------------------------------
556   TopoDS_Shape& SCV = CutVevo.ChangeShape();
557   SCV = Glue.Shells();
558   //------------------------------------------------------------------------
559   // Transfert de la map des elements generes et du shape de Cutvevo dans 
560   // myMap et Repositionnement dans l espace initial.
561   //------------------------------------------------------------------------
562   Transfert (CutVevo, MapProf, MapSpine, LSpine.Inverted(), InitLS, InitLP);
563
564   //Orientation du solid.
565   if (Solid) MakeSolid();
566
567 //  modified by NIZHNY-EAP Mon Jan 24 11:26:48 2000 ___BEGIN___
568   BRepLib::UpdateTolerances(myShape,Standard_False);
569 //  modified by NIZHNY-EAP Mon Jan 24 11:26:50 2000 ___END___
570   myIsDone = Standard_True;
571 }
572
573
574
575 //=======================================================================
576 //function : IsInversed
577 //purpose  : 
578 //=======================================================================
579
580 static void IsInversed(const TopoDS_Shape& S,
581                        const TopoDS_Edge&  E1,
582                        const TopoDS_Edge&  E2,
583                        Standard_Boolean*   Inverse)
584 {  
585
586   Inverse[0] = Inverse[1] = 0;
587   if (S.ShapeType() != TopAbs_EDGE) return;
588
589   gp_Pnt P;
590   gp_Vec DS,DC1,DC2 ;
591   BRepAdaptor_Curve CS(TopoDS::Edge(S));
592   if (S.Orientation() == TopAbs_FORWARD) {
593     CS.D1(CS.FirstParameter(),P,DS);
594   }
595   else {
596     CS.D1(CS.LastParameter(),P,DS);
597     DS.Reverse();
598   }
599     
600
601   if (!BRep_Tool::Degenerated(E1)) {
602     BRepAdaptor_Curve C1(TopoDS::Edge(E1));
603     if (E1.Orientation() == TopAbs_FORWARD) {
604       C1.D1(C1.FirstParameter(),P,DC1);
605     }
606     else {
607      C1.D1(C1.LastParameter(),P,DC1);
608      DC1.Reverse();
609     }
610     Inverse[0] = (DS.Dot(DC1) < 0.);
611   }
612   else Inverse[0] = 1;
613
614   if (!BRep_Tool::Degenerated(E2)) {
615     BRepAdaptor_Curve C2(TopoDS::Edge(E2));
616     if (E2.Orientation() == TopAbs_FORWARD) {
617       C2.D1(C2.FirstParameter(),P,DC2);
618     }
619     else {
620      C2.D1(C2.LastParameter(),P,DC2);
621      DC2.Reverse();
622     }
623     Inverse[1] = (DS.Dot(DC2) < 0.);
624   }
625   else Inverse[1] = 1;
626 }
627
628 //=======================================================================
629 //function : SetWork
630 //purpose  : 
631 //=======================================================================
632
633 void BRepFill_Evolved::SetWork(const TopoDS_Face& Sp,
634                                const TopoDS_Wire& Pr)
635 {
636   mySpine   = Sp;
637   myProfile = Pr;
638 }
639                                         
640 //=======================================================================
641 //function : ConcaveSide
642 //purpose  : Determine si les pipes ont ete construits du cote de la 
643 //           concavite. Dans ce cas il peuvent etre boucles.
644 //           WARNING: Pas fini... Seulement fait pour les cercles.
645 //=======================================================================
646
647 static Standard_Boolean ConcaveSide(const TopoDS_Shape& S,
648                                     const TopoDS_Face&  F)
649 {
650
651   if (S.ShapeType() == TopAbs_VERTEX) return Standard_False;
652
653   if (S.ShapeType() == TopAbs_EDGE) {
654     Standard_Real f,l;
655     Handle(Geom2d_Curve) G2d = 
656       BRep_Tool::CurveOnSurface(TopoDS::Edge(S),F,f,l);
657     Handle(Geom2d_Curve) G2dOC;
658     
659     Geom2dAdaptor_Curve  AC(G2d,f,l);
660     if ( AC.GetType() == GeomAbs_Circle) {
661       Standard_Boolean Direct = AC.Circle().IsDirect();
662       if (S.Orientation() == TopAbs_REVERSED) Direct = (!Direct);
663       return Direct;
664     }
665   }
666   return Standard_False;
667 }
668
669 //=======================================================================
670 //function : ElementaryPerform
671 //purpose  : 
672 //=======================================================================
673
674 void BRepFill_Evolved::ElementaryPerform (const TopoDS_Face&              Sp,
675                                           const TopoDS_Wire&              Pr,
676                                           const BRepMAT2d_BisectingLocus& Locus,
677                                                 BRepMAT2d_LinkTopoBilo&   Link,
678                                           const GeomAbs_JoinType          Join)
679 {
680
681 #ifdef DRAW
682   if (AffichEdge) {       
683     sprintf(name,"PROFIL_%d",++NbPROFILS);      
684     DBRep::Set(name,Pr);
685   }
686 #endif
687   TopoDS_Shape aLocalShape = Sp.Oriented(TopAbs_FORWARD);
688   mySpine   = TopoDS::Face(aLocalShape);
689 //  mySpine   = TopoDS::Face(Sp.Oriented(TopAbs_FORWARD));
690   myProfile = Pr;
691   myMap.Clear();
692
693   BRep_Builder myBuilder;
694   myBuilder.MakeCompound(TopoDS::Compound(myShape));
695   
696   //---------------------------------------------------------------------
697   // MapNodeVertex : associe a chaque noeud de la carte (key1) et
698   //                 a chaque element du profil (key2) un vertex (item).
699   // MapBis        : ensemble des edges ou vertex (item) generes par
700   //                 une bisectrice sur une face ou un edge (key)des 
701   //                 tuyaux ou revol.
702   // MapVerPar     : Map des parametres des vertex sur les edges paralleles 
703   //                 la liste contenue dans MapVerPar (E) correspond aux 
704   //                 parametres sur E des vertex contenu dans  MapBis(E);
705   // MapBS         : liens BasicElt de la carte => Topologie du spine.
706   //---------------------------------------------------------------------
707
708
709   BRepFill_DataMapOfNodeDataMapOfShapeShape MapNodeVertex; 
710   TopTools_DataMapOfShapeSequenceOfShape    MapBis;  
711   BRepFill_DataMapOfShapeSequenceOfReal     MapVerPar;
712
713   TopTools_DataMapOfShapeShape              EmptyMap;
714   TopTools_SequenceOfShape                  EmptySeq;
715   TopTools_ListOfShape                      EmptyList;
716   TColStd_SequenceOfReal                    EmptySeqOfReal;
717
718   // Repere du profile.
719   gp_Ax3 AxeRef(gp_Pnt(0.,0.,0.),
720                 gp_Dir(0.,0.,1.),
721                 gp_Dir(1.,0.,0.));  
722
723   //---------------------------------------------------------------
724   // Construction des revols et des tuyaux.
725   //---------------------------------------------------------------
726   BRepTools_WireExplorer ProfExp;
727   TopExp_Explorer        FaceExp;
728   BRepTools_WireExplorer WireExp;
729
730   for (FaceExp.Init(mySpine,TopAbs_WIRE); FaceExp.More(); FaceExp.Next()){
731
732     for (WireExp.Init(TopoDS::Wire(FaceExp.Current())); WireExp.More(); 
733          WireExp.Next()) {
734
735       TopoDS_Edge   CurrentEdge = WireExp.Current();
736       TopoDS_Vertex VFirst,VLast;
737       EdgeVertices(CurrentEdge,VFirst,VLast);
738
739       for (Link.Init(VLast); Link.More(); Link.Next()) {
740         //------------------------.
741         //Construction d un Revol
742         //------------------------.
743         MakeRevol (CurrentEdge, VLast, AxeRef);
744       }
745
746       for (Link.Init(CurrentEdge); Link.More(); Link.Next()) {
747         //------------------------.
748         //Construction d un Tuyau
749         //-------------------------
750         MakePipe (CurrentEdge, AxeRef);
751       }
752     }
753   }
754
755 #ifdef DRAW
756   if (AffichEdge) {
757     cout << " Fin Construction des primitives geometriques"<<endl;
758   }
759 #endif
760
761   TopoDS_Vertex  VF,VL;
762   
763   //---------------------------------------------------
764   // Constructions des edges associes aux bissectrices.
765   //---------------------------------------------------
766   Handle(MAT_Arc)        CurrentArc;
767   Handle(Geom2d_Curve)   Bis, PCurve1, PCurve2 ;
768   Handle(Geom_Curve)     CBis;
769   Standard_Boolean       Reverse;
770   TopoDS_Edge            CurrentEdge;
771   TopoDS_Shape           S       [2];
772   TopoDS_Face            F       [2];
773   TopoDS_Edge            E       [4];
774   TopLoc_Location        L;
775   Standard_Integer       k;
776
777   for (Standard_Integer i = 1; i <= Locus.Graph()->NumberOfArcs(); i++) {
778     CurrentArc = Locus.Graph()->Arc(i);
779     SimpleExpression(Locus.GeomBis(CurrentArc,Reverse), Bis); 
780     
781     //-----------------------------------------------------------------------
782     // Recuperation des elements du spine correspondant aux basicElts separes.
783     //-----------------------------------------------------------------------
784     S [0] = Link.GeneratingShape(CurrentArc->FirstElement());
785     S [1] = Link.GeneratingShape(CurrentArc->SecondElement());
786
787     Standard_Boolean Concave0 = ConcaveSide(S[0],mySpine);
788     Standard_Boolean Concave1 = ConcaveSide(S[1],mySpine);
789
790     TopTools_SequenceOfShape VOnF,VOnL;
791     TColgp_SequenceOfPnt     ParOnF,ParOnL;
792     
793     TopTools_DataMapOfShapeSequenceOfShape MapSeqVer;
794     BRepFill_DataMapOfShapeSequenceOfPnt   MapSeqPar;
795
796     Standard_Integer vv = 0;
797     for(ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()) {
798       vv++;
799       //-------------------------------------------------------
800       // Recuperation des deux faces separees par la bissectrice.
801       //-------------------------------------------------------
802       F [0] = TopoDS::Face(myMap(S[0])(ProfExp.Current()).First());
803       F [1] = TopoDS::Face(myMap(S[1])(ProfExp.Current()).First());
804       
805       //-----------------------------------------------------------
806       // Recuperation des edges paralleles sur chaque face.
807       //-----------------------------------------------------------
808       TopoDS_Vertex VF,VL;
809
810       EdgeVertices(ProfExp.Current(),VF,VL);
811
812       E [0] = TopoDS::Edge(myMap(S[0])(VF).First());
813       E [1] = TopoDS::Edge(myMap(S[0])(VL).First());
814       E [2] = TopoDS::Edge(myMap(S[1])(VF).First());
815       E [3] = TopoDS::Edge(myMap(S[1])(VL).First());
816
817       Standard_Boolean Inv0[2];
818       Standard_Boolean Inv1[2];
819
820       Inv0[0] = Inv0[1] = Inv1[0]= Inv1[1] = 0;
821       if (Concave0) IsInversed(S[0],E[0],E[1],Inv0);
822       if (Concave1) IsInversed(S[1],E[2],E[3],Inv1);
823       
824       //---------------------------------------------
825       // Construction des geometries.
826       //---------------------------------------------
827       BRepFill_TrimSurfaceTool Trim (Bis,F[0],F[1],
828                                      E[0],E[2],Inv0[0],Inv1[0]);
829       //-----------------------------------------------------------
830       //Construction des vertex correspondant au noeud de la carte.
831       //-----------------------------------------------------------
832       TopoDS_Vertex VS,VE;
833       Handle(MAT_Node) Node1, Node2;
834
835       if (Reverse) {
836         Node1 = CurrentArc->SecondNode();
837         Node2 = CurrentArc->FirstNode();
838       }
839       else  {
840         Node1 = CurrentArc->FirstNode();
841         Node2 = CurrentArc->SecondNode();
842       }
843       //--------------------------------------------------------
844       // Cas Particulier ou le noeud est sur un vertex du spine.
845       //--------------------------------------------------------
846       if (Node1->OnBasicElt()) {
847         if (S[0].ShapeType() == TopAbs_VERTEX) {
848           Node1 = CurrentArc->FirstElement()->StartArc()->FirstNode();
849         }
850         else if (S[1].ShapeType() == TopAbs_VERTEX) {
851           Node1 = CurrentArc->SecondElement()->StartArc()->FirstNode();
852         }
853       } 
854       // Fin cas particulier.
855       
856       Standard_Integer 
857         StartOnF  = VertexFromNode(Node1, 
858                                    TopoDS::Edge(ProfExp.Current()), 
859                                    VF, VL ,
860                                    MapNodeVertex,VS);
861       
862       Standard_Integer 
863         EndOnF    = VertexFromNode(Node2, 
864                                    TopoDS::Edge(ProfExp.Current()), 
865                                    VF, VL ,
866                                    MapNodeVertex,VE);
867
868       //-----------------------------------------------------------
869       // Construction des vertex sur les edges paralleles au spine.
870       //-----------------------------------------------------------
871       if (!MapSeqVer.IsBound(VF)) {
872         if (Inv0 [0] || Inv1 [0]) {
873           ParOnF.Clear();
874           VOnF  .Clear();
875         }
876         else {
877           Trim.IntersectWith(E [0], E [2], ParOnF);
878           VOnF  .Clear();
879           for (Standard_Integer s = 1; s <= ParOnF.Length(); s++) {
880             TopoDS_Vertex VC;
881             myBuilder.MakeVertex (VC);
882             VOnF.Append(VC);
883           }
884           if (StartOnF == 1) {
885             VOnF  .SetValue(1,VS);
886           }
887           if (EndOnF == 1) {      
888             VOnF  .SetValue(ParOnF.Length(),VE);
889           }
890         }
891       }
892       else {
893         ParOnF = MapSeqPar(VF);
894         VOnF   = MapSeqVer(VF);
895       }
896       
897       if (!MapSeqVer.IsBound(VL)) {
898         if (Inv0 [1] || Inv1 [1]) {
899           ParOnL.Clear();
900           VOnL  .Clear();
901         }
902         else {
903           Trim.IntersectWith(E [1], E [3], ParOnL);
904           VOnL.Clear();
905           for (Standard_Integer s = 1; s <= ParOnL.Length(); s++) {     
906             TopoDS_Vertex VC;
907             myBuilder.MakeVertex (VC); 
908             VOnL.Append(VC);
909           }
910           if (StartOnF == 3) {
911             VOnL  .SetValue(1,VS);
912           }
913           if (EndOnF == 3)   {
914             VOnL  .SetValue(ParOnL.Length(),VE);
915           }
916         }
917       }
918       else {
919         ParOnL = MapSeqPar(VL);
920         VOnL   = MapSeqVer(VL);
921       }
922       
923       //----------------------------------------------------------
924       // Test si la Bissectrice ne se projette pas sur la face
925       //----------------------------------------------------------
926       if ((StartOnF == 0) && (EndOnF == 0) && 
927            VOnL.IsEmpty() && VOnF.IsEmpty())
928         // Aucune trace de la bisectrice sur la face.
929         continue;
930
931       if ((StartOnF == 0) && (EndOnF == 0) && 
932            (VOnL.Length() + VOnF.Length() == 1)) 
933         // le premier ou dernier noeud de l arc est sur une edge
934         // mais l arc n est pas sur la face. 
935         continue; 
936
937       //---------------------------------------------------------
938       // determination des intervalles de la bissectrice qui se
939       // projettent sur F[0] et F[1].
940       //---------------------------------------------------------
941       TColStd_SequenceOfReal     LastPar,FirstPar;
942       TopTools_SequenceOfShape   FirstV,LastV;
943
944       ComputeIntervals (VOnF,VOnL,ParOnF,ParOnL,Trim,Bis,
945                         VS,VE,FirstPar,LastPar,FirstV,LastV);
946
947       for (Standard_Integer Ti =  1; Ti <= FirstPar.Length(); Ti++) {
948         TopoDS_Vertex V1 = TopoDS::Vertex(FirstV.Value(Ti));
949         TopoDS_Vertex V2 = TopoDS::Vertex(LastV .Value(Ti));
950
951         GeomAbs_Shape Continuity;
952
953         Trim.Project(FirstPar.Value(Ti),LastPar.Value(Ti),
954                      CBis,PCurve1,PCurve2,Continuity);
955         
956         //-------------------------------------
957         // Codage de l edge.
958         //-------------------------------------
959         myBuilder.MakeEdge(CurrentEdge, CBis, 
960                            BRepFill_Confusion());
961
962         myBuilder.UpdateVertex(V1,CBis->Value(CBis->FirstParameter()),
963                                BRepFill_Confusion()); 
964         myBuilder.UpdateVertex(V2,CBis->Value(CBis->LastParameter()),
965                                BRepFill_Confusion());
966
967         myBuilder.Add(CurrentEdge,V1.Oriented(TopAbs_FORWARD));
968         myBuilder.Add(CurrentEdge,V2.Oriented(TopAbs_REVERSED));
969
970         myBuilder.Range(CurrentEdge,
971                         CBis->FirstParameter(),
972                         CBis->LastParameter());
973         myBuilder.UpdateEdge(CurrentEdge,PCurve1,F[0],BRepFill_Confusion());
974         myBuilder.UpdateEdge(CurrentEdge,PCurve2,F[1],BRepFill_Confusion());
975
976         myBuilder.Continuity(CurrentEdge,F[0],F[1],Continuity);
977         
978 #ifdef DRAW
979         if (AffichEdge) {
980           sprintf(name,"ARCEDGE_%d_%d_%d",i,vv,Ti);     
981           DBRep::Set(name,CurrentEdge);
982         }
983 #endif
984         //-------------------------------------------
985         // Stockage de l edge pour chacune des faces.
986         //-------------------------------------------
987         for (k = 0; k <= 1;k++) {
988           if (!MapBis.IsBound(F[k])) {
989             MapBis.Bind(F[k],EmptySeq);
990           }
991         }
992         //---------------------------------------------------------------
993         // l orientation de l edge depend du sens de la depouille.
994         // depouille => meme orientation E[0] , inverse orientation E[2]
995         // si contredepouille c est l inverse.
996         //--------------------------------------------------------------
997         E[0].Orientation(OriEdgeInFace(E[0],F[0]));
998         E[2].Orientation(OriEdgeInFace(E[2],F[1]));
999                          
1000         if (DistanceToOZ(VF) < DistanceToOZ(VL)  ) { 
1001           // Depouille
1002           MapBis(F[0]).Append(CurrentEdge.Oriented  (E[0].Orientation()));
1003           CurrentEdge.Orientation(TopAbs::Complement(E[2].Orientation()));
1004           MapBis(F[1]).Append(CurrentEdge);
1005         }
1006         else {
1007           //Contre Depouille
1008           MapBis(F[1]).Append(CurrentEdge.Oriented  (E[2].Orientation()));
1009           CurrentEdge.Orientation(TopAbs::Complement(E[0].Orientation()));
1010           MapBis(F[0]).Append(CurrentEdge);
1011         }
1012       }
1013
1014       //----------------------------------------------
1015       // Stockage des vertex sur les edges paralleles.
1016       // on remplit MapBis et MapVerPar.
1017       // VOnF pour E[0] et E[2].
1018       // VOnL pour E[1] et E[3].
1019       //----------------------------------------------
1020       for (k = 0; k <= 2; k = k+2) {
1021         if ( !MapSeqVer.IsBound(VF)) {
1022           if (!VOnF.IsEmpty()) {
1023             if (!MapBis.IsBound(E[k])) {
1024               MapBis   .Bind(E[k],EmptySeq);
1025               MapVerPar.Bind(E[k],EmptySeqOfReal);
1026             } 
1027             for (Standard_Integer ii = 1; ii <= VOnF.Length(); ii++) {
1028               MapBis (E[k]).Append(VOnF.Value(ii));
1029               if (k == 0) MapVerPar (E[k]).Append(ParOnF.Value(ii).Y());
1030               else        MapVerPar (E[k]).Append(ParOnF.Value(ii).Z());
1031             }
1032           }
1033         }
1034       }
1035         
1036       for (k = 1; k <= 3; k = k+2) {
1037         if ( !MapSeqVer.IsBound(VL)) {
1038           if (!VOnL.IsEmpty()) {
1039             if (!MapBis.IsBound(E[k])) {
1040               MapBis   .Bind(E[k],EmptySeq);
1041               MapVerPar.Bind(E[k],EmptySeqOfReal);
1042             }
1043             for (Standard_Integer ii = 1; ii <= VOnL.Length(); ii++) {
1044               MapBis(E[k]).Append(VOnL.Value(ii));
1045               if (k == 1) MapVerPar (E[k]).Append(ParOnL.Value(ii).Y());
1046               else        MapVerPar (E[k]).Append(ParOnL.Value(ii).Z());
1047             }
1048           }
1049         }
1050       }
1051
1052       //----------------------------------------------------------------
1053       // Edge [1] de la face courante sera Edge [0] de la face suivante.
1054       // => copie de VonL dans VonF. Pour ne pas creer deux fois les memes
1055       // vertex.
1056       //-----------------------------------------------------------------
1057
1058       MapSeqPar.Bind(VF,ParOnF);
1059       MapSeqVer.Bind(VF,VOnF);
1060       MapSeqPar.Bind(VL,ParOnL);
1061       MapSeqVer.Bind(VL,VOnL);
1062
1063     }
1064   }
1065
1066 #ifdef DEB
1067  if (AffichEdge) {
1068    cout << " Fin Construction des edges et vertex sur les bissectrices"<<endl;
1069  }
1070 #endif
1071
1072   //----------------------------------
1073   // Construction des edges paralleles.
1074   //----------------------------------
1075   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape ite1;
1076   TopoDS_Shape           CurrentProf,PrecProf;
1077   TopoDS_Face            CurrentFace;
1078   TopoDS_Shape           CurrentSpine;
1079   TopoDS_Vertex          VCF,VCL;
1080
1081   for (ite1.Initialize(myMap); ite1.More(); ite1.Next()) {
1082     CurrentSpine = ite1.Key();
1083
1084     for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){      
1085       CurrentProf = ProfExp.Current();
1086       EdgeVertices(TopoDS::Edge(CurrentProf),VCF,VCL);
1087       CurrentEdge  = TopoDS::Edge(myMap(CurrentSpine)(VCF).First());
1088       
1089       //-------------------------------------------------------------
1090       //RQ : Current Edge est oriente par rapport a la face (oriente forward)
1091       //     genere par l edge CurrentProf .
1092       //-------------------------------------------------------------
1093       if (MapBis.IsBound(CurrentEdge)) {
1094         
1095         //--------------------------------------------------------
1096         // Recherche si une des deux faces connexes de l edge
1097         // appartient au volevo. Les edges sur cette face servent
1098         // a eliminer certains vertex qui peuvent apparaitre deux
1099         // fois sur l edge parallele. Ces Vertex corespondent a des
1100         // noeuds de la carte.
1101         //---------------------------------------------------------
1102         TopoDS_Shape     FaceControle;
1103         Standard_Boolean YaFace = Standard_True;
1104         
1105         FaceControle = myMap(CurrentSpine)(CurrentProf).First();
1106         if (!MapBis.IsBound(FaceControle)){
1107           YaFace = Standard_False;
1108           if (!PrecProf.IsNull()) {
1109             FaceControle = myMap(CurrentSpine)(PrecProf).First();
1110             if (MapBis.IsBound(FaceControle)){
1111               YaFace = Standard_True;
1112             }
1113           }
1114         }
1115         
1116         if (YaFace) {
1117           //------------------------------------------------------------
1118           // Pas de face connexe dans le volevo => pas d edge parallele.
1119           //------------------------------------------------------------
1120           TopTools_SequenceOfShape S;
1121           TrimEdge (CurrentEdge,
1122                     MapBis   (FaceControle), 
1123                     MapBis   (CurrentEdge) ,  
1124                     MapVerPar(CurrentEdge) , S);
1125           
1126           for ( k = 1; k <= S.Length(); k++) {
1127             myMap(CurrentSpine)(VCF).Append(S.Value(k));
1128             
1129 #ifdef DRAW         
1130             if (AffichEdge) {
1131               sprintf(name,"PAREDGE_%d_%d",++NbEDGES,k);        
1132               DBRep::Set(name,S.Value(k));
1133             }
1134 #endif      
1135           }
1136         }
1137       }
1138       PrecProf = CurrentProf;
1139     }
1140     
1141     //------------------------------------------------------------
1142     // Construction edge parallele du dernier vertex de myProfile.
1143     //------------------------------------------------------------
1144     CurrentEdge  = TopoDS::Edge(myMap(CurrentSpine)(VCL).First());
1145     
1146     if (MapBis.IsBound(CurrentEdge)) {
1147       Standard_Boolean YaFace = Standard_True;
1148       TopoDS_Shape     FaceControle;
1149       
1150       FaceControle = myMap(CurrentSpine)(CurrentProf).First();
1151       if (!MapBis.IsBound(FaceControle)){
1152         YaFace = Standard_False;
1153       }
1154       // le nombre d element de la liste permet de savoir
1155       // si les edges ont deja ete faite (profile ferme) .
1156       if (YaFace && myMap(CurrentSpine)(VCL).Extent()<= 1) {
1157         TopTools_SequenceOfShape S;
1158         TrimEdge (CurrentEdge, 
1159                   MapBis   (FaceControle), 
1160                   MapBis   (CurrentEdge) , 
1161                   MapVerPar(CurrentEdge) , S);
1162         
1163         for ( k = 1; k <= S.Length(); k++) {
1164           myMap(CurrentSpine)(VCL).Append(S.Value(k));
1165           
1166 #ifdef DRAW         
1167           if (AffichEdge) {       
1168             sprintf(name,"PAREDGE_%d_%d",++NbEDGES,k);  
1169             DBRep::Set(name,S.Value(k));
1170           }
1171 #endif
1172         }
1173       }
1174     }
1175   }
1176   
1177 #ifdef DRAW
1178   if (AffichEdge) {
1179     cout <<" Fin Construction des edges paralleles"<<endl;
1180   }
1181 #endif
1182
1183   //-------------------------------------------------------------------
1184   // Decoupe des faces par les edges.
1185   //-------------------------------------------------------------------
1186   for (ite1.Initialize(myMap); ite1.More(); ite1.Next()) {
1187     CurrentSpine = ite1.Key();
1188     
1189     for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){
1190       CurrentProf = ProfExp.Current();
1191       CurrentFace = TopoDS::Face(myMap(CurrentSpine)(CurrentProf).First());
1192       myMap(CurrentSpine)(CurrentProf).Clear();
1193       
1194       if (MapBis.IsBound(CurrentFace)) {
1195         //----------------------------------------------------------
1196         // Si la face ne contient pas d edges pour la restreindre
1197         // c est qu'elle n apparait pas dans le volevo.
1198         // la decoupe de la face par les edges peut generer plusieurs
1199         // faces.
1200         //
1201         // On ajoute les edges generes sur les edges paralleles a 
1202         // l ensemble des edges qui limitent la face.
1203         //
1204         //------------------------------------------------------------
1205         EdgeVertices(TopoDS::Edge(CurrentProf),VCF,VCL);
1206
1207         TopTools_ListIteratorOfListOfShape itl;
1208         const TopTools_ListOfShape& LF = myMap(CurrentSpine)(VCF);
1209
1210         TopAbs_Orientation Ori = OriEdgeInFace(TopoDS::Edge(LF.First()),
1211                                                CurrentFace);
1212         for (itl.Initialize(LF), itl.Next(); itl.More(); itl.Next()) {
1213           TopoDS_Edge RE = TopoDS::Edge(itl.Value());
1214           MapBis(CurrentFace).Append(RE.Oriented(Ori));
1215         }
1216         const TopTools_ListOfShape& LL = myMap(CurrentSpine)(VCL);        
1217         Ori = OriEdgeInFace(TopoDS::Edge(LL.First()),CurrentFace);
1218         for (itl.Initialize(LL), itl.Next() ; itl.More(); itl.Next()) {  
1219           TopoDS_Edge RE = TopoDS::Edge(itl.Value());
1220           MapBis(CurrentFace).Append(RE.Oriented(Ori));
1221         }
1222         
1223         //Decoupe de la face.
1224         TopTools_SequenceOfShape  S;
1225
1226         TrimFace (CurrentFace, MapBis(CurrentFace), S);
1227
1228         for (Standard_Integer ii = 1; ii <= S.Length(); ii++) {
1229           myBuilder.Add (myShape,S.Value(ii));
1230           myMap(CurrentSpine)(CurrentProf).Append(S.Value(ii));
1231         }
1232       }
1233     }
1234     //-----------------------------------------------------------------
1235     // Suppression premiere edge (edge d origine)des listes de myMap 
1236     // correspondant aux vertex du profil.
1237     //-----------------------------------------------------------------
1238     TopExp_Explorer Explo(myProfile,TopAbs_VERTEX);
1239     TopTools_MapOfShape vmap;
1240
1241     for ( ; Explo.More(); Explo.Next()){
1242       if (vmap.Add(Explo.Current())) {
1243         myMap(CurrentSpine)(Explo.Current()).RemoveFirst();
1244       }
1245     }
1246   }      
1247   myIsDone = Standard_True;
1248
1249 #ifdef DRAW  
1250   if (AffichEdge) {       
1251     cout <<" Fin de construction d un volevo elementaire."<<endl;           
1252     sprintf(name,"VEVO_%d",++NbVEVOS);  
1253     DBRep::Set(name,myShape);
1254   }
1255 #endif
1256 }
1257
1258 //=======================================================================
1259 //function : PlanarPerform
1260 //purpose  : 
1261 //=======================================================================
1262
1263 void BRepFill_Evolved::PlanarPerform (const TopoDS_Face&              Sp,
1264                                       const TopoDS_Wire&              Pr,
1265                                       const BRepMAT2d_BisectingLocus& Locus,
1266                                             BRepMAT2d_LinkTopoBilo&   Link,
1267                                       const GeomAbs_JoinType          Join)
1268 {
1269   TopoDS_Shape aLocalShape = Sp.Oriented(TopAbs_FORWARD);
1270   mySpine   = TopoDS::Face(aLocalShape);
1271 //  mySpine   = TopoDS::Face(Sp.Oriented(TopAbs_FORWARD));
1272   myProfile = Pr;
1273   myMap.Clear();
1274
1275   BRep_Builder B;
1276   B.MakeCompound(TopoDS::Compound(myShape));
1277    
1278   BRepTools_WireExplorer             ProfExp;
1279   TopExp_Explorer                    Exp,exp1,exp2;
1280   TopoDS_Shape                       Rest;
1281   TopTools_DataMapOfShapeListOfShape EmptyMap;
1282   TopTools_ListOfShape               EmptyList;
1283   TopTools_DataMapOfShapeShape       MapVP;
1284   BRepFill_OffsetWire                Paral;
1285
1286   for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){
1287     const TopoDS_Edge& E = ProfExp.Current();
1288     BRepAlgo_FaceRestrictor FR;
1289     BRepFill_OffsetAncestors OffAnc;
1290
1291     TopoDS_Vertex V[2];
1292     EdgeVertices(E,V[0],V[1]);
1293     Standard_Real Alt = Altitud(V[0]);
1294     Standard_Real Offset[2];
1295     Offset[0] = DistanceToOZ(V[0]);
1296     Offset[1] = DistanceToOZ(V[1]);
1297     Standard_Boolean IsMinV1 = ( Offset[0] < Offset[1]);
1298
1299     for (Standard_Integer i = 0; i <= 1; i++) {
1300       if (!MapVP.IsBound(V[i])) {
1301         //------------------------------------------------
1302         // Calcul des paralleles correspondant aux vertex.
1303         //------------------------------------------------
1304         Paral.PerformWithBiLo(mySpine,Offset[i],Locus,Link,Join,Alt);
1305         OffAnc.Perform(Paral);
1306         MapVP.Bind(V[i],Paral.Shape());
1307
1308         //-----------------------------
1309         // Mise a jour myMap (.)(V[i])
1310         //-----------------------------
1311         for (Exp.Init(Paral.Shape(),TopAbs_EDGE);
1312              Exp.More();
1313              Exp.Next()) {
1314           const TopoDS_Edge& WC = TopoDS::Edge(Exp.Current());
1315           const TopoDS_Shape& GS = OffAnc.Ancestor(WC);
1316           if ( !myMap.IsBound(GS)) 
1317             myMap.Bind(GS, EmptyMap);
1318           if ( !myMap(GS).IsBound(V[i]))
1319             myMap(GS).Bind(V[i],Paral.GeneratedShapes(GS));
1320         }
1321       }
1322       TopoDS_Shape Rest = MapVP(V[i]);
1323       
1324       Standard_Boolean ToReverse = Standard_False;
1325        if ( ( IsMinV1 && (i==1)) || (!IsMinV1 && (i==0)) )
1326         ToReverse = Standard_True;
1327
1328       if (!Rest.IsNull()) {
1329         if (Rest.ShapeType() == TopAbs_WIRE) {
1330           if ( ToReverse){
1331             TopoDS_Shape aLocalShape  = Rest.Reversed();
1332             TopoDS_Wire aWire = TopoDS::Wire(aLocalShape);
1333             FR.Add(aWire);
1334           }       
1335           else
1336             FR.Add(TopoDS::Wire(Rest));
1337         }
1338         else {
1339           for (Exp.Init(Rest,TopAbs_WIRE);Exp.More();Exp.Next()) {
1340             TopoDS_Wire WCop = TopoDS::Wire(Exp.Current());
1341             if ( ToReverse){
1342               TopoDS_Shape aLocalShape = WCop.Reversed();
1343               TopoDS_Wire bWire =   TopoDS::Wire(aLocalShape);
1344 //            TopoDS_Wire bWire =   TopoDS::Wire(WCop.Reversed());
1345               FR.Add(bWire);
1346             }       
1347             else
1348               FR.Add(WCop);
1349           }
1350         }
1351       }
1352     }
1353 #ifdef DRAW  
1354     if (AffichEdge) {     
1355       TopTools_DataMapIteratorOfDataMapOfShapeShape it(MapVP);
1356       Standard_Integer k = 0;
1357       for (; it.More(); it.Next()) {
1358         sprintf(name,"PARALI_%d",++k);  
1359         DBRep::Set(name,it.Value());
1360       }
1361     }
1362 #endif
1363
1364     //----------------------------------------------------
1365     // Construction des faces limitees par les paralleles.
1366     // - mise a hauteur de la face support.
1367     //----------------------------------------------------
1368     gp_Trsf T; T.SetTranslation(gp_Vec(0,0,Alt));
1369     TopLoc_Location LT(T);
1370     TopoDS_Shape aLocalShape = mySpine.Moved(LT);
1371     FR.Init(TopoDS::Face(aLocalShape));
1372 //    FR.Init(TopoDS::Face(mySpine.Moved(LT)));
1373     FR.Perform();
1374
1375     for ( ;FR.More(); FR.Next()) {
1376       const TopoDS_Face& F = FR.Current();
1377       B.Add(myShape,F);
1378       //---------------------------------------
1379       // Mise a jour myMap(.)(E)
1380       //---------------------------------------
1381       for ( Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1382         const TopoDS_Edge& CE = TopoDS::Edge(Exp.Current());
1383         if (OffAnc.HasAncestor(CE)) {
1384           const TopoDS_Shape& InitE = OffAnc.Ancestor(CE);
1385           if ( !myMap.IsBound(InitE)) 
1386             myMap.Bind(InitE, EmptyMap);
1387           if ( !myMap(InitE).IsBound(E))
1388             myMap(InitE).Bind(E,EmptyList);
1389           myMap(InitE)(E).Append(F);
1390         }
1391       }
1392     }
1393   }  // Fin boucle sur profil.
1394 }
1395
1396
1397 //=======================================================================
1398 //function : VerticalPerform
1399 //purpose  : 
1400 //=======================================================================
1401
1402 void BRepFill_Evolved::VerticalPerform (const TopoDS_Face&              Sp,
1403                                         const TopoDS_Wire&              Pr,
1404                                         const BRepMAT2d_BisectingLocus& Locus,
1405                                               BRepMAT2d_LinkTopoBilo&   Link,
1406                                         const GeomAbs_JoinType          Join)
1407 {
1408   TopoDS_Shape aLocalShape = Sp.Oriented(TopAbs_FORWARD);
1409   mySpine   = TopoDS::Face(aLocalShape);
1410 //  mySpine   = TopoDS::Face(Sp.Oriented(TopAbs_FORWARD));
1411   myProfile = Pr;
1412   myMap.Clear();
1413
1414   BRep_Builder B;
1415   B.MakeCompound(TopoDS::Compound(myShape));
1416    
1417   BRepTools_WireExplorer   ProfExp;
1418   TopExp_Explorer          Exp;
1419   BRepFill_OffsetWire      Paral;
1420   BRepFill_OffsetAncestors OffAnc;
1421   TopoDS_Vertex            V1,V2;
1422
1423   Standard_Boolean First = Standard_True;
1424   TopoDS_Shape     Base;
1425   TopTools_DataMapOfShapeListOfShape  EmptyMap;
1426
1427   for (ProfExp.Init(myProfile); ProfExp.More(); ProfExp.Next()){
1428     const TopoDS_Edge& E = ProfExp.Current();
1429     EdgeVertices(E,V1,V2);
1430     Standard_Real Alt1 = Altitud(V1);
1431     Standard_Real Alt2 = Altitud(V2);
1432
1433      if (First) {
1434       Standard_Real Offset = DistanceToOZ(V1);
1435       if (Abs(Offset) < BRepFill_Confusion()) {
1436         Offset = 0.;
1437       }
1438       Paral.PerformWithBiLo(mySpine,Offset,Locus,Link,Join,Alt1);   
1439       OffAnc.Perform(Paral);
1440       Base = Paral.Shape();
1441       
1442       // MAJ myMap
1443       for (Exp.Init(Base,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1444         const TopoDS_Edge&  E  = TopoDS::Edge(Exp.Current());
1445         const TopoDS_Shape& AE =  OffAnc.Ancestor(E);
1446         if (!myMap.IsBound(AE)) {
1447           myMap.Bind(AE,EmptyMap);
1448         }
1449         if (!myMap(AE).IsBound(V1)) {
1450           TopTools_ListOfShape L;
1451           myMap(AE).Bind(V1,L);
1452         }
1453         myMap(AE)(V1).Append(E);
1454       }
1455       First = Standard_False;
1456     }
1457     
1458     
1459 #ifdef DRAW  
1460     if (AffichEdge) {     
1461       sprintf(name,"PARALI_%d",++NbVEVOS);      
1462       DBRep::Set(name,Base);
1463     }
1464 #endif
1465     
1466     BRepSweep_Prism PS(Base,gp_Vec(0,0,Alt2 - Alt1),Standard_False);
1467 #ifdef DRAW  
1468     if (AffichEdge) {     
1469       sprintf(name,"PRISM_%d",NbVEVOS); 
1470       DBRep::Set(name,PS.Shape());
1471     }
1472 #endif
1473
1474     Base = PS.LastShape();
1475     
1476     for (Exp.Init(PS.Shape(),TopAbs_FACE); Exp.More(); Exp.Next()) {
1477       B.Add(myShape,Exp.Current());
1478     }
1479     
1480     // MAJ myMap
1481     BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape 
1482       it(myMap);
1483     
1484     for (; it.More(); it.Next()) {
1485       const TopTools_ListOfShape& LOF = it.Value()(V1);
1486       TopTools_ListIteratorOfListOfShape itLOF(LOF);
1487       if (!myMap(it.Key()).IsBound(V2)) {
1488         TopTools_ListOfShape L;
1489         myMap(it.Key()).Bind(V2,L);
1490       }
1491       
1492       if (!myMap(it.Key()).IsBound(E)) {
1493         TopTools_ListOfShape L;
1494         myMap(it.Key()).Bind(E,L);
1495       }
1496
1497       for (; itLOF.More(); itLOF.Next()) {
1498         const TopoDS_Shape& OS = itLOF.Value();
1499         myMap(it.Key())(V2).Append(PS.LastShape(OS));
1500         myMap(it.Key())(E).Append(PS.Shape(OS));
1501       }
1502     }
1503   }
1504 }
1505
1506 //=======================================================================
1507 //function : Bubble
1508 //purpose  : Ordonne la sequence de point en x croissant. 
1509 //=======================================================================
1510
1511 static void Bubble(TColStd_SequenceOfReal& Seq) 
1512 {
1513   Standard_Boolean Invert = Standard_True;
1514   Standard_Integer NbPoints = Seq.Length();
1515
1516   while (Invert) {
1517     Invert = Standard_False;
1518     for ( Standard_Integer i = 1; i < NbPoints; i++) {
1519       if ( Seq.Value(i+1) < Seq.Value(i)) {
1520         Seq.Exchange(i,i+1);
1521         Invert = Standard_True;
1522       }
1523     }
1524   }
1525 }
1526
1527
1528 //=======================================================================
1529 //function : PrepareProfile
1530 //purpose  : - Projection du profil dans le plan de travail.
1531 //           - Decoupe du profil aux extrema de distance du profil
1532 //           a l axe Oz.
1533 //           - On isole les parties verticales et horizontales.
1534 //           - Reconstruction de wires a partir des edges decoupees.
1535 //           Les nouveaux wires stockes dans <WorkProf> sont toujours du
1536 //           meme cote de l axe OZ ou sont confondus avec celui-ci
1537 //=======================================================================
1538
1539 void BRepFill_Evolved::PrepareProfile(TopTools_ListOfShape&         WorkProf, 
1540                                       TopTools_DataMapOfShapeShape& MapProf  ) 
1541 const 
1542 {
1543   // Le profil est suppose place de telle sorte que la seule transformation 
1544   // a effectuer soit une projection dans le plan yOz.
1545
1546   // initialise the projection Plane and the Line to evaluate the extrema.
1547   Handle(Geom_Plane) Plane = new Geom_Plane(gp_Ax3(gp::YOZ()));
1548   Handle(Geom2d_Line) Line = new Geom2d_Line(gp::OY2d());
1549
1550   // Map vertex initiaux -> vertex projete.
1551   TopTools_DataMapOfShapeShape MapVerRefMoved;
1552
1553   TopoDS_Vertex V1,V2,VRef1,VRef2;
1554   TopoDS_Wire   W;
1555   BRep_Builder  B;
1556   TopTools_ListOfShape WP;
1557   B.MakeWire(W);
1558   WP.Append(W);
1559
1560   BRepTools_WireExplorer Exp(myProfile) ;
1561
1562   while (Exp.More()) {
1563     TopTools_ListOfShape Cuts;
1564     Standard_Boolean     NewWire = Standard_False;
1565     const TopoDS_Edge&   E = TopoDS::Edge(Exp.Current());
1566
1567     // Decoupe de l edge.
1568     CutEdgeProf (E ,Plane ,Line ,Cuts ,MapVerRefMoved);
1569
1570     EdgeVertices(E,VRef1,VRef2);
1571
1572     if ( Cuts.IsEmpty()) { 
1573       // Pas d extrema ni d intersections ni de vertex sur l axe.
1574       B.Add(W,E);
1575       MapProf.Bind(E,E);
1576     }
1577     else {
1578       while (!Cuts.IsEmpty()) {
1579         const TopoDS_Edge& NE = TopoDS::Edge(Cuts.First());
1580         MapProf.Bind(NE,E);
1581         EdgeVertices(NE,V1,V2);
1582         if (!MapProf.IsBound(V1)) MapProf.Bind(V1,E);
1583         if (!MapProf.IsBound(V2)) MapProf.Bind(V2,E);
1584
1585         B.Add(W,NE);
1586         Cuts.RemoveFirst();
1587
1588         if (DistanceToOZ(V2) < BRepFill_Confusion() &&
1589             DistanceToOZ(V1) > BRepFill_Confusion()) {
1590           // NE se termine sur l axe OZ => nouveau wire
1591           if (Cuts.IsEmpty()) {
1592             // derniere portion de l edge courante
1593             // Si ce n est pas le dernier edge de myProfile 
1594             // on creera un nouveau wire.
1595             NewWire = Standard_True;
1596           }
1597           else {
1598             // Nouveau wire.
1599             B.MakeWire(W);
1600             WP.Append(W);
1601           }
1602         }
1603       }
1604     }
1605     Exp.Next();
1606     if (Exp.More() && NewWire) {
1607       B.MakeWire(W);
1608       WP.Append(W);
1609     }
1610   }
1611
1612   // Dans la liste des Wires, on cherche les edges generant des vevo plans
1613   // ou verticaux.
1614   TopTools_ListIteratorOfListOfShape ite;
1615   TopoDS_Wire CurW,NW;
1616   TopExp_Explorer EW;
1617   
1618
1619   for (ite.Initialize(WP); ite.More(); ite.Next()) {
1620     CurW = TopoDS::Wire(ite.Value());
1621     Standard_Boolean YaModif = Standard_False;
1622     for (EW.Init(CurW,TopAbs_EDGE); EW.More(); EW.Next()) {
1623       const TopoDS_Edge& EE = TopoDS::Edge(EW.Current());
1624       if (IsVertical(EE) || IsPlanar(EE)) {
1625         YaModif = Standard_True;
1626         break;
1627       }
1628     }
1629     
1630     if (YaModif) {
1631       //Status = 0 for the begining
1632       //         3 vertical
1633       //         2 horizontal
1634       //         1 other
1635       Standard_Integer Status = 0; 
1636                                     
1637       for (EW.Init(CurW,TopAbs_EDGE); EW.More(); EW.Next()) {
1638         const TopoDS_Edge& EE = TopoDS::Edge(EW.Current());
1639         if (IsVertical(EE)) {
1640           if (Status != 3) {
1641             B.MakeWire(NW);
1642             WorkProf.Append(NW);
1643             Status = 3;
1644           }
1645         }
1646         else if (IsPlanar(EE)) {
1647           if (Status != 2) {
1648             B.MakeWire(NW);
1649             WorkProf.Append(NW);
1650             Status = 2;
1651           }
1652         }
1653         else if ( Status != 1) {
1654           B.MakeWire(NW);
1655           WorkProf.Append(NW);
1656           Status = 1;
1657         }
1658         B.Add(NW,EE);
1659       }
1660     }
1661     else {
1662       WorkProf.Append(CurW);
1663     }
1664   }
1665
1666   //bind des vertex modifies dans MapProf;
1667   TopTools_DataMapIteratorOfDataMapOfShapeShape gilbert(MapVerRefMoved);
1668   for ( ;gilbert.More() ;gilbert.Next()) {
1669     MapProf.Bind(gilbert.Value(),gilbert.Key());
1670   }
1671 }
1672
1673
1674 //=======================================================================
1675 //function : PrepareSpine
1676 //purpose  : 
1677 //=======================================================================
1678
1679 void BRepFill_Evolved::PrepareSpine(TopoDS_Face&                 WorkSpine, 
1680                                     TopTools_DataMapOfShapeShape& MapSpine) 
1681 const
1682 {
1683   BRep_Builder      B;
1684   TopTools_ListOfShape Cuts;
1685   TopTools_ListIteratorOfListOfShape IteCuts;
1686   TopoDS_Vertex V1,V2;
1687   
1688   TopLoc_Location L;
1689   const Handle(Geom_Surface)& S    = BRep_Tool::Surface  (mySpine,L);
1690   Standard_Real               TolF = BRep_Tool::Tolerance(mySpine);
1691   B.MakeFace(WorkSpine,S,L,TolF);
1692   
1693   for (TopoDS_Iterator IteF(mySpine) ; IteF.More(); IteF.Next()) {
1694
1695     TopoDS_Wire NW;
1696     B.MakeWire (NW);
1697
1698     for (TopoDS_Iterator IteW(IteF.Value()); IteW.More(); IteW.Next()) {
1699       
1700       const TopoDS_Edge& E = TopoDS::Edge(IteW.Value());
1701       EdgeVertices(E,V1,V2);
1702       MapSpine.Bind(V1,V1);
1703       MapSpine.Bind(V2,V2);
1704       Cuts.Clear();
1705
1706       // Decoupe
1707       CutEdge (E, mySpine, Cuts);
1708       
1709       if (Cuts.IsEmpty()) {
1710         B.Add(NW,E);
1711         MapSpine.Bind(E,E);
1712       }
1713       else {    
1714         for (IteCuts.Initialize(Cuts); IteCuts.More(); IteCuts.Next()) {
1715           const TopoDS_Edge& NE = TopoDS::Edge(IteCuts.Value());
1716           B.Add(NW,NE);
1717           MapSpine.Bind(NE,E);
1718           EdgeVertices(NE,V1,V2);
1719           if (!MapSpine.IsBound(V1)) MapSpine.Bind(V1,E);
1720           if (!MapSpine.IsBound(V2)) MapSpine.Bind(V2,E);
1721         }
1722       }
1723     }
1724     B.Add(WorkSpine, NW);
1725   }
1726
1727   // On construit les courbes 3d de la spine Sinon aux fraise
1728   BRepLib::BuildCurves3d(WorkSpine);
1729
1730 #ifdef DRAW
1731   if (AffichEdge) {
1732     sprintf(name,"workspine");  
1733     DBRep::Set(name,WorkSpine);
1734   }
1735 #endif 
1736
1737 }
1738 //=======================================================================
1739 //function : GeneratedShapes
1740 //purpose  : 
1741 //=======================================================================
1742
1743 const TopoDS_Shape&  BRepFill_Evolved::Top() const 
1744 {
1745   return myTop;
1746 }
1747
1748 //=======================================================================
1749 //function : GeneratedShapes
1750 //purpose  : 
1751 //=======================================================================
1752
1753 const TopoDS_Shape&  BRepFill_Evolved::Bottom() const 
1754 {
1755   return myBottom;
1756 }
1757
1758 //=======================================================================
1759 //function : GeneratedShapes
1760 //purpose  : 
1761 //=======================================================================
1762
1763 const TopTools_ListOfShape&  BRepFill_Evolved::GeneratedShapes ( 
1764    const TopoDS_Shape& SpineShape,
1765    const TopoDS_Shape& ProfShape )
1766 const 
1767 {
1768   if (myMap            .IsBound(SpineShape) &&
1769       myMap(SpineShape).IsBound(ProfShape)     ) {
1770     return myMap(SpineShape)(ProfShape);
1771   }
1772   else {
1773     static TopTools_ListOfShape Empty;
1774     return Empty;
1775   }
1776 }
1777
1778 //=======================================================================
1779 //function : Generated
1780 //purpose  : 
1781 //=================================================================== ====
1782
1783 BRepFill_DataMapOfShapeDataMapOfShapeListOfShape& BRepFill_Evolved::Generated()
1784 {
1785   return myMap;
1786 }
1787
1788 //=======================================================================
1789 //function : Compare
1790 //purpose  : 
1791 //=======================================================================
1792
1793 static TopAbs_Orientation Compare (const TopoDS_Edge& E1,
1794                                    const TopoDS_Edge& E2) 
1795 {
1796   TopAbs_Orientation OO = TopAbs_FORWARD;
1797   TopoDS_Vertex V1[2],V2[2];
1798   TopExp::Vertices (E1,V1[0],V1[1]);
1799   TopExp::Vertices (E2,V2[0],V2[1]);
1800   gp_Pnt P1 = BRep_Tool::Pnt(V1[0]);
1801   gp_Pnt P2 =BRep_Tool::Pnt(V2[0]);
1802   gp_Pnt P3 =BRep_Tool::Pnt(V2[1]);
1803   if (P1.Distance(P3) < P1.Distance(P2)) OO = TopAbs_REVERSED; 
1804
1805   return OO;
1806 }
1807
1808 //=======================================================================
1809 //function : Add
1810 //purpose  : 
1811 //=======================================================================
1812
1813 void BRepFill_Evolved::Add(      BRepFill_Evolved& Vevo, 
1814                            const TopoDS_Wire&      Prof,
1815                                  BRepTools_Quilt&  Glue)                
1816
1817 {  
1818   BRepFill_DataMapOfShapeDataMapOfShapeListOfShape& MapVevo = Vevo.Generated();
1819   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape                  iteP;
1820   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape    iteS;
1821   TopoDS_Shape CurrentSpine, CurrentProf;
1822
1823   if (Vevo.Shape().IsNull()) return;
1824
1825   //-------------------------------------------------
1826   // Recherche des wires communs a <me> et a <Vevo>.
1827   //-------------------------------------------------
1828
1829   TopExp_Explorer ExProf;
1830   for (ExProf.Init(Prof,TopAbs_VERTEX); ExProf.More(); ExProf.Next()) {
1831     const TopoDS_Shape& VV = ExProf.Current();
1832      //---------------------------------------------------------------
1833     // Parcours des edge generes par VV dans myMap si elles existent 
1834     // et Bind dans Glue
1835     //---------------------------------------------------------------
1836    
1837     //------------------------------------------------- -------------
1838     // Remarque les courbes des edges a bindes sont dans le meme sens.
1839     //          si on reste du meme cote.
1840     //          si on passe de gauche a droite elles sont inversees.
1841     //------------------------------------------------- -------------
1842 #ifndef DEB
1843     Standard_Boolean   Commun = Standard_False;
1844 #else
1845     Standard_Boolean   Commun;
1846 #endif
1847 #ifdef DEB
1848     TopAbs_Orientation OriSide = 
1849 #endif
1850       Relative(myProfile,Prof,
1851                TopoDS::Vertex(VV),
1852                Commun);
1853
1854     if (Commun) {
1855       for (iteS.Initialize(myMap); iteS.More(); iteS.Next()) {
1856         const TopoDS_Shape& SP = iteS.Key();
1857         if (iteS.Value().IsBound(VV) && 
1858             MapVevo.IsBound(SP) && MapVevo(SP).IsBound(VV)) {
1859           
1860           const TopTools_ListOfShape& MyList   = myMap(SP)(VV);
1861           const TopTools_ListOfShape& VevoList = Vevo.GeneratedShapes(SP,VV);
1862           TopTools_ListIteratorOfListOfShape MyIte  (MyList);
1863           TopTools_ListIteratorOfListOfShape VevoIte(VevoList);
1864           for (; MyIte.More(); MyIte.Next(), VevoIte.Next()) {
1865             const TopoDS_Edge& ME = TopoDS::Edge(MyIte  .Value());
1866             const TopoDS_Edge& VE = TopoDS::Edge(VevoIte.Value());
1867             TopAbs_Orientation OG = Compare(ME,VE);
1868             TopoDS_Shape aLocalShape  = VE.Oriented (TopAbs_FORWARD);
1869             TopoDS_Shape aLocalShape2 = ME.Oriented (OG);
1870             Glue.Bind(TopoDS::Edge(aLocalShape),TopoDS::Edge(aLocalShape2));
1871 //          Glue.Bind(TopoDS::Edge(VE.Oriented (TopAbs_FORWARD)),
1872 //                    TopoDS::Edge(ME.Oriented (OG)));
1873           }
1874         }
1875       }
1876     }
1877   }
1878   Glue.Add(Vevo.Shape());
1879
1880   //----------------------------------------------------------
1881   // Ajout de la map des elements generes dans Vevo dans myMap.
1882   //----------------------------------------------------------
1883   TopTools_DataMapOfShapeListOfShape        EmptyMap;
1884   TopTools_ListOfShape                      EmptyList;
1885
1886   for (iteS.Initialize(MapVevo); iteS.More() ; iteS.Next()) {
1887     CurrentSpine = iteS.Key();
1888     for (iteP.Initialize(MapVevo(CurrentSpine)); iteP.More(); iteP.Next()) {
1889       CurrentProf  = iteP.Key();
1890       if (!myMap.IsBound(CurrentSpine)) {
1891         //------------------------------------------------
1892         // L element du spine n etait pas encore present .
1893         // => profil precedent pas sur le bord.
1894         //-------------------------------------------------
1895         myMap.Bind(CurrentSpine,EmptyMap);
1896       }
1897       if (!myMap(CurrentSpine).IsBound(CurrentProf)) {
1898         myMap(CurrentSpine).Bind(CurrentProf,EmptyList);      
1899         const TopTools_ListOfShape& GenShapes 
1900           = MapVevo (CurrentSpine)(CurrentProf);
1901         TopTools_ListIteratorOfListOfShape itl (GenShapes);
1902         for (; itl.More(); itl.Next()) {
1903           // lors de Glue.Add les shapes partages son recrees.
1904           if (Glue.IsCopied(itl.Value())) 
1905             myMap(CurrentSpine)(CurrentProf).Append(Glue.Copy(itl.Value()));
1906           else
1907             myMap(CurrentSpine)(CurrentProf).Append(itl.Value());
1908         }
1909       }
1910     }
1911   }
1912 }
1913
1914 //=======================================================================
1915 //function : ChangeShape
1916 //purpose  : 
1917 //=======================================================================
1918
1919 TopoDS_Shape&  BRepFill_Evolved::ChangeShape()
1920 {
1921   return myShape;
1922 }
1923
1924 //=======================================================================
1925 //function : Transfert
1926 //purpose  : 
1927 //=======================================================================
1928
1929 void BRepFill_Evolved::Transfert(      BRepFill_Evolved&             Vevo, 
1930                                  const TopTools_DataMapOfShapeShape& MapProf, 
1931                                  const TopTools_DataMapOfShapeShape& MapSpine,
1932                                  const TopLoc_Location&              LS,
1933                                  const TopLoc_Location&              InitLS,
1934                                  const TopLoc_Location&              InitLP)
1935 {  
1936   //--------------------------------------------------------------
1937   // Transfert du shape de Vevo dans myShape et Repositionnement
1938   // des shapes.
1939   //--------------------------------------------------------------
1940   myShape = Vevo.Shape();
1941   mySpine  .Location(InitLS); 
1942   myProfile.Location(InitLP);
1943   myShape  .Move    (LS);
1944
1945   //
1946   // En attendant mieux, on force le Same Parameter ici 
1947   //  ( Pb Sameparameter entre YaPlanar et Tuyaux 
1948   //
1949   BRep_Builder B;
1950   TopExp_Explorer ex(myShape,TopAbs_EDGE);
1951   while (ex.More()) {
1952     B.SameRange(TopoDS::Edge(ex.Current()), Standard_False);
1953     B.SameParameter(TopoDS::Edge(ex.Current()), Standard_False);
1954     BRepLib::SameParameter(TopoDS::Edge(ex.Current()));
1955     ex.Next();
1956   }
1957
1958
1959   //--------------------------------------------------------------
1960   // Transfert de myMap de Vevo dans myMap.
1961   //--------------------------------------------------------------
1962   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape iteS;
1963   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape               iteP; 
1964   TopTools_DataMapOfShapeListOfShape EmptyMap;
1965   TopTools_ListOfShape               EmptyList;
1966   TopoDS_Shape                       InitialSpine, InitialProf;
1967
1968   BRepFill_DataMapOfShapeDataMapOfShapeListOfShape& MapVevo 
1969     = Vevo.Generated();
1970
1971   for (iteS.Initialize(MapVevo); iteS.More(); iteS.Next()) {
1972     InitialSpine = MapSpine(iteS.Key());
1973     InitialSpine.Move(LS);
1974
1975     for (iteP.Initialize(MapVevo(iteS.Key())); iteP.More(); iteP.Next()) {
1976       InitialProf  = MapProf (iteP.Key());
1977       InitialProf.Location(InitLP);
1978
1979       TopTools_ListOfShape& GenShapes = 
1980         MapVevo.ChangeFind(iteS.Key()).ChangeFind(iteP.Key());
1981
1982       TopTools_ListIteratorOfListOfShape itl;
1983       for (itl.Initialize(GenShapes); itl.More(); itl.Next()) {
1984         itl.Value().Move(LS);
1985       }
1986
1987       if (!myMap.IsBound(InitialSpine)) {
1988         myMap.Bind(InitialSpine,EmptyMap);
1989       }
1990      
1991       if (!myMap(InitialSpine).IsBound(InitialProf)) {
1992         myMap(InitialSpine).Bind(InitialProf,EmptyList);
1993       }
1994       myMap(InitialSpine)(InitialProf).Append(GenShapes);
1995     }
1996   }
1997   //--------------------------------------------------------------
1998   // Transfert de Top et Bottom de Vevo dans myTop et myBottom.
1999   //--------------------------------------------------------------
2000   myTop    = Vevo.Top()   ; myTop.Move(LS);
2001   myBottom = Vevo.Bottom(); myBottom.Move(LS);
2002 }
2003
2004 //=======================================================================
2005 //function : IsDone
2006 //purpose  : 
2007 //=======================================================================
2008
2009 Standard_Boolean BRepFill_Evolved::IsDone() const 
2010 {
2011   return myIsDone;
2012 }
2013
2014 //=======================================================================
2015 //function : Shape
2016 //purpose  : 
2017 //=======================================================================
2018
2019 const TopoDS_Shape& BRepFill_Evolved::Shape() const 
2020 {
2021   return myShape;
2022 }
2023
2024 //=======================================================================
2025 //function : JoinType
2026 //purpose  : 
2027 //=======================================================================
2028
2029 GeomAbs_JoinType BRepFill_Evolved::JoinType() const 
2030 {
2031   return myJoinType;
2032 }
2033
2034 //=======================================================================
2035 //function : AddTopAndBottom
2036 //purpose  : 
2037 //=======================================================================
2038
2039 void BRepFill_Evolved::AddTopAndBottom(BRepTools_Quilt& Glue)
2040 {  
2041 //  recuperation premier et dernier vertex du profil.
2042   TopoDS_Vertex V[2];
2043   TopExp::Vertices (myProfile,V[0],V[1]);
2044   if (V[0].IsSame(V[1])) return;
2045
2046   TopTools_ListIteratorOfListOfShape itL;
2047   Standard_Boolean ToReverse=Standard_False;
2048   for (Standard_Integer i = 0; i<=1; i++) {
2049     
2050     BRepAlgo_Loop Loop;
2051     // Construction des supports.
2052     gp_Pln S (0.,0.,1.,- Altitud(V[i]));
2053     TopoDS_Face F = BRepLib_MakeFace(S);
2054     Loop.Init(F);
2055
2056     TopExp_Explorer     ExpSpine(mySpine,TopAbs_EDGE);
2057     TopTools_MapOfShape View;
2058
2059     for (; ExpSpine.More(); ExpSpine.Next()) {
2060       const TopoDS_Edge& ES = TopoDS::Edge(ExpSpine.Current());
2061       const TopTools_ListOfShape& L = GeneratedShapes(ES,V[i]);
2062       Standard_Boolean ComputeOrientation = 0;
2063
2064       for (itL.Initialize(L); itL.More(); itL.Next()) {
2065         const TopoDS_Edge& E = TopoDS::Edge(itL.Value());
2066         
2067         if (!ComputeOrientation) {
2068           BRepAdaptor_Curve C1(ES);
2069           BRepAdaptor_Curve C2(E);
2070           Standard_Real f,l,fs,ls;
2071           BRep_Tool::Range(E ,f ,l);
2072           BRep_Tool::Range(ES,fs,ls);
2073           Standard_Real u  = 0.3*f  + 0.7*l;
2074           Standard_Real us = 0.3*fs + 0.7*ls;
2075           gp_Pnt P;
2076           gp_Vec V1,V2;
2077           C1.D1(us,P,V1); C2.D1(u,P,V2);
2078           ToReverse = (V1.Dot(V2) < 0.);
2079           ComputeOrientation = 1;
2080         }
2081         
2082         TopAbs_Orientation Or = ES.Orientation();
2083         if (ToReverse) Or = TopAbs::Reverse(Or);
2084         TopoDS_Shape aLocalShape = E.Oriented(Or);
2085         Loop.AddConstEdge(TopoDS::Edge(aLocalShape));
2086 //      Loop.AddConstEdge(TopoDS::Edge(E.Oriented(Or)));
2087       }
2088     }
2089
2090     gp_Pnt PV = BRep_Tool::Pnt(V[i]);
2091     Standard_Boolean IsOut = PV.Y() < 0;
2092     
2093     for (ExpSpine.Init(mySpine,TopAbs_VERTEX); ExpSpine.More(); ExpSpine.Next()) {
2094       const TopoDS_Vertex& ES = TopoDS::Vertex(ExpSpine.Current());
2095       if (View.Add(ES)) {
2096         const TopTools_ListOfShape& L = GeneratedShapes(ES,V[i]);
2097         for (itL.Initialize(L); itL.More(); itL.Next()) {
2098           const TopoDS_Edge& E = TopoDS::Edge(itL.Value());
2099           if (!BRep_Tool::Degenerated(E)){
2100             // le centre du cercle (ie le vertex) est IN le bouchon si vertex IsOut
2101             //                                        OUT                     !IsOut
2102             BRepAdaptor_Curve C(E);
2103             Standard_Real f,l;
2104             BRep_Tool::Range(E,f,l);
2105             Standard_Real u = 0.3*f + 0.7*l;
2106             gp_Pnt P = BRep_Tool::Pnt(ES);
2107             gp_Pnt PC;
2108             gp_Vec VC;
2109             C.D1(u,PC,VC);
2110             gp_Vec PPC(P,PC);
2111             gp_Vec Prod = PPC.Crossed(VC);
2112             if (IsOut) {
2113               ToReverse = Prod.Z() < 0.;
2114             }
2115             else { 
2116               ToReverse = Prod.Z() > 0.;
2117             }
2118             TopAbs_Orientation Or = TopAbs_FORWARD;
2119             if (ToReverse)     Or = TopAbs_REVERSED;
2120             TopoDS_Shape aLocalShape = E.Oriented(Or);
2121             Loop.AddConstEdge(TopoDS::Edge(aLocalShape));
2122 //          Loop.AddConstEdge(TopoDS::Edge(E.Oriented(Or)));
2123           }
2124         }
2125       }
2126     }
2127     
2128     Loop.Perform();
2129     Loop.WiresToFaces();
2130     const TopTools_ListOfShape& L = Loop.NewFaces();
2131     TopTools_ListIteratorOfListOfShape itL(L);
2132     
2133     // Maj de myTop et myBottom pour l historique
2134     // et addition des faces construites.
2135     TopoDS_Compound  Bouchon;
2136     BRep_Builder     B;
2137     B.MakeCompound(Bouchon);
2138     Standard_Integer j = 0;
2139
2140     for (itL.Initialize(L); itL.More(); itL.Next()) {
2141       j++;
2142       Glue.Add(itL.Value());
2143       if (j ==1 && i == 0) myTop    = itL.Value();
2144       if (j ==1 && i == 1) myBottom = itL.Value();
2145       B.Add(Bouchon,itL.Value());
2146     }
2147     if (i == 0 && j > 1) myTop    = Bouchon;
2148     if (i == 1 && j > 1) myBottom = Bouchon;
2149   }
2150 }
2151
2152 //================================================================== =====
2153 //function : MakePipe
2154 //purpose  : 
2155 //=======================================================================
2156
2157 void BRepFill_Evolved::MakeSolid()
2158 {
2159
2160   TopExp_Explorer  exp(myShape,TopAbs_SHELL);
2161   Standard_Integer ish=0;
2162   TopoDS_Compound  Res;
2163   TopoDS_Solid     Sol;
2164   BRep_Builder     B;
2165   B.MakeCompound(Res);
2166
2167   for (; exp.More(); exp.Next()) {
2168     TopoDS_Shape Sh = exp.Current();
2169     B.MakeSolid(Sol);
2170     B.Add(Sol,Sh);
2171     BRepClass3d_SolidClassifier SC(Sol);
2172     SC.PerformInfinitePoint(BRepFill_Confusion());
2173     if (SC.State() == TopAbs_IN) {
2174       B.MakeSolid(Sol);
2175       B.Add(Sol,Sh.Reversed());
2176     }
2177     B.Add(Res,Sol);
2178     ish++;
2179   }
2180   if (ish == 1) { myShape = Sol;}
2181   else          { myShape = Res;}
2182
2183 }
2184
2185 //=======================================================================
2186 //function : MakePipe
2187 //purpose  : 
2188 //=======================================================================
2189
2190 void BRepFill_Evolved::MakePipe(const TopoDS_Edge& SE,
2191                                 const gp_Ax3&      AxeRef)
2192 {  
2193   BRepTools_WireExplorer ProfExp;
2194   TopExp_Explorer        FaceExp;
2195
2196   gp_Trsf trsf;
2197   if (Side(myProfile,BRepFill_Confusion()) > 3) { // side right 
2198     trsf.SetRotation(gp::OZ(),PI);
2199   }
2200   TopLoc_Location DumLoc (trsf);
2201   TopoDS_Shape aLocalShape = myProfile.Moved(DumLoc);
2202   TopoDS_Wire DummyProf = 
2203     PutProfilAt (TopoDS::Wire(aLocalShape),
2204                  AxeRef,SE,
2205                  mySpine,Standard_True);
2206 //  TopoDS_Wire DummyProf = 
2207 //    PutProfilAt (TopoDS::Wire(myProfile.Moved(DumLoc)),
2208 //               AxeRef,SE,
2209 //               mySpine,Standard_True);
2210
2211   // Copie du profil pour eviter l accumulation des 
2212   // locations sur les Edges de myProfile!
2213  
2214   Handle(BRepTools_TrsfModification) TrsfMod 
2215     = new BRepTools_TrsfModification(gp_Trsf());
2216   BRepTools_Modifier Modif(DummyProf,TrsfMod);
2217
2218   TopoDS_Wire GenProf = TopoDS::Wire(Modif.ModifiedShape(DummyProf));
2219
2220 #ifdef DRAW
2221   if (AffichGeom) {
2222     sprintf(name,"EVOLBASE_%d",++NbFACES);
2223     DBRep::Set(name,SE);
2224     sprintf(name,"EVOLPROF_%d",NbFACES);
2225     DBRep::Set(name,GenProf);
2226   }
2227 #endif
2228
2229 //  BRepFill_Pipe Pipe(BRepLib_MakeWire(SE),GenProf);   
2230   BRepFill_Pipe Pipe = BRepFill_Pipe(BRepLib_MakeWire(SE),GenProf);     
2231   
2232 #ifdef DRAW
2233   if (AffichGeom) {
2234     sprintf(name,"EVOL_%d",++NbFACES);
2235     DBRep::Set(name,Pipe.Shape());
2236   }
2237 #endif
2238   //---------------------------------------------
2239   // Rangement du Tuyau dans myMap.
2240   //---------------------------------------------
2241
2242   BRepTools_WireExplorer GenProfExp;
2243   TopTools_ListOfShape   L;
2244   TopoDS_Vertex          VF,VL,VFG,VLG;
2245   Standard_Boolean       FirstVertex = Standard_True;
2246   TopTools_DataMapOfShapeListOfShape  P;
2247   
2248   myMap.Bind(SE,P);
2249
2250   for (ProfExp.Init(myProfile),GenProfExp.Init(GenProf);
2251        ProfExp.More();
2252        ProfExp.Next(),GenProfExp.Next()) {
2253
2254     EdgeVertices(ProfExp   .Current(),VF ,VL);
2255     EdgeVertices(GenProfExp.Current(),VFG,VLG);
2256     
2257     if (FirstVertex) {
2258       myMap(SE).Bind(VF,L);
2259       myMap(SE)(VF).Append(Pipe.Edge(SE,VFG)); 
2260       FirstVertex = Standard_False;
2261     }
2262     myMap(SE).Bind(VL,L);
2263     myMap(SE)(VL).Append(Pipe.Edge(SE,VLG));
2264     myMap(SE).Bind(ProfExp.Current(),L);
2265     myMap(SE)(ProfExp.Current()).Append
2266       (Pipe.Face(SE,GenProfExp.Current()));
2267   }
2268 }
2269
2270
2271 //=======================================================================
2272 //function : MakeRevol
2273 //purpose  : 
2274 //=======================================================================
2275
2276 void BRepFill_Evolved::MakeRevol(const TopoDS_Edge&   SE,
2277                                  const TopoDS_Vertex& VLast,
2278                                  const gp_Ax3&        AxeRef)
2279 {  
2280   BRepTools_WireExplorer ProfExp;
2281   TopExp_Explorer        FaceExp;
2282
2283   gp_Trsf trsf;
2284   if (Side(myProfile,BRepFill_Confusion()) > 3) { // side right 
2285     trsf.SetRotation(gp::OZ(),PI);
2286   }
2287   TopLoc_Location DumLoc (trsf);
2288   TopoDS_Shape aLocalShape = myProfile.Moved(DumLoc);
2289   TopoDS_Wire GenProf = 
2290     PutProfilAt (TopoDS::Wire(aLocalShape),
2291                  AxeRef,SE,
2292                  mySpine,Standard_False);
2293 //  TopoDS_Wire GenProf = 
2294 //    PutProfilAt (TopoDS::Wire(myProfile.Moved(DumLoc)),
2295 //               AxeRef,SE,
2296 //               mySpine,Standard_False);
2297
2298   gp_Ax1 AxeRev( BRep_Tool::Pnt(VLast), -gp::DZ());  
2299
2300   // Positionnement de la couture sur l edge du spine
2301   // pour que les bissectrices ne traversent pas les coutures.
2302   gp_Trsf dummy;
2303   dummy.SetRotation(AxeRev, 1.5*PI);
2304   TopLoc_Location DummyLoc(dummy);
2305   GenProf.Move(DummyLoc);
2306   
2307   BRepSweep_Revol Rev(GenProf,AxeRev,Standard_True);
2308   
2309 #ifdef DRAW  
2310   if (AffichGeom) {
2311     sprintf(name,"EVOLBASE_%d",++NbFACES);
2312     char* Temp = name ;
2313     DrawTrSurf::Set(Temp,new Geom_Line(AxeRev));
2314 //    DrawTrSurf::Set(name,new Geom_Line(AxeRev));
2315     sprintf(name,"EVOLPROF_%d",NbFACES);
2316     DBRep::Set(name,GenProf);
2317     
2318     sprintf(name,"EVOL_%d",NbFACES);
2319     DBRep::Set(name,Rev.Shape());
2320   }
2321 #endif
2322   //--------------------------------------------
2323   // Rangement du revol dans myMap.
2324   //---------------------------------------------
2325   BRepTools_WireExplorer GenProfExp;
2326   TopTools_ListOfShape   L;
2327   TopoDS_Vertex          VF,VL,VFG,VLG;
2328   Standard_Boolean       FirstVertex = Standard_True;
2329   TopTools_DataMapOfShapeListOfShape  R;
2330   
2331   myMap.Bind(VLast,R);
2332   
2333   for (ProfExp.Init(myProfile),GenProfExp.Init(GenProf);
2334        ProfExp.More();
2335        ProfExp.Next(),GenProfExp.Next()) {
2336     
2337     EdgeVertices(ProfExp   .Current(),VF ,VL);
2338     EdgeVertices(GenProfExp.Current(),VFG,VLG);
2339     
2340     TopAbs_Orientation Or = GenProfExp.Current().Orientation();
2341
2342     if (FirstVertex) {
2343       myMap(VLast).Bind(VF,L);
2344       const TopoDS_Shape& RV = Rev.Shape(VFG);
2345 //      TopAbs_Orientation OO = TopAbs::Compose(RV.Orientation(),Or);
2346       TopAbs_Orientation OO = RV.Orientation();
2347       myMap(VLast)(VF).Append(RV.Oriented(OO));
2348       FirstVertex = Standard_False;
2349     }
2350     myMap(VLast).Bind(ProfExp.Current(),L);     
2351     const TopoDS_Shape& RF = Rev.Shape(GenProfExp.Current());
2352     TopAbs_Orientation  OO = TopAbs::Compose(RF.Orientation(),Or);
2353
2354     myMap(VLast)(ProfExp.Current()).Append(RF.Oriented(OO));
2355     myMap(VLast).Bind(VL,L);
2356     const TopoDS_Shape& RV = Rev.Shape(VLG);
2357 //    OO = TopAbs::Compose(RV.Orientation(),Or);
2358     OO = RV.Orientation();
2359     myMap(VLast)(VL).Append(RV.Oriented(OO));
2360   }
2361 }
2362
2363 //=======================================================================
2364 //function : FindLocation
2365 //purpose  : 
2366 //=======================================================================
2367
2368 TopLoc_Location BRepFill_Evolved::FindLocation(const TopoDS_Face& Face)
2369 const 
2370 {
2371   TopLoc_Location L;
2372   Handle(Geom_Surface) S;
2373   S = BRep_Tool::Surface(Face, L);
2374   
2375   if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) {
2376     BRepLib_FindSurface FS( Face, -1, Standard_True);
2377     if ( FS.Found()) {
2378       S = FS.Surface();
2379       L = FS.Location();
2380     }
2381     else
2382       Standard_NoSuchObject::Raise
2383         ("BRepFill_Evolved : The Face is not planar");
2384   }
2385   
2386   if (!L.IsIdentity())
2387     S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
2388
2389   Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(S);
2390   gp_Ax3 Axis = P->Position();
2391
2392   gp_Trsf T;
2393   gp_Ax3 AxeRef(gp_Pnt(0.,0.,0.),
2394                 gp_Dir(0.,0.,1.),
2395                 gp_Dir(1.,0.,0.));  
2396   T.SetTransformation(AxeRef,Axis);
2397
2398   return TopLoc_Location(T);
2399 }
2400
2401
2402 //=======================================================================
2403 //function : TransformInitWork
2404 //purpose  : 
2405 //=======================================================================
2406
2407 void BRepFill_Evolved::TransformInitWork(const TopLoc_Location& LS,
2408                                          const TopLoc_Location& LP)
2409 {
2410   mySpine.Move  (LS);
2411   myProfile.Move(LP);
2412
2413 #ifdef DRAW
2414   if (AffichEdge) {
2415     sprintf(name,"movedspine");
2416     TopoDS_Face SL = mySpine;
2417     DBRep::Set(name,SL);    
2418     sprintf(name,"movedprofile");
2419     TopoDS_Wire PL = myProfile;
2420     DBRep::Set(name,PL);
2421   }
2422 #endif  
2423 }
2424
2425
2426 //=======================================================================
2427 //function : ContinuityOnOffsetEdge
2428 //purpose  : Codage des regularites sur les edges paralleles de CutVevo
2429 //           communes aux parties gauches et droites du volevo.
2430 //=======================================================================
2431 void  BRepFill_Evolved::ContinuityOnOffsetEdge (const TopTools_ListOfShape& WorkProf) 
2432 {
2433   BRepTools_WireExplorer WExp ; 
2434   BRepFill_DataMapIteratorOfDataMapOfShapeDataMapOfShapeListOfShape iteS;
2435   TopoDS_Vertex          VF,VL,V;
2436   TopoDS_Edge            PrecE,CurE,FirstE;
2437   BRep_Builder           B;
2438
2439
2440   WExp.Init(myProfile);
2441   FirstE = WExp.Current();
2442   PrecE  = FirstE;
2443   EdgeVertices (FirstE, VF, V);
2444   if (WExp.More()) WExp.Next();
2445   
2446   for (; WExp.More(); WExp.Next()) {
2447     CurE = WExp.Current();
2448     V    = WExp.CurrentVertex();
2449     
2450     if (DistanceToOZ(V) <= BRepFill_Confusion()) {
2451       // les regularites sont deja codes sur les edges des volevos elementaires
2452       Standard_Real     U1 = BRep_Tool::Parameter(V,CurE);
2453       Standard_Real     U2 = BRep_Tool::Parameter(V,PrecE);
2454       BRepAdaptor_Curve Curve1(CurE);
2455       BRepAdaptor_Curve Curve2(PrecE);
2456       GeomAbs_Shape     Continuity = BRepLProp::Continuity(Curve1,Curve2,U1,U2);
2457       
2458       if (Continuity >=1) {
2459         //-----------------------------------------------------
2460         //Code continuite pour toutes les edges generes par V.
2461         //-----------------------------------------------------
2462         for (iteS.Initialize(myMap); iteS.More(); iteS.Next()) {
2463           const TopoDS_Shape& SP = iteS.Key(); 
2464           if (myMap (SP).IsBound(V) 
2465               && myMap (SP).IsBound(CurE) &&  myMap (SP).IsBound(PrecE)){
2466             if (!myMap(SP)(V)    .IsEmpty() &&
2467                 !myMap(SP)(CurE) .IsEmpty() &&
2468                 !myMap(SP)(PrecE).IsEmpty()   ) 
2469               B.Continuity (TopoDS::Edge(myMap(SP)(V)    .First()),
2470                             TopoDS::Face(myMap(SP)(CurE) .First()),
2471                             TopoDS::Face(myMap(SP)(PrecE).First()),
2472                             Continuity);
2473           }
2474         }
2475       }
2476     }
2477     PrecE = CurE;
2478   }
2479   
2480   EdgeVertices (PrecE, V, VL);
2481   
2482   if (VF.IsSame(VL)) {
2483     //Profil ferme.
2484     Standard_Real     U1 = BRep_Tool::Parameter(VF,CurE);
2485     Standard_Real     U2 = BRep_Tool::Parameter(VF,FirstE);
2486     BRepAdaptor_Curve Curve1(CurE);
2487     BRepAdaptor_Curve Curve2(FirstE);
2488     GeomAbs_Shape     Continuity = BRepLProp::Continuity(Curve1,Curve2,U1,U2);
2489     
2490     if (Continuity >=1) {
2491       //-----------------------------------------------------
2492       //Code continuite pour toutes les edges generes par V.
2493       //-----------------------------------------------------
2494       for (iteS.Initialize(myMap); iteS.More(); iteS.Next()) {
2495         const TopoDS_Shape& SP = iteS.Key(); 
2496         if (myMap (SP).IsBound(VF) 
2497             && myMap (SP).IsBound(CurE) &&  myMap (SP).IsBound(FirstE)){
2498           if (!myMap(SP)(VF)    .IsEmpty() &&
2499               !myMap(SP)(CurE)  .IsEmpty() &&
2500               !myMap(SP)(FirstE).IsEmpty()   ) 
2501             B.Continuity (TopoDS::Edge(myMap(SP)(VF)    .First()),
2502                           TopoDS::Face(myMap(SP)(CurE)  .First()),
2503                           TopoDS::Face(myMap(SP)(FirstE).First()),
2504                           Continuity);
2505         }
2506       }
2507     }
2508   }
2509 }
2510     
2511 //=======================================================================
2512 //function : AddDegeneratedEdge
2513 //purpose  : il peut manquer des edges degeneres dans certaine face
2514 //           les edges degeneres manquantes ont des vertex correspondant 
2515 //           aux node de la carte.
2516 //           Aujourd hui on se contente de comparer les points UV des vertex
2517 //           sur les edges a une certaine tolerance.
2518 //=======================================================================
2519
2520 static void AddDegeneratedEdge(TopoDS_Face& F,
2521                                TopoDS_Wire& W) 
2522 {
2523   TopLoc_Location      L;
2524   Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2525   if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2526     Handle(Geom_Surface) SB = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
2527     if (SB->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2528       return;
2529     }
2530   }
2531   
2532   if (S->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2533     return;
2534   }
2535   
2536
2537   BRep_Builder         B;
2538   Standard_Real        TolConf = 1.e-4;
2539
2540   Standard_Boolean Change = Standard_True;
2541   
2542   while (Change) {
2543     Change = Standard_False;
2544     BRepTools_WireExplorer WE(W,F);
2545     gp_Pnt2d PF,PrevP,P1,P2;
2546     TopoDS_Vertex VF,V1,V2;
2547     
2548     for (; WE.More(); WE.Next()) {
2549       const TopoDS_Edge& CE = WE.Current();
2550       EdgeVertices (CE,V1,V2);
2551       if (CE.Orientation() == TopAbs_REVERSED)
2552         BRep_Tool::UVPoints(CE, F, P2, P1);
2553       else 
2554         BRep_Tool::UVPoints(CE, F, P1, P2);
2555       if (VF.IsNull()) {
2556         VF = V1;
2557         PF = P1;
2558       }
2559       else {
2560         if (!P1.IsEqual(PrevP,TolConf)) {
2561           // edge degenere a inserer.
2562           Change = Standard_True;
2563           gp_Vec2d V(PrevP,P1);
2564           Handle(Geom2d_Line) C2d = new Geom2d_Line(PrevP,gp_Dir2d(V));
2565           Standard_Real f = 0, l = PrevP.Distance(P1);
2566           Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(C2d,f,l);
2567           TopoDS_Edge NE = BRepLib_MakeEdge(C2d,S);
2568           B.Degenerated(NE,Standard_True);
2569           B.Add(NE,V1.Oriented(TopAbs_FORWARD));
2570           B.Add(NE,V1.Oriented(TopAbs_REVERSED));
2571           B.Range(NE,f,l);
2572           B.Add(W,NE);
2573           break;
2574         }
2575       }
2576       PrevP = P2;
2577     }
2578     if (!Change && VF.IsSame(V2)) {  // ferme
2579       if (!PF.IsEqual(P2,TolConf)) {
2580         // edge degenere a inserer.
2581         Change = Standard_True;
2582         gp_Vec2d V(P2,PF);
2583         Handle(Geom2d_Line) C2d = new Geom2d_Line(P2,gp_Dir2d(V));
2584         Standard_Real f = 0, l = P2.Distance(PF);
2585         Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(C2d,f,l);
2586         TopoDS_Edge NE = BRepLib_MakeEdge(C2d,S);
2587         B.Degenerated(NE,Standard_True);
2588         B.Add(NE,VF.Oriented(TopAbs_FORWARD));
2589         B.Add(NE,VF.Oriented(TopAbs_REVERSED));
2590         B.Range(NE,f,l);
2591         B.Add(W,NE);
2592       }
2593     }
2594   }
2595 }
2596   
2597 //=======================================================================
2598 //function : TrimFace
2599 //purpose  : 
2600 //=======================================================================
2601
2602 void TrimFace(const TopoDS_Face&              Face,
2603                     TopTools_SequenceOfShape& TheEdges,
2604                     TopTools_SequenceOfShape& S)
2605 {
2606
2607 #ifdef DRAW
2608   Standard_Integer NB = TheEdges.Length();
2609   if ( AffichEdge) {
2610     char name[100];
2611     cout << " TrimFace " << ++NbTRIMFACES;
2612     cout << " : " << NB << " edges dans la restriction" << endl;
2613     for ( Standard_Integer j = 1; j <= NB; j++) {
2614       sprintf(name,"TRIMEDGE_%d_%d",NbTRIMFACES,j);
2615       DBRep::Set(name,TopoDS::Edge(TheEdges.Value(j)));
2616     }
2617   }
2618 #endif
2619
2620
2621   //--------------------------------------
2622   // Creation des wires limitant les faces.
2623   //--------------------------------------
2624   BRep_Builder             TheBuilder;
2625
2626   Standard_Integer NbEdges;
2627   Standard_Boolean NewWire  = Standard_True;
2628   Standard_Boolean AddEdge  = Standard_False;
2629   TopoDS_Wire      GoodWire;
2630
2631
2632   while ( !TheEdges.IsEmpty()) {
2633
2634     BRepLib_MakeWire MWire(TopoDS::Edge(TheEdges.First()));
2635     GoodWire = MWire.Wire();
2636     TheEdges.Remove(1);
2637     NbEdges = TheEdges.Length();
2638     NewWire = Standard_False;
2639
2640     while (!NewWire) {
2641       AddEdge  = Standard_False;
2642
2643       for ( Standard_Integer i = 1; i <= NbEdges && !AddEdge; i++) {
2644         const TopoDS_Edge& E = TopoDS::Edge(TheEdges.Value(i));
2645         if ( BRep_Tool::Degenerated(E)) {
2646             TheEdges.Remove(i);
2647             AddEdge = Standard_True;
2648             NbEdges = TheEdges.Length();
2649             GoodWire = MWire.Wire();
2650         }
2651         else {
2652           MWire.Add(E);
2653           if ( MWire.Error() == BRepLib_WireDone) {
2654             // on a reussi la connection 
2655             // on l`enleve dans la sequence et on recommence au debut.
2656             TheEdges.Remove(i);
2657             AddEdge = Standard_True;
2658             NbEdges = TheEdges.Length();
2659             GoodWire = MWire.Wire();
2660           }
2661         }
2662       }
2663       NewWire = (!AddEdge);
2664     }
2665     TopoDS_Shape aLocalShape = Face.EmptyCopied();
2666     TopoDS_Face FaceCut = TopoDS::Face(aLocalShape);
2667 //    TopoDS_Face FaceCut = TopoDS::Face(Face.EmptyCopied());
2668     FaceCut.Orientation(TopAbs_FORWARD);
2669     BRepTools::Update  (FaceCut);
2670     AddDegeneratedEdge (FaceCut,GoodWire);
2671     TheBuilder.Add     (FaceCut,GoodWire);
2672     FaceCut.Orientation(Face.Orientation());
2673     S.Append(FaceCut);
2674   }
2675 }
2676
2677
2678
2679 //=======================================================================
2680 //function : PutProfilAt
2681 //purpose  : 
2682 //=======================================================================
2683
2684 const TopoDS_Wire PutProfilAt (const TopoDS_Wire&     ProfRef,
2685                                const gp_Ax3&          AxeRef, 
2686                                const TopoDS_Edge&     E,
2687                                const TopoDS_Face&     F,
2688                                const Standard_Boolean AtStart)
2689 {       
2690   gp_Vec2d             D1;
2691   gp_Pnt2d             P;
2692   TopoDS_Wire          Prof;
2693   Handle(Geom2d_Curve) C2d;
2694   Standard_Real        First,Last;
2695
2696   C2d = BRep_Tool::CurveOnSurface(E,F,First,Last);
2697   if (C2d.IsNull()) {
2698     Standard_ConstructionError::Raise("ConstructionError in PutProfilAt"); 
2699   }
2700
2701   if (E.Orientation() == TopAbs_REVERSED) {
2702    if (!AtStart) C2d->D1(First,P,D1);else C2d->D1(Last,P,D1);
2703    D1.Reverse();
2704   }
2705   else {
2706    if (!AtStart) C2d->D1(Last,P,D1) ;else C2d->D1(First,P,D1); 
2707   }
2708   gp_Pnt P3d(P.X() ,P.Y() ,0.);
2709   gp_Vec V3d(D1.X(),D1.Y(),0.);
2710
2711   gp_Ax3  Ax( P3d, gp::DZ(), V3d);
2712   gp_Trsf Trans;
2713   Trans.SetTransformation(Ax,AxeRef);
2714   TopoDS_Shape aLocalShape = ProfRef.Moved(TopLoc_Location(Trans));
2715   Prof = TopoDS::Wire(aLocalShape);
2716 //  Prof = TopoDS::Wire(ProfRef.Moved(TopLoc_Location(Trans)));
2717   return Prof;
2718 }
2719
2720       
2721 //=======================================================================
2722 //function : TrimEdge
2723 //purpose  : 
2724 //=======================================================================
2725
2726 void TrimEdge (const TopoDS_Edge&        Edge,
2727                const TopTools_SequenceOfShape& TheEdgesControle,
2728                      TopTools_SequenceOfShape& TheVer,
2729                      TColStd_SequenceOfReal&   ThePar,
2730                      TopTools_SequenceOfShape& S)
2731 {
2732   Standard_Boolean         Change = Standard_True;
2733   BRep_Builder             TheBuilder;
2734   S.Clear();
2735   //-----------------------------------------------------------
2736   // Tri des deux sequence en fonction du parametre sur l edge.
2737   //-----------------------------------------------------------
2738   while (Change) {
2739     Change = Standard_False;
2740     for (Standard_Integer i = 1; i < ThePar.Length(); i++) {
2741       if (ThePar.Value(i) > ThePar.Value(i+1)) {
2742         ThePar.Exchange(i,i+1);
2743         TheVer.Exchange(i,i+1);
2744         Change = Standard_True;
2745       }
2746     }
2747   }
2748
2749   //----------------------------------------------------------
2750   // Si un vertex n est pas dans le detrompeur il est elimine.
2751   //----------------------------------------------------------
2752   if (!BRep_Tool::Degenerated(Edge)) {
2753     for (Standard_Integer k = 1; k <= TheVer.Length(); k ++) {
2754       if ( DoubleOrNotInFace (TheEdgesControle,
2755                               TopoDS::Vertex(TheVer.Value(k)))) {
2756         TheVer.Remove(k);
2757         ThePar.Remove(k);
2758         k--;
2759       }
2760     }
2761   }
2762
2763   //-------------------------------------------------------------------
2764   // Traitement des vertex doubles pour les edges non degeneres.
2765   // Si un vertex_double apparait deux fois dans les edges de contole
2766   // le vertex est elimine .
2767   // sinon on garde une seule de ces representations.
2768   //-------------------------------------------------------------------
2769   if (!BRep_Tool::Degenerated(Edge)) {
2770     for (Standard_Integer k = 1; k < TheVer.Length(); k ++) {
2771       if (TheVer.Value(k).IsSame(TheVer.Value(k+1))) {
2772         TheVer.Remove(k+1);
2773         ThePar.Remove(k+1);
2774         if ( DoubleOrNotInFace (TheEdgesControle,
2775                                 TopoDS::Vertex(TheVer.Value(k)))) {
2776           TheVer.Remove(k);
2777           ThePar.Remove(k);
2778 //        k--;
2779         }
2780         k--;
2781       }
2782     }
2783   }
2784
2785   //-----------------------------------------------------------
2786   // Creation des edges.
2787   // le nombre de vertex doit etre pair les edges a creer vont 
2788   // d un vertex d indice impair i au vertex i+1;
2789   //-----------------------------------------------------------
2790   for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) {
2791     TopoDS_Shape aLocalShape = Edge.EmptyCopied();
2792     TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape);
2793 //    TopoDS_Edge NewEdge = TopoDS::Edge(Edge.EmptyCopied());
2794
2795     if (NewEdge.Orientation() == TopAbs_REVERSED) {
2796       TheBuilder.Add  (NewEdge,TheVer.Value(k)  .Oriented(TopAbs_REVERSED));
2797       TheBuilder.Add  (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD));
2798     }
2799     else {      
2800       TheBuilder.Add  (NewEdge,TheVer.Value(k)  .Oriented(TopAbs_FORWARD));
2801       TheBuilder.Add  (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED));
2802     }
2803     TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1));
2804 //  modified by NIZHNY-EAP Wed Dec 22 12:09:48 1999 ___BEGIN___
2805     BRepLib::UpdateTolerances(NewEdge,Standard_False);
2806 //  modified by NIZHNY-EAP Wed Dec 22 13:34:19 1999 ___END___
2807     S.Append(NewEdge);
2808   }
2809
2810
2811 //=======================================================================
2812 //function : ComputeIntervals
2813 //purpose  : 
2814 //=======================================================================
2815
2816 void ComputeIntervals (const TopTools_SequenceOfShape& VOnF,
2817                        const TopTools_SequenceOfShape& VOnL,
2818                        const TColgp_SequenceOfPnt&     ParOnF,
2819                        const TColgp_SequenceOfPnt&     ParOnL,
2820                        const BRepFill_TrimSurfaceTool& Trim,
2821                        const Handle(Geom2d_Curve)&     Bis,
2822                        const TopoDS_Vertex&            VS,
2823                        const TopoDS_Vertex&            VE,
2824                              TColStd_SequenceOfReal&   FirstPar,
2825                              TColStd_SequenceOfReal&   LastPar,
2826                              TopTools_SequenceOfShape& FirstV,
2827                              TopTools_SequenceOfShape& LastV )
2828 {
2829   Standard_Integer IOnF    = 1,IOnL = 1;
2830   Standard_Real    U1,U2;
2831   TopoDS_Shape     V1,V2;
2832   
2833   if (!VS.IsNull()) {
2834     U1  = Bis->FirstParameter();
2835     V1  = VS;
2836   }
2837   while ( IOnF <= VOnF.Length() || IOnL <= VOnL.Length()) {
2838     //---------------------------------------------------------
2839     // Recuperation du plus petit parametre sur la bissectrice
2840     // par rapport aux positions courrantes IOnF,IOnL.
2841     //---------------------------------------------------------
2842     if ( IOnL > VOnL.Length() ||
2843         (IOnF <= VOnF.Length() &&
2844          ParOnF.Value(IOnF).X() < ParOnL.Value(IOnL).X())) {
2845         
2846       U2 = ParOnF.Value(IOnF).X();
2847       V2 = VOnF  .Value(IOnF);
2848       IOnF++;
2849     }     
2850     else{
2851       U2 = ParOnL.Value(IOnL).X();
2852       V2 = VOnL  .Value(IOnL);
2853       IOnL++;
2854     }
2855     //---------------------------------------------------------------------
2856     // Quand V2 et V1 sont differents on teste le point milieu P de 
2857     // l intervalle par rapport a la face. Si P est dans la face l interval
2858     // est valide.
2859     //--------------------------------------------------------------------- 
2860     if (!V1.IsNull() && !V2.IsSame(V1)) {
2861       gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
2862       if (Trim.IsOnFace(P)) {
2863         FirstPar.Append(U1); LastPar .Append(U2);
2864         FirstV.  Append(V1); LastV   .Append(V2);
2865       }
2866     }
2867     U1 = U2;
2868     V1 = V2;
2869   }  
2870
2871   if (!VE.IsNull()) {
2872     U2 = Bis->LastParameter();
2873     V2 = VE;
2874     if (!V2.IsSame(V1)) {
2875       gp_Pnt2d P = Bis->Value((U2 + U1)*0.5);
2876       if (Trim.IsOnFace(P)) {
2877         FirstPar.Append(U1); LastPar .Append(U2);
2878         FirstV.Append  (V1);   LastV .Append(V2);
2879       }
2880     }
2881   }
2882   
2883 }
2884
2885 //=======================================================================
2886 //function : Relative
2887 //purpose  : Commun est vrai si les deux wires ont V en commun
2888 //           return FORWARD si les wires au voisinage du vertex sont
2889 //           du meme cote. REVERSED sinon.
2890 //=======================================================================
2891 static TopAbs_Orientation Relative (const TopoDS_Wire&   W1,
2892                                     const TopoDS_Wire&   W2,
2893                                     const TopoDS_Vertex& V,
2894                                     Standard_Boolean&    Commun)
2895 {
2896   TopExp_Explorer Exp;
2897   TopoDS_Edge     E1,E2;
2898   TopoDS_Vertex   V1,V2;
2899
2900   for (Exp.Init(W1,TopAbs_EDGE); Exp.More(); Exp.Next()) {
2901     const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
2902     TopExp::Vertices(E,V1,V2);
2903     if (V1.IsSame(V) || V2.IsSame(V)) {
2904       E1 = E;
2905       break;
2906     }
2907   }
2908   for (Exp.Init(W2,TopAbs_EDGE); Exp.More(); Exp.Next()) {
2909     const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
2910     TopExp::Vertices(E,V1,V2);
2911     if (V1.IsSame(V) || V2.IsSame(V)) {
2912       E2 = E;
2913       break;
2914     }
2915   }
2916
2917   if (E1.IsNull() || E2.IsNull()) {
2918     Commun = Standard_False;
2919     return TopAbs_FORWARD;
2920   }
2921   Commun = Standard_True;
2922
2923   TopoDS_Wire WW1 = BRepLib_MakeWire(E1);
2924   TopoDS_Wire WW2 = BRepLib_MakeWire(E2);
2925   Standard_Real Tol = BRepFill_Confusion();
2926   if (Side(WW1,Tol) < 4 && Side(WW2,Tol) < 4) // les deux a gauche
2927     return TopAbs_FORWARD;
2928   if (Side(WW1,Tol) > 4 && Side(WW2,Tol) > 4) // les deux a droite
2929     return TopAbs_FORWARD;
2930   
2931   return TopAbs_REVERSED;
2932 }
2933 //=======================================================================
2934 //function : OriEdgeInFace
2935 //purpose  : 
2936 //=======================================================================
2937
2938 TopAbs_Orientation OriEdgeInFace (const TopoDS_Edge& E,
2939                                   const TopoDS_Face& F )
2940
2941 {
2942 #ifdef DEB
2943   TopAbs_Orientation O = 
2944 #endif
2945     F.Orientation();
2946
2947   TopExp_Explorer Exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
2948
2949   for (; Exp.More() ;Exp.Next()) {
2950     if (Exp.Current().IsSame(E)) {
2951       return Exp.Current().Orientation();
2952     }
2953   }
2954   Standard_ConstructionError::Raise("BRepFill_Evolved::OriEdgeInFace");
2955   return E.Orientation();
2956 }
2957
2958
2959
2960 //=======================================================================
2961 //function : IsOnFace
2962 //purpose  : Retourne la position du point defini par d1
2963 //           dans la face defini Par d2 d3.
2964 //           
2965 //           0 : le point est en dehors de la face.
2966 //           1 : le point est sur ledge correspondant a d2.
2967 //           2 : le point est a l interieur de la face.
2968 //           3 : le point est sur ledge correspondant a d3.
2969 //=======================================================================
2970
2971 Standard_Integer  PosOnFace (Standard_Real d1,
2972                              Standard_Real d2,
2973                              Standard_Real d3)
2974 {
2975   if (Abs(d1 - d2) <= BRepFill_Confusion())
2976     return 1;
2977   if (Abs(d1 - d3) <= BRepFill_Confusion())
2978     return 3;
2979
2980   if (d2 < d3) { 
2981     if (d1 > (d2 + BRepFill_Confusion()) && 
2982         d1 < (d3 - BRepFill_Confusion())    ) 
2983       return 2;
2984   }
2985   else {
2986     if (d1 > (d3 + BRepFill_Confusion()) && 
2987         d1 < (d2 - BRepFill_Confusion())   ) 
2988       return 2;
2989   }
2990   return 0;
2991 }
2992
2993 //=======================================================================
2994 //function : DoubleOrNotInFace
2995 //purpose  : Return True if V apparait 0 ou  deux fois dans la sequence
2996 //           d edges EC 
2997 //=======================================================================
2998
2999 Standard_Boolean DoubleOrNotInFace(const TopTools_SequenceOfShape& EC,
3000                                    const TopoDS_Vertex&            V)
3001 {
3002   Standard_Boolean Vu = Standard_False;
3003
3004   for (Standard_Integer i = 1; i <= EC.Length(); i++) {
3005     TopoDS_Vertex V1,V2;
3006     TopExp::Vertices(TopoDS::Edge(EC.Value(i)),V1,V2);
3007     if (V1.IsSame(V)) {
3008       if  (Vu) return Standard_True;
3009       else       Vu = Standard_True;
3010     }
3011     if (V2.IsSame(V)) {
3012       if  (Vu) return Standard_True;
3013       else       Vu = Standard_True;
3014     }
3015   }
3016   if (Vu) return Standard_False;
3017   else    return Standard_True;   
3018 }
3019
3020
3021 //=======================================================================
3022 //function : DistanceToOZ
3023 //purpose  : 
3024 //=======================================================================
3025
3026 Standard_Real DistanceToOZ (const TopoDS_Vertex& V) 
3027 {
3028   gp_Pnt PV3d = BRep_Tool::Pnt(V);
3029   return Abs(PV3d.Y()); 
3030 }
3031
3032 //=======================================================================
3033 //function : Altitud
3034 //purpose  : 
3035 //=======================================================================
3036
3037 Standard_Real Altitud (const TopoDS_Vertex& V) 
3038 {
3039   gp_Pnt PV3d = BRep_Tool::Pnt(V);
3040   return PV3d.Z(); 
3041 }
3042
3043 //=======================================================================
3044 //function : SimpleExpression 
3045 //purpose  : 
3046 //=======================================================================
3047
3048 void SimpleExpression (const Bisector_Bisec&  B, 
3049                        Handle(Geom2d_Curve)&  Bis)
3050 {
3051   Bis = B.Value();
3052
3053   Handle(Standard_Type) BT = Bis->DynamicType();
3054   if (BT == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
3055     Handle(Geom2d_TrimmedCurve) TrBis 
3056       = Handle(Geom2d_TrimmedCurve)::DownCast(Bis);
3057     Handle(Geom2d_Curve) BasBis = TrBis->BasisCurve();
3058     BT = BasBis->DynamicType();
3059     if (BT == STANDARD_TYPE(Bisector_BisecAna)) {
3060       Bis = Handle(Bisector_BisecAna)::DownCast(BasBis)->Geom2dCurve();
3061       Bis = new Geom2d_TrimmedCurve (Bis,
3062                                      TrBis->FirstParameter(),
3063                                      TrBis->LastParameter());
3064     }
3065   }
3066 }
3067
3068 //=======================================================================
3069 //function : CutEdgeProf
3070 //purpose  : Projection et Decoupe d une edge aux extrema de distance a 
3071 //           l axe OZ.
3072 //=======================================================================
3073
3074 void CutEdgeProf (const TopoDS_Edge&                  E,
3075                   const Handle(Geom_Plane)&           Plane,
3076                   const Handle(Geom2d_Line)&          Line,
3077                         TopTools_ListOfShape&         Cuts,
3078                         TopTools_DataMapOfShapeShape& MapVerRefMoved)
3079
3080   Cuts.Clear();
3081
3082   Standard_Real             f,l;
3083   Handle(Geom_Curve)        C;
3084   Handle(Geom_TrimmedCurve) CT;
3085   Handle(Geom2d_Curve)      C2d;
3086   TopLoc_Location           L;
3087
3088   // On recupere la courbe associee a chaque Edge
3089   C  = BRep_Tool::Curve(E,L,f,l);
3090   CT = new Geom_TrimmedCurve(C,f,l);
3091   CT->Transform(L.Transformation());
3092   
3093   // on la projete dans le plan et on recupere la PCurve associee
3094   gp_Dir Normal = Plane->Pln().Axis().Direction();
3095   C = 
3096     Handle(Geom_Curve)::DownCast(GeomProjLib::ProjectOnPlane(CT,Plane,
3097                                                                Normal,
3098                                                                Standard_False));
3099   C2d = GeomProjLib::Curve2d(C,Plane);
3100   
3101   // On calcule les extrema avec la droite
3102   TColStd_SequenceOfReal Seq;
3103   
3104   Standard_Real U1 = -Precision::Infinite();
3105   Standard_Real U2 =  Precision::Infinite();
3106   f= C2d->FirstParameter();
3107   l= C2d->LastParameter();
3108
3109   Bnd_Box2d B;
3110   Geom2dAdaptor_Curve AC2d(C2d);
3111   BndLib_Add2dCurve::Add(AC2d,BRepFill_Confusion(),B);
3112   Standard_Real xmin,xmax;
3113   B.Get(xmin,U1,xmax,U2);
3114
3115 //  modified by NIZHNY-EAP Wed Feb  2 16:32:37 2000 ___BEGIN___
3116   // no sense if C2 is normal to Line or really is a point
3117   if (U1 != U2) {
3118     Geom2dAPI_ExtremaCurveCurve Extrema(Line,C2d,U1-1.,U2+1.,f,l);
3119     
3120     Standard_Integer i, Nb = Extrema.NbExtrema();
3121     for ( i = 1; i <= Nb; i++) {
3122       Extrema.Parameters(i,U1,U2);
3123       Seq.Append(U2);
3124     }
3125   }
3126 //  modified by NIZHNY-EAP Wed Feb  2 16:33:05 2000 ___END___
3127   
3128   // On calcule les intersection avec Oy.
3129   Geom2dAdaptor_Curve ALine(Line);
3130   Standard_Real Tol = Precision::Intersection();
3131   Standard_Real TolC = 0.;
3132   
3133   Geom2dInt_GInter Intersector(ALine,AC2d,TolC,Tol);
3134   Standard_Integer i, Nb = Intersector.NbPoints();
3135   
3136   for ( i = 1; i <= Nb; i++) {
3137     Seq.Append(Intersector.Point(i).ParamOnSecond());
3138   }
3139
3140   // Compute the new edges.
3141   BRep_Builder Builder;
3142   TopoDS_Vertex VV,Vf,Vl,VRf,VRl;
3143   TopExp::Vertices(E,VRf,VRl);
3144
3145   if (!MapVerRefMoved.IsBound(VRf)) {
3146     Builder.MakeVertex(Vf,C->Value(f),BRep_Tool::Tolerance(VRf));
3147     MapVerRefMoved.Bind(VRf,Vf);
3148   }
3149   else {
3150     Vf = TopoDS::Vertex(MapVerRefMoved(VRf));
3151   }
3152   
3153   if (!MapVerRefMoved.IsBound(VRl)) {
3154     Builder.MakeVertex(Vl,C->Value(l),BRep_Tool::Tolerance(VRl));
3155     MapVerRefMoved.Bind(VRl,Vl);
3156   }
3157   else {
3158     Vl = TopoDS::Vertex(MapVerRefMoved(VRl));
3159   }
3160
3161   if ( !Seq.IsEmpty()) {
3162
3163     Bubble(Seq);
3164
3165     Standard_Boolean Empty = Standard_False;
3166
3167     Standard_Real CurParam = f;
3168     Standard_Real Param;
3169     
3170     while ( !Empty) {
3171       Param = Seq.First();
3172       Seq.Remove(1);
3173       Empty = Seq.IsEmpty();
3174       if (Abs( Param - CurParam) > BRepFill_Confusion() &&
3175           Abs( Param - l)        > BRepFill_Confusion() ) {
3176         
3177         VV = BRepLib_MakeVertex( C->Value(Param));
3178         
3179         TopoDS_Edge EE = BRepLib_MakeEdge(C,Vf,VV);
3180         EE.Orientation(E.Orientation());
3181         if ( EE.Orientation() == TopAbs_FORWARD)
3182           Cuts.Append(EE);
3183         else
3184           Cuts.Prepend(EE);
3185         
3186         // on reinitialise 
3187         CurParam = Param;
3188         Vf = VV;
3189       }
3190     }
3191   }
3192
3193   TopoDS_Edge EE = BRepLib_MakeEdge(C,Vf,Vl);
3194   EE.Orientation(E.Orientation());
3195   if ( EE.Orientation() == TopAbs_FORWARD)
3196     Cuts.Append(EE);
3197   else
3198     Cuts.Prepend(EE);
3199 }
3200
3201 //=======================================================================
3202 //function : CutEdge
3203 //purpose  : Decoupe d une edge aux extrema de courbures et aux points
3204 //           d inflexion.
3205 //           Les cercles fermes sont aussi decoupes en deux.
3206 //           Si <Cuts> est vide l edge n est pas modifie.
3207 //           Le premier et le dernier vertex de l edge originale
3208 //           appartiennent respectivement a la premiere et derniere
3209 //           portions.
3210 //=======================================================================
3211 void CutEdge (const TopoDS_Edge& E, 
3212               const TopoDS_Face& F,
3213                     TopTools_ListOfShape& Cuts)
3214 {
3215   Cuts.Clear();
3216   MAT2d_CutCurve              Cuter;
3217   Standard_Real               f,l; 
3218   Handle(Geom2d_Curve)        C2d;
3219   Handle(Geom2d_TrimmedCurve) CT2d;
3220   
3221   TopoDS_Vertex V1,V2,VF,VL;
3222   TopExp::Vertices (E,V1,V2);
3223   BRep_Builder B;
3224   
3225   C2d  = BRep_Tool::CurveOnSurface (E,F,f,l);
3226   CT2d = new Geom2d_TrimmedCurve(C2d,f,l);
3227
3228   if (CT2d->BasisCurve()->IsKind(STANDARD_TYPE(Geom2d_Circle)) &&
3229       E.Closed()) {
3230     //---------------------------
3231     // Decoupe cercle ferme.
3232     //---------------------------
3233     Standard_Real m1 = (2*f +   l)/3.;
3234     Standard_Real m2 = (  f + 2*l)/3.;
3235     gp_Pnt2d P1 = CT2d->Value(m1);
3236     gp_Pnt2d P2 = CT2d->Value(m2);
3237
3238     TopoDS_Vertex VL1 = BRepLib_MakeVertex(gp_Pnt(P1.X(), P1.Y(), 0.));
3239     TopoDS_Vertex VL2 = BRepLib_MakeVertex(gp_Pnt(P2.X(), P2.Y(), 0.));
3240     TopoDS_Shape aLocalShape1 = E.EmptyCopied();
3241     TopoDS_Shape aLocalShape2 = E.EmptyCopied();
3242     TopoDS_Shape aLocalShape3 = E.EmptyCopied();
3243     TopoDS_Edge FE = TopoDS::Edge(aLocalShape1);    
3244     TopoDS_Edge ME = TopoDS::Edge(aLocalShape2);    
3245     TopoDS_Edge LE = TopoDS::Edge(aLocalShape3);
3246 //    TopoDS_Edge FE = TopoDS::Edge(E.EmptyCopied());    
3247 //   TopoDS_Edge ME = TopoDS::Edge(E.EmptyCopied());    
3248 //    TopoDS_Edge LE = TopoDS::Edge(E.EmptyCopied());
3249
3250     FE.Orientation(TopAbs_FORWARD);
3251     ME.Orientation(TopAbs_FORWARD);
3252     LE.Orientation(TopAbs_FORWARD );
3253
3254     B.Add  (FE,V1);
3255     B.Add  (FE,VL1.Oriented(TopAbs_REVERSED));
3256     B.Range(FE, f, m1);    
3257
3258     B.Add  (ME,VL1.Oriented(TopAbs_FORWARD));
3259     B.Add  (ME,VL2.Oriented(TopAbs_REVERSED));
3260     B.Range(ME, m1, m2);    
3261
3262     B.Add  (LE,VL2.Oriented(TopAbs_FORWARD));
3263     B.Add  (LE,V2);
3264     B.Range(LE, m2, l);
3265
3266     Cuts.Append(FE.Oriented(E.Orientation()));
3267     Cuts.Append(ME.Oriented(E.Orientation()));
3268     Cuts.Append(LE.Oriented(E.Orientation()));
3269     //--------
3270     // Retour.
3271     //--------
3272     return;
3273   }
3274
3275   //-------------------------
3276   // Decoupe de la courbe.
3277   //-------------------------
3278   Cuter.Perform(CT2d);
3279
3280   if (Cuter.UnModified()) {
3281     //-----------------------------
3282     // edge non modifiee => retour.
3283     //-----------------------------
3284     return;
3285   }
3286   else {
3287     //--------------------------------------
3288     // Creation des edges decoupees.
3289     //--------------------------------------
3290     VF = V1;
3291
3292     for ( Standard_Integer k = 1; k <= Cuter.NbCurves(); k++) {
3293       Handle(Geom2d_TrimmedCurve)CC = Cuter.Value(k);
3294       if (k == Cuter.NbCurves()) {VL = V2;}
3295       else { 
3296         gp_Pnt2d P = CC->Value(CC->LastParameter());
3297         VL = BRepLib_MakeVertex(gp_Pnt(P.X(), P.Y(), 0.));
3298       }
3299       TopoDS_Shape aLocalShape = E.EmptyCopied();
3300       TopoDS_Edge NE = TopoDS::Edge(aLocalShape);
3301 //      TopoDS_Edge NE = TopoDS::Edge(E.EmptyCopied());
3302       NE.Orientation(TopAbs_FORWARD);
3303       B.Add  (NE,VF.Oriented(TopAbs_FORWARD));
3304       B.Add  (NE,VL.Oriented(TopAbs_REVERSED));      
3305       B.Range(NE,CC->FirstParameter(),CC->LastParameter());
3306       Cuts.Append(NE.Oriented(E.Orientation()));
3307       VF = VL;
3308     }
3309   }
3310 }
3311
3312 //=======================================================================
3313 //function : VertexFromNode
3314 //purpose  : Test si la position de aNode par rapport aux distance to OZ
3315 //           des vertex VF et VL. retourne Status.
3316 //           si Status est different de 0 Recupere ou cree le vertex 
3317 //           correspondant a aNode.
3318 //=======================================================================
3319
3320 Standard_Integer VertexFromNode
3321 (const Handle(MAT_Node)&                          aNode, 
3322  const TopoDS_Edge&                                E, 
3323  const TopoDS_Vertex&                              VF, 
3324  const TopoDS_Vertex&                              VL,
3325        BRepFill_DataMapOfNodeDataMapOfShapeShape&  MapNodeVertex,
3326        TopoDS_Vertex&                              VN)
3327 {      
3328   TopoDS_Shape                 ShapeOnNode;
3329   TopTools_DataMapOfShapeShape EmptyMap;
3330   Standard_Integer             Status = 0;
3331   BRep_Builder                 B;
3332
3333   if (!aNode->Infinite()) {
3334     Status    = PosOnFace(aNode->Distance(),
3335                           DistanceToOZ(VF) , DistanceToOZ(VL));
3336   }
3337   if      (Status == 2) ShapeOnNode = E;
3338   else if (Status == 1) ShapeOnNode = VF;
3339   else if (Status == 3) ShapeOnNode = VL;
3340   
3341   if (!ShapeOnNode.IsNull()) {
3342     //------------------------------------------------
3343     // le vertex correspondra a un noeud de la carte
3344     //------------------------------------------------
3345     if (MapNodeVertex.IsBound(aNode) &&
3346         MapNodeVertex(aNode).IsBound(ShapeOnNode)) {
3347       VN = TopoDS::Vertex
3348         (MapNodeVertex(aNode)(ShapeOnNode));
3349     }
3350     else { 
3351       B.MakeVertex (VN);
3352       if (!MapNodeVertex.IsBound(aNode)) {
3353         MapNodeVertex.Bind(aNode,EmptyMap);
3354       }
3355       MapNodeVertex(aNode).Bind(ShapeOnNode,VN);
3356     }
3357   }
3358   return Status;
3359 }
3360