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