0023024: Update headers of OCCT files
[occt.git] / src / BOP / BOP_SolidSolid.cxx
CommitLineData
b311480e 1// Created on: 2001-05-25
2// Created by: Peter KURNEV
3// Copyright (c) 2001-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <BOP_SolidSolid.ixx>
23
24#include <Standard_Failure.hxx>
25#include <Standard_ErrorHandler.hxx>
26
27
28#include <TColStd_IndexedMapOfInteger.hxx>
29#include <TColStd_MapOfInteger.hxx>
30
31#include <TopAbs_Orientation.hxx>
32#include <TopLoc_Location.hxx>
33
34#include <TopoDS.hxx>
35#include <TopoDS_Shape.hxx>
36#include <TopoDS_Vertex.hxx>
37#include <TopoDS_Edge.hxx>
38#include <TopoDS_Face.hxx>
39#include <TopoDS_Wire.hxx>
40#include <TopoDS_Shell.hxx>
41#include <TopoDS_Solid.hxx>
42#include <TopoDS_Compound.hxx>
43
44#include <TopTools_ListOfShape.hxx>
45#include <TopTools_ListIteratorOfListOfShape.hxx>
46#include <TopTools_IndexedMapOfShape.hxx>
47#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48
49#include <TopExp.hxx>
50
51#include <BRep_Tool.hxx>
52#include <BRep_Builder.hxx>
53
54#include <BooleanOperations_ShapesDataStructure.hxx>
55#include <BooleanOperations_StateOfShape.hxx>
56#include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
57
58#include <BOPTColStd_Dump.hxx>
59#include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
60
61#include <BOPTools_SSInterference.hxx>
62#include <BOPTools_InterferencePool.hxx>
63#include <BOPTools_CArray1OfSSInterference.hxx>
64#include <BOPTools_SequenceOfCurves.hxx>
65#include <BOPTools_ListOfPaveBlock.hxx>
66#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
67#include <BOPTools_PaveBlock.hxx>
68#include <BOPTools_PaveFiller.hxx>
69#include <BOPTools_DSFiller.hxx>
70#include <BOPTools_CommonBlockPool.hxx>
71#include <BOPTools_ListOfCommonBlock.hxx>
72#include <BOPTools_ListIteratorOfListOfCommonBlock.hxx>
73#include <BOPTools_CommonBlock.hxx>
74#include <BOPTools_PaveBlock.hxx>
75
76#include <BOP_WireEdgeSet.hxx>
77#include <BOP_ShellFaceSet.hxx>
78#include <BOP_SolidBuilder.hxx>
79#include <BOP_Draw.hxx>
80#include <BOP_FaceBuilder.hxx>
81#include <BOP_CorrectTolerances.hxx>
82#include <BOP_BuilderTools.hxx>
83#include <BOP_Refiner.hxx>
84
85#include <BOPTools_Curve.hxx>
86#include <BOPTools_Tools3D.hxx>
87#include <BOPTools_Tools2D.hxx>
88#include <IntTools_Context.hxx>
89#include <BRepTools.hxx>
90#include <Geom_Surface.hxx>
91#include <Geom_Curve.hxx>
92#include <gp_Pln.hxx>
93#include <BOP_SDFWESFiller.hxx>
94
95#include <TColStd_ListIteratorOfListOfInteger.hxx>
96
97#include <BOP_SolidSolidHistoryCollector.hxx>
98
99static Standard_Boolean CheckFaceIntersection(const Standard_Integer theFaceIndex,
100 const BOPTools_DSFiller* theDSFiller);
101
102static Standard_Boolean BuildWESForCommonZone(const Standard_Integer theFaceIndex,
103 const TColStd_IndexedMapOfInteger& theFFIndicesMap,
104 const BOPTools_DSFiller* theDSFiller,
105 const BOP_Operation& theOperation,
106 BOP_WireEdgeSet& theWES,
107 BOP_WireEdgeSet& theWESAvoid);
108
109static void LocalAddPartsEFSo (const Standard_Integer nF1,
110 const Standard_Integer iFF,
111 const TopTools_IndexedDataMapOfShapeListOfShape& aMEFObj,
112 const TopTools_IndexedDataMapOfShapeListOfShape& aMEFTool,
113 const BOPTools_DSFiller* theDSFiller,
114 const BOP_Operation& theOperation,
115 const TopTools_ListOfShape& theListOfSDFace,
116 TopTools_IndexedMapOfShape& anEMap,
117 BOP_WireEdgeSet& aWES);
118
119static Standard_Boolean LocalIsKeepTwice(const TopoDS_Face& aF1,
120 const TopoDS_Face& aF2,
121 const TopoDS_Face& aF2Adj,
122 const TopoDS_Edge& aSpEF2,
123 const TopTools_ListOfShape& theFacesToAvoid2,
124 const TopTools_ListOfShape& theFacesToAvoidAdj);
125
126//=======================================================================
127// function: BOP_SolidSolid::BOP_SolidSolid
128// purpose:
129//=======================================================================
130 BOP_SolidSolid::BOP_SolidSolid()
131{
132}
133//=======================================================================
134// function: Destroy
135// purpose:
136//=======================================================================
137 void BOP_SolidSolid::Destroy() {}
138
139//=======================================================================
140// function: DoDoWithFiller
141// purpose:
142//=======================================================================
143 void BOP_SolidSolid::DoWithFiller(const BOPTools_DSFiller& aDSFiller)
144{
145 myErrorStatus=0;
146 myIsDone=Standard_False;
147 //
148 myResultMap.Clear();
149 myModifiedMap.Clear();
150 //
151 myDSFiller=(BOPTools_DSFiller*) &aDSFiller;
152 //
153 try {
154 OCC_CATCH_SIGNALS
155
156 // modified by NIZHNY-MKK Fri Sep 3 15:14:17 2004.BEGIN
157 if(!myDSFiller->IsDone()) {
158 myErrorStatus = 1;
159 BOPTColStd_Dump::PrintMessage("DSFiller is invalid: Can not build result\n");
160 return;
161 }
162 // modified by NIZHNY-MKK Fri Sep 3 15:14:20 2004.END
163 Standard_Boolean bIsNewFiller;
164 bIsNewFiller=aDSFiller.IsNewFiller();
165
166 if (bIsNewFiller) {
167 Prepare();
168
169 PrepareFaceSplits();
170
171 aDSFiller.SetNewFiller(!bIsNewFiller);
172 }
173 //
174 DoNewFaces();
175 //
176 BuildResult();
177 //
178 // Treat of internals
179 CollectInternals();
180 BOP_Refiner aRefiner;
181 aRefiner.SetShape(myResult);
182 aRefiner.SetInternals(myInternals);
183 aRefiner.Do();
184 //
185 BOP_CorrectTolerances::CorrectTolerances(myResult, 0.01);
186 //
187 FillModified();
188
189 if(!myHistory.IsNull()) {
190 Handle(BOP_SolidSolidHistoryCollector) aSolidHistory =
191 Handle(BOP_SolidSolidHistoryCollector)::DownCast(myHistory);
192 aSolidHistory->SetResult(myResult, myDSFiller);
193 }
194
195 myIsDone=Standard_True;
196 }
197 catch ( Standard_Failure ) {
198 myErrorStatus = 1;
199 BOPTColStd_Dump::PrintMessage("Can not build result\n");
200 }
201}
202
203//=================================================================================
204// function: BuildResult
205// purpose:
206//=================================================================================
207 void BOP_SolidSolid::BuildResult()
208{
209 BOP_ShellFaceSet theSFS(TopoDS::Solid(myShape1));
210
211 PrepareSFS(myNewFaces, theSFS);
212 //
213 BOP_SolidBuilder aSOBU;
214
215 BRep_Builder aBB;
216 TopoDS_Solid aNewSolid;
217 TopoDS_Shell aNewShell;
218 TopTools_ListOfShape aListOfResult;
219
220 aSOBU.InitSolidBuilder(theSFS, Standard_True);
221 for(aSOBU.InitSolid(); aSOBU.MoreSolid(); aSOBU.NextSolid()) {
222 aBB.MakeSolid(aNewSolid);
223
224 for(aSOBU.InitShell(); aSOBU.MoreShell(); aSOBU.NextShell()) {
225
226 if(aSOBU.IsOldShell()) {
227 aNewShell = aSOBU.OldShell();
228 }
229 else {
230 aBB.MakeShell(aNewShell);
231
232 for(aSOBU.InitFace(); aSOBU.MoreFace(); aSOBU.NextFace()) {
233 TopoDS_Face aFace = aSOBU.Face();
234 aBB.Add(aNewShell, aFace);
235 }
236
237 Standard_Boolean isclosed = Standard_False;
238 TopTools_IndexedDataMapOfShapeListOfShape aMap;
239 TopExp::MapShapesAndAncestors(aNewShell, TopAbs_EDGE, TopAbs_FACE, aMap);
240 Standard_Integer nbedge = aMap.Extent();
241
242 for(Standard_Integer eiterator = 1; eiterator <= nbedge; eiterator++) {
243 const TopoDS_Shape& aShape = aMap.FindKey(eiterator);
244 TopAbs_Orientation anOrientation = aShape.Orientation();
245
246 if((anOrientation == TopAbs_INTERNAL) ||
247 (anOrientation == TopAbs_EXTERNAL) ||
248 (BRep_Tool::Degenerated(TopoDS::Edge(aShape))))
249 continue;
250 Standard_Integer nbface = aMap(eiterator).Extent();
251
252 if(nbface < 2) { // (here should be additional condition)
253 isclosed = Standard_False;
254 break;
255 }
256 }
257 aNewShell.Closed(isclosed);
258 } // end else of if(aSOBU.IsOldShell())
259 aBB.Add(aNewSolid, aNewShell);
260 }
261 aListOfResult.Append(aNewSolid);
262 }
263
264 TopoDS_Compound aCompound;
265 aBB.MakeCompound(aCompound);
266
267 TopTools_ListIteratorOfListOfShape aResultIt(aListOfResult);
268
269 for(; aResultIt.More(); aResultIt.Next()) {
270 aBB.Add(aCompound, aResultIt.Value());
271 }
272
273 myResult=aCompound;
274}
275
276//=======================================================================
277// function: DoNewFaces
278// purpose:
279//=======================================================================
280 void BOP_SolidSolid::DoNewFaces()
281{
282 const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
283 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
284 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
285 //
286 // EF Maps
287 const TopoDS_Shape& anObj=aDS.Object();
288 const TopoDS_Shape& aTool=aDS.Tool();
289
290 TopTools_IndexedMapOfShape anEMap;
291 TopTools_IndexedDataMapOfShapeListOfShape aMEFObj, aMEFTool;
292 TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE , TopAbs_FACE , aMEFObj);
293 TopExp::MapShapesAndAncestors (aTool, TopAbs_EDGE , TopAbs_FACE , aMEFTool);
294 //
295 Standard_Boolean bIsTouchCase, bIsTouch, bToReverseFace;
296 Standard_Integer i, aNb, j, aNbj, iFF, nF1, iRank;
297 TopTools_ListOfShape aListOfNewFaces;
298 TopAbs_Orientation anOriF1;
299 TopTools_ListIteratorOfListOfShape anIt;
300
301 const TColStd_DataMapOfIntegerListOfInteger& aMapOfFaceSplits = myDSFiller->SplitFacePool();
302
303 //
304 // DoMap
305 BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
306 BOP_BuilderTools::DoMap(aFFs, aFFMap);
307 //
308 aNb=aFFMap.Extent();
309 for (i=1; i<=aNb; i++) {
310 //
311 // a. Prepare info about the Face nF1 and create WES for nF1
312 nF1=aFFMap.FindKey(i);
313 const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
314
315 anOriF1=aF1.Orientation();
316 iRank=aDS.Rank(nF1);
317
318 if(aMapOfFaceSplits.IsBound(nF1)) {
319 TopoDS_Face aFace = aF1;
320 TopTools_ListOfShape aLF;
321
322 const TColStd_ListOfInteger& aListOfSplitIndex = aMapOfFaceSplits.Find(nF1);
323 TColStd_ListIteratorOfListOfInteger aSplIt(aListOfSplitIndex);
324
325 for(; aSplIt.More(); aSplIt.Next()) {
326 Standard_Integer nFSpl = aSplIt.Value();
327 Standard_Boolean bAddFace = Standard_False;
328
329 BooleanOperations_StateOfShape aSt = aDS.GetState(nFSpl);
330
331 if(aSt != BooleanOperations_ON) {
332 BooleanOperations_StateOfShape aStateComp = BOP_BuilderTools::StateToCompare(iRank, myOperation);
333
334 if(aStateComp == aSt) {
335 bAddFace = Standard_True;
336 }
337 }
338 else {
339 if(iRank == 1) {
340 bAddFace = TakeOnSplit(nFSpl, nF1);
341 }
342 }
343
344 if(bAddFace) {
345 const TopoDS_Shape& aFaceSpl = aDS.Shape(nFSpl);
346 aLF.Append(aFaceSpl);
347 }
348 }
349
350 TopTools_ListOfShape aLFx;
351 anIt.Initialize(aLF);
352
353 for (; anIt.More(); anIt.Next()) {
354 TopoDS_Shape& aFx=anIt.Value();
355 aFx.Orientation(anOriF1);
356 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
357
358 if (bToReverseFace) {
359 aFx.Reverse();
360 }
361 aListOfNewFaces.Append(aFx);
362 aLFx.Append(aFx);
363
364 if(!myHistory.IsNull()) {
365 Handle(BOP_SolidSolidHistoryCollector) aSolidHistory =
366 Handle(BOP_SolidSolidHistoryCollector)::DownCast(myHistory);
367 aSolidHistory->AddNewShape(aFace, aFx, myDSFiller);
368 }
369 }
370 //
371 // Fill "Modified"
372 FillModified(aFace, aLFx);
373 continue;
374 }
375
376 myFace=aF1;
377 myFace.Orientation(TopAbs_FORWARD);
378 BOP_WireEdgeSet aWES (myFace);
379
380 const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
381 aNbj=aFFIndicesMap.Extent();
382 //
383 // b. The Switch: Same Domain Faces or Non-Same Domain Faces
384 bIsTouchCase=Standard_False;
385 for (j=1; j<=aNbj; j++) {
386 iFF=aFFIndicesMap(j);
387 BOPTools_SSInterference& aFF=aFFs(iFF);
388 bIsTouchCase=aFF.IsTangentFaces();
389 if (bIsTouchCase) {
390 break;
391 }
392 }
393
394 // modified by NIZHNY-MKK Tue Sep 16 11:11:22 2003.BEGIN
395 Standard_Boolean bIsCommonalgo = CheckFaceIntersection(nF1, myDSFiller);
396 BOP_WireEdgeSet atmpWES (myFace);
397 BOP_WireEdgeSet atmpWESAvoid (myFace);
398
399 if(!bIsCommonalgo) {
400 bIsCommonalgo = !BuildWESForCommonZone(nF1, aFFIndicesMap, myDSFiller,
401 myOperation, atmpWES, atmpWESAvoid);
402 }
403
404 if(bIsCommonalgo) {
405 //
406 // c. Filling the WES for nF1
407 if (bIsTouchCase) {
408 // XXXXXXXXXXXXXXXXXXXXXXXXXX
409 // X nF1 has SD face(s) X
410 // XXXXXXXXXXXXXXXXXXXXXXXXXX
411 //
412 // 1. Add Split Parts having states in accordance with operation
413 AddSplitPartsINOUT (nF1, aWES);
414 //
415 // 2. Add Section Edges to the WES
416 for (j=1; j<=aNbj; j++) {
417 iFF=aFFIndicesMap(j);
418 BOPTools_SSInterference& aFF=aFFs(iFF);
419 bIsTouch=aFF.IsTangentFaces();
420
421 if (!bIsTouch) {
422 AddSectionPartsSo(nF1, iFF, aWES);
423 }
424 }
425 //
426 // 3. Add IN2D, ON2D Parts to the WES
427 for (j=1; j<=aNbj; j++) {
428 iFF = aFFIndicesMap(j);
429 BOPTools_SSInterference& aFF=aFFs(iFF);
430 bIsTouch = aFF.IsTangentFaces();
431
432 if (bIsTouch) {
433 Standard_Integer nF2;
434 nF2 = aFF.OppositeIndex(nF1);
435 AddINON2DPartsSo(iFF, nF1, nF2, aWES);
436 AddPartsEFSDSo(nF1, iFF, aMEFObj, aMEFTool, aWES);
437 AddPartsEESDSo(nF1, iFF, aMEFObj, aMEFTool, aWES);
438 }
439 }
440 //
441 // 4. On3D parts
442 for (j=1; j<=aNbj; j++) {
443 iFF=aFFIndicesMap(j);
444 BOPTools_SSInterference& aFF=aFFs(iFF);
445 bIsTouch=aFF.IsTangentFaces();
446
447 if (!bIsTouch) {
448 AddSplitPartsON3DSo (nF1, iFF, aWES);
449 }
450 }
451
452 // 5. Add EF parts (E (from F2) on F1 ),
453 // where F2 is non-same-domain face to F1
454 anEMap.Clear();
455 //
456 // anEMap will contain all Split parts that has already in aWES
457 const TopTools_ListOfShape& aLE=aWES.StartElements();
458 anIt.Initialize (aLE);
459
460 for (; anIt.More(); anIt.Next()) {
461 TopoDS_Shape& anE=anIt.Value();
462 anEMap.Add(anE);
463 }
464 //
465 for (j=1; j<=aNbj; j++) {
466 iFF = aFFIndicesMap(j);
467 BOPTools_SSInterference& aFF=aFFs(iFF);
468 bIsTouch = aFF.IsTangentFaces();
469
470 if (!bIsTouch) {
471 AddPartsEFNonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES);
472 AddPartsEENonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES);
473 }
474 }
475 } // end of if (bIsTouchCase)
476 //
477 else {
478 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
479 // X nF1 does not have SD face(s) X
480 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
481 //
482 // 1. Add Split Parts having states in accordance with operation
483 AddSplitPartsINOUT (nF1, aWES);
484 //
485 // 2. Add Split Parts with state ON
486 AddSplitPartsONSo (nF1, aMEFObj, aMEFTool, aWES);
487 //
488 // 3. Add Section Edges to the WES
489
490 for (j=1; j<=aNbj; j++) {
491 iFF=aFFIndicesMap(j);
492 AddSectionPartsSo(nF1, iFF, aWES);
493 }
494 //
495 // 4. Add EF parts (E (from F2) on F1 )
496 anEMap.Clear();
497 for (j=1; j<=aNbj; j++) {
498 iFF=aFFIndicesMap(j);
499 AddPartsEFSo(nF1, iFF, aMEFObj, aMEFTool, anEMap, aWES);
500 }
501 }
502 } // end of if(bIsCommonalgo)
503 else {
504 TopTools_IndexedMapOfOrientedShape aMapOfSDFaceEdges;
505 BOP_WireEdgeSet aSDWES(myFace);
506
507 if (bIsTouchCase) {
508 // Add IN2D, ON2D Parts to the WES
509 for (j=1; j<=aNbj; j++) {
510 iFF = aFFIndicesMap(j);
511 BOPTools_SSInterference& aFF = aFFs(iFF);
512 bIsTouch = aFF.IsTangentFaces();
513
514 if (bIsTouch) {
515 Standard_Integer nF2 = aFF.OppositeIndex(nF1);
516 AddINON2DPartsSo(iFF, nF1, nF2, aSDWES);
517 AddPartsEFSDSo(nF1, iFF, aMEFObj, aMEFTool, aSDWES);
518 AddPartsEESDSo(nF1, iFF, aMEFObj, aMEFTool, aSDWES);
519 }
520 }
521 //
522 // On3D parts
523 for (j=1; j<=aNbj; j++) {
524 iFF = aFFIndicesMap(j);
525 BOPTools_SSInterference& aFF = aFFs(iFF);
526 bIsTouch = aFF.IsTangentFaces();
527
528 if (!bIsTouch) {
529 AddSplitPartsON3DSo (nF1, iFF, aSDWES);
530 }
531 }
532
533 TopTools_IndexedMapOfOrientedShape aMapOfWESEdges;
534
535 for(aSDWES.InitStartElements(); aSDWES.MoreStartElements(); aSDWES.NextStartElement()) {
536 aMapOfWESEdges.Add(aSDWES.StartElement());
537 }
538
539 // Build SameDomain faces.
540 // Only edges from aMapOfWESEdges are represented in these faces
541 TopTools_ListOfShape aListOfSDFaces;
542
543 for (j = 1; j <= aNbj; j++) {
544 iFF = aFFIndicesMap(j);
545 BOPTools_SSInterference& aFF = aFFs(iFF);
546 bIsTouch = aFF.IsTangentFaces();
547
548 if (bIsTouch) {
549
550 Standard_Integer nF2 = aFF.OppositeIndex(nF1);
551 TopoDS_Face aF1FWD = aF1;
552 aF1FWD.Orientation (TopAbs_FORWARD);
553
554 BOP_WireEdgeSet aWEScommon (aF1FWD);
555 BOP_SDFWESFiller aWESFiller(nF1, nF2, *myDSFiller);
556 aWESFiller.SetSenseFlag(aFF.SenseFlag());
557 aWESFiller.SetOperation(BOP_COMMON);
558 aWESFiller.Do(aWEScommon);
559
560 BOP_FaceBuilder aFB;
561 aFB.Do(aWEScommon);
562 const TopTools_ListOfShape& aLF = aFB.NewFaces();
563 TopTools_ListIteratorOfListOfShape anItLF(aLF);
564
565 for (; anItLF.More(); anItLF.Next()) {
566 const TopoDS_Shape& aFR = anItLF.Value();
567
568 if (aFR.ShapeType()==TopAbs_FACE) {
569 const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
570 //
571 Standard_Boolean bIsValidIn2D = Standard_False;
572 Standard_Boolean bNegativeFlag = Standard_False;
573 bIsValidIn2D = BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
574
575 if (bIsValidIn2D) {
576
577 // if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
578 Standard_Boolean bfound = Standard_True;
579 TopExp_Explorer anExp(aFaceResult, TopAbs_EDGE);
580
581 for(; anExp.More(); anExp.Next()) {
582 if(!aMapOfWESEdges.Contains(anExp.Current())) {
583 bfound = Standard_False;
584 break;
585 }
586 }
587
588 if(bfound)
589 aListOfSDFaces.Append(aFaceResult);
590 // }
591 }
592 }
593 }
594 }
595 }
596 // end for (j = 1; j <= aNbj...
597
598 TopTools_ListIteratorOfListOfShape anItSD(aListOfSDFaces);
599
600 for(; anItSD.More(); anItSD.Next()) {
601 const TopoDS_Shape& aShape = anItSD.Value();
602 TopoDS_Face aFx = TopoDS::Face(aShape);
603 TopExp_Explorer anExp(aFx, TopAbs_EDGE);
604
605 for(; anExp.More(); anExp.Next()) {
606 aMapOfSDFaceEdges.Add(anExp.Current());
607 }
608 aFx.Orientation(anOriF1);
609 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
610
611 if (bToReverseFace) {
612 aFx.Reverse();
613 }
614 aListOfNewFaces.Append(aFx);
615 }
616 }
617
618 // Build Common Zone faces, based on intersection lines and
619 // splits with state ON (see BuildWESForCommonZone()).
620 TopTools_ListOfShape aListOfCommonZoneFace;
621 Standard_Integer awesit = 0;
622
623 for(awesit = 0; awesit < 2; awesit++) {
624 BOP_WireEdgeSet& aCurWEStmp = (awesit == 0) ? atmpWES : atmpWESAvoid;
625 BOP_WireEdgeSet aCurWES(myFace);
626
627 for(aCurWEStmp.InitStartElements(); aCurWEStmp.MoreStartElements(); aCurWEStmp.NextStartElement()) {
628 if(!aMapOfSDFaceEdges.Contains(aCurWEStmp.StartElement())) {
629 aCurWES.AddStartElement(aCurWEStmp.StartElement());
630 }
631 }
632
633 if(!aCurWES.StartElements().IsEmpty()) {
634 BOP_FaceBuilder aFB;
635
636 aFB.SetTreatment(0); // 0 -Do internal edges, 1 -No Internal Edges
637 aFB.SetTreatSDScales(1);
638 aFB.Do(aCurWES);
639 const TopTools_ListOfShape& aLF = aFB.NewFaces();
640 anIt.Initialize(aLF);
641
642 for (; anIt.More(); anIt.Next()) {
643 TopoDS_Shape& aFx=anIt.Value();
644 aFx.Orientation(anOriF1);
645
646 if(awesit == 0) {
647 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
648
649 if (bToReverseFace) {
650 aFx.Reverse();
651 }
652 aListOfNewFaces.Append(aFx);
653 }
654 aListOfCommonZoneFace.Append(aFx);
655 }
656 }
657 }
658 // end for(awesit = ...
659
660 // Construct WES to build faces out of common zone
661 BOP_WireEdgeSet aWES2 (myFace);
662 AddSplitPartsINOUT (nF1, aWES2);
663 //
664
665 if(!bIsTouchCase) {
666 AddSplitPartsONSo (nF1, aMEFObj, aMEFTool, aWES2);
667 }
668 //
669 for (j=1; j<=aNbj; j++) {
670 iFF=aFFIndicesMap(j);
671 AddSectionPartsSo(nF1, iFF, aWES2);
672 }
673 anEMap.Clear();
674
675 if(bIsTouchCase) {
676 for(aSDWES.InitStartElements(); aSDWES.MoreStartElements(); aSDWES.NextStartElement()) {
677 aWES2.AddStartElement(aSDWES.StartElement());
678 }
679
680 for(aWES2.InitStartElements(); aWES2.MoreStartElements(); aWES2.NextStartElement()) {
681 anEMap.Add(aWES2.StartElement());
682 }
683 }
684
685 for (j=1; j<=aNbj; j++) {
686 iFF = aFFIndicesMap(j);
687
688 if(!bIsTouchCase) {
689 LocalAddPartsEFSo(nF1, iFF, aMEFObj, aMEFTool, myDSFiller,
690 myOperation, aListOfCommonZoneFace, anEMap, aWES2);
691 }
692 else {
693 BOPTools_SSInterference& aFF = aFFs(iFF);
694 bIsTouch = aFF.IsTangentFaces();
695
696 if (!bIsTouch) {
697 AddPartsEFNonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES2);
698 AddPartsEENonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES2);
699 }
700 }
701 }
702
703 aWES.ClearContents();
704
705 aWES2.InitStartElements();
706
707 for (; aWES2.MoreStartElements(); aWES2.NextStartElement()) {
708 if(aMapOfSDFaceEdges.Contains(aWES2.StartElement()))
709 continue;
710 Standard_Boolean bisequal = Standard_False;
711 Standard_Integer wesit = 0;
712
713 for(wesit = 0; wesit < 2; wesit++) {
714 BOP_WireEdgeSet& acurwes = (wesit == 0) ? atmpWES : atmpWESAvoid;
715 acurwes.InitStartElements();
716
717 for (; !bisequal && acurwes.MoreStartElements(); acurwes.NextStartElement()) {
718 const TopoDS_Shape& anE = acurwes.StartElement();
719 bisequal = anE.IsEqual(aWES2.StartElement());
720 }
721 }
722
723 if(!bisequal) {
724 aWES.AddStartElement(aWES2.StartElement());
725 }
726 }
727 //end for (; aWES2.MoreStartElements...
728 }
729 // modified by NIZHNY-MKK Tue Sep 16 11:11:33 2003.END
730
731 //
732 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
733 // Display the WES
734 if (myDraw) {
735 const TopTools_ListOfShape& aWESL=aWES.StartElements();
736 BOP_Draw::DrawListOfEdgesWithPC (myFace, aWESL, i, "ew_");
737 BOP_Draw::Wait();
738 }
739 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
740 //
741 // d. Build new Faces from myFace
742 BOP_FaceBuilder aFB;
743
744 aFB.SetTreatment(0); // 0 -Do internal edges, 1 -No Internal Edges
745 aFB.SetTreatSDScales(1);
746 aFB.Do(aWES);
747
748 const TopTools_ListOfShape& aLF=aFB.NewFaces();
749 //
750 // e. Do Internal Vertices
751 DoInternalVertices(nF1, aLF);
752 //
753 // f. Orient new faces
754 TopTools_ListOfShape aLFx;
755 anIt.Initialize(aLF);
756 for (; anIt.More(); anIt.Next()) {
757 TopoDS_Shape& aFx=anIt.Value();
758 aFx.Orientation(anOriF1);
759 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
760 if (bToReverseFace) {
761 aFx.Reverse();
762 }
763 aListOfNewFaces.Append(aFx);
764 aLFx.Append(aFx);
765
766 if(!myHistory.IsNull()) {
767 Handle(BOP_SolidSolidHistoryCollector) aSolidHistory =
768 Handle(BOP_SolidSolidHistoryCollector)::DownCast(myHistory);
769 aSolidHistory->AddNewShape(aF1, aFx, myDSFiller);
770 }
771 }
772 //
773 // Fill "Modified"
774 FillModified(aF1, aLFx);
775 //
776 }// for (i=1; i<=aNb; i++)
777
778 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
779 // Display the new Faces
780 if (myDraw) {
781 BOP_Draw::DrawListOfShape(aListOfNewFaces, "fn_");
782 }
783 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
784 myNewFaces.Clear();
785 myNewFaces.Append(aListOfNewFaces);
786}
787
788//=================================================================================
789// function: PrepareSFS
790// purpose:
791//=================================================================================
792 void BOP_SolidSolid::PrepareSFS(const TopTools_ListOfShape& theNewFaces,
793 BOP_ShellFaceSet& theSFS)
794{
795
796 const BooleanOperations_ShapesDataStructure& theDS=myDSFiller->DS();
797
798 Standard_Integer iRank, lastindex, firstindex, i, a;
799 BooleanOperations_StateOfShape aChoosenState;
800
801 for(iRank = 1; iRank <= 2; iRank++) {
802 aChoosenState = BOP_BuilderTools::StateToCompare(iRank, myOperation);
803 //
804 const TopoDS_Shape& aSolid = (iRank==1) ? myShape1 : myShape2;
805
806 firstindex=1;
807 lastindex=theDS.NumberOfShapesOfTheObject();
808 if (iRank==2) {
809 firstindex=lastindex+1;
810 lastindex=theDS.NumberOfSourceShapes();
811 }
812
813 for(i = firstindex; i <= lastindex; i++) {
814
815 if((theDS.GetShapeType(i) != TopAbs_FACE) || (theDS.GetState(i) != aChoosenState))
816 continue;
817
818
819 // compute orientation
820 TopoDS_Shape aFace=theDS.Shape(i);
821
822 TopAbs_Orientation anOri = TopAbs_FORWARD;
823
824 for(a = 1; a <= theDS.NumberOfAncestors(i); a++) {
825 const TopoDS_Shape& aShell = theDS.GetShape(theDS.GetAncestor(i, a));
826
827 TopAbs_Orientation anAncestorOrientation = aShell.Orientation();
828 Standard_Boolean found = Standard_False;
829
830 TopExp_Explorer aSolidExp(aSolid, TopAbs_SHELL);
831 for(; !found && aSolidExp.More(); aSolidExp.Next()) {
832
833 if(aShell.IsSame(aSolidExp.Current())) {
834 anAncestorOrientation = aSolidExp.Current().Orientation();
835 found = Standard_True;
836 }
837 }
838
839 if(!found) {
840 // raise the exception: programming error
841 BOPTColStd_Dump::PrintMessage
842 ("BOP_SolidSolid::PrepareSFS(). Raises the exception: programming error...\n");
843 continue;
844 }
845
846 TopoDS_Shape anOrientedShell = aShell;
847 anOrientedShell.Orientation(anAncestorOrientation);
848
849 TopExp_Explorer aShellExp(anOrientedShell, TopAbs_FACE);
850 for(; aShellExp.More(); aShellExp.Next()) {
851
852 if(!aFace.IsSame(aShellExp.Current()))
853 continue;
854
855 anOri = aShellExp.Current().Orientation();
856
857 if(BOP_BuilderTools::ToReverseFace(iRank, myOperation)) {
858 anOri = TopAbs::Complement(anOri);
859 }
860 aFace.Orientation(anOri);
861
862 theSFS.AddStartElement(aFace);
863 } // end shell explorer
864 }
865 } // end source shapes explorer
866 }
867
868 TopTools_ListIteratorOfListOfShape anIt(theNewFaces);
869
870 for(;anIt.More(); anIt.Next()) {
871 theSFS.AddStartElement(anIt.Value());
872 }
873}
874
875// --------------------------------------------------------------------------------------------------------
876// static function: CheckFaceIntersection
877// purpose: Returns Standard_True if there are no any common zone for given face,
878// Returns Standard_False if there are common zones or probability of existance of the common zone
879// is high.
880// --------------------------------------------------------------------------------------------------------
881Standard_Boolean CheckFaceIntersection(const Standard_Integer theFaceIndex,
882 const BOPTools_DSFiller* theDSFiller) {
883
884 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
885 const BOPTools_PaveFiller& aPaveFiller = theDSFiller->PaveFiller();
886 BOPTools_PaveFiller* pPaveFiller = (BOPTools_PaveFiller*)&aPaveFiller;
887 BOPTools_CommonBlockPool& aCBPool = pPaveFiller->ChangeCommonBlockPool();
888// const BOPTools_SplitShapesPool& aSplitShapesPool = aPaveFiller.SplitShapesPool();
889
890 BOPTools_InterferencePool* pIntrPool=
891 (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
892
893 BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
894 Standard_Integer i = 0;
895
896 for(i = 1; i <= aFFs.Length(); i++) {
897 BOPTools_SSInterference& aFF = aFFs(i);
898
899 if((aFF.Index1() != theFaceIndex) && (aFF.Index2() != theFaceIndex))
900 continue;
901
902 Standard_Integer otherindex = aFF.OppositeIndex(theFaceIndex);
903
904 BOPTools_SequenceOfCurves& aSC = aFF.Curves();
905 Standard_Integer aNbCurves = aSC.Length();
906
907 if(aNbCurves > 0) {
908 TopoDS_Shape aF1 = aDS.Shape(theFaceIndex);
909 TopoDS_Shape aF2 = aDS.Shape(otherindex);
910 TopExp_Explorer anExp;
911
912 for(Standard_Integer j = 0; j < 2; j++) {
913 Standard_Integer afaceindextocompare = (j == 0) ? otherindex : theFaceIndex;
914 Standard_Integer aFaceRank = 1;
915 if(j == 0) {
916 anExp.Init(aF1, TopAbs_EDGE);
917 aFaceRank = aDS.Rank(theFaceIndex);
918 }
919 else {
920 anExp.Init(aF2, TopAbs_EDGE);
921 aFaceRank = aDS.Rank(otherindex);
922 }
923
924 for(; anExp.More(); anExp.Next()) {
925 const TopoDS_Edge& aEF = TopoDS::Edge(anExp.Current());
926 Standard_Integer nEF = aDS.ShapeIndex(aEF, aFaceRank);
927 BOPTools_ListOfCommonBlock& aLCB = aCBPool(aDS.RefEdge(nEF));
928 BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
929
930 for (; anItCB.More(); anItCB.Next()) {
931 BOPTools_CommonBlock& aCB=anItCB.Value();
932 Standard_Integer nFace = aCB.Face();
933
934 if(nFace == afaceindextocompare)
935 return Standard_False;
936 }
937 }
938 }
939 }
940 }
941
942 return Standard_True;
943}
944
945// ----------------------------------------------------------------------------------------------------------------
946// static function: BuildWESForCommonZone
947// purpose: Finds common zones which contains boundaries represented by new geometry
948// Fills theWES if zones could be included in result,
949// Fills theWESAvoid if zones could not be included in result.
950// Returns true if common zones are found, otherwise returns false.
951// ----------------------------------------------------------------------------------------------------------------
952Standard_Boolean BuildWESForCommonZone(const Standard_Integer theFaceIndex,
953 const TColStd_IndexedMapOfInteger& theFFIndicesMap,
954 const BOPTools_DSFiller* theDSFiller,
955 const BOP_Operation& theOperation,
956 BOP_WireEdgeSet& theWES,
957 BOP_WireEdgeSet& theWESAvoid) {
958
959 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
960// const BOPTools_PaveFiller& aPaveFiller = theDSFiller->PaveFiller();
961// BOPTools_PaveFiller* pPaveFiller = (BOPTools_PaveFiller*)&aPaveFiller;
962// BOPTools_CommonBlockPool& aCBPool = pPaveFiller->ChangeCommonBlockPool();
963// const BOPTools_SplitShapesPool& aSplitShapesPool = aPaveFiller.SplitShapesPool();
964
965 BOPTools_InterferencePool* pIntrPool=
966 (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
967
968 BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
969
970 TopoDS_Face aFace = TopoDS::Face(aDS.Shape(theFaceIndex));
971 TopoDS_Face myFace = aFace;
972 myFace.Orientation(TopAbs_FORWARD);
973// Standard_Integer iFaceRank = aDS.Rank(theFaceIndex);
974 TopTools_IndexedDataMapOfShapeListOfShape aMapFCommonZones, aMapFCommonZones2;
975 Standard_Integer j = 0, k = 0;
976
977 for (j = 1; j <= theFFIndicesMap.Extent(); j++) {
978 BOP_WireEdgeSet atmpWES(myFace);
979
980 Standard_Integer iFF= theFFIndicesMap(j);
981 BOPTools_SSInterference& aFF = aFFs(iFF);
982 Standard_Integer aFaceIndex2 = aFF.OppositeIndex(theFaceIndex);
983 TopoDS_Face aFace2 = TopoDS::Face(aDS.Shape(aFaceIndex2));
984// Standard_Integer iFaceRank2 = aDS.Rank(aFaceIndex2);
985
986 BOPTools_SequenceOfCurves& aSC = aFF.Curves();
987 Standard_Integer aNbCurves = aSC.Length();
988 Standard_Integer i = 0;
989
990 for (i = 1; i <= aNbCurves; i++) {
991 const BOPTools_Curve& aBC = aSC(i);
992 const BOPTools_ListOfPaveBlock& aLPB = aBC.NewPaveBlocks();
993 BOPTools_ListIteratorOfListOfPaveBlock anIt(aLPB);
994
995 for (; anIt.More(); anIt.Next()) {
996 const BOPTools_PaveBlock& aPB=anIt.Value();
997 Standard_Integer nE = aPB.Edge();
998 const TopoDS_Edge& aE = TopoDS::Edge(aDS.Shape(nE));
999
1000 TopoDS_Edge aES=aE;
1001 atmpWES.AddStartElement(aES);
1002 aES.Reverse();
1003 atmpWES.AddStartElement(aES);
1004 }
1005 }
1006 BOP_SDFWESFiller aWESFiller(theFaceIndex, aFaceIndex2, *theDSFiller);
1007 Standard_Integer iSenseFlag = 0;
1008 Standard_Integer iRankF1 = aDS.Rank(theFaceIndex);
1009
1010 // compute iSenseFlag. begin
1011 gp_Dir aDNF1, aDNF2;
1012 const BOPTools_ListOfPaveBlock& aLPB = aFF.PaveBlocks();
1013
1014 if (aLPB.IsEmpty()) {
1015 continue;
1016 }
1017 const BOPTools_PaveBlock& aPB = aLPB.First();
1018 const TopoDS_Edge& aSpE = TopoDS::Edge(aDS.Shape(aPB.Edge()));
1019 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aFace, aDNF1);
1020 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aFace2, aDNF2);
1021 Standard_Real aScPr = aDNF1*aDNF2;
1022
1023 if (aScPr<0.) {
1024 iSenseFlag = -1;
1025 }
1026 else if (aScPr>0.) {
1027 iSenseFlag = 1;
1028 }
1029 // compute iSenseFlag. end
1030
1031 aWESFiller.SetSenseFlag(iSenseFlag);
1032 aWESFiller.SetOperation(BOP_COMMON);
1033 aWESFiller.Do(atmpWES);
1034
1035 BOP_FaceBuilder aFB;
1036 aFB.Do(atmpWES);
1037 const TopTools_ListOfShape& aLF = aFB.NewFaces();
1038
1039 if(aLF.IsEmpty()) {
1040 continue;
1041 }
1042
1043 TopTools_ListIteratorOfListOfShape anIt(aLF);
1044
1045 for(; anIt.More(); anIt.Next()) {
1046 const TopoDS_Face& aCurFace = TopoDS::Face(anIt.Value());
1047 // check common zone.begin
1048 Standard_Boolean IsSameDomain = Standard_True;
1049 Standard_Boolean bIsValidIn2D = Standard_False, bNegativeFlag = Standard_False;
1050 bIsValidIn2D = BOPTools_Tools3D::IsValidArea (aCurFace, bNegativeFlag);
1051
1052 if(bIsValidIn2D) {
1053 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aCurFace);
1054 Standard_Real aTolerance = BRep_Tool::Tolerance(aFace) + BRep_Tool::Tolerance(aFace2);
1055 IntTools_Context aContext;
1056 Standard_Real umin, umax, vmin, vmax;
1057 BRepTools::UVBounds(aCurFace, umin, umax, vmin, vmax);
1058 Standard_Real deltau = (umax - umin) * 0.1;
1059 Standard_Real deltav = (vmax - vmin) * 0.1;
1060
1061 for(Standard_Integer uit = 1; IsSameDomain && (uit < 9); uit++) {
1062 Standard_Real U = umin + uit * deltau;
1063
1064 for(Standard_Integer vit = 1; vit < 9; vit++) {
1065 Standard_Real V = vmin + vit * deltav;
1066
1067 if(aContext.IsPointInOnFace(aCurFace, gp_Pnt2d(U, V))) {
1068 gp_Pnt aCurPoint = aSurface->Value(U, V);
1069
1070 if(!aContext.IsValidPointForFace(aCurPoint, aFace2, aTolerance)) {
1071 IsSameDomain = Standard_False;
1072 break;
1073 }
1074 }
1075 }
1076 }
1077 }
1078 // check common zone.end
1079
1080 if(IsSameDomain) {
1081 Standard_Integer addcommonzone = Standard_False;
1082
1083 if (iSenseFlag==1) {
1084 switch (theOperation) {
1085
1086 case BOP_FUSE:
1087 if (iRankF1==1) {
1088 addcommonzone = Standard_True;
1089 }
1090 break;
1091
1092 case BOP_COMMON:
1093 if (iRankF1==1) {
1094 addcommonzone = Standard_True;
1095 }
1096 break;
1097
1098 case BOP_CUT:
1099 case BOP_CUT21:
1100 break;
1101
1102 default:
1103 break;
1104 }
1105 }
1106 else if (iSenseFlag==-1) { // iSenseFlag<0
1107 switch (theOperation) {
1108
1109 case BOP_FUSE:
1110 case BOP_COMMON:
1111 break;
1112
1113 case BOP_CUT:
1114 if (iRankF1==1) {
1115 addcommonzone = Standard_True;
1116 }
1117 break;
1118
1119 case BOP_CUT21:
1120 if (iRankF1==2) {
1121 addcommonzone = Standard_True;
1122 }
1123 default:
1124 break;
1125 }
1126 }
1127 TopTools_ListOfShape thelist;
1128 if(addcommonzone) {
1129 if(!aMapFCommonZones.Contains(aFace2))
1130 aMapFCommonZones.Add(aFace2, thelist);
1131 aMapFCommonZones.ChangeFromKey(aFace2).Append(aCurFace);
1132 }
1133 else {
1134 if(!aMapFCommonZones2.Contains(aFace2))
1135 aMapFCommonZones2.Add(aFace2, thelist);
1136 aMapFCommonZones2.ChangeFromKey(aFace2).Append(aCurFace);
1137 }
1138 }
1139 }
1140 }
1141
1142 if(aMapFCommonZones.IsEmpty() && aMapFCommonZones2.IsEmpty()) {
1143 return Standard_False;
1144 }
1145 Standard_Integer amapit = 0;
1146
1147 for(amapit = 0; amapit < 2; amapit++) {
1148 const TopTools_IndexedDataMapOfShapeListOfShape& aMap =
1149 (amapit == 0) ? aMapFCommonZones : aMapFCommonZones2;
1150 BOP_WireEdgeSet& aWES = (amapit == 0) ? theWES : theWESAvoid;
1151
1152 for(k = 1; k <= aMap.Extent(); k++) {
1153 const TopTools_ListOfShape& alf = aMap(k);
1154 TopTools_ListIteratorOfListOfShape anIt(alf);
1155
1156 for(; anIt.More(); anIt.Next()) {
1157 TopExp_Explorer anExp(anIt.Value(), TopAbs_EDGE);
1158
1159 for(; anExp.More(); anExp.Next()) {
1160 aWES.AddStartElement(anExp.Current());
1161 }
1162 }
1163 }
1164 }
1165 //end for(amapit = ...
1166
1167 return Standard_True;
1168}
1169
1170// ----------------------------------------------------------------------------------------------------------------
1171// static function: LocalAddPartsEFSo
1172// purpose: Adds split parts of edges, which lay on face nF1, to theWES.
1173// It uses found common zones (theListOfSDFace) to check
1174// if a split part should be represented in theWES twice or not.
1175// ----------------------------------------------------------------------------------------------------------------
1176void LocalAddPartsEFSo (const Standard_Integer nF1,
1177 const Standard_Integer iFF,
1178 const TopTools_IndexedDataMapOfShapeListOfShape& theMEFObj,
1179 const TopTools_IndexedDataMapOfShapeListOfShape& theMEFTool,
1180 const BOPTools_DSFiller* theDSFiller,
1181 const BOP_Operation& theOperation,
1182 const TopTools_ListOfShape& theListOfSDFace,
1183 TopTools_IndexedMapOfShape& theEMap,
1184 BOP_WireEdgeSet& theWES) {
1185
1186 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
1187 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&theDSFiller->InterfPool();
1188 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
1189
1190 const BOPTools_PaveFiller& aPF = theDSFiller->PaveFiller();
1191 BOPTools_PaveFiller* pPaveFiller =(BOPTools_PaveFiller*)&aPF;
1192 BOPTools_CommonBlockPool& aCBPool = pPaveFiller->ChangeCommonBlockPool();
1193 BOPTools_SSInterference& aFF=aFFs(iFF);
1194 Standard_Integer nF2 = aFF.OppositeIndex(nF1);
1195 const TopoDS_Face& aFace =TopoDS::Face(aDS.Shape(nF1));
1196 const TopoDS_Face& aFace2 =TopoDS::Face(aDS.Shape(nF2));
1197
1198 Standard_Integer anindextocompare = nF1;
1199 Standard_Integer iFaceRank1, iFaceRank2;
1200 iFaceRank1 = aDS.Rank(nF1);
1201 iFaceRank2 = aDS.Rank(nF2);
1202 Standard_Integer aFaceRank = iFaceRank2;
1203 const TopTools_IndexedDataMapOfShapeListOfShape& aMEF = (aFaceRank == 1) ? theMEFObj : theMEFTool;
1204 TopExp_Explorer anExp(aFace2, TopAbs_EDGE);
1205
1206 for(; anExp.More(); anExp.Next()) {
1207 const TopoDS_Edge& aEF = TopoDS::Edge(anExp.Current());
1208 Standard_Integer nEF = aDS.ShapeIndex(aEF, aFaceRank);
1209 BOPTools_ListOfCommonBlock& aLCB = aCBPool(aDS.RefEdge(nEF));
1210 BOPTools_ListIteratorOfListOfCommonBlock anItCB(aLCB);
1211
1212 for (; anItCB.More(); anItCB.Next()) {
1213 BOPTools_CommonBlock& aCB=anItCB.Value();
1214 Standard_Integer nFace = aCB.Face();
1215
1216 if (nFace == anindextocompare) {
1217 BOPTools_PaveBlock& aPB = aCB.PaveBlock1(nEF);
1218
1219 Standard_Integer nSplit = aPB.Edge();
1220 const TopoDS_Shape& aSplit = aDS.Shape(nSplit);
1221
1222 if (theEMap.Contains(aSplit)) {
1223 continue;// next CB
1224 }
1225 theEMap.Add(aSplit);
1226 TopoDS_Edge aSS = TopoDS::Edge(aSplit);
1227 //
1228 TopoDS_Face aFAdj;
1229 Standard_Boolean bIsAdjExists = Standard_False;
1230
1231 bIsAdjExists = BOPTools_Tools3D::GetAdjacentFace(aFace2, aEF, aMEF, aFAdj);
1232 Standard_Boolean bIsKeepTwice = Standard_False;
1233
1234 if(bIsAdjExists) {
1235 bIsKeepTwice = LocalIsKeepTwice(aFace, aFace2, aFAdj, aSS, theListOfSDFace, theListOfSDFace);
1236 }
1237 else {
1238 bIsKeepTwice = BOPTools_Tools3D::IsTouchCase(aSS, aFace, aFace2);
1239 }
1240
1241 if(bIsKeepTwice) {
1242 theWES.AddStartElement(aSS);
1243 aSS.Reverse();
1244 theWES.AddStartElement(aSS);
1245 }
1246 else {
1247 aSS.Orientation(TopAbs_FORWARD);
1248 TopoDS_Face myFace = aFace;
1249 myFace.Orientation(TopAbs_FORWARD);
1250 BOP_BuilderTools::OrientSectionEdgeOnF1
1251 (myFace, aFace2, iFaceRank1, theOperation, aSS);
1252
1253 theWES.AddStartElement(aSS);
1254 }
1255 }
1256 }
1257 }
1258}
1259
1260// --------------------------------------------------------------------------------------------------------
1261// static function: LocalIsKeepTwice
1262// purpose:
1263// --------------------------------------------------------------------------------------------------------
1264Standard_Boolean LocalIsKeepTwice(const TopoDS_Face& aF1,
1265 const TopoDS_Face& aF2,
1266 const TopoDS_Face& aF2Adj,
1267 const TopoDS_Edge& aSpEF2,
1268 const TopTools_ListOfShape& theFacesToAvoid2,
1269 const TopTools_ListOfShape& theFacesToAvoidAdj) {
1270
1271 Standard_Real aT1, aT2, aT, dt=1.e-7, A, B, C, D, d2, d2Adj;
1272 gp_Dir aDNF1, aDNF2, DBF2, aDNF2Adj, DBF2Adj;
1273 gp_Vec aD1Sp;
1274 gp_Pnt aP, aPF2, aPF2Adj;
1275
1276 Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aSpEF2, aT1, aT2);
1277 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
1278 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF1, aT, aDNF1);
1279
1280 //
1281 aC3D->D1(aT, aP, aD1Sp);
1282 gp_Dir aDD1Sp(aD1Sp);
1283
1284 if (aSpEF2.Orientation()==TopAbs_REVERSED) {
1285 aDD1Sp.Reverse();
1286 }
1287 // Split Normal on F2
1288 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2, aT, aDNF2);
1289 if (aF2.Orientation()==TopAbs_REVERSED) {
1290 aDNF2.Reverse();
1291 }
1292 // Binormal on F2
1293 DBF2=aDNF2^aDD1Sp;
1294
1295 TopTools_ListIteratorOfListOfShape anIt;
1296 IntTools_Context aContext;
1297 Standard_Boolean dtfound = Standard_False;
1298 Standard_Real acurdt = dt;
1299
1300 while(!dtfound) {
1301 dtfound = Standard_True;
1302
1303 aPF2.SetCoord(aP.X() + acurdt*DBF2.X(),
1304 aP.Y() + acurdt*DBF2.Y(),
1305 aP.Z() + acurdt*DBF2.Z());
1306
1307 for(anIt.Initialize(theFacesToAvoid2); anIt.More(); anIt.Next()) {
1308 const TopoDS_Face& aFace = TopoDS::Face(anIt.Value());
1309
1310 if(aContext.IsValidPointForFace(aPF2, aFace, BRep_Tool::Tolerance(aFace))) {
1311 dtfound = Standard_False;
1312 break;
1313 }
1314 }
1315
1316 if(!aContext.IsValidPointForFace(aPF2, aF2, BRep_Tool::Tolerance(aF2))) {
1317 acurdt = dt;
1318 break;
1319 }
1320 acurdt *= 2.;
1321 }
1322
1323 if(!dtfound) {
1324 dt = 1.e-07;
1325 // Point near aP
1326 aPF2.SetCoord(aP.X()+dt*DBF2.X(),
1327 aP.Y()+dt*DBF2.Y(),
1328 aP.Z()+dt*DBF2.Z());
1329 }
1330 //
1331 aDD1Sp.Reverse();
1332
1333 // Split Normal on F2Adj
1334 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2Adj, aT, aDNF2Adj);
1335 if (aF2Adj.Orientation()==TopAbs_REVERSED) {
1336 aDNF2Adj.Reverse();
1337 }
1338 // Binormal on F2Adj
1339 DBF2Adj=aDNF2Adj^aDD1Sp;
1340
1341 dt = 1.e-07;
1342 acurdt = dt;
1343 dtfound = Standard_False;
1344
1345 while(!dtfound) {
1346 dtfound = Standard_True;
1347 aPF2Adj.SetCoord(aP.X() + acurdt*DBF2Adj.X(),
1348 aP.Y() + acurdt*DBF2Adj.Y(),
1349 aP.Z() + acurdt*DBF2Adj.Z());
1350
1351 for(anIt.Initialize(theFacesToAvoidAdj); anIt.More(); anIt.Next()) {
1352 const TopoDS_Face& aFace = TopoDS::Face(anIt.Value());
1353
1354 if(aContext.IsValidPointForFace(aPF2Adj, aFace, BRep_Tool::Tolerance(aFace))) {
1355 dtfound = Standard_False;
1356 break;
1357 }
1358 }
1359
1360 if(!aContext.IsValidPointForFace(aPF2Adj, aF2Adj, BRep_Tool::Tolerance(aF2Adj))) {
1361 acurdt = dt;
1362 break;
1363 }
1364 acurdt *= 2.;
1365 }
1366
1367 if(!dtfound) {
1368 dt = 1.e-07;
1369 aPF2Adj.SetCoord(aP.X()+dt*DBF2Adj.X(),
1370 aP.Y()+dt*DBF2Adj.Y(),
1371 aP.Z()+dt*DBF2Adj.Z());
1372 }
1373 //
1374 // Tangent Plane on F1
1375 gp_Pln aPlnN1(aP, aDNF1);
1376 aPlnN1.Coefficients(A, B, C, D);
1377 //
1378 d2 = A*aPF2.X() + B*aPF2.Y() + C*aPF2.Z() + D;
1379 d2Adj= A*aPF2Adj.X() + B*aPF2Adj.Y()+ C*aPF2Adj.Z() + D;
1380 //
1381 if (fabs(d2)<1.e-10) {
1382 d2=0.;
1383 }
1384 if (fabs(d2Adj)<1.e-10) {
1385 d2Adj=0.;
1386 }
1387 //
1388 aT=d2*d2Adj;
1389 //
1390 return (aT >= 0.);
1391}
1392
1393//=================================================================================
1394// function: SetHistoryCollector
1395// purpose:
1396//=================================================================================
1397void BOP_SolidSolid::SetHistoryCollector(const Handle(BOP_HistoryCollector)& theHistory)
1398{
1399 if(theHistory.IsNull() ||
1400 !theHistory->IsKind(STANDARD_TYPE(BOP_SolidSolidHistoryCollector)))
1401 myHistory.Nullify();
1402 else
1403 myHistory = theHistory;
1404}