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