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