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