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