0023024: Update headers of OCCT files
[occt.git] / src / BRepAlgoAPI / BRepAlgoAPI_Section.cxx
CommitLineData
b311480e 1// Created on: 1994-02-18
2// Created by: Remi LEQUETTE
3// Copyright (c) 1994-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21// modified by Michael KLOKOV Wed Mar 6 15:01:25 2002
22
23#include <BRepAlgoAPI_Section.ixx>
24
25
26#include <BRepBuilderAPI_MakeFace.hxx>
27#include <BRepBuilderAPI_MakeShell.hxx>
28#include <Geom_Plane.hxx>
29#include <Geom2d_TrimmedCurve.hxx>
30#include <BOP_Section.hxx>
31#include <BOPTools_SSIntersectionAttribute.hxx>
32
33#include <BOPTools_SplitShapesPool.hxx>
34#include <BOPTools_InterferencePool.hxx>
35
36#include <BOPTools_PaveBlock.hxx>
37#include <BOPTools_PaveFiller.hxx>
38#include <BooleanOperations_ShapesDataStructure.hxx>
39#include <BOPTools_ListOfPaveBlock.hxx>
40#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
41#include <BOPTools_SSInterference.hxx>
42#include <BOPTools_Curve.hxx>
43#include <TopExp.hxx>
44#include <TopTools_IndexedMapOfShape.hxx>
45#include <TopTools_MapOfShape.hxx>
46#include <TopoDS.hxx>
47#include <TopoDS_Face.hxx>
48#include <BRep_Tool.hxx>
49
50#include <BOP_SectionHistoryCollector.hxx>
51
52static TopoDS_Shape MakeShape(const Handle(Geom_Surface)& S)
53{
54 GeomAbs_Shape c = S->Continuity();
1c72dff6 55 if (c >= GeomAbs_C2) return BRepBuilderAPI_MakeFace(S, Precision::Confusion());
7fd59977 56 else return BRepBuilderAPI_MakeShell(S);
57}
58
59static Standard_Boolean HasAncestorFaces(const BOPTools_DSFiller& theDSFiller,
60 const TopoDS_Shape& E,
61 TopoDS_Shape& F1,
62 TopoDS_Shape& F2);
63
64//=======================================================================
65//function : Constructor
66//purpose :
67//=======================================================================
68BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& Sh1,
69 const TopoDS_Shape& Sh2,
70 const Standard_Boolean PerformNow)
71: BRepAlgoAPI_BooleanOperation(Sh1, Sh2, BOP_SECTION)
72{
73 InitParameters();
74 myparameterschanged = Standard_True;
75
76 if(myS1.IsNull() || myS2.IsNull()) {
77 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
78 myshapeisnull = Standard_True;
79 }
80 if (PerformNow)
81 Build();
82}
83
84BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& aS1,
85 const TopoDS_Shape& aS2,
86 const BOPTools_DSFiller& aDSF,
87 const Standard_Boolean PerformNow)
88: BRepAlgoAPI_BooleanOperation(aS1, aS2, aDSF, BOP_SECTION)
89{
90 InitParameters();
91 myparameterschanged = Standard_True;
92
93 if(myS1.IsNull() || myS2.IsNull()) {
94 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
95 myshapeisnull = Standard_True;
96 }
97
98 if(PerformNow) {
99 Build();
100 }
101}
102
103
104//=======================================================================
105//function : Constructor
106//purpose :
107//=======================================================================
108BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& Sh,
109 const gp_Pln& Pl,
110 const Standard_Boolean PerformNow)
111: BRepAlgoAPI_BooleanOperation(Sh, MakeShape(new Geom_Plane(Pl)), BOP_SECTION)
112{
113 InitParameters();
114 myparameterschanged = Standard_True;
115
116 if(Sh.IsNull() || myS2.IsNull()) {
117 // StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
118 myshapeisnull = Standard_True;
119 }
120 if (PerformNow)
121 Build();
122}
123
124//=======================================================================
125//function : Constructor
126//purpose :
127//=======================================================================
128BRepAlgoAPI_Section::BRepAlgoAPI_Section(const TopoDS_Shape& Sh,
129 const Handle(Geom_Surface)& Sf,
130 const Standard_Boolean PerformNow)
131: BRepAlgoAPI_BooleanOperation(Sh, MakeShape(Sf), BOP_SECTION)
132{
133 InitParameters();
134 myparameterschanged = Standard_True;
135
136 if(Sh.IsNull() || myS2.IsNull()) {
137// StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
138 myshapeisnull = Standard_True;
139 }
140 if (PerformNow)
141 Build();
142}
143
144//=======================================================================
145//function : Constructor
146//purpose :
147//=======================================================================
148BRepAlgoAPI_Section::BRepAlgoAPI_Section(const Handle(Geom_Surface)& Sf,
149 const TopoDS_Shape& Sh,
150 const Standard_Boolean PerformNow)
151: BRepAlgoAPI_BooleanOperation(MakeShape(Sf), Sh, BOP_SECTION)
152{
153 InitParameters();
154 myparameterschanged = Standard_True;
155
156 if(myS1.IsNull() || Sh.IsNull()) {
157// StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
158 myshapeisnull = Standard_True;
159 }
160 if (PerformNow)
161 Build();
162}
163
164//=======================================================================
165//function : Constructor
166//purpose :
167//=======================================================================
168BRepAlgoAPI_Section::BRepAlgoAPI_Section(const Handle(Geom_Surface)& Sf1,
169 const Handle(Geom_Surface)& Sf2,
170 const Standard_Boolean PerformNow)
171: BRepAlgoAPI_BooleanOperation(MakeShape(Sf1), MakeShape(Sf2), BOP_SECTION)
172{
173 InitParameters();
174 myparameterschanged = Standard_True;
175
176 if(myS1.IsNull() || myS2.IsNull()) {
177// StdFail_NotDone::Raise("BRepAlgoAPI_Section : Shape NULL");
178 myshapeisnull = Standard_True;
179 }
180
181 if (PerformNow)
182 Build();
183}
184
185//=======================================================================
186//function : Init1
187//purpose :
188//=======================================================================
189void BRepAlgoAPI_Section::Init1(const TopoDS_Shape& S1)
190{
191 if(!S1.IsNull()) {
192 if (!S1.IsEqual(myS1)) {
193 myS1 = S1;
194
195 if(!myS2.IsNull()) {
196 myshapeisnull = Standard_False;
197 }
198 myparameterschanged = Standard_True;
199 }
200 }
201 else {
202 if(!myS1.IsNull()) {
203 myS1 = S1;
204 myshapeisnull = Standard_True;
205 myparameterschanged = Standard_True;
206 }
207 }
208
209 if(myparameterschanged)
210 NotDone();
211}
212
213//=======================================================================
214//function : Init1
215//purpose :
216//=======================================================================
217void BRepAlgoAPI_Section::Init1(const gp_Pln& Pl)
218{
219 Init1(MakeShape(new Geom_Plane(Pl)));
220}
221
222//=======================================================================
223//function : Init1
224//purpose :
225//=======================================================================
226void BRepAlgoAPI_Section::Init1(const Handle(Geom_Surface)& Sf)
227{
228 Init1(MakeShape(Sf));
229}
230
231//=======================================================================
232//function : Init2
233//purpose :
234//=======================================================================
235void BRepAlgoAPI_Section::Init2(const TopoDS_Shape& S2)
236{
237 if(!S2.IsNull()) {
238 if (!S2.IsEqual(myS2)) {
239 myS2 = S2;
240
241 if(!myS1.IsNull()) {
242 myshapeisnull = Standard_False;
243 }
244 myparameterschanged = Standard_True;
245 }
246 }
247 else {
248 if(!myS2.IsNull()) {
249 myS2 = S2;
250 myshapeisnull = Standard_True;
251 myparameterschanged = Standard_True;
252 }
253 }
254
255 if(myparameterschanged) {
256 NotDone();
257 }
258}
259
260//=======================================================================
261//function : Init2
262//purpose :
263//=======================================================================
264void BRepAlgoAPI_Section::Init2(const gp_Pln& Pl)
265{
266 Init2(MakeShape(new Geom_Plane(Pl)));
267}
268
269//=======================================================================
270//function : Init2
271//purpose :
272//=======================================================================
273void BRepAlgoAPI_Section::Init2(const Handle(Geom_Surface)& Sf)
274{
275 Init2(MakeShape(Sf));
276}
277
278//=======================================================================
279//function : Approximation
280//purpose :
281//=======================================================================
282void BRepAlgoAPI_Section::Approximation(const Standard_Boolean B)
283{
284 if(myApprox != B) {
285 myApprox = B;
286 myparameterschanged = Standard_True;
287 }
288}
289
290//=======================================================================
291//function : ComputePCurveOn1
292//purpose :
293//=======================================================================
294void BRepAlgoAPI_Section::ComputePCurveOn1(const Standard_Boolean B)
295{
296 if(myComputePCurve1 != B) {
297 myComputePCurve1 = B;
298 myparameterschanged = Standard_True;
299 }
300}
301
302//=======================================================================
303//function : ComputePCurveOn2
304//purpose :
305//=======================================================================
306void BRepAlgoAPI_Section::ComputePCurveOn2(const Standard_Boolean B)
307{
308 if(myComputePCurve2 != B) {
309 myComputePCurve2 = B;
310 myparameterschanged = Standard_True;
311 }
312}
313
314//=======================================================================
315//function : Build
316//purpose :
317//=======================================================================
318void BRepAlgoAPI_Section::Build()
319{
320 if(myshapeisnull) {
321 myErrorStatus = 2;
322 NotDone();
323 return;
324 }
325
326 if(myparameterschanged) {
327
328 myBuilderCanWork = Standard_False;
329
330 Standard_Boolean bIsNewFiller = PrepareFiller();
331 //
332 if (myErrorStatus!=1) {
333 NotDone();
334 // there were errors during the preparation
335 return;
336 }
337 //
338 if (bIsNewFiller) {
339 //Prepare the DS
340 BOPTools_SSIntersectionAttribute aSectionAttribute(myApprox, myComputePCurve1, myComputePCurve2);
341 myDSFiller->Perform(aSectionAttribute);
342 }
343 BOP_Section* aSectionAlgo = new BOP_Section();
344 aSectionAlgo->SetShapes(myS1, myS2);
345
346 myHistory = new BOP_SectionHistoryCollector(myS1, myS2);
347 aSectionAlgo->SetHistoryCollector(myHistory);
348
349 aSectionAlgo->DoWithFiller(*myDSFiller);
350
351 myBuilder = aSectionAlgo;
352
353 if(aSectionAlgo->IsDone()) {
354 myErrorStatus=0;
355 myBuilderCanWork=Standard_True;
356 myShape = aSectionAlgo->Result();
357 Done();
358 }
359 else {
360 myErrorStatus = 100 + aSectionAlgo->ErrorStatus();
361 NotDone();
362 }
363 myparameterschanged = Standard_False;
364 }
365}
366
367//=======================================================================
368//function : HasAncestorFaceOn1
369//purpose :
370//=======================================================================
371Standard_Boolean BRepAlgoAPI_Section::HasAncestorFaceOn1(const TopoDS_Shape& E, TopoDS_Shape& F) const
372{
373 Standard_Boolean aResult = Standard_False;
374 if(E.IsNull()) {
375 return aResult;
376 }
377
378 if(E.ShapeType() != TopAbs_EDGE) {
379 return aResult;
380 }
381 TopoDS_Shape F1, F2;
382 aResult = HasAncestorFaces(*myDSFiller, E, F1, F2);
383
384 if(F1.IsNull()) {
385 return Standard_False;
386 }
387 F = F1;
388 return aResult;
389}
390
391//=======================================================================
392//function : HasAncestorFaceOn2
393//purpose :
394//=======================================================================
395Standard_Boolean BRepAlgoAPI_Section::HasAncestorFaceOn2(const TopoDS_Shape& E,TopoDS_Shape& F) const
396{
397 Standard_Boolean aResult = Standard_False;
398 if(E.IsNull()) {
399 return aResult;
400 }
401
402 if(E.ShapeType() != TopAbs_EDGE) {
403 return aResult;
404 }
405 TopoDS_Shape F1, F2;
406 aResult = HasAncestorFaces(*myDSFiller, E, F1, F2);
407
408 if(F2.IsNull()) {
409 return Standard_False;
410 }
411 F = F2;
412 return aResult;
413}
414
415//=======================================================================
416//function : PCurveOn1
417//purpose :
418//=======================================================================
419Handle(Geom2d_Curve) BRepAlgoAPI_Section::PCurveOn1(const TopoDS_Shape& E) const
420{
421 Handle(Geom2d_Curve) aResult;
422
423 if(myComputePCurve1) {
424 TopoDS_Shape aShape;
425
426 if(HasAncestorFaceOn1(E, aShape)) {
427 const TopoDS_Edge& anEdge = TopoDS::Edge(E);
428 const TopoDS_Face& aFace = TopoDS::Face(aShape);
429 Standard_Real f, l;
430 aResult = BRep_Tool::CurveOnSurface(anEdge, aFace, f, l);
431
432 if(!aResult->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
433 aResult = new Geom2d_TrimmedCurve(aResult, f, l);
434 }
435 }
436 }
437 return aResult;
438}
439
440//=======================================================================
441//function : PCurveOn2
442//purpose :
443//=======================================================================
444Handle(Geom2d_Curve) BRepAlgoAPI_Section::PCurveOn2(const TopoDS_Shape& E) const
445{
446 Handle(Geom2d_Curve) aResult;
447
448 if(myComputePCurve2) {
449 TopoDS_Shape aShape;
450
451 if(HasAncestorFaceOn2(E, aShape)) {
452 const TopoDS_Edge& anEdge = TopoDS::Edge(E);
453 const TopoDS_Face& aFace = TopoDS::Face(aShape);
454 Standard_Real f, l;
455 aResult = BRep_Tool::CurveOnSurface(anEdge, aFace, f, l);
456
457 if(!aResult->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
458 aResult = new Geom2d_TrimmedCurve(aResult, f, l);
459 }
460 }
461 }
462 return aResult;
463}
464
465//=======================================================================
466//function : InitParameters
467//purpose :
468//=======================================================================
469void BRepAlgoAPI_Section::InitParameters()
470{
471 myparameterschanged = Standard_False;
472 myshapeisnull = Standard_False;
473 myApprox = Standard_False;
474 myComputePCurve1 = Standard_False;
475 myComputePCurve2 = Standard_False;
476}
477
478// ------------------------------------------------------------------------
479// static function : HasAncestorFaces
480// purpose :
481// ------------------------------------------------------------------------
482static Standard_Boolean HasAncestorFaces(const BOPTools_DSFiller& theDSFiller,
483 const TopoDS_Shape& E,
484 TopoDS_Shape& F1,
485 TopoDS_Shape& F2) {
486
487 BOPTools_PaveFiller* aPaveFiller = (BOPTools_PaveFiller*) &theDSFiller.PaveFiller();
488 const BOPTools_CArray1OfSSInterference& aFFs = aPaveFiller->InterfPool()->SSInterferences();
489 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller.DS();
490 Standard_Integer aNb = aFFs.Extent();
491 Standard_Integer i = 0;
492
493 for (i = 1; i <= aNb; i++) {
494 BOPTools_SSInterference* aFFi = (BOPTools_SSInterference*) &aFFs(i);
495 const BOPTools_SequenceOfCurves& aSeqOfCurve = aFFi->Curves();
496
497 for(Standard_Integer j = 1; j <= aSeqOfCurve.Length(); j++) {
498 const BOPTools_Curve& aCurve = aSeqOfCurve.Value(j);
499 BOPTools_ListIteratorOfListOfPaveBlock anIt(aCurve.NewPaveBlocks());
500
501 for(; anIt.More(); anIt.Next()) {
502 const BOPTools_PaveBlock& aPB = anIt.Value();
503 Standard_Integer anIndex = aPB.Edge();
504
505 if(anIndex <= 0)
506 continue;
507
508 if(E.IsSame(aDS.Shape(anIndex))) {
509 for(Standard_Integer fIt = 0; fIt < 2; fIt++) {
510 anIndex = (fIt == 0) ? aFFi->Index1() : aFFi->Index2();
511
512 if(anIndex > 0) {
513 if (fIt == 0)
514 F1 = aDS.Shape(anIndex);
515 else
516 F2 = aDS.Shape(anIndex);
517 }
518 }
519 return Standard_True;
520 }
521 }
522 }
523
524 BOPTools_ListIteratorOfListOfPaveBlock anIt(aFFi->PaveBlocks());
525
526 for(; anIt.More(); anIt.Next()) {
527 const BOPTools_PaveBlock& aPB = anIt.Value();
528 Standard_Integer anIndex = aPB.Edge();
529
530 if(anIndex <= 0)
531 continue;
532
533 if(E.IsSame(aDS.Shape(anIndex))) {
534 for(Standard_Integer fIt = 0; fIt < 2; fIt++) {
535 anIndex = (fIt == 0) ? aFFi->Index1() : aFFi->Index2();
536
537 if(anIndex > 0) {
538 if (fIt == 0)
539 F1 = aDS.Shape(anIndex);
540 else
541 F2 = aDS.Shape(anIndex);
542 }
543 }
544 return Standard_True;
545 }
546 }
547 }
548 return Standard_False;
549}