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