0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / BRepFill / BRepFill_Draft.cxx
1 // File:        BRepFill_Draft.cxx
2 // Created:     Mon Jun  8 15:13:03 1998
3 // Author:      Stephanie HUMEAU
4 //              <shu@sun17>
5
6
7 #include <BRepFill_Draft.ixx>
8
9 #include <BRepFill_DraftLaw.hxx>
10 #include <BRepFill_ShapeLaw.hxx>
11 #include <BRepFill_Sweep.hxx>
12
13 #include <BndLib_Add3dCurve.hxx>
14 #include <BndLib_AddSurface.hxx>
15 #include <Bnd_Box.hxx>
16 #include <gp_Dir.hxx>
17 #include <gp_Pnt.hxx>
18 #include <gp_Trsf.hxx>
19 #include <gp_Ax3.hxx>
20 #include <gp_Lin.hxx>
21 #include <gp_Mat.hxx>
22 #include <TColgp_Array1OfPnt.hxx>
23
24 #include <GeomAdaptor_Surface.hxx>
25 #include <BRepAdaptor_Surface.hxx>
26 #include <Adaptor3d_HCurve.hxx>
27
28 #include <GeomLProp_SLProps.hxx>
29 #include <Geom_Surface.hxx>
30 #include <Geom_Line.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Geom_Geometry.hxx>
33 #include <Geom_Plane.hxx>
34 #include <Geom_RectangularTrimmedSurface.hxx>
35
36 #include <GeomAdaptor_HSurface.hxx>
37 #include <Adaptor3d_Surface.hxx>
38 #include <BRepAdaptor_Curve.hxx>
39
40 #include <GeomFill_LocationDraft.hxx>
41
42 #include <TopoDS.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Wire.hxx>  
45 #include <TopoDS_Shell.hxx> 
46 #include <TopoDS_Solid.hxx> 
47 #include <TopoDS_Iterator.hxx>
48 #include <TopExp_Explorer.hxx> 
49 #include <TopExp.hxx>
50 #include <TopAbs.hxx>
51 #include <BRepLib_MakeWire.hxx>
52 #include <BRepLib_MakeEdge.hxx>
53 #include <BRepLib_MakeFace.hxx>
54 #include <BRepLib_FindSurface.hxx>
55 #include <BRep_Builder.hxx>
56
57 #include <BRep_Tool.hxx>
58 #include <BRepTools.hxx>
59 #include <BRepAlgo_DSAccess.hxx>
60 #include <BRepBuilderAPI_Sewing.hxx>
61 #include <BRepClass3d_SolidClassifier.hxx>
62
63 #include <TopTools_ListIteratorOfListOfShape.hxx>
64 #include <TopTools_ListOfShape.hxx>
65 #include <BRepExtrema_DistShapeShape.hxx>
66
67 #include <Precision.hxx> 
68 #include <TColStd_Array1OfReal.hxx>
69
70 #include <Standard_NoSuchObject.hxx>
71 #include <StdFail_NotDone.hxx>
72
73 #ifdef DRAW
74 #include <Geom_Circle.hxx>
75 #include <gp.hxx>
76 #include <DBRep.hxx>
77 #include <DrawTrSurf.hxx>
78 static Standard_Boolean Affich = 0;
79 #endif
80
81 //=======================================================================
82 //function : Trsf
83 //purpose  : 
84 //======================================================================
85 static void ComputeTrsf(const TopoDS_Wire& W,
86                         const gp_Dir& D,
87                         Bnd_Box& Box,
88                         gp_Trsf& Tf)
89 {
90   // Calculate approximate barycenter
91   BRepTools_WireExplorer Exp(W);
92 // Class BRep_Tool without fields and without Constructor :
93 //  BRep_Tool BT;
94   gp_XYZ Bary(0.,0.,0.);
95   Standard_Integer nb;
96
97   for (nb=0; Exp.More(); Exp.Next()) {
98 //    Bary += BT.Pnt(Exp.CurrentVertex()).XYZ();
99     Bary += BRep_Tool::Pnt(Exp.CurrentVertex()).XYZ();
100     nb++;
101   }
102   Bary /= nb;
103
104   // Calculate the Transformation  
105   gp_Ax3 N(Bary, D);
106   Tf.SetTransformation(N);
107   BRepAdaptor_Curve AC;
108 //  BndLib_Add3dCurve BC;  
109
110   // transformation to the wire
111   TopoDS_Wire TheW = W;
112   TopLoc_Location Loc(Tf);
113   TheW.Location(Loc);
114
115
116   // Calculate the box
117   Box.SetVoid();
118   for (Exp.Init(TheW); Exp.More(); Exp.Next()) {
119     AC.Initialize(Exp.Current());
120 //    BC.Add(AC, 0.1, Box);
121     BndLib_Add3dCurve::Add(AC, 0.1, Box);
122   }
123 }
124
125 //=======================================================================
126 //function : Length
127 //purpose  : 
128 //======================================================================
129 static Standard_Real Longueur(const Bnd_Box& WBox,
130                               const Bnd_Box& SBox,
131                               gp_Dir& D,
132                               gp_Pnt& P)
133 {
134   // face of the box most remoted from the face input in 
135   // the direction of skin
136   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,WZmin,WZmax,L;
137
138   //"coord" of the box
139   WBox.Get(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
140   WZmin = Zmin;
141   WZmax = Zmax;   
142
143   SBox.Get(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax);
144   P.SetCoord( (Xmin+Xmax)/2, (Ymin+Ymax)/2, Zmax);
145
146   if (Zmax < WZmin) {
147     // Skin in the wrong direction. Invert...
148     D.Reverse();
149     L = WZmax - Zmin;
150     P.SetZ(Zmin);
151   }
152   else {
153     L = Zmax - WZmin;
154   }
155   return L;
156 }
157
158 //=======================================================================
159 //function : GoodOrientation
160 //purpose  : Check if the law is oriented to have an exterior skin
161 //======================================================================
162 static Standard_Boolean GoodOrientation(const Bnd_Box& B,
163                                         const Handle(BRepFill_LocationLaw)& Law,
164                                         const gp_Dir& D)
165 {
166   Standard_Real f, l, r, t;
167   Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
168
169   B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
170   gp_Pnt P1(aXmin, aYmin, aZmin), P2(aXmax, aYmax, aZmax);
171   gp_Vec V(P1, P2);
172
173   Law->CurvilinearBounds(Law->NbLaw(), f, l);
174   r = V.Magnitude()/l;
175  
176   Standard_Integer ii, Ind;
177 //#ifndef DEB
178   Standard_Integer Nb = (Standard_Integer) (4+(10*r));
179 //#else
180 //  Standard_Integer Nb = 4+(10*r);
181 //#endif
182   r = l/Nb;
183
184   Nb++; // Number of points
185
186   TColgp_Array1OfPnt Pnts(1, Nb);
187   Handle(Adaptor3d_HCurve) AC;
188   gp_XYZ Bary(0.,0.,0.);
189   
190   for (ii=1; ii<=Nb; ii++) {
191     Law->Parameter((ii-1)*r, Ind, t);
192     AC = Law->Law(Ind)->GetCurve();
193     AC->D0(t,  Pnts(ii));
194     Bary+= Pnts(ii).XYZ();
195   }
196
197   Bary /= Nb;
198   gp_Pnt Centre(Bary);
199   gp_Vec Normal(D.XYZ());
200   Standard_Real Angle = 0;
201   gp_Vec Ref(Centre,  Pnts(1));
202
203   for (ii=2; ii<=Nb; ii++) {
204     gp_Vec R(Centre, Pnts(ii));
205     Angle += Ref.AngleWithRef(R, Normal);
206     Ref = R;
207   }
208
209   return (Angle >= 0);
210 }
211
212 //=======================================================================
213 //function : Constructeur
214 //purpose  : 
215 //======================================================================
216  BRepFill_Draft::BRepFill_Draft(const TopoDS_Shape& S,
217                                 const gp_Dir& Dir,
218                                 const Standard_Real Angle)
219 {
220   myLoc.Nullify();
221   mySec.Nullify();
222   myFaces.Nullify();
223   mySections.Nullify(); 
224    
225   switch (S.ShapeType()) {
226   case TopAbs_WIRE :
227     {
228       myWire = TopoDS::Wire(S);
229       break;
230     }
231   case TopAbs_FACE :
232     {  
233       TopoDS_Iterator Exp (S);
234       myWire = TopoDS::Wire(Exp.Value());
235       break;
236     }
237   case TopAbs_SHELL :
238     {  
239       TopTools_ListOfShape List;
240       TopTools_IndexedDataMapOfShapeListOfShape edgemap;
241       TopExp::MapShapesAndAncestors(S,TopAbs_EDGE,TopAbs_FACE,edgemap);
242       Standard_Integer iedge, nbf;
243       for (iedge = 1; iedge <= edgemap.Extent(); iedge++) {   
244         const TopoDS_Edge& theEdge = TopoDS::Edge(edgemap.FindKey(iedge));    
245         // skip degenerated edges
246         if (!BRep_Tool::Degenerated(theEdge)) {
247           nbf = edgemap(iedge).Extent();
248           if (nbf==1) List.Append(theEdge);
249         }
250       }
251
252       if( List.Extent()>0) {
253         BRepLib_MakeWire MW;
254         MW.Add(List);
255         BRepLib_WireError Err = MW.Error();
256         if (Err == BRepLib_WireDone) {
257           myWire = MW.Wire();
258         }
259         else {
260 #if DEB
261           cout << "Error in MakeWire" << endl;
262 #endif 
263           Standard_ConstructionError::Raise("BRepFill_Draft");
264         }
265       }
266       else {
267 #if DEB
268           cout << "No Free Borders !" << endl;
269 #endif 
270           Standard_ConstructionError::Raise("BRepFill_Draft");
271       }
272       break;
273     }
274     default :
275       Standard_ConstructionError::Raise("BRepFill_Draft");
276   }
277
278   // Attention to closed non declared wires !
279   if (!myWire.Closed()) {
280     TopoDS_Vertex Vf, Vl;
281     TopExp::Vertices(myWire, Vf, Vl);
282     if (Vf.IsSame(Vl)) myWire.Closed(Standard_True);
283   }
284 #if DRAW
285   if (Affich) {
286     DBRep::Set("TheWire", myWire);
287   }
288 #endif
289
290   myAngle = Abs(Angle);
291   myDir = Dir;
292   myTop = S;
293   myDone = Standard_False;
294   myTol = 1.e-4;
295   myCont = GeomAbs_C1;
296   SetOptions();
297   SetDraft();
298 }
299
300 //=======================================================================
301 //function :SetOptions
302 //purpose  : Defines the style
303 //======================================================================
304  void BRepFill_Draft::SetOptions(const BRepFill_TransitionStyle Style,
305                                  const Standard_Real Min,
306                                  const Standard_Real Max)
307 {
308   myStyle =  Style;
309   angmin = Min; 
310   angmax = Max;
311 }
312
313 //=======================================================================
314 //function :SetDraft
315 //purpose  :
316 //======================================================================
317  void BRepFill_Draft::SetDraft(const Standard_Boolean Internal)
318 {
319   IsInternal = Internal;
320 }
321
322
323 //=======================================================================
324 //function :Perform
325 //purpose  : calculate a surface of skinning
326 //======================================================================
327  void BRepFill_Draft::Perform(const Standard_Real LengthMax)
328 {
329   Handle(Geom_Surface) S;
330   S.Nullify();
331   Bnd_Box WBox;//, SBox;
332   gp_Trsf Trsf;
333
334
335   ComputeTrsf(myWire, myDir, WBox, Trsf); 
336   Init(S, LengthMax, WBox);
337   BuildShell(S); 
338   Sewing(); 
339 }
340
341 //=======================================================================
342 //function :Perform
343 //purpose  : calculate a surface of skinning
344 //======================================================================
345  void BRepFill_Draft::Perform(const Handle(Geom_Surface)& Surface,
346                               const Standard_Boolean KeepInsideSurface)
347 {
348   Bnd_Box WBox, SBox;
349   gp_Trsf Trsf;
350   gp_Pnt Pt;
351   Standard_Real L;
352
353   ComputeTrsf(myWire, myDir, WBox, Trsf);
354
355   // box with bounds of the stop surface  
356   Handle(Geom_Surface) Surf;
357   Surf =   Handle(Geom_Surface)::DownCast(Surface->Transformed(Trsf));
358   GeomAdaptor_Surface S1 (Surf);   
359 //  BndLib_AddSurface AS; 
360 //  AS.Add(S1, 0.1, SBox);
361   BndLib_AddSurface::Add(S1, 0.1, SBox);
362
363   // calculate the maximum length of the rule.
364   L = Longueur(WBox, SBox, myDir, Pt);
365   L /= Abs(Cos(myAngle));
366
367   // Construction
368   Init(Surface, L, WBox);
369   BuildShell(Surface, !KeepInsideSurface);
370   Sewing(); 
371 }
372
373 //================================================================
374 //function :Perform
375 //purpose  : calculate the surface of skinning, stopped by a shape
376 //================================================================
377  void BRepFill_Draft::Perform(const TopoDS_Shape& StopShape,
378                               const Standard_Boolean KeepOutSide)
379 {
380   Bnd_Box WBox, SBox;
381   gp_Trsf Trsf;
382   gp_Pnt Pt;
383   Standard_Real L;
384
385   ComputeTrsf(myWire, myDir, WBox, Trsf); 
386
387 // bounding box of the stop shape
388   Bnd_Box BSurf;//, TheBox;
389   Standard_Real Umin, Umax, Vmin, Vmax;
390 #ifdef DEB
391   Standard_Real Tol = Precision::Confusion()/10;
392 #endif
393 //  BRepTools B;
394 //  BRep_Tool BT;
395   Handle(Geom_Surface) Surf;
396  
397 //  BndLib_AddSurface AS;
398   
399   TopExp_Explorer Ex (StopShape, TopAbs_FACE);
400
401   SBox.SetVoid();
402   while (Ex.More()) { // parse faces of the stop shape
403 //    B.UVBounds(TopoDS::Face(Ex.Current()), Umin,Umax,Vmin,Vmax); 
404     BRepTools::UVBounds(TopoDS::Face(Ex.Current()), Umin,Umax,Vmin,Vmax); 
405     Surf = Handle(Geom_Surface)::DownCast(
406 //     BT.Surface(TopoDS::Face(Ex.Current()))->Transformed(Trsf) ); 
407      BRep_Tool::Surface(TopoDS::Face(Ex.Current()))->Transformed(Trsf) ); 
408     GeomAdaptor_Surface S1 (Surf);
409 // bounding box of the current face
410 //    AS.Add(S1, Umin, Umax, Vmin, Vmax, 0.1, BSurf); 
411     BndLib_AddSurface::Add(S1, Umin, Umax, Vmin, Vmax, 0.1, BSurf);
412     SBox.Add(BSurf);    // group boxes
413     Ex.Next();
414   }// while_Ex
415
416   // calculate the maximum length of the rule.
417   L = Longueur(WBox, SBox, myDir, Pt);
418   L /= Abs(Cos(myAngle));
419
420 // surface of stop
421   gp_Trsf Inv;
422   Inv = Trsf.Inverted(); // inverted transformation
423   Pt.Transform(Inv); // coordinate in the absolute reference
424   Handle(Geom_Plane) Plan = new (Geom_Plane)(Pt, myDir);
425   Surf = new (Geom_RectangularTrimmedSurface) (Plan,-L, L, -L, L); 
426
427 #if DRAW
428   if (Affich) {
429     char* Temp = "ThePlan" ;
430     DrawTrSurf::Set(Temp, Surf);
431 //    DrawTrSurf::Set("ThePlan", Surf);
432   }
433 #endif
434
435 // Sweeping and restriction
436   Init(Plan,  L*1.01, WBox);
437   BuildShell(Surf, Standard_False);
438   Fuse(StopShape,  KeepOutSide);
439   Sewing();
440 }
441
442 //=======================================================================
443 //function : Init
444 //purpose  : Construction of laws.
445 //======================================================================
446  void BRepFill_Draft::Init(const Handle(Geom_Surface)& ,
447                            const Standard_Real Length,
448                            const Bnd_Box&  Box)
449 {
450   Standard_Boolean B;
451
452 // law of positioning   
453   Handle(GeomFill_LocationDraft) Loc
454     = new (GeomFill_LocationDraft) (myDir, myAngle); 
455   myLoc = new (BRepFill_DraftLaw) (myWire, Loc);
456
457   B = GoodOrientation(Box, myLoc, myDir);
458
459   if (IsInternal ^ (!B) )  {
460     myAngle = - myAngle;
461     Loc->SetAngle(myAngle);
462     myLoc = new (BRepFill_DraftLaw) (myWire, Loc);
463   }
464
465   myLoc->CleanLaw(angmin); // Clean small discontinuities.
466
467 // law of section
468 // generating line is straight and parallel to binormal.
469   gp_Pnt P(0, 0, 0);
470   gp_Vec D (0., 1., 0.);
471
472 // Control of the orientation
473   Standard_Real f,l;
474   myLoc->Law(1)->GetDomain(f,l);
475   gp_Mat M;
476
477   gp_Vec Bid; 
478   myLoc->Law(1)->D0( (f+l)/2, M, Bid);
479   gp_Dir BN(M.Column(2));
480   
481   Standard_Real ang = myDir.Angle(BN);
482   if (ang > M_PI/2) D.Reverse();    
483   Handle(Geom_Line) L = new (Geom_Line) (P, D);
484
485   Handle(Geom_Curve) TC = new (Geom_TrimmedCurve) (L, 0, Length);
486
487
488 #if DRAW
489   if (Affich > 2) {
490      TC = new (Geom_Circle) (gp::XOY(), Length);
491   }
492 #endif 
493
494   BRepLib_MakeEdge ME(TC);
495   TopoDS_Edge EG = ME.Edge();
496   
497   BRepLib_MakeWire MW(EG);
498   TopoDS_Wire G = MW.Wire();
499
500   mySec = new (BRepFill_ShapeLaw) (G, Standard_True);
501 }
502
503
504 //=======================================================================
505 //function : BuildShell
506 //purpose  : Construction of the skinning surface 
507 //======================================================================
508  void BRepFill_Draft::BuildShell(const Handle(Geom_Surface)& Surf,
509                                  const Standard_Boolean  KeepOutSide) 
510 {
511 // construction of the surface
512   BRepFill_Sweep Sweep(mySec, myLoc, Standard_True);
513   Sweep.SetTolerance(myTol);
514   Sweep.SetAngularControl(angmin, angmax);
515   Sweep.Build(myStyle, GeomFill_Location, myCont);
516   if (Sweep.IsDone()) {
517     myShape = Sweep.Shape();
518     myShell = TopoDS::Shell(myShape);
519     myFaces    = Sweep.SubShape();
520     mySections = Sweep.Sections();    
521     myDone = Standard_True;
522     // Control of the orientation
523     Standard_Boolean out=Standard_True;
524     TopExp_Explorer ex(myShell,TopAbs_FACE);
525     TopoDS_Face F;
526     F = TopoDS::Face(ex.Current());
527     BRepAdaptor_Surface SF(F);
528     Standard_Real u, v;
529     gp_Pnt P;
530     gp_Vec V1, V2, V;
531     u = SF.FirstUParameter();
532     v = SF.FirstVParameter();
533     SF.D1(u,v,P,V1,V2);
534     V = V1.Crossed(V2);
535     if (F.Orientation() == TopAbs_REVERSED) V.Reverse();
536     if (V.Magnitude() > 1.e-10) {
537       out = myDir.Angle(V) > M_PI/2;
538     }
539     if (out == IsInternal) {
540       myShell.Reverse();
541       myShape.Reverse();
542     }    
543   }
544   else {
545     myDone = Standard_False;
546     return;
547   }
548
549   if (!Surf.IsNull()) { // Add the face at end
550
551   // Waiting the use of traces & retriction in BRepFill_Sweep
552   // Make Fuse.
553     BRepLib_MakeFace MkF;
554     MkF.Init(Surf, Standard_True, Precision::Confusion());
555     Fuse(MkF.Face(), KeepOutSide);
556   }
557 }
558
559
560 //=======================================================================
561 //function : Fuse
562 //purpose  : Boolean operation between the skin and the  
563 //           stop shape 
564 //======================================================================
565  Standard_Boolean BRepFill_Draft::Fuse(const TopoDS_Shape& StopShape,
566                            const Standard_Boolean KeepOutSide)
567 {
568   BRep_Builder B;
569   Standard_Boolean issolid = Standard_False;
570   TopoDS_Solid Sol1, Sol2;
571   TopAbs_State State1 = TopAbs_OUT,  State2 = TopAbs_OUT;
572
573
574   if (myShape.ShapeType()==TopAbs_SOLID) {
575     Sol1 = TopoDS::Solid(myShape);
576     issolid = Standard_True;
577   }
578   else {
579     B.MakeSolid(Sol1);
580     B.Add(Sol1, myShape); // shell => solid (for fusion)    
581   }
582
583
584   switch (StopShape.ShapeType()) {
585   case TopAbs_COMPOUND :
586     {
587       TopoDS_Iterator It(StopShape);
588       return Fuse(It.Value(), KeepOutSide);
589     }
590   case TopAbs_SOLID : 
591     {
592       Sol2 = TopoDS::Solid(StopShape);
593       break;
594     }
595  case TopAbs_SHELL :
596     {
597       B.MakeSolid(Sol2);
598       B.Add(Sol2, StopShape); // shell => solid (for fusion) 
599       break;
600     }
601
602  case TopAbs_FACE :
603     {
604       TopoDS_Shell S;
605       B.MakeShell(S);
606       B.Add(S, StopShape);
607       B.MakeSolid(Sol2);
608       B.Add(Sol2, S); // shell => solid (for fusion)
609       break;
610     }
611
612   default :
613     {
614       return Standard_False; // Impossible to do
615     }
616   }
617       
618   BRepAlgo_DSAccess DSA;
619   DSA.Load(Sol1, Sol2);
620   DSA.Intersect(Sol1, Sol2); // intersection of 2 solids
621  
622 // removal of edges corresponding to "unused" intersections
623   Standard_Integer NbPaquet;
624 // gp_Pnt P1,P2;
625   TopoDS_Vertex V,V1;
626   TopTools_ListOfShape List;
627   List  = DSA.GetSectionEdgeSet();// list of edges
628   
629   NbPaquet = List.Extent();
630
631   if (NbPaquet == 0) {
632 #if DRAW
633     cout << "No fusion" << endl;
634     DBRep::Set("DepPart", Sol1);
635     DBRep::Set("StopPart", Sol2);
636 #endif
637     return Standard_False;
638   }
639
640   if (NbPaquet > 1) {
641     // It is required to select packs.
642     TColStd_Array1OfReal Dist(1, NbPaquet);
643     TopTools_ListIteratorOfListOfShape it(List);
644     Standard_Real D, Dmin = 1.e10;
645     Standard_Integer ii;
646  
647     //Classify the packs by distance.
648     BRepExtrema_DistShapeShape Dist2;
649     Dist2.LoadS1( myWire );
650     for (ii=1; it.More();it.Next(),ii++){
651       Dist2.LoadS2( it.Value() );
652       Dist2.Perform();
653       if (Dist2.IsDone()) {
654         D = Dist2.Value();
655         Dist(ii) = D;
656         if (D < Dmin) Dmin = D;
657       }
658       else
659         Dist(ii) = 1.e10;
660     }
661
662     // remove edges "farther" than Dmin
663     for (ii=1, it.Initialize(List); it.More();it.Next(), ii++){
664       if (Dist(ii) > Dmin) {
665         DSA.SuppressEdgeSet(it.Value());
666       }
667 #if DRAW
668      else if (Affich) {
669         DBRep::Set("KeepEdges", it.Value());
670       }
671 #endif
672     }
673   }
674
675   if (StopShape.ShapeType() != TopAbs_SOLID) {
676     // It is required to choose the state by the geometry
677
678     //(1) Return an edge of section
679     List  = DSA.GetSectionEdgeSet();// list of edges
680     TopTools_ListIteratorOfListOfShape it(List);
681     TopoDS_Iterator iter(it.Value());
682     TopoDS_Edge E = TopoDS::Edge(iter.Value());
683
684     //(2) Return geometry on StopShape
685 // Class BRep_Tool without fields and without Constructor :
686 //    BRep_Tool BT;
687     Handle(Geom_Surface) S;
688     Handle(Geom2d_Curve) C2d;
689     gp_Pnt2d P2d;
690     Standard_Real f,l;  
691     TopLoc_Location L;
692 //    BT.CurveOnSurface(E, C2d, S, L, f, l, 2);
693     BRep_Tool::CurveOnSurface(E, C2d, S, L, f, l, 2);
694
695     // Find a normal.
696     C2d->D0((f+l)/2,P2d); 
697     GeomLProp_SLProps SP(S, P2d.X(), P2d.Y(), 1, 1.e-12);
698     if (! SP.IsNormalDefined()) {
699       C2d->D0((3*f+l)/4,P2d);
700       SP.SetParameters(P2d.X(), P2d.Y());
701       if ( !SP.IsNormalDefined()) {
702         C2d->D0((f+3*l)/4,P2d);
703         SP.SetParameters(P2d.X(), P2d.Y());
704       }
705     }
706
707     // Subtract State1
708     if (myDir.Angle(SP.Normal()) < M_PI/2)  State1 = TopAbs_IN;
709     else  State1 = TopAbs_OUT;
710   }
711
712   if (! KeepOutSide) { // Invert State2;
713     if (State2 == TopAbs_IN) State2 = TopAbs_OUT;
714     else State2 = TopAbs_IN;
715   }
716  
717 //recalculate the final shape
718   TopoDS_Shape result = DSA.Merge(State1, State2); 
719
720   if (issolid) myShape =  result;
721   else {
722     TopExp_Explorer Exp;
723     Exp.Init(result, TopAbs_SHELL);
724     if (Exp.More()) myShape = Exp.Current();
725   }
726
727 // Update the History 
728   Standard_Integer ii;
729   for (ii=1; ii<=myLoc->NbLaw(); ii++) {
730     const TopTools_ListOfShape& L = DSA.Modified(myFaces->Value(1,ii));
731     if (L.Extent()>0) 
732       myFaces->SetValue(1, ii, L.First());
733   }
734   for (ii=1; ii<=myLoc->NbLaw()+1; ii++) {
735     const TopTools_ListOfShape& L = DSA.Modified(mySections->Value(1,ii));
736     if (L.Extent()>0) 
737       mySections->SetValue(1, ii, L.First());
738   } 
739  
740   return Standard_True;
741 }
742
743 //=======================================================================
744 //function : Sewing 
745 //purpose  : Assemble the skin with the above face
746 //======================================================================
747  Standard_Boolean BRepFill_Draft::Sewing()
748 {
749   Standard_Boolean ToAss;
750   Standard_Boolean Ok = Standard_False;
751   ToAss = (myTop.ShapeType() != TopAbs_WIRE);
752
753   if ((!ToAss) || (!myDone)) return Standard_False;
754
755    // Assembly make a shell from the faces of the shape + the input shape
756   Handle(BRepBuilderAPI_Sewing) Ass =  new BRepBuilderAPI_Sewing(5*myTol, Standard_True, 
757                                                      Standard_True, Standard_False);
758   Ass->Add(myShape);
759   Ass->Add(myTop);
760   ToAss = Standard_True;
761  
762
763   Standard_Integer NbCE;
764   
765   Ass->Perform();
766   // Check if the assembly is real.
767   NbCE = Ass->NbContigousEdges();
768   
769   if (NbCE > 0) {
770     TopoDS_Shape res;
771     res = Ass->SewedShape();   
772     if ((res.ShapeType() == TopAbs_SHELL)||
773         (res.ShapeType() == TopAbs_SOLID))  {
774       myShape = res;
775       Ok = Standard_True;
776     }
777     else if (res.ShapeType() == TopAbs_COMPOUND) {
778       TopoDS_Iterator It(res);
779       res = It.Value();
780       It.Next();
781       if (!It.More()) {//Only one part => this is correct
782         myShape = res;
783         Ok = Standard_True;
784       }
785     }
786   }
787
788   if (Ok) {
789     // Update the History
790     Standard_Integer ii;
791     for (ii=1; ii<=myLoc->NbLaw(); ii++) {
792       if (Ass->IsModified(myFaces->Value(1,ii)))     
793         myFaces->SetValue(1, ii, 
794                           Ass->Modified(myFaces->Value(1,ii)));
795     }
796     for (ii=1; ii<=myLoc->NbLaw()+1; ii++) {
797       if (Ass->IsModified(mySections->Value(1,ii))) 
798         mySections->SetValue(1, ii, 
799                              Ass->Modified(mySections->Value(1,ii)));
800     }   
801
802     if (myShape.Closed()) { // Make a Solid
803       TopoDS_Solid solid;
804       BRep_Builder BS;
805       BS.MakeSolid(solid); 
806       BS.Add(solid,TopoDS::Shell(myShape));
807       
808       BRepClass3d_SolidClassifier SC(solid);
809       SC.PerformInfinitePoint(Precision::Confusion());
810       if ( SC.State() == TopAbs_IN) {
811         BS.MakeSolid(solid);
812         myShape.Reverse();
813         BS.Add(solid,TopoDS::Shell(myShape));
814       }
815       myShape = solid;
816     }    
817   }
818 #if DEB
819   else cout << "Draft : No assembly !" << endl;
820 #endif
821   return Ok;
822 }
823
824 //=======================================================================
825 //function : Generated
826 //purpose  : return a sub-part generated by sweeping
827 //======================================================================
828  const TopTools_ListOfShape& 
829  BRepFill_Draft::Generated(const TopoDS_Shape& S) 
830 {
831   myGenerated.Clear();
832   TopoDS_Edge E;
833   Standard_Integer ii;
834   E = TopoDS::Edge(S);
835   if (E.IsNull()) {
836    for (ii=0; ii<=myLoc->NbLaw(); ii++)
837       if (E.IsSame(myLoc->Vertex(ii))) {
838         myGenerated.Append(mySections->Value(1, ii+1));
839         break;
840       } 
841   }
842   else {
843     for (ii=1; ii<=myLoc->NbLaw(); ii++)
844       if (E.IsSame(myLoc->Edge(ii))) {
845         myGenerated.Append(myFaces->Value(1, ii));
846         break;
847       }
848   }
849   
850   return myGenerated;
851 }
852
853 //=======================================================================
854 //function : Shape
855 //purpose  : return the complete shape
856 //======================================================================
857  TopoDS_Shape BRepFill_Draft::Shape()const
858 {
859   return myShape;
860 }
861
862 //=====================================================================
863 //function : Shell
864 //purpose  : surface of skinning with the input face (=>shell)
865 //=====================================================================
866  TopoDS_Shell BRepFill_Draft::Shell()const
867 {
868   return myShell;
869 }
870
871 //=======================================================================
872 //function : IsDone
873 //purpose  : 
874 //======================================================================
875  Standard_Boolean BRepFill_Draft::IsDone()const
876 {
877   return myDone;
878 }