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