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