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