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