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