0024624: Lost word in license statement in source files
[occt.git] / src / BRepAlgo / BRepAlgo_BooleanOperation.cxx
CommitLineData
b311480e 1// Created on: 1993-10-15
2// Created by: Remi LEQUETTE
3// Copyright (c) 1993-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
17#define TRC 0
18#define MODIF 1
19
20#include <BRepAlgo_BooleanOperation.ixx>
21#include <TopOpeBRep_DSFiller.hxx>
22#include <TopOpeBRepDS_HDataStructure.hxx>
23#include <TopOpeBRepDS_BuildTool.hxx>
24#include <TopOpeBRepTool_OutCurveType.hxx>
25#include <TopOpeBRepTool_GeomTool.hxx>
26#include <BRep_Builder.hxx>
27#include <BRepLib.hxx>
28#include <TopoDS.hxx>
29#include <TopTools_ListOfShape.hxx>
30#include <TopTools_ListIteratorOfListOfShape.hxx>
31#include <TopTools_MapOfShape.hxx>
32#include <BRep_Tool.hxx>
33#include <BRepClass3d_SolidClassifier.hxx>
34
0d969553 35// sewing
7fd59977 36#include <BRepTools_Substitution.hxx>
37#include <BRepBuilderAPI_Sewing.hxx>
38#include <BRepCheck.hxx>
39#include <BRepCheck_Edge.hxx>
40#include <BRepCheck_Shell.hxx>
41
42#include <TopOpeBRepDS_DSX.hxx>
43
44#include <TopOpeBRepBuild_Tools.hxx>
45#include <TopExp_Explorer.hxx>
46#include <TopExp.hxx>
47#include <TopTools_IndexedMapOfShape.hxx>
48
49
50#ifdef DEB
1d0a9d4d 51extern Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
7fd59977 52#endif
53
54#define Opecom(st1,st2) (((st1)==TopAbs_IN) && ((st2)==TopAbs_IN))
55#define Opefus(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_OUT))
56#define Opecut(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_IN))
57
58// -------------------------------------------------------------------
59static void Sub_Classify(TopExp_Explorer& Ex,
60 const TopAbs_State St1,
61 TopTools_ListOfShape& Solids2,
62 BRep_Builder& BB,
63 TopTools_ListIteratorOfListOfShape& LIter,
64 TopoDS_Shape& myShape);
65
66
67#ifdef DEB
68Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
69#endif
70
71//modified by NIZHNY-MZV Wed Apr 19 17:19:11 2000
72//see comments at the top of file TopOpeBRepBuild_Builder1.cxx
73//about using of this global variable
1d0a9d4d 74extern Standard_Boolean GLOBAL_USE_NEW_BUILDER;
7fd59977 75//
76//modified by NIZNHY-PKV Sun Dec 15 17:17:56 2002 f
1d0a9d4d 77extern void FDSCNX_Close();// see TopOpeBRepDS_connex.cxx
78extern void FDSSDM_Close();// see TopOpeBRepDS_samdom.cxx
7fd59977 79
80//=======================================================================
81//function : Delete
82//purpose : alias ~BRepAlgoAPI_BooleanOperation
83//=======================================================================
84 void BRepAlgo_BooleanOperation::Delete()
85{
86 FDSSDM_Close();
87 FDSCNX_Close();
88}
89//modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
90
91//=======================================================================
92//function : BRepAlgoAPI_BooleanOperation
93//purpose :
94//=======================================================================
95 BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1,
96 const TopoDS_Shape& S2)
97: myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
98{
99 TopOpeBRepDS_BuildTool BT;
100 myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
101}
102
103//=======================================================================
104//function : PerformDS
105//purpose :
106//=======================================================================
107 void BRepAlgo_BooleanOperation::PerformDS()
108{
109// const Standard_Boolean CheckShapes = Standard_True;
110
111 // create a data structure
112 Handle(TopOpeBRepDS_HDataStructure) HDS;
113 if (myHBuilder->DataStructure().IsNull())
114 HDS = new TopOpeBRepDS_HDataStructure();
115 else {
116 HDS = myHBuilder->DataStructure();
117 HDS->ChangeDS().Init();
118 }
119
120#ifdef DEB
121 TopOpeBRepDS_SettraceSPSX_HDS(HDS);
122#endif
123
124 // fill the data Structure
125 TopOpeBRep_DSFiller DSFiller;
126
127 // define face/face intersection tolerances
128 Standard_Boolean forcetoli = Standard_False;
129 if (forcetoli) {
7fd59977 130 Standard_Real tolarc=0,toltang=0;
7fd59977 131 TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
132 TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
133 tobfi.ForceTolerances(tolarc,toltang);
134 }
135 DSFiller.Insert(myS1,myS2,HDS);
136
0d969553
Y
137 // 020499 : JYL : reject if there is an edge of the SD
138 // not coded sameparameter and not degenerated
7fd59977 139 Standard_Boolean esp = HDS->EdgesSameParameter();
140 Standard_Boolean tede = Standard_True;
141 if (!esp) {
142 Standard_Integer i,n = HDS->NbShapes();
143 for (i = 1 ; i <= n; i++) {
144 const TopoDS_Shape& s = HDS->Shape(i);
145 if ( s.ShapeType() == TopAbs_EDGE ) {
146 const TopoDS_Edge& e = TopoDS::Edge(s);
147 Standard_Boolean sp = BRep_Tool::SameParameter(e);
148 Standard_Boolean de = BRep_Tool::Degenerated(e);
149 if ( !sp && !de ) {
150 tede = Standard_False;
151 break;
152 }
153 }
154 }
155 }
156 myBuilderCanWork = (esp || tede) ;
157#ifdef DEB
158 if (!esp) cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<endl;
159#endif
160 if (!myBuilderCanWork) return;
161
162 Standard_Real tol3dAPPROX = 1e-7;
163 Standard_Real tol2dAPPROX = 1e-7;
164 // set tolerance values used by the APPROX process
165
166 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
167 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
168 GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
169
170 //modified by NIZHNY-MZV Thu Apr 20 09:35:44 2000
171 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
172 //about using of this global variable
173 GLOBAL_USE_NEW_BUILDER = Standard_True;
174 myHBuilder->Perform(HDS,myS1,myS2);
175 GLOBAL_USE_NEW_BUILDER = Standard_False;
176}
177
178//=======================================================================
179//function : Perform
180//purpose :
181//=======================================================================
182 void BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1,
183 const TopAbs_State St2)
184{
185 if ( ! BuilderCanWork() ) {
186 return;
187 }
188
189 // modif JYL suite aux modifs LBR #if MODIF ...
190 // on privilegie le traitement KPart (si c'en est un)
191 // a tous les autres
192 Standard_Integer kp = myHBuilder->IsKPart();
193 BRep_Builder BB;
194 Standard_Boolean sewing = Standard_True;
195 if ( kp ) {
196 //modified by NIZHNY-MZV Thu Apr 20 09:34:33 2000
197 //see comments at the top of file TopOpeBRepBuild_Builder1.cxx
198 //about using of this global variable
199 GLOBAL_USE_NEW_BUILDER = Standard_True;
200 myHBuilder->MergeKPart(St1,St2);
201 GLOBAL_USE_NEW_BUILDER = Standard_False;
202
203 BB.MakeCompound(TopoDS::Compound(myShape));
204 Done();
205
206 TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
207 for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
208
209 }
210 else {
211#if MODIF
212
213 //======================================================================
0d969553
Y
214 //== Exploration of input shapes
215 //== Creation of the list of solids
216 //== Creation of the list of faces OUT OF solid
217 //== Creation of the list of edges OUT OF face
7fd59977 218 Standard_Integer nbs1,nbs2,nbf1,nbf2,nbe1,nbe2,nbv1,nbv2;
219
220 TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
221 TopExp_Explorer Ex;
222 for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
223 Solids1.Append(Ex.Current()); nbs1++;
224 }
225 for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) {
226 Solids2.Append(Ex.Current()); nbs2++;
227 }
0d969553 228 //== Faces not in a solid
7fd59977 229 for(Ex.Init(myS1,TopAbs_FACE,TopAbs_SOLID),nbf1=0; Ex.More(); Ex.Next()) {
230 Faces1.Append(Ex.Current()); nbf1++;
231 }
232 for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next()) {
233 Faces2.Append(Ex.Current()); nbf2++;
234 }
0d969553 235 //== Edges not in a solid
7fd59977 236 for(Ex.Init(myS1,TopAbs_EDGE,TopAbs_FACE),nbe1=0; Ex.More(); Ex.Next()) {
237 Edges1.Append(Ex.Current()); nbe1++;
238 }
239 for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0; Ex.More(); Ex.Next()) {
240 Edges2.Append(Ex.Current()); nbe2++;
241 }
0d969553 242 //== Vertices not in an edge
7fd59977 243 for(Ex.Init(myS1,TopAbs_VERTEX,TopAbs_EDGE),nbv1=0; Ex.More(); Ex.Next()) {
244 Vertex1.Append(Ex.Current()); nbv1++;
245 }
246 for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0; Ex.More(); Ex.Next()) {
247 Vertex2.Append(Ex.Current()); nbv2++;
248 }
249
250 //-- cout<<"Solids1: "<<nbs1<<" Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<endl;
251 //-- cout<<"Solids2: "<<nbs2<<" Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<endl;
252
253 //==
254
0d969553 255 //== Reject operations without direction
7fd59977 256
257
0d969553 258 //-- Cut Solid by Edge
7fd59977 259// Standard_Boolean Correct = Standard_True;
260 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_IN)
261 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_IN)) {
262 //-- cout<<"***** Invalid Operation : Cut of a Solid by a Non Solid "<<endl;
263 Done();
264 return;
265 }
266
267 if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_OUT)
268 || (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_OUT)) {
269 //-- cout<<"***** Invalid Operation : Fusion of a Solid and a Non Solid "<<endl;
270 Done();
271 return;
272 }
273
274
275 if( (nbs1>0 && nbs2>0)
276 && (nbe1 || nbe2 || nbf1 || nbf2 || nbv1 || nbv2)) {
277 //-- cout<<"***** Not Yet Implemented : Compound of solid and non Solid"<<endl;
278 Done();
279 return;
280 }
281 //======================================================================
282 // make a compound with the new solids
283 BB.MakeCompound(TopoDS::Compound(myShape));
284
285 TopTools_ListIteratorOfListOfShape LIter;
286 //----------------------------------------------------------------------
287 TopoDS_Shape SNULL;
288
289 if (nbf1 && nbf2) {
290 SNULL.Nullify();
291 if ( Opecom(St1,St2) ) {
292 TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
293 for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
294 }
295 else {
296 if(nbf1) {
297 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
298
299 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
300 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
301 TopTools_ListIteratorOfListOfShape its;
302 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
303 its.More();its.Next()) BB.Add(myShape,its.Value());
304 }
305 else {
306 const TopoDS_Shape& LV = LIter.Value();
307 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
308 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
309 BB.Add(myShape,LV);
310 }
311 else {
0d969553 312 //-- Classify :
7fd59977 313 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
314 }
0d969553 315 //-- End Classification
7fd59977 316 }
317 }
318 } // nbf1
319 SNULL.Nullify();
320 if ( Opefus(St1,St2) ) {
321 if(nbf2) {
322 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
323 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
324 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
325 TopTools_ListIteratorOfListOfShape its;
326 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
327 its.More();its.Next()) BB.Add(myShape,its.Value());
328 }
329 else {
330 const TopoDS_Shape& LV = LIter.Value();
331 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
332 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
333 BB.Add(myShape,LV);
334 }
335 else {
0d969553 336 //-- Classify :
7fd59977 337 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
338 }
0d969553 339 //-- End Classification
7fd59977 340 }
341 }
342 } // nbf2
343 } // Fus
344 }
345 } // nbf1 && nbf2
346 else if (nbf1 || nbf2) {
347 SNULL.Nullify();
348 if(nbf1) {
349 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
350 // modified by IFV for treating operation between shell and solid
351 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS1,St1);
352 TopTools_IndexedMapOfShape aMapOfFaces;
353
354 sewing = Standard_False;
355
356 if(MergedShapes.Extent() != 0) {
357 TopTools_ListIteratorOfListOfShape its(MergedShapes);
358 for(; its.More(); its.Next()) {
359 BB.Add(myShape,its.Value());
360 }
361 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
362 }
363
364 for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
365
366 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
367 TopTools_ListIteratorOfListOfShape its;
368 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
369 its.More();its.Next()) {
370 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
371 }
372 }
373 else {
374 const TopoDS_Shape& LV = LIter.Value();
375 if(!aMapOfFaces.Contains(LV)) {
376 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
377 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
378 BB.Add(myShape,LV);
379 }
380 else {
0d969553 381 //-- Classify :
7fd59977 382 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
383 }
0d969553 384 //-- End Classification
7fd59977 385 }
386 }
387 }
388 } // nbf1
389 SNULL.Nullify();
390 if(nbf2) {
391 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
392 // modified by IFV for treating operation between shell and solid
393 const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS2,St2);
394 TopTools_IndexedMapOfShape aMapOfFaces;
395 sewing = Standard_False;
396
397 if(MergedShapes.Extent() != 0) {
398 TopTools_ListIteratorOfListOfShape its(MergedShapes);
399 for(; its.More(); its.Next()) {
400 BB.Add(myShape,its.Value());
401 }
402 TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
403 }
404
405 for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
406 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
407 TopTools_ListIteratorOfListOfShape its;
408 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
409 its.More();its.Next()) {
410 if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
411 }
412 }
413 else {
414 const TopoDS_Shape& LV = LIter.Value();
415 if(!aMapOfFaces.Contains(LV)) {
416 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
417 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
418 BB.Add(myShape,LV);
419 }
420 else {
0d969553 421 //-- Classify :
7fd59977 422 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
423 }
0d969553 424 //-- End Classification
7fd59977 425 }
426 }
427 }
428 } // nbf2
429 } // (nbf1 || nbf2)
430
431 //----------------------------------------------------------------------
432 if(nbe1) {
433 myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
434
435 for(LIter.Initialize(Edges1);LIter.More();LIter.Next()) {
436 if (myHBuilder->IsSplit(LIter.Value(),St1)) {
437 TopTools_ListIteratorOfListOfShape its;
438 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
439 its.More();its.Next()) {
440 BB.Add(myShape,its.Value());
441 }
442 }
443 else {
444 const TopoDS_Shape& LV = LIter.Value();
445 if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
446 ||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
447 BB.Add(myShape,LV);
448 }
449 else {
0d969553 450 //-- Classify :
7fd59977 451 Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
452 }
0d969553 453 //-- End Classification
7fd59977 454 }
455 }
456 }
457 if(nbe2) {
458 myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
459
460 for(LIter.Initialize(Edges2);LIter.More();LIter.Next()) {
461 if (myHBuilder->IsSplit(LIter.Value(),St2)) {
462 TopTools_ListIteratorOfListOfShape its;
463 for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
464 its.More();its.Next()) {
465 BB.Add(myShape,its.Value());
466 }
467 }
468 else {
469 const TopoDS_Shape& LV = LIter.Value();
470 if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
471 ||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
472 BB.Add(myShape,LV);
473 }
474 else {
0d969553 475 //-- Classify :
7fd59977 476 Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
477 }
0d969553 478 //-- End Classification
7fd59977 479 }
480 }
481 }
482 //----------------------------------------------------------------------
0d969553
Y
483 //-- V1:Vertex1 state1 = OUT -> Preserve V1 if V1 is Out all S2
484 //-- V1:Vertex1 state1 = IN -> Preserve V1 if V1 is In one of S2
7fd59977 485 if(nbv1 && nbs2) {
486 if(St1 == TopAbs_IN) {
487 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
488 Standard_Boolean keep = Standard_False;
489 Standard_Boolean ok = Standard_True;
490 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
491 gp_Pnt P=BRep_Tool::Pnt(V);
492 Standard_Real Tol = BRep_Tool::Tolerance(V);
493 TopTools_ListIteratorOfListOfShape SIter;
494 for(SIter.Initialize(Solids2);
495 SIter.More() && ok==Standard_True;
496 SIter.Next()) {
497 BRepClass3d_SolidClassifier SolClass(SIter.Value());
498 SolClass.Perform(P,Tol);
499 if(SolClass.State() == TopAbs_IN) {
500 ok=Standard_False;
501 keep = Standard_True;
502 }
503 }
504 if(keep) {
505 BB.Add(myShape,LIter.Value());
506 }
507 }
508 }
509 else {
510 if(St1 == TopAbs_OUT) {
511 for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
512 Standard_Boolean keep = Standard_True;
513 Standard_Boolean ok = Standard_True;
514 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
515 gp_Pnt P=BRep_Tool::Pnt(V);
516 Standard_Real Tol = BRep_Tool::Tolerance(V);
517 TopTools_ListIteratorOfListOfShape SIter;
518 for(SIter.Initialize(Solids2);
519 SIter.More() && ok==Standard_True;
520 SIter.Next()) {
521 BRepClass3d_SolidClassifier SolClass(SIter.Value());
522 SolClass.Perform(P,Tol);
523 if(SolClass.State() != TopAbs_OUT) {
524 keep = Standard_False;
525 ok = Standard_False;
526 }
527 }
528 if(keep) {
529 BB.Add(myShape,LIter.Value());
530 }
531 }
532 }
533 }
534 }
535
536 if(nbv2 && nbs1) {
537 if(St2 == TopAbs_IN) {
538 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
539 Standard_Boolean keep = Standard_False;
540 Standard_Boolean ok = Standard_True;
541 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
542 gp_Pnt P=BRep_Tool::Pnt(V);
543 Standard_Real Tol = BRep_Tool::Tolerance(V);
544 TopTools_ListIteratorOfListOfShape SIter;
545 for(SIter.Initialize(Solids1);
546 SIter.More() && ok==Standard_True;
547 SIter.Next()) {
548 BRepClass3d_SolidClassifier SolClass(SIter.Value());
549 SolClass.Perform(P,Tol);
550 if(SolClass.State() == TopAbs_IN) {
551 ok=Standard_False;
552 keep = Standard_True;
553 }
554 }
555 if(keep) {
556 BB.Add(myShape,LIter.Value());
557 }
558 }
559 }
560 else {
561 if(St2 == TopAbs_OUT) {
562 for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
563 Standard_Boolean keep = Standard_True;
564 Standard_Boolean ok = Standard_True;
565 const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
566 gp_Pnt P=BRep_Tool::Pnt(V);
567 Standard_Real Tol = BRep_Tool::Tolerance(V);
568 TopTools_ListIteratorOfListOfShape SIter;
569 for(SIter.Initialize(Solids1);
570 SIter.More() && ok==Standard_True;
571 SIter.Next()) {
572 BRepClass3d_SolidClassifier SolClass(SIter.Value());
573 SolClass.Perform(P,Tol);
574 if(SolClass.State() != TopAbs_OUT) {
575 keep = Standard_False;
576 ok = Standard_False;
577 }
578 }
579 if(keep) {
580 BB.Add(myShape,LIter.Value());
581 }
582 }
583 }
584 }
585 }
586
587 if(nbs1 && nbs2 ) {
588 myHBuilder->MergeShapes(myS1,St1,myS2,St2);
589 if(myHBuilder->IsMerged(myS1,St1)) {
590 TopTools_ListIteratorOfListOfShape its;
591 its = myHBuilder->Merged(myS1,St1);
592 Standard_Integer nbSolids = 0;
593 for(; its.More(); its.Next(), nbSolids++) {
594 BB.Add(myShape,its.Value());
595 }
596 }
597 }
598
599#else
600
601 myHBuilder->MergeSolids(myS1,St1,myS2,St2);
602 TopTools_ListIteratorOfListOfShape its;
603
604 BB.MakeCompound(TopoDS::Compound(myShape));
605 its = myHBuilder->Merged(myS1,St1);
606 while (its.More()) {
607 BB.Add(myShape,its.Value());
608 its.Next();
609 }
610
611#endif
612// #if MODIF
613
614 }
615
616 // Creation of the Map used in IsDeleted.
617 TopExp_Explorer ex;
618 ex.Init(myShape,TopAbs_FACE);
619 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
0d969553 620 ex.Init(myShape,TopAbs_EDGE); // for FRIKO
7fd59977 621 for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
622
0d969553 623 // Checking same parameter of new edges of section
7fd59977 624 Standard_Real eTol,cTol;
625 for (myHBuilder->InitSection(1);
626 myHBuilder->MoreSection();
627 myHBuilder->NextSection()) {
628 const TopoDS_Shape& cur = myHBuilder->CurrentSection();
629 if (cur.ShapeType()==TopAbs_EDGE) {
630 BRepCheck_Edge bce(TopoDS::Edge(cur));
631 cTol=bce.Tolerance();
632 eTol = BRep_Tool::Tolerance(TopoDS::Edge(cur));
633 if (eTol<cTol) {
634 BB.UpdateEdge(TopoDS::Edge(cur), cTol);
635 for (ex.Init(cur, TopAbs_VERTEX); ex.More(); ex.Next()) {
636 eTol = BRep_Tool::Tolerance(TopoDS::Vertex(ex.Current()));
637 if (eTol<cTol) {
0d969553
Y
638 // Update can only increase tolerance, so if the vertex
639 // has a greater tolerance thanits edges it is not touched
7fd59977 640 BB.UpdateVertex(TopoDS::Vertex(ex.Current()), cTol);
641 }
642 }
643 }
644 }
645 }
646
647 Standard_Real maxTol = RealLast(); // MSV: unlimit tolerance
648 TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
649
650 TopExp_Explorer ex1, ex2, ex3;
651 TopTools_ListOfShape theOldShell, theNewShell;
652 Standard_Boolean modif =Standard_False;
653
654#ifdef DEB
655 Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
656 if (nosew) sewing = Standard_False;
657#endif
658
659 if (sewing) {
660 topToSew.Clear();
661 for (ex1.Init(myShape, TopAbs_SHELL); ex1.More(); ex1.Next()) {
662 BRepCheck_Shell bcs(TopoDS::Shell(ex1.Current()));
663 if (bcs.Closed()==BRepCheck_NotClosed) {
0d969553 664 // it is required to add them face by face to avoid IsModified on faces
7fd59977 665 BRepBuilderAPI_Sewing brts;
666 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
667 brts.Add(ex3.Current());
668 }
669 brts.Perform();
670 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
671 if (ex2.More()) {
672 ex2.Next();
673 if (!ex2.More()) {
674 ex2.Init(brts.SewedShape(), TopAbs_SHELL);
675 theOldShell.Append(ex1.Current());
676 theNewShell.Append(ex2.Current());
677 modif =Standard_True;
678 for (ex3.Init(ex1.Current(), TopAbs_EDGE); ex3.More(); ex3.Next()) {
679 const TopoDS_Edge& ledg = TopoDS::Edge(ex3.Current());
680 if (brts.IsSectionBound(ledg)) {
681 topToSew.Bind(ledg, brts.SectionToBoundary(ledg));
682 if (!BRep_Tool::SameParameter(brts.SectionToBoundary(ledg))) {
683 BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(brts.SectionToBoundary(ledg)));
684 }
685 }
686 }
687 for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
688 if (brts.IsModified(ex3.Current())) {
689 topToSew.Bind(ex3.Current(), brts.Modified(ex3.Current()));
690 }
691 }
692 }
693 }
694 }
695 }
696 } // sewing
697
698 if (modif) {
699 BRepTools_Substitution bsub;
700 TopTools_ListIteratorOfListOfShape itl(theOldShell);
701 TopTools_ListOfShape forSub;
702 for (; itl.More();itl.Next()) {
703 forSub.Append(theNewShell.First());
704 bsub.Substitute(itl.Value(), forSub);
705 theNewShell.RemoveFirst();
706 forSub.Clear();
707 }
708 bsub.Build(myShape);
709 if (bsub.IsCopied(myShape)) {
710 myShape=(bsub.Copy(myShape)).First();
711 }
712 }
713
714 Done();
715}
716
717
718
719//=======================================================================
720//function : Builder
721//purpose :
722//=======================================================================
723 Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const
724{
725 return myHBuilder;
726}
727
728
729//=======================================================================
730//function : TopoDS_Shape&
731//purpose :
732//=======================================================================
733 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const
734{
735 return myS1;
736}
737
738
739//=======================================================================
740//function : TopoDS_Shape&
741//purpose :
742//=======================================================================
743 const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const
744{
745 return myS2;
746}
747
748//=======================================================================
749//function : BuilderCanWork
750//purpose :
751//=======================================================================
752 void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
753{
754 myBuilderCanWork = Val;
755}
756
757//=======================================================================
758//function : BuilderCanWork
759//purpose :
760//=======================================================================
761 Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
762{
763 return myBuilderCanWork;
764}
765
766
767void Sub_Classify(TopExp_Explorer& Ex,
768 const TopAbs_State St1,
769 TopTools_ListOfShape& Solids2,
770 BRep_Builder& BB,
771 TopTools_ListIteratorOfListOfShape& LIter,
772 TopoDS_Shape& myShape) {
773 Ex.Init(LIter.Value(),TopAbs_VERTEX);
774 if(Ex.More()) {
775 if(St1 == TopAbs_IN) {
776 Standard_Boolean keep = Standard_False;
777 Standard_Boolean ok = Standard_True;
778 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
779 gp_Pnt P=BRep_Tool::Pnt(V);
780 Standard_Real Tol = BRep_Tool::Tolerance(V);
781 TopTools_ListIteratorOfListOfShape SIter;
782 for(SIter.Initialize(Solids2);
783 SIter.More() && ok==Standard_True;
784 SIter.Next()) {
785 BRepClass3d_SolidClassifier SolClass(SIter.Value());
786 SolClass.Perform(P,Tol);
787 if(SolClass.State() == TopAbs_IN) {
788 ok=Standard_False;
789 keep = Standard_True;
790 }
791 }
792 if(keep) {
793 BB.Add(myShape,LIter.Value());
794 }
795 }
796 else {
797 if(St1 == TopAbs_OUT) {
798 Standard_Boolean keep = Standard_True;
799 Standard_Boolean ok = Standard_True;
800 const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
801 gp_Pnt P=BRep_Tool::Pnt(V);
802 Standard_Real Tol = BRep_Tool::Tolerance(V);
803 TopTools_ListIteratorOfListOfShape SIter;
804 for(SIter.Initialize(Solids2);
805 SIter.More() && ok==Standard_True;
806 SIter.Next()) {
807 BRepClass3d_SolidClassifier SolClass(SIter.Value());
808 SolClass.Perform(P,Tol);
809 if(SolClass.State() != TopAbs_OUT) {
810 keep = Standard_False;
811 ok = Standard_False;
812 }
813 }
814 if(keep) {
815 BB.Add(myShape,LIter.Value());
816 }
817 }
818 }
819 }
820}
821
822
823//=======================================================================
824//function : InitParameters
0d969553 825//purpose : Info on geometry : PCurve, Approx, ...
7fd59977 826//=======================================================================
827void BRepAlgo_BooleanOperation::InitParameters()
828{
829 TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
830 TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
831
832 GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
833 GTofBTofBuilder.DefineCurves(Standard_True);
834 GTofBTofBuilder.DefinePCurves1(Standard_True);
835 GTofBTofBuilder.DefinePCurves2(Standard_True);
836}
837
838//=======================================================================
839//function : Modified
840//purpose :
841//=======================================================================
842const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S)
843{
844 myGenerated.Clear();
845 TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
846 aMap.Clear();
847 if (myHBuilder->IsSplit(S, TopAbs_OUT)) {
848 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_OUT));
849 for(;It.More();It.Next()) {
850 if (topToSew.IsBound(It.Value()))
851 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
852 else
853 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
854 }
855 }
856 if (myHBuilder->IsSplit(S, TopAbs_IN)) {
857 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_IN));
858 for(;It.More();It.Next()) {
859 if (topToSew.IsBound(It.Value()))
860 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
861 else
862 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
863 }
864 }
865 if (myHBuilder->IsSplit(S, TopAbs_ON)) {
866 TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_ON));
867 for(;It.More();It.Next()) {
868 if (topToSew.IsBound(It.Value()))
869 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
870 else
871 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
872 }
873 }
874
875 if (myHBuilder->IsMerged(S, TopAbs_OUT)) {
876 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_OUT));
877 for(;It.More();It.Next()) {
878 if (topToSew.IsBound(It.Value()))
879 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
880 else
881 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
882 }
883 }
884 if (myHBuilder->IsMerged(S, TopAbs_IN)) {
885 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_IN));
886 for(;It.More();It.Next()) {
887 if (topToSew.IsBound(It.Value()))
888 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
889 else
890 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
891 }
892 }
893 if (myHBuilder->IsMerged(S, TopAbs_ON)) {
894 TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_ON));
895 for(;It.More();It.Next()) {
896 if (topToSew.IsBound(It.Value()))
897 {if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
898 else
899 {if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
900 }
901 }
902 return myGenerated;
903}
904
905
906//=======================================================================
907//function : IsDeleted
908//purpose :
909//=======================================================================
910Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S)
911{
912 Standard_Boolean Deleted = Standard_True;
913 if (myMap.Contains(S) ||
914 myHBuilder->IsMerged(S, TopAbs_OUT) ||
915 myHBuilder->IsMerged(S, TopAbs_IN) ||
916 myHBuilder->IsMerged(S, TopAbs_ON) ||
917 myHBuilder->IsSplit (S, TopAbs_OUT) ||
918 myHBuilder->IsSplit (S, TopAbs_IN) ||
919 myHBuilder->IsSplit (S, TopAbs_ON))
920 return Standard_False;
921
922 return Deleted;
923}