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