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