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