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