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