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