1 // Created on: 2001-05-25
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
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.
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.
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.
22 #include <BOP_SolidSolid.ixx>
24 #include <Standard_Failure.hxx>
25 #include <Standard_ErrorHandler.hxx>
28 #include <TColStd_IndexedMapOfInteger.hxx>
29 #include <TColStd_MapOfInteger.hxx>
31 #include <TopAbs_Orientation.hxx>
32 #include <TopLoc_Location.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>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
51 #include <BRep_Tool.hxx>
52 #include <BRep_Builder.hxx>
54 #include <BooleanOperations_ShapesDataStructure.hxx>
55 #include <BooleanOperations_StateOfShape.hxx>
56 #include <BooleanOperations_IndexedDataMapOfShapeInteger.hxx>
58 #include <BOPTColStd_Dump.hxx>
59 #include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
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>
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>
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>
93 #include <BOP_SDFWESFiller.hxx>
95 #include <TColStd_ListIteratorOfListOfInteger.hxx>
97 #include <BOP_SolidSolidHistoryCollector.hxx>
99 static Standard_Boolean CheckFaceIntersection(const Standard_Integer theFaceIndex,
100 const BOPTools_DSFiller* theDSFiller);
102 static 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);
109 static 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);
119 static 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);
126 //=======================================================================
127 // function: BOP_SolidSolid::BOP_SolidSolid
129 //=======================================================================
130 BOP_SolidSolid::BOP_SolidSolid()
133 //=======================================================================
136 //=======================================================================
137 void BOP_SolidSolid::Destroy() {}
139 //=======================================================================
140 // function: DoDoWithFiller
142 //=======================================================================
143 void BOP_SolidSolid::DoWithFiller(const BOPTools_DSFiller& aDSFiller)
146 myIsDone=Standard_False;
149 myModifiedMap.Clear();
151 myDSFiller=(BOPTools_DSFiller*) &aDSFiller;
156 // modified by NIZHNY-MKK Fri Sep 3 15:14:17 2004.BEGIN
157 if(!myDSFiller->IsDone()) {
159 BOPTColStd_Dump::PrintMessage("DSFiller is invalid: Can not build result\n");
162 // modified by NIZHNY-MKK Fri Sep 3 15:14:20 2004.END
163 Standard_Boolean bIsNewFiller;
164 bIsNewFiller=aDSFiller.IsNewFiller();
171 aDSFiller.SetNewFiller(!bIsNewFiller);
178 // Treat of internals
180 BOP_Refiner aRefiner;
181 aRefiner.SetShape(myResult);
182 aRefiner.SetInternals(myInternals);
185 BOP_CorrectTolerances::CorrectTolerances(myResult, 0.01);
189 if(!myHistory.IsNull()) {
190 Handle(BOP_SolidSolidHistoryCollector) aSolidHistory =
191 Handle(BOP_SolidSolidHistoryCollector)::DownCast(myHistory);
192 aSolidHistory->SetResult(myResult, myDSFiller);
195 myIsDone=Standard_True;
197 catch ( Standard_Failure ) {
199 BOPTColStd_Dump::PrintMessage("Can not build result\n");
203 //=================================================================================
204 // function: BuildResult
206 //=================================================================================
207 void BOP_SolidSolid::BuildResult()
209 BOP_ShellFaceSet theSFS(TopoDS::Solid(myShape1));
211 PrepareSFS(myNewFaces, theSFS);
213 BOP_SolidBuilder aSOBU;
216 TopoDS_Solid aNewSolid;
217 TopoDS_Shell aNewShell;
218 TopTools_ListOfShape aListOfResult;
220 aSOBU.InitSolidBuilder(theSFS, Standard_True);
221 for(aSOBU.InitSolid(); aSOBU.MoreSolid(); aSOBU.NextSolid()) {
222 aBB.MakeSolid(aNewSolid);
224 for(aSOBU.InitShell(); aSOBU.MoreShell(); aSOBU.NextShell()) {
226 if(aSOBU.IsOldShell()) {
227 aNewShell = aSOBU.OldShell();
230 aBB.MakeShell(aNewShell);
232 for(aSOBU.InitFace(); aSOBU.MoreFace(); aSOBU.NextFace()) {
233 TopoDS_Face aFace = aSOBU.Face();
234 aBB.Add(aNewShell, aFace);
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();
242 for(Standard_Integer eiterator = 1; eiterator <= nbedge; eiterator++) {
243 const TopoDS_Shape& aShape = aMap.FindKey(eiterator);
244 TopAbs_Orientation anOrientation = aShape.Orientation();
246 if((anOrientation == TopAbs_INTERNAL) ||
247 (anOrientation == TopAbs_EXTERNAL) ||
248 (BRep_Tool::Degenerated(TopoDS::Edge(aShape))))
250 Standard_Integer nbface = aMap(eiterator).Extent();
252 if(nbface < 2) { // (here should be additional condition)
253 isclosed = Standard_False;
257 aNewShell.Closed(isclosed);
258 } // end else of if(aSOBU.IsOldShell())
259 aBB.Add(aNewSolid, aNewShell);
261 aListOfResult.Append(aNewSolid);
264 TopoDS_Compound aCompound;
265 aBB.MakeCompound(aCompound);
267 TopTools_ListIteratorOfListOfShape aResultIt(aListOfResult);
269 for(; aResultIt.More(); aResultIt.Next()) {
270 aBB.Add(aCompound, aResultIt.Value());
276 //=======================================================================
277 // function: DoNewFaces
279 //=======================================================================
280 void BOP_SolidSolid::DoNewFaces()
282 const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
283 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
284 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
287 const TopoDS_Shape& anObj=aDS.Object();
288 const TopoDS_Shape& aTool=aDS.Tool();
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);
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;
301 const TColStd_DataMapOfIntegerListOfInteger& aMapOfFaceSplits = myDSFiller->SplitFacePool();
305 BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
306 BOP_BuilderTools::DoMap(aFFs, aFFMap);
309 for (i=1; i<=aNb; i++) {
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));
315 anOriF1=aF1.Orientation();
318 if(aMapOfFaceSplits.IsBound(nF1)) {
319 TopoDS_Face aFace = aF1;
320 TopTools_ListOfShape aLF;
322 const TColStd_ListOfInteger& aListOfSplitIndex = aMapOfFaceSplits.Find(nF1);
323 TColStd_ListIteratorOfListOfInteger aSplIt(aListOfSplitIndex);
325 for(; aSplIt.More(); aSplIt.Next()) {
326 Standard_Integer nFSpl = aSplIt.Value();
327 Standard_Boolean bAddFace = Standard_False;
329 BooleanOperations_StateOfShape aSt = aDS.GetState(nFSpl);
331 if(aSt != BooleanOperations_ON) {
332 BooleanOperations_StateOfShape aStateComp = BOP_BuilderTools::StateToCompare(iRank, myOperation);
334 if(aStateComp == aSt) {
335 bAddFace = Standard_True;
340 bAddFace = TakeOnSplit(nFSpl, nF1);
345 const TopoDS_Shape& aFaceSpl = aDS.Shape(nFSpl);
346 aLF.Append(aFaceSpl);
350 TopTools_ListOfShape aLFx;
351 anIt.Initialize(aLF);
353 for (; anIt.More(); anIt.Next()) {
354 TopoDS_Shape& aFx=anIt.Value();
355 aFx.Orientation(anOriF1);
356 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
358 if (bToReverseFace) {
361 aListOfNewFaces.Append(aFx);
364 if(!myHistory.IsNull()) {
365 Handle(BOP_SolidSolidHistoryCollector) aSolidHistory =
366 Handle(BOP_SolidSolidHistoryCollector)::DownCast(myHistory);
367 aSolidHistory->AddNewShape(aFace, aFx, myDSFiller);
372 FillModified(aFace, aLFx);
377 myFace.Orientation(TopAbs_FORWARD);
378 BOP_WireEdgeSet aWES (myFace);
380 const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
381 aNbj=aFFIndicesMap.Extent();
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();
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);
400 bIsCommonalgo = !BuildWESForCommonZone(nF1, aFFIndicesMap, myDSFiller,
401 myOperation, atmpWES, atmpWESAvoid);
406 // c. Filling the WES for nF1
408 // XXXXXXXXXXXXXXXXXXXXXXXXXX
409 // X nF1 has SD face(s) X
410 // XXXXXXXXXXXXXXXXXXXXXXXXXX
412 // 1. Add Split Parts having states in accordance with operation
413 AddSplitPartsINOUT (nF1, aWES);
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();
422 AddSectionPartsSo(nF1, iFF, aWES);
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();
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);
442 for (j=1; j<=aNbj; j++) {
443 iFF=aFFIndicesMap(j);
444 BOPTools_SSInterference& aFF=aFFs(iFF);
445 bIsTouch=aFF.IsTangentFaces();
448 AddSplitPartsON3DSo (nF1, iFF, aWES);
452 // 5. Add EF parts (E (from F2) on F1 ),
453 // where F2 is non-same-domain face to F1
456 // anEMap will contain all Split parts that has already in aWES
457 const TopTools_ListOfShape& aLE=aWES.StartElements();
458 anIt.Initialize (aLE);
460 for (; anIt.More(); anIt.Next()) {
461 TopoDS_Shape& anE=anIt.Value();
465 for (j=1; j<=aNbj; j++) {
466 iFF = aFFIndicesMap(j);
467 BOPTools_SSInterference& aFF=aFFs(iFF);
468 bIsTouch = aFF.IsTangentFaces();
471 AddPartsEFNonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES);
472 AddPartsEENonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES);
475 } // end of if (bIsTouchCase)
478 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
479 // X nF1 does not have SD face(s) X
480 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
482 // 1. Add Split Parts having states in accordance with operation
483 AddSplitPartsINOUT (nF1, aWES);
485 // 2. Add Split Parts with state ON
486 AddSplitPartsONSo (nF1, aMEFObj, aMEFTool, aWES);
488 // 3. Add Section Edges to the WES
490 for (j=1; j<=aNbj; j++) {
491 iFF=aFFIndicesMap(j);
492 AddSectionPartsSo(nF1, iFF, aWES);
495 // 4. Add EF parts (E (from F2) on F1 )
497 for (j=1; j<=aNbj; j++) {
498 iFF=aFFIndicesMap(j);
499 AddPartsEFSo(nF1, iFF, aMEFObj, aMEFTool, anEMap, aWES);
502 } // end of if(bIsCommonalgo)
504 TopTools_IndexedMapOfOrientedShape aMapOfSDFaceEdges;
505 BOP_WireEdgeSet aSDWES(myFace);
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();
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);
523 for (j=1; j<=aNbj; j++) {
524 iFF = aFFIndicesMap(j);
525 BOPTools_SSInterference& aFF = aFFs(iFF);
526 bIsTouch = aFF.IsTangentFaces();
529 AddSplitPartsON3DSo (nF1, iFF, aSDWES);
533 TopTools_IndexedMapOfOrientedShape aMapOfWESEdges;
535 for(aSDWES.InitStartElements(); aSDWES.MoreStartElements(); aSDWES.NextStartElement()) {
536 aMapOfWESEdges.Add(aSDWES.StartElement());
539 // Build SameDomain faces.
540 // Only edges from aMapOfWESEdges are represented in these faces
541 TopTools_ListOfShape aListOfSDFaces;
543 for (j = 1; j <= aNbj; j++) {
544 iFF = aFFIndicesMap(j);
545 BOPTools_SSInterference& aFF = aFFs(iFF);
546 bIsTouch = aFF.IsTangentFaces();
550 Standard_Integer nF2 = aFF.OppositeIndex(nF1);
551 TopoDS_Face aF1FWD = aF1;
552 aF1FWD.Orientation (TopAbs_FORWARD);
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);
562 const TopTools_ListOfShape& aLF = aFB.NewFaces();
563 TopTools_ListIteratorOfListOfShape anItLF(aLF);
565 for (; anItLF.More(); anItLF.Next()) {
566 const TopoDS_Shape& aFR = anItLF.Value();
568 if (aFR.ShapeType()==TopAbs_FACE) {
569 const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
571 Standard_Boolean bIsValidIn2D = Standard_False;
572 Standard_Boolean bNegativeFlag = Standard_False;
573 bIsValidIn2D = BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
577 // if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
578 Standard_Boolean bfound = Standard_True;
579 TopExp_Explorer anExp(aFaceResult, TopAbs_EDGE);
581 for(; anExp.More(); anExp.Next()) {
582 if(!aMapOfWESEdges.Contains(anExp.Current())) {
583 bfound = Standard_False;
589 aListOfSDFaces.Append(aFaceResult);
596 // end for (j = 1; j <= aNbj...
598 TopTools_ListIteratorOfListOfShape anItSD(aListOfSDFaces);
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);
605 for(; anExp.More(); anExp.Next()) {
606 aMapOfSDFaceEdges.Add(anExp.Current());
608 aFx.Orientation(anOriF1);
609 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
611 if (bToReverseFace) {
614 aListOfNewFaces.Append(aFx);
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;
623 for(awesit = 0; awesit < 2; awesit++) {
624 BOP_WireEdgeSet& aCurWEStmp = (awesit == 0) ? atmpWES : atmpWESAvoid;
625 BOP_WireEdgeSet aCurWES(myFace);
627 for(aCurWEStmp.InitStartElements(); aCurWEStmp.MoreStartElements(); aCurWEStmp.NextStartElement()) {
628 if(!aMapOfSDFaceEdges.Contains(aCurWEStmp.StartElement())) {
629 aCurWES.AddStartElement(aCurWEStmp.StartElement());
633 if(!aCurWES.StartElements().IsEmpty()) {
636 aFB.SetTreatment(0); // 0 -Do internal edges, 1 -No Internal Edges
637 aFB.SetTreatSDScales(1);
639 const TopTools_ListOfShape& aLF = aFB.NewFaces();
640 anIt.Initialize(aLF);
642 for (; anIt.More(); anIt.Next()) {
643 TopoDS_Shape& aFx=anIt.Value();
644 aFx.Orientation(anOriF1);
647 bToReverseFace=BOP_BuilderTools::ToReverseFace(iRank, myOperation);
649 if (bToReverseFace) {
652 aListOfNewFaces.Append(aFx);
654 aListOfCommonZoneFace.Append(aFx);
658 // end for(awesit = ...
660 // Construct WES to build faces out of common zone
661 BOP_WireEdgeSet aWES2 (myFace);
662 AddSplitPartsINOUT (nF1, aWES2);
666 AddSplitPartsONSo (nF1, aMEFObj, aMEFTool, aWES2);
669 for (j=1; j<=aNbj; j++) {
670 iFF=aFFIndicesMap(j);
671 AddSectionPartsSo(nF1, iFF, aWES2);
676 for(aSDWES.InitStartElements(); aSDWES.MoreStartElements(); aSDWES.NextStartElement()) {
677 aWES2.AddStartElement(aSDWES.StartElement());
680 for(aWES2.InitStartElements(); aWES2.MoreStartElements(); aWES2.NextStartElement()) {
681 anEMap.Add(aWES2.StartElement());
685 for (j=1; j<=aNbj; j++) {
686 iFF = aFFIndicesMap(j);
689 LocalAddPartsEFSo(nF1, iFF, aMEFObj, aMEFTool, myDSFiller,
690 myOperation, aListOfCommonZoneFace, anEMap, aWES2);
693 BOPTools_SSInterference& aFF = aFFs(iFF);
694 bIsTouch = aFF.IsTangentFaces();
697 AddPartsEFNonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES2);
698 AddPartsEENonSDSo (nF1, iFF, aMEFObj, aMEFTool, aFFIndicesMap, anEMap, aWES2);
703 aWES.ClearContents();
705 aWES2.InitStartElements();
707 for (; aWES2.MoreStartElements(); aWES2.NextStartElement()) {
708 if(aMapOfSDFaceEdges.Contains(aWES2.StartElement()))
710 Standard_Boolean bisequal = Standard_False;
711 Standard_Integer wesit = 0;
713 for(wesit = 0; wesit < 2; wesit++) {
714 BOP_WireEdgeSet& acurwes = (wesit == 0) ? atmpWES : atmpWESAvoid;
715 acurwes.InitStartElements();
717 for (; !bisequal && acurwes.MoreStartElements(); acurwes.NextStartElement()) {
718 const TopoDS_Shape& anE = acurwes.StartElement();
719 bisequal = anE.IsEqual(aWES2.StartElement());
724 aWES.AddStartElement(aWES2.StartElement());
727 //end for (; aWES2.MoreStartElements...
729 // modified by NIZHNY-MKK Tue Sep 16 11:11:33 2003.END
732 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
735 const TopTools_ListOfShape& aWESL=aWES.StartElements();
736 BOP_Draw::DrawListOfEdgesWithPC (myFace, aWESL, i, "ew_");
739 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
741 // d. Build new Faces from myFace
744 aFB.SetTreatment(0); // 0 -Do internal edges, 1 -No Internal Edges
745 aFB.SetTreatSDScales(1);
748 const TopTools_ListOfShape& aLF=aFB.NewFaces();
750 // e. Do Internal Vertices
751 DoInternalVertices(nF1, aLF);
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) {
763 aListOfNewFaces.Append(aFx);
766 if(!myHistory.IsNull()) {
767 Handle(BOP_SolidSolidHistoryCollector) aSolidHistory =
768 Handle(BOP_SolidSolidHistoryCollector)::DownCast(myHistory);
769 aSolidHistory->AddNewShape(aF1, aFx, myDSFiller);
774 FillModified(aF1, aLFx);
776 }// for (i=1; i<=aNb; i++)
778 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
779 // Display the new Faces
781 BOP_Draw::DrawListOfShape(aListOfNewFaces, "fn_");
783 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
785 myNewFaces.Append(aListOfNewFaces);
788 //=================================================================================
789 // function: PrepareSFS
791 //=================================================================================
792 void BOP_SolidSolid::PrepareSFS(const TopTools_ListOfShape& theNewFaces,
793 BOP_ShellFaceSet& theSFS)
796 const BooleanOperations_ShapesDataStructure& theDS=myDSFiller->DS();
798 Standard_Integer iRank, lastindex, firstindex, i, a;
799 BooleanOperations_StateOfShape aChoosenState;
801 for(iRank = 1; iRank <= 2; iRank++) {
802 aChoosenState = BOP_BuilderTools::StateToCompare(iRank, myOperation);
804 const TopoDS_Shape& aSolid = (iRank==1) ? myShape1 : myShape2;
807 lastindex=theDS.NumberOfShapesOfTheObject();
809 firstindex=lastindex+1;
810 lastindex=theDS.NumberOfSourceShapes();
813 for(i = firstindex; i <= lastindex; i++) {
815 if((theDS.GetShapeType(i) != TopAbs_FACE) || (theDS.GetState(i) != aChoosenState))
819 // compute orientation
820 TopoDS_Shape aFace=theDS.Shape(i);
822 TopAbs_Orientation anOri = TopAbs_FORWARD;
824 for(a = 1; a <= theDS.NumberOfAncestors(i); a++) {
825 const TopoDS_Shape& aShell = theDS.GetShape(theDS.GetAncestor(i, a));
827 TopAbs_Orientation anAncestorOrientation = aShell.Orientation();
828 Standard_Boolean found = Standard_False;
830 TopExp_Explorer aSolidExp(aSolid, TopAbs_SHELL);
831 for(; !found && aSolidExp.More(); aSolidExp.Next()) {
833 if(aShell.IsSame(aSolidExp.Current())) {
834 anAncestorOrientation = aSolidExp.Current().Orientation();
835 found = Standard_True;
840 // raise the exception: programming error
841 BOPTColStd_Dump::PrintMessage
842 ("BOP_SolidSolid::PrepareSFS(). Raises the exception: programming error...\n");
846 TopoDS_Shape anOrientedShell = aShell;
847 anOrientedShell.Orientation(anAncestorOrientation);
849 TopExp_Explorer aShellExp(anOrientedShell, TopAbs_FACE);
850 for(; aShellExp.More(); aShellExp.Next()) {
852 if(!aFace.IsSame(aShellExp.Current()))
855 anOri = aShellExp.Current().Orientation();
857 if(BOP_BuilderTools::ToReverseFace(iRank, myOperation)) {
858 anOri = TopAbs::Complement(anOri);
860 aFace.Orientation(anOri);
862 theSFS.AddStartElement(aFace);
863 } // end shell explorer
865 } // end source shapes explorer
868 TopTools_ListIteratorOfListOfShape anIt(theNewFaces);
870 for(;anIt.More(); anIt.Next()) {
871 theSFS.AddStartElement(anIt.Value());
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
880 // --------------------------------------------------------------------------------------------------------
881 Standard_Boolean CheckFaceIntersection(const Standard_Integer theFaceIndex,
882 const BOPTools_DSFiller* theDSFiller) {
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();
890 BOPTools_InterferencePool* pIntrPool=
891 (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
893 BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
894 Standard_Integer i = 0;
896 for(i = 1; i <= aFFs.Length(); i++) {
897 BOPTools_SSInterference& aFF = aFFs(i);
899 if((aFF.Index1() != theFaceIndex) && (aFF.Index2() != theFaceIndex))
902 Standard_Integer otherindex = aFF.OppositeIndex(theFaceIndex);
904 BOPTools_SequenceOfCurves& aSC = aFF.Curves();
905 Standard_Integer aNbCurves = aSC.Length();
908 TopoDS_Shape aF1 = aDS.Shape(theFaceIndex);
909 TopoDS_Shape aF2 = aDS.Shape(otherindex);
910 TopExp_Explorer anExp;
912 for(Standard_Integer j = 0; j < 2; j++) {
913 Standard_Integer afaceindextocompare = (j == 0) ? otherindex : theFaceIndex;
914 Standard_Integer aFaceRank = 1;
916 anExp.Init(aF1, TopAbs_EDGE);
917 aFaceRank = aDS.Rank(theFaceIndex);
920 anExp.Init(aF2, TopAbs_EDGE);
921 aFaceRank = aDS.Rank(otherindex);
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);
930 for (; anItCB.More(); anItCB.Next()) {
931 BOPTools_CommonBlock& aCB=anItCB.Value();
932 Standard_Integer nFace = aCB.Face();
934 if(nFace == afaceindextocompare)
935 return Standard_False;
942 return Standard_True;
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 // ----------------------------------------------------------------------------------------------------------------
952 Standard_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) {
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();
965 BOPTools_InterferencePool* pIntrPool=
966 (BOPTools_InterferencePool*)&theDSFiller->InterfPool();
968 BOPTools_CArray1OfSSInterference& aFFs = pIntrPool->SSInterferences();
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;
977 for (j = 1; j <= theFFIndicesMap.Extent(); j++) {
978 BOP_WireEdgeSet atmpWES(myFace);
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);
986 BOPTools_SequenceOfCurves& aSC = aFF.Curves();
987 Standard_Integer aNbCurves = aSC.Length();
988 Standard_Integer i = 0;
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);
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));
1001 atmpWES.AddStartElement(aES);
1003 atmpWES.AddStartElement(aES);
1006 BOP_SDFWESFiller aWESFiller(theFaceIndex, aFaceIndex2, *theDSFiller);
1007 Standard_Integer iSenseFlag = 0;
1008 Standard_Integer iRankF1 = aDS.Rank(theFaceIndex);
1010 // compute iSenseFlag. begin
1011 gp_Dir aDNF1, aDNF2;
1012 const BOPTools_ListOfPaveBlock& aLPB = aFF.PaveBlocks();
1014 if (aLPB.IsEmpty()) {
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;
1026 else if (aScPr>0.) {
1029 // compute iSenseFlag. end
1031 aWESFiller.SetSenseFlag(iSenseFlag);
1032 aWESFiller.SetOperation(BOP_COMMON);
1033 aWESFiller.Do(atmpWES);
1035 BOP_FaceBuilder aFB;
1037 const TopTools_ListOfShape& aLF = aFB.NewFaces();
1043 TopTools_ListIteratorOfListOfShape anIt(aLF);
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);
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;
1061 for(Standard_Integer uit = 1; IsSameDomain && (uit < 9); uit++) {
1062 Standard_Real U = umin + uit * deltau;
1064 for(Standard_Integer vit = 1; vit < 9; vit++) {
1065 Standard_Real V = vmin + vit * deltav;
1067 if(aContext.IsPointInOnFace(aCurFace, gp_Pnt2d(U, V))) {
1068 gp_Pnt aCurPoint = aSurface->Value(U, V);
1070 if(!aContext.IsValidPointForFace(aCurPoint, aFace2, aTolerance)) {
1071 IsSameDomain = Standard_False;
1078 // check common zone.end
1081 Standard_Integer addcommonzone = Standard_False;
1083 if (iSenseFlag==1) {
1084 switch (theOperation) {
1088 addcommonzone = Standard_True;
1094 addcommonzone = Standard_True;
1106 else if (iSenseFlag==-1) { // iSenseFlag<0
1107 switch (theOperation) {
1115 addcommonzone = Standard_True;
1121 addcommonzone = Standard_True;
1127 TopTools_ListOfShape thelist;
1129 if(!aMapFCommonZones.Contains(aFace2))
1130 aMapFCommonZones.Add(aFace2, thelist);
1131 aMapFCommonZones.ChangeFromKey(aFace2).Append(aCurFace);
1134 if(!aMapFCommonZones2.Contains(aFace2))
1135 aMapFCommonZones2.Add(aFace2, thelist);
1136 aMapFCommonZones2.ChangeFromKey(aFace2).Append(aCurFace);
1142 if(aMapFCommonZones.IsEmpty() && aMapFCommonZones2.IsEmpty()) {
1143 return Standard_False;
1145 Standard_Integer amapit = 0;
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;
1152 for(k = 1; k <= aMap.Extent(); k++) {
1153 const TopTools_ListOfShape& alf = aMap(k);
1154 TopTools_ListIteratorOfListOfShape anIt(alf);
1156 for(; anIt.More(); anIt.Next()) {
1157 TopExp_Explorer anExp(anIt.Value(), TopAbs_EDGE);
1159 for(; anExp.More(); anExp.Next()) {
1160 aWES.AddStartElement(anExp.Current());
1165 //end for(amapit = ...
1167 return Standard_True;
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 // ----------------------------------------------------------------------------------------------------------------
1176 void 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) {
1186 const BooleanOperations_ShapesDataStructure& aDS = theDSFiller->DS();
1187 BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&theDSFiller->InterfPool();
1188 BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
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));
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);
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);
1212 for (; anItCB.More(); anItCB.Next()) {
1213 BOPTools_CommonBlock& aCB=anItCB.Value();
1214 Standard_Integer nFace = aCB.Face();
1216 if (nFace == anindextocompare) {
1217 BOPTools_PaveBlock& aPB = aCB.PaveBlock1(nEF);
1219 Standard_Integer nSplit = aPB.Edge();
1220 const TopoDS_Shape& aSplit = aDS.Shape(nSplit);
1222 if (theEMap.Contains(aSplit)) {
1225 theEMap.Add(aSplit);
1226 TopoDS_Edge aSS = TopoDS::Edge(aSplit);
1229 Standard_Boolean bIsAdjExists = Standard_False;
1231 bIsAdjExists = BOPTools_Tools3D::GetAdjacentFace(aFace2, aEF, aMEF, aFAdj);
1232 Standard_Boolean bIsKeepTwice = Standard_False;
1235 bIsKeepTwice = LocalIsKeepTwice(aFace, aFace2, aFAdj, aSS, theListOfSDFace, theListOfSDFace);
1238 bIsKeepTwice = BOPTools_Tools3D::IsTouchCase(aSS, aFace, aFace2);
1242 theWES.AddStartElement(aSS);
1244 theWES.AddStartElement(aSS);
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);
1253 theWES.AddStartElement(aSS);
1260 // --------------------------------------------------------------------------------------------------------
1261 // static function: LocalIsKeepTwice
1263 // --------------------------------------------------------------------------------------------------------
1264 Standard_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) {
1271 Standard_Real aT1, aT2, aT, dt=1.e-7, A, B, C, D, d2, d2Adj;
1272 gp_Dir aDNF1, aDNF2, DBF2, aDNF2Adj, DBF2Adj;
1274 gp_Pnt aP, aPF2, aPF2Adj;
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);
1281 aC3D->D1(aT, aP, aD1Sp);
1282 gp_Dir aDD1Sp(aD1Sp);
1284 if (aSpEF2.Orientation()==TopAbs_REVERSED) {
1287 // Split Normal on F2
1288 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2, aT, aDNF2);
1289 if (aF2.Orientation()==TopAbs_REVERSED) {
1295 TopTools_ListIteratorOfListOfShape anIt;
1296 IntTools_Context aContext;
1297 Standard_Boolean dtfound = Standard_False;
1298 Standard_Real acurdt = dt;
1301 dtfound = Standard_True;
1303 aPF2.SetCoord(aP.X() + acurdt*DBF2.X(),
1304 aP.Y() + acurdt*DBF2.Y(),
1305 aP.Z() + acurdt*DBF2.Z());
1307 for(anIt.Initialize(theFacesToAvoid2); anIt.More(); anIt.Next()) {
1308 const TopoDS_Face& aFace = TopoDS::Face(anIt.Value());
1310 if(aContext.IsValidPointForFace(aPF2, aFace, BRep_Tool::Tolerance(aFace))) {
1311 dtfound = Standard_False;
1316 if(!aContext.IsValidPointForFace(aPF2, aF2, BRep_Tool::Tolerance(aF2))) {
1326 aPF2.SetCoord(aP.X()+dt*DBF2.X(),
1328 aP.Z()+dt*DBF2.Z());
1333 // Split Normal on F2Adj
1334 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2Adj, aT, aDNF2Adj);
1335 if (aF2Adj.Orientation()==TopAbs_REVERSED) {
1338 // Binormal on F2Adj
1339 DBF2Adj=aDNF2Adj^aDD1Sp;
1343 dtfound = Standard_False;
1346 dtfound = Standard_True;
1347 aPF2Adj.SetCoord(aP.X() + acurdt*DBF2Adj.X(),
1348 aP.Y() + acurdt*DBF2Adj.Y(),
1349 aP.Z() + acurdt*DBF2Adj.Z());
1351 for(anIt.Initialize(theFacesToAvoidAdj); anIt.More(); anIt.Next()) {
1352 const TopoDS_Face& aFace = TopoDS::Face(anIt.Value());
1354 if(aContext.IsValidPointForFace(aPF2Adj, aFace, BRep_Tool::Tolerance(aFace))) {
1355 dtfound = Standard_False;
1360 if(!aContext.IsValidPointForFace(aPF2Adj, aF2Adj, BRep_Tool::Tolerance(aF2Adj))) {
1369 aPF2Adj.SetCoord(aP.X()+dt*DBF2Adj.X(),
1370 aP.Y()+dt*DBF2Adj.Y(),
1371 aP.Z()+dt*DBF2Adj.Z());
1374 // Tangent Plane on F1
1375 gp_Pln aPlnN1(aP, aDNF1);
1376 aPlnN1.Coefficients(A, B, C, D);
1378 d2 = A*aPF2.X() + B*aPF2.Y() + C*aPF2.Z() + D;
1379 d2Adj= A*aPF2Adj.X() + B*aPF2Adj.Y()+ C*aPF2Adj.Z() + D;
1381 if (fabs(d2)<1.e-10) {
1384 if (fabs(d2Adj)<1.e-10) {
1393 //=================================================================================
1394 // function: SetHistoryCollector
1396 //=================================================================================
1397 void BOP_SolidSolid::SetHistoryCollector(const Handle(BOP_HistoryCollector)& theHistory)
1399 if(theHistory.IsNull() ||
1400 !theHistory->IsKind(STANDARD_TYPE(BOP_SolidSolidHistoryCollector)))
1401 myHistory.Nullify();
1403 myHistory = theHistory;