0024880: Invalid result of pipe creation
[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//
d5f74e42 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
973c2be1 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
c8ea5b8e 17
7fd59977 18#include <BRepFill_Draft.ixx>
19
20#include <BRepFill_DraftLaw.hxx>
21#include <BRepFill_ShapeLaw.hxx>
22#include <BRepFill_Sweep.hxx>
c8ea5b8e 23#include <BRepFill_DataMapOfShapeHArray2OfShape.hxx>
7fd59977 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>
90static Standard_Boolean Affich = 0;
91#endif
92
93//=======================================================================
94//function : Trsf
95//purpose :
96//======================================================================
97static void ComputeTrsf(const TopoDS_Wire& W,
98 const gp_Dir& D,
99 Bnd_Box& Box,
100 gp_Trsf& Tf)
101{
0d969553 102 // Calculate approximate barycenter
7fd59977 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
0d969553 116 // Calculate the Transformation
7fd59977 117 gp_Ax3 N(Bary, D);
118 Tf.SetTransformation(N);
119 BRepAdaptor_Curve AC;
120// BndLib_Add3dCurve BC;
121
0d969553 122 // transformation to the wire
7fd59977 123 TopoDS_Wire TheW = W;
124 TopLoc_Location Loc(Tf);
125 TheW.Location(Loc);
126
127
0d969553 128 // Calculate the box
7fd59977 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//=======================================================================
0d969553 138//function : Length
7fd59977 139//purpose :
140//======================================================================
141static Standard_Real Longueur(const Bnd_Box& WBox,
142 const Bnd_Box& SBox,
143 gp_Dir& D,
144 gp_Pnt& P)
145{
0d969553
Y
146 // face of the box most remoted from the face input in
147 // the direction of skin
7fd59977 148 Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,WZmin,WZmax,L;
149
0d969553 150 //"coord" of the box
7fd59977 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) {
0d969553 159 // Skin in the wrong direction. Invert...
7fd59977 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
0d969553 172//purpose : Check if the law is oriented to have an exterior skin
7fd59977 173//======================================================================
174static 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
0d969553 196 Nb++; // Number of points
7fd59977 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
0d969553 280 cout << "No Free Borders !" << endl;
7fd59977 281#endif
282 Standard_ConstructionError::Raise("BRepFill_Draft");
283 }
284 break;
285 }
286 default :
287 Standard_ConstructionError::Raise("BRepFill_Draft");
288 }
289
0d969553 290 // Attention to closed non declared wires !
7fd59977 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
0d969553 314//purpose : Defines the style
7fd59977 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
0d969553 337//purpose : calculate a surface of skinning
7fd59977 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
0d969553 355//purpose : calculate a surface of skinning
7fd59977 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
0d969553 367 // box with bounds of the stop surface
7fd59977 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
0d969553 375 // calculate the maximum length of the rule.
7fd59977 376 L = Longueur(WBox, SBox, myDir, Pt);
377 L /= Abs(Cos(myAngle));
378
0d969553 379 // Construction
7fd59977 380 Init(Surface, L, WBox);
381 BuildShell(Surface, !KeepInsideSurface);
382 Sewing();
383}
384
0d969553 385//================================================================
7fd59977 386//function :Perform
0d969553
Y
387//purpose : calculate the surface of skinning, stopped by a shape
388//================================================================
7fd59977 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
0d969553 399// bounding box of the stop shape
7fd59977 400 Bnd_Box BSurf;//, TheBox;
401 Standard_Real Umin, Umax, Vmin, Vmax;
7fd59977 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();
0d969553 411 while (Ex.More()) { // parse faces of the stop shape
7fd59977 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);
0d969553 418// bounding box of the current face
7fd59977 419// AS.Add(S1, Umin, Umax, Vmin, Vmax, 0.1, BSurf);
420 BndLib_AddSurface::Add(S1, Umin, Umax, Vmin, Vmax, 0.1, BSurf);
0d969553 421 SBox.Add(BSurf); // group boxes
7fd59977 422 Ex.Next();
423 }// while_Ex
424
0d969553 425 // calculate the maximum length of the rule.
7fd59977 426 L = Longueur(WBox, SBox, myDir, Pt);
427 L /= Abs(Cos(myAngle));
428
0d969553 429// surface of stop
7fd59977 430 gp_Trsf Inv;
0d969553
Y
431 Inv = Trsf.Inverted(); // inverted transformation
432 Pt.Transform(Inv); // coordinate in the absolute reference
7fd59977 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
0d969553 444// Sweeping and restriction
7fd59977 445 Init(Plan, L*1.01, WBox);
446 BuildShell(Surf, Standard_False);
447 Fuse(StopShape, KeepOutSide);
448 Sewing();
449}
450
451//=======================================================================
452//function : Init
0d969553 453//purpose : Construction of laws.
7fd59977 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
0d969553 461// law of positioning
7fd59977 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
0d969553 474 myLoc->CleanLaw(angmin); // Clean small discontinuities.
7fd59977 475
0d969553
Y
476// law of section
477// generating line is straight and parallel to binormal.
7fd59977 478 gp_Pnt P(0, 0, 0);
479 gp_Vec D (0., 1., 0.);
480
0d969553 481// Control of the orientation
7fd59977 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);
c6541a0c 491 if (ang > M_PI/2) D.Reverse();
7fd59977 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
0d969553 515//purpose : Construction of the skinning surface
7fd59977 516//======================================================================
517 void BRepFill_Draft::BuildShell(const Handle(Geom_Surface)& Surf,
518 const Standard_Boolean KeepOutSide)
519{
0d969553 520// construction of the surface
7fd59977 521 BRepFill_Sweep Sweep(mySec, myLoc, Standard_True);
522 Sweep.SetTolerance(myTol);
523 Sweep.SetAngularControl(angmin, angmax);
c8ea5b8e 524 TopTools_MapOfShape Dummy;
525 BRepFill_DataMapOfShapeHArray2OfShape Dummy2;
8e817497 526 BRepFill_DataMapOfShapeHArray2OfShape Dummy3;
527 Sweep.Build(Dummy, Dummy2, Dummy3, myStyle, myCont);
7fd59977 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;
0d969553 534 // Control of the orientation
7fd59977 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) {
c6541a0c 549 out = myDir.Angle(V) > M_PI/2;
7fd59977 550 }
551 if (out == IsInternal) {
552 myShell.Reverse();
553 myShape.Reverse();
554 }
555 }
556 else {
557 myDone = Standard_False;
558 return;
559 }
560
0d969553 561 if (!Surf.IsNull()) { // Add the face at end
7fd59977 562
0d969553
Y
563 // Waiting the use of traces & retriction in BRepFill_Sweep
564 // Make Fuse.
7fd59977 565 BRepLib_MakeFace MkF;
1c72dff6 566 MkF.Init(Surf, Standard_True, Precision::Confusion());
7fd59977 567 Fuse(MkF.Face(), KeepOutSide);
568 }
569}
570
571
572//=======================================================================
573//function : Fuse
0d969553
Y
574//purpose : Boolean operation between the skin and the
575// stop shape
7fd59977 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);
0d969553 592 B.Add(Sol1, myShape); // shell => solid (for fusion)
7fd59977 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);
0d969553 610 B.Add(Sol2, StopShape); // shell => solid (for fusion)
7fd59977 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);
0d969553 620 B.Add(Sol2, S); // shell => solid (for fusion)
7fd59977 621 break;
622 }
623
624 default :
625 {
0d969553 626 return Standard_False; // Impossible to do
7fd59977 627 }
628 }
629
630 BRepAlgo_DSAccess DSA;
631 DSA.Load(Sol1, Sol2);
0d969553 632 DSA.Intersect(Sol1, Sol2); // intersection of 2 solids
7fd59977 633
0d969553 634// removal of edges corresponding to "unused" intersections
7fd59977 635 Standard_Integer NbPaquet;
636// gp_Pnt P1,P2;
637 TopoDS_Vertex V,V1;
638 TopTools_ListOfShape List;
0d969553 639 List = DSA.GetSectionEdgeSet();// list of edges
7fd59977 640
641 NbPaquet = List.Extent();
642
643 if (NbPaquet == 0) {
644#if DRAW
0d969553 645 cout << "No fusion" << endl;
7fd59977 646 DBRep::Set("DepPart", Sol1);
647 DBRep::Set("StopPart", Sol2);
648#endif
649 return Standard_False;
650 }
651
652 if (NbPaquet > 1) {
0d969553 653 // It is required to select packs.
7fd59977 654 TColStd_Array1OfReal Dist(1, NbPaquet);
655 TopTools_ListIteratorOfListOfShape it(List);
656 Standard_Real D, Dmin = 1.e10;
657 Standard_Integer ii;
658
0d969553 659 //Classify the packs by distance.
7fd59977 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
0d969553 674 // remove edges "farther" than Dmin
7fd59977 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) {
0d969553 688 // It is required to choose the state by the geometry
7fd59977 689
0d969553
Y
690 //(1) Return an edge of section
691 List = DSA.GetSectionEdgeSet();// list of edges
7fd59977 692 TopTools_ListIteratorOfListOfShape it(List);
693 TopoDS_Iterator iter(it.Value());
694 TopoDS_Edge E = TopoDS::Edge(iter.Value());
695
0d969553 696 //(2) Return geometry on StopShape
7fd59977 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
0d969553 707 // Find a normal.
7fd59977 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
0d969553 719 // Subtract State1
c6541a0c 720 if (myDir.Angle(SP.Normal()) < M_PI/2) State1 = TopAbs_IN;
7fd59977 721 else State1 = TopAbs_OUT;
722 }
723
0d969553 724 if (! KeepOutSide) { // Invert State2;
7fd59977 725 if (State2 == TopAbs_IN) State2 = TopAbs_OUT;
726 else State2 = TopAbs_IN;
727 }
728
0d969553 729//recalculate the final shape
7fd59977 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
0d969553 739// Update the History
7fd59977 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
0d969553 757//purpose : Assemble the skin with the above face
7fd59977 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
0d969553 767 // Assembly make a shell from the faces of the shape + the input shape
7fd59977 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();
0d969553 778 // Check if the assembly is real.
7fd59977 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();
0d969553 793 if (!It.More()) {//Only one part => this is correct
7fd59977 794 myShape = res;
795 Ok = Standard_True;
796 }
797 }
798 }
799
800 if (Ok) {
0d969553 801 // Update the History
7fd59977 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
0d969553 814 if (myShape.Closed()) { // Make a Solid
7fd59977 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
0d969553 831 else cout << "Draft : No assembly !" << endl;
7fd59977 832#endif
833 return Ok;
834}
835
836//=======================================================================
837//function : Generated
0d969553 838//purpose : return a sub-part generated by sweeping
7fd59977 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
0d969553 867//purpose : return the complete shape
7fd59977 868//======================================================================
869 TopoDS_Shape BRepFill_Draft::Shape()const
870{
871 return myShape;
872}
873
0d969553 874//=====================================================================
7fd59977 875//function : Shell
0d969553
Y
876//purpose : surface of skinning with the input face (=>shell)
877//=====================================================================
7fd59977 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}