1 // File: BRepAlgoAPI_Section.cxx
2 // Created: Fri Feb 18 11:14:56 1994
3 // Author: Remi LEQUETTE
5 // modified by Michael KLOKOV Wed Mar 6 15:01:25 2002
7 #include <BRepAlgoAPI_Section.ixx>
10 #include <BRepBuilderAPI_MakeFace.hxx>
11 #include <BRepBuilderAPI_MakeShell.hxx>
12 #include <Geom_Plane.hxx>
13 #include <Geom2d_TrimmedCurve.hxx>
14 #include <BOP_Section.hxx>
15 #include <BOPTools_SSIntersectionAttribute.hxx>
17 #include <BOPTools_SplitShapesPool.hxx>
18 #include <BOPTools_InterferencePool.hxx>
20 #include <BOPTools_PaveBlock.hxx>
21 #include <BOPTools_PaveFiller.hxx>
22 #include <BooleanOperations_ShapesDataStructure.hxx>
23 #include <BOPTools_ListOfPaveBlock.hxx>
24 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
25 #include <BOPTools_SSInterference.hxx>
26 #include <BOPTools_Curve.hxx>
28 #include <TopTools_IndexedMapOfShape.hxx>
29 #include <TopTools_MapOfShape.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <BRep_Tool.hxx>
34 #include <BOP_SectionHistoryCollector.hxx>
36 static TopoDS_Shape MakeShape(const Handle(Geom_Surface)& S)
38 GeomAbs_Shape c = S->Continuity();
39 if (c >= GeomAbs_C2) return BRepBuilderAPI_MakeFace(S, Precision::Confusion());
40 else return BRepBuilderAPI_MakeShell(S);
43 static Standard_Boolean HasAncestorFaces(const BOPTools_DSFiller& theDSFiller,
44 const TopoDS_Shape& E,
48 //=======================================================================
49 //function : Constructor
51 //=======================================================================
52 BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& Sh1,
53 const TopoDS_Shape& Sh2,
54 const Standard_Boolean PerformNow)
55 : BRepAlgoAPI_BooleanOperation(Sh1, Sh2, BOP_SECTION)
58 myparameterschanged = Standard_True;
60 if(myS1.IsNull() || myS2.IsNull()) {
61 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
62 myshapeisnull = Standard_True;
68 BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& aS1,
69 const TopoDS_Shape& aS2,
70 const BOPTools_DSFiller& aDSF,
71 const Standard_Boolean PerformNow)
72 : BRepAlgoAPI_BooleanOperation(aS1, aS2, aDSF, BOP_SECTION)
75 myparameterschanged = Standard_True;
77 if(myS1.IsNull() || myS2.IsNull()) {
78 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
79 myshapeisnull = Standard_True;
88 //=======================================================================
89 //function : Constructor
91 //=======================================================================
92 BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& Sh,
94 const Standard_Boolean PerformNow)
95 : BRepAlgoAPI_BooleanOperation(Sh, MakeShape(new Geom_Plane(Pl)), BOP_SECTION)
98 myparameterschanged = Standard_True;
100 if(Sh.IsNull() || myS2.IsNull()) {
101 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
102 myshapeisnull = Standard_True;
108 //=======================================================================
109 //function : Constructor
111 //=======================================================================
112 BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& Sh,
113 const Handle(Geom_Surface)& Sf,
114 const Standard_Boolean PerformNow)
115 : BRepAlgoAPI_BooleanOperation(Sh, MakeShape(Sf), BOP_SECTION)
118 myparameterschanged = Standard_True;
120 if(Sh.IsNull() || myS2.IsNull()) {
121 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
122 myshapeisnull = Standard_True;
128 //=======================================================================
129 //function : Constructor
131 //=======================================================================
132 BRepAlgoAPI_Section::BRepAlgoAPI_Section(const Handle(Geom_Surface)& Sf,
133 const TopoDS_Shape& Sh,
134 const Standard_Boolean PerformNow)
135 : BRepAlgoAPI_BooleanOperation(MakeShape(Sf), Sh, BOP_SECTION)
138 myparameterschanged = Standard_True;
140 if(myS1.IsNull() || Sh.IsNull()) {
141 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
142 myshapeisnull = Standard_True;
148 //=======================================================================
149 //function : Constructor
151 //=======================================================================
152 BRepAlgoAPI_Section::BRepAlgoAPI_Section(const Handle(Geom_Surface)& Sf1,
153 const Handle(Geom_Surface)& Sf2,
154 const Standard_Boolean PerformNow)
155 : BRepAlgoAPI_BooleanOperation(MakeShape(Sf1), MakeShape(Sf2), BOP_SECTION)
158 myparameterschanged = Standard_True;
160 if(myS1.IsNull() || myS2.IsNull()) {
161 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
162 myshapeisnull = Standard_True;
169 //=======================================================================
172 //=======================================================================
173 void BRepAlgoAPI_Section::Init1(const TopoDS_Shape& S1)
176 if (!S1.IsEqual(myS1)) {
180 myshapeisnull = Standard_False;
182 myparameterschanged = Standard_True;
188 myshapeisnull = Standard_True;
189 myparameterschanged = Standard_True;
193 if(myparameterschanged)
197 //=======================================================================
200 //=======================================================================
201 void BRepAlgoAPI_Section::Init1(const gp_Pln& Pl)
203 Init1(MakeShape(new Geom_Plane(Pl)));
206 //=======================================================================
209 //=======================================================================
210 void BRepAlgoAPI_Section::Init1(const Handle(Geom_Surface)& Sf)
212 Init1(MakeShape(Sf));
215 //=======================================================================
218 //=======================================================================
219 void BRepAlgoAPI_Section::Init2(const TopoDS_Shape& S2)
222 if (!S2.IsEqual(myS2)) {
226 myshapeisnull = Standard_False;
228 myparameterschanged = Standard_True;
234 myshapeisnull = Standard_True;
235 myparameterschanged = Standard_True;
239 if(myparameterschanged) {
244 //=======================================================================
247 //=======================================================================
248 void BRepAlgoAPI_Section::Init2(const gp_Pln& Pl)
250 Init2(MakeShape(new Geom_Plane(Pl)));
253 //=======================================================================
256 //=======================================================================
257 void BRepAlgoAPI_Section::Init2(const Handle(Geom_Surface)& Sf)
259 Init2(MakeShape(Sf));
262 //=======================================================================
263 //function : Approximation
265 //=======================================================================
266 void BRepAlgoAPI_Section::Approximation(const Standard_Boolean B)
270 myparameterschanged = Standard_True;
274 //=======================================================================
275 //function : ComputePCurveOn1
277 //=======================================================================
278 void BRepAlgoAPI_Section::ComputePCurveOn1(const Standard_Boolean B)
280 if(myComputePCurve1 != B) {
281 myComputePCurve1 = B;
282 myparameterschanged = Standard_True;
286 //=======================================================================
287 //function : ComputePCurveOn2
289 //=======================================================================
290 void BRepAlgoAPI_Section::ComputePCurveOn2(const Standard_Boolean B)
292 if(myComputePCurve2 != B) {
293 myComputePCurve2 = B;
294 myparameterschanged = Standard_True;
298 //=======================================================================
301 //=======================================================================
302 void BRepAlgoAPI_Section::Build()
310 if(myparameterschanged) {
312 myBuilderCanWork = Standard_False;
314 Standard_Boolean bIsNewFiller = PrepareFiller();
316 if (myErrorStatus!=1) {
318 // there were errors during the preparation
324 BOPTools_SSIntersectionAttribute aSectionAttribute(myApprox, myComputePCurve1, myComputePCurve2);
325 myDSFiller->Perform(aSectionAttribute);
327 BOP_Section* aSectionAlgo = new BOP_Section();
328 aSectionAlgo->SetShapes(myS1, myS2);
330 myHistory = new BOP_SectionHistoryCollector(myS1, myS2);
331 aSectionAlgo->SetHistoryCollector(myHistory);
333 aSectionAlgo->DoWithFiller(*myDSFiller);
335 myBuilder = aSectionAlgo;
337 if(aSectionAlgo->IsDone()) {
339 myBuilderCanWork=Standard_True;
340 myShape = aSectionAlgo->Result();
344 myErrorStatus = 100 + aSectionAlgo->ErrorStatus();
347 myparameterschanged = Standard_False;
351 //=======================================================================
352 //function : HasAncestorFaceOn1
354 //=======================================================================
355 Standard_Boolean BRepAlgoAPI_Section::HasAncestorFaceOn1(const TopoDS_Shape& E, TopoDS_Shape& F) const
357 Standard_Boolean aResult = Standard_False;
362 if(E.ShapeType() != TopAbs_EDGE) {
366 aResult = HasAncestorFaces(*myDSFiller, E, F1, F2);
369 return Standard_False;
375 //=======================================================================
376 //function : HasAncestorFaceOn2
378 //=======================================================================
379 Standard_Boolean BRepAlgoAPI_Section::HasAncestorFaceOn2(const TopoDS_Shape& E,TopoDS_Shape& F) const
381 Standard_Boolean aResult = Standard_False;
386 if(E.ShapeType() != TopAbs_EDGE) {
390 aResult = HasAncestorFaces(*myDSFiller, E, F1, F2);
393 return Standard_False;
399 //=======================================================================
400 //function : PCurveOn1
402 //=======================================================================
403 Handle(Geom2d_Curve) BRepAlgoAPI_Section::PCurveOn1(const TopoDS_Shape& E) const
405 Handle(Geom2d_Curve) aResult;
407 if(myComputePCurve1) {
410 if(HasAncestorFaceOn1(E, aShape)) {
411 const TopoDS_Edge& anEdge = TopoDS::Edge(E);
412 const TopoDS_Face& aFace = TopoDS::Face(aShape);
414 aResult = BRep_Tool::CurveOnSurface(anEdge, aFace, f, l);
416 if(!aResult->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
417 aResult = new Geom2d_TrimmedCurve(aResult, f, l);
424 //=======================================================================
425 //function : PCurveOn2
427 //=======================================================================
428 Handle(Geom2d_Curve) BRepAlgoAPI_Section::PCurveOn2(const TopoDS_Shape& E) const
430 Handle(Geom2d_Curve) aResult;
432 if(myComputePCurve2) {
435 if(HasAncestorFaceOn2(E, aShape)) {
436 const TopoDS_Edge& anEdge = TopoDS::Edge(E);
437 const TopoDS_Face& aFace = TopoDS::Face(aShape);
439 aResult = BRep_Tool::CurveOnSurface(anEdge, aFace, f, l);
441 if(!aResult->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
442 aResult = new Geom2d_TrimmedCurve(aResult, f, l);
449 //=======================================================================
450 //function : InitParameters
452 //=======================================================================
453 void BRepAlgoAPI_Section::InitParameters()
455 myparameterschanged = Standard_False;
456 myshapeisnull = Standard_False;
457 myApprox = Standard_False;
458 myComputePCurve1 = Standard_False;
459 myComputePCurve2 = Standard_False;
462 // ------------------------------------------------------------------------
463 // static function : HasAncestorFaces
465 // ------------------------------------------------------------------------
466 static Standard_Boolean HasAncestorFaces(const BOPTools_DSFiller& theDSFiller,
467 const TopoDS_Shape& E,
471 BOPTools_PaveFiller* aPaveFiller = (BOPTools_PaveFiller*) &theDSFiller.PaveFiller();
472 const BOPTools_CArray1OfSSInterference& aFFs = aPaveFiller->InterfPool()->SSInterferences();
473 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS();
474 Standard_Integer aNb = aFFs.Extent();
475 Standard_Integer i = 0;
477 for (i = 1; i <= aNb; i++) {
478 BOPTools_SSInterference* aFFi = (BOPTools_SSInterference*) &aFFs(i);
479 const BOPTools_SequenceOfCurves& aSeqOfCurve = aFFi->Curves();
481 for(Standard_Integer j = 1; j <= aSeqOfCurve.Length(); j++) {
482 const BOPTools_Curve& aCurve = aSeqOfCurve.Value(j);
483 BOPTools_ListIteratorOfListOfPaveBlock anIt(aCurve.NewPaveBlocks());
485 for(; anIt.More(); anIt.Next()) {
486 const BOPTools_PaveBlock& aPB = anIt.Value();
487 Standard_Integer anIndex = aPB.Edge();
492 if(E.IsSame(aDS.Shape(anIndex))) {
493 for(Standard_Integer fIt = 0; fIt < 2; fIt++) {
494 anIndex = (fIt == 0) ? aFFi->Index1() : aFFi->Index2();
498 F1 = aDS.Shape(anIndex);
500 F2 = aDS.Shape(anIndex);
503 return Standard_True;
508 BOPTools_ListIteratorOfListOfPaveBlock anIt(aFFi->PaveBlocks());
510 for(; anIt.More(); anIt.Next()) {
511 const BOPTools_PaveBlock& aPB = anIt.Value();
512 Standard_Integer anIndex = aPB.Edge();
517 if(E.IsSame(aDS.Shape(anIndex))) {
518 for(Standard_Integer fIt = 0; fIt < 2; fIt++) {
519 anIndex = (fIt == 0) ? aFFi->Index1() : aFFi->Index2();
523 F1 = aDS.Shape(anIndex);
525 F2 = aDS.Shape(anIndex);
528 return Standard_True;
532 return Standard_False;