1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
18 #include <QANewModTopOpe_Tools.ixx>
20 #include <BRepAlgoAPI_Cut.hxx>
21 #include <BRepAlgoAPI_Common.hxx>
24 #include <TopoDS_Face.hxx>
25 #include <TopoDS_Edge.hxx>
27 #include <BRepTools.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30 #include <Geom_Surface.hxx>
31 #include <BOPInt_Context.hxx>
32 #include <TopExp_Explorer.hxx>
34 #include <GeomAPI_ProjectPointOnSurf.hxx>
35 #include <TopTools_IndexedMapOfShape.hxx>
36 #include <TopTools_DataMapOfIntegerShape.hxx>
38 #include <TCollection_CompareOfReal.hxx>
39 #include <SortTools_QuickSortOfReal.hxx>
41 #include <TColStd_Array1OfReal.hxx>
42 #include <TColStd_IndexedMapOfReal.hxx>
43 #include <TColStd_ListOfInteger.hxx>
44 #include <TColStd_ListIteratorOfListOfInteger.hxx>
46 #include <BOPAlgo_PaveFiller.hxx>
47 #include <BOPDS_DS.hxx>
48 #include <BOPAlgo_Builder.hxx>
49 #include <BOPAlgo_BOP.hxx>
50 #include <IntTools_CommonPrt.hxx>
51 #include <TopTools_ListIteratorOfListOfShape.hxx>
52 #include <BOPDS_CommonBlock.hxx>
53 #include <BOPTools_AlgoTools3D.hxx>
55 static Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
56 const TopoDS_Face& theFace2);
58 static Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
59 const TopoDS_Shape& theNewShape,
60 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
62 static void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation& theBOP,
63 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap);
65 static void SortVertexOnEdge(const TopoDS_Edge& theEdge,
66 const TopTools_ListOfShape& theListOfVertex,
67 TopTools_ListOfShape& theListOfVertexSorted);
69 static TopAbs_State GetEdgeState(const BOPDS_PDS& pDS,
70 const Handle(BOPDS_PaveBlock)& aPB);
72 // ========================================================================================
75 // ========================================================================================
76 Standard_Integer QANewModTopOpe_Tools::NbPoints(const BOPAlgo_PPaveFiller& theDSFiller)
78 Standard_Integer i, anbpoints, aNb;
80 const BOPDS_PDS& pDS = theDSFiller->PDS();
84 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
86 for (i = 0; i < aNb; ++i) {
87 BOPDS_InterfFF& aFF=aFFs(i);
88 const BOPDS_VectorOfPoint& aVP=aFF.Points();
89 anbpoints += aVP.Extent();
93 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
95 for (i = 0; i < aNb; ++i) {
96 BOPDS_InterfEF& aEF=aEFs(i);
97 IntTools_CommonPrt aCP = aEF.CommonPart();
98 if(aCP.Type() == TopAbs_VERTEX) {
104 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
106 for (i = 0; i < aNb; ++i) {
107 BOPDS_InterfEE& aEE=aEEs(i);
108 IntTools_CommonPrt aCP = aEE.CommonPart();
109 if(aCP.Type() == TopAbs_VERTEX) {
117 // ========================================================================================
118 // function: NewVertex
120 // ========================================================================================
121 TopoDS_Shape QANewModTopOpe_Tools::NewVertex(const BOPAlgo_PPaveFiller& theDSFiller,
122 const Standard_Integer theIndex)
124 TopoDS_Shape aVertex;
125 Standard_Integer i, j, anbpoints, aNb, aNbP;
127 const BOPDS_PDS& pDS = theDSFiller->PDS();
131 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
133 for (i = 0; i < aNb; ++i) {
134 BOPDS_InterfFF& aFF=aFFs(i);
135 const BOPDS_VectorOfPoint& aVP=aFF.Points();
137 for(j = 0; j < aNbP; ++j) {
140 if (theIndex == anbpoints) {
141 const BOPDS_Point& aNP = aVP(j);
142 return pDS->Shape(aNP.Index());
148 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
150 for (i = 0; i < aNb; ++i) {
151 BOPDS_InterfEF& aEF=aEFs(i);
152 IntTools_CommonPrt aCP = aEF.CommonPart();
153 if(aCP.Type() == TopAbs_VERTEX) {
156 if (theIndex == anbpoints) {
157 return pDS->Shape(aEF.IndexNew());
163 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
165 for (i = 0; i < aNb; ++i) {
166 BOPDS_InterfEE& aEE=aEEs(i);
167 IntTools_CommonPrt aCP = aEE.CommonPart();
168 if(aCP.Type() == TopAbs_VERTEX) {
171 if (theIndex == anbpoints) {
172 return pDS->Shape(aEE.IndexNew());
181 // ========================================================================================
182 // function: HasDomain
184 // ========================================================================================
185 Standard_Boolean QANewModTopOpe_Tools::HasSameDomain(const BOPAlgo_PBOP& theBuilder,
186 const TopoDS_Shape& theFace)
188 Standard_Integer bRet;
189 bRet = Standard_False;
191 if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
194 BOPCol_ListIteratorOfListOfShape aIt;
195 const BOPCol_DataMapOfShapeListOfShape& aImages = theBuilder->Images();
196 if (!aImages.IsBound(theFace)) {
199 const BOPCol_ListOfShape& aLF=aImages.Find(theFace);
201 if (aLF.Extent() == 0) {
204 const BOPCol_DataMapOfShapeShape& aShapesSD = theBuilder->ShapesSD();
207 for (; aIt.More(); aIt.Next()) {
208 const TopoDS_Shape& aFsp = aIt.Value();
209 if (aShapesSD.IsBound(aFsp)) {
210 bRet = Standard_True;
218 // ========================================================================================
219 // function: SameDomain
221 // ========================================================================================
222 void QANewModTopOpe_Tools::SameDomain(const BOPAlgo_PBOP& theBuilder,
223 const TopoDS_Shape& theFace,
224 TopTools_ListOfShape& theResultList)
226 theResultList.Clear();
228 if(theFace.IsNull() || (theFace.ShapeType() != TopAbs_FACE))
231 BOPCol_ListIteratorOfListOfShape aIt;
232 const BOPCol_ListOfShape& aLF=theBuilder->Splits().Find(theFace);
234 if (aLF.Extent() == 0) {
237 const BOPCol_DataMapOfShapeShape& aShapesSD = theBuilder->ShapesSD();
238 const BOPCol_DataMapOfShapeShape& aOrigins = theBuilder->Origins();
241 for (; aIt.More(); aIt.Next()) {
242 const TopoDS_Shape& aFSp = aIt.Value();
243 if (aShapesSD.IsBound(aFSp)) {
244 const TopoDS_Shape& aFSD = aShapesSD.Find(aFSp);
245 const TopoDS_Shape& aFOr = aOrigins.Find(aFSD);
246 if (theFace.IsEqual(aFOr)) {
247 BOPCol_DataMapIteratorOfDataMapOfShapeShape aItSD;
248 aItSD.Initialize(aShapesSD);
249 for (; aItSD.More(); aItSD.Next()) {
250 const TopoDS_Shape& aS = aItSD.Value();
251 if (aFSD.IsEqual(aS)) {
252 const TopoDS_Shape& aSK = aItSD.Key();
253 const TopoDS_Shape& aSKOr = aOrigins.Find(aSK);
254 if (!aSKOr.IsEqual(theFace)) {
255 theResultList.Append(aSKOr);
260 theResultList.Append(aFOr);
266 // ========================================================================================
269 // ========================================================================================
270 Standard_Boolean QANewModTopOpe_Tools::IsSplit(const BOPAlgo_PPaveFiller& theDSFiller,
271 const TopoDS_Shape& theEdge,
272 const TopAbs_State theState)
274 if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE))
275 return Standard_False;
277 Standard_Integer index, nSp;
279 const BOPDS_PDS& pDS = theDSFiller->PDS();
280 index = pDS->Index(theEdge);
282 return Standard_False;
285 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(index);
286 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
287 aPBIt.Initialize(aLPB);
288 for (; aPBIt.More(); aPBIt.Next()) {
289 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
292 TopAbs_State aSplitState = GetEdgeState(pDS, aPB);
294 if(aSplitState == theState) {
295 return Standard_True;
299 return Standard_False;
302 // ========================================================================================
305 // ========================================================================================
306 void QANewModTopOpe_Tools::Splits(const BOPAlgo_PPaveFiller& theDSFiller,
307 const TopoDS_Shape& theEdge,
308 const TopAbs_State theState,
309 TopTools_ListOfShape& theResultList)
311 theResultList.Clear();
313 if(theEdge.IsNull() || (theEdge.ShapeType() != TopAbs_EDGE))
316 Standard_Integer index, nSp;
318 const BOPDS_PDS& pDS = theDSFiller->PDS();
319 index = pDS->Index(theEdge);
324 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(index);
325 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
326 aPBIt.Initialize(aLPB);
327 for (; aPBIt.More(); aPBIt.Next()) {
328 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
331 TopAbs_State aSplitState = GetEdgeState(pDS, aPB);
333 if(aSplitState == theState) {
334 TopoDS_Shape aSplit = pDS->Shape(nSp);
335 theResultList.Append(aSplit);
340 // ========================================================================================
343 // ========================================================================================
344 Standard_Boolean QANewModTopOpe_Tools::SplitE(const TopoDS_Edge& theEdge,
345 TopTools_ListOfShape& theSplits)
347 // prequesitory : <Eanc> is a valid edge.
348 TopAbs_Orientation oEanc = theEdge.Orientation();
349 TopoDS_Shape aLocalShape = theEdge.Oriented(TopAbs_FORWARD);
350 TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
351 TopTools_ListOfShape aListOfVertex;
352 TopExp_Explorer exv(EFOR,TopAbs_VERTEX);
354 for (;exv.More(); exv.Next()) {
355 const TopoDS_Shape& v = exv.Current();
356 aListOfVertex.Append(v);
358 Standard_Integer nv = aListOfVertex.Extent();
360 if (nv <= 2) return Standard_False;
361 TopTools_ListOfShape aListOfVertexSorted;
363 SortVertexOnEdge(EFOR, aListOfVertex, aListOfVertexSorted);
366 TopTools_ListIteratorOfListOfShape anIt(aListOfVertexSorted);
369 v0 = TopoDS::Vertex(anIt.Value());
372 else return Standard_False;
374 for (; anIt.More(); anIt.Next()) {
375 TopoDS_Vertex v = TopoDS::Vertex(anIt.Value());
377 // prequesitory: par0 < par
378 Standard_Real par0 = BRep_Tool::Parameter(v0, EFOR);
379 Standard_Real par = BRep_Tool::Parameter(v, EFOR);
381 // here, ed has the same geometries than Ein, but with no subshapes.
382 TopoDS_Edge ed = TopoDS::Edge(EFOR.EmptyCopied());
384 v0.Orientation(TopAbs_FORWARD);
386 v.Orientation(TopAbs_REVERSED);
388 BB.Range(ed, par0, par);
390 theSplits.Append(ed.Oriented(oEanc));
393 return Standard_True;
397 // ========================================================================================
398 // function: EdgeCurveAncestors
400 // ========================================================================================
401 Standard_Boolean QANewModTopOpe_Tools::EdgeCurveAncestors(const BOPAlgo_PPaveFiller& theDSFiller,
402 const TopoDS_Shape& theEdge,
403 TopoDS_Shape& theFace1,
404 TopoDS_Shape& theFace2)
409 Standard_Integer i, j, aNb, aNbC, nE, nF1, nF2;
410 BOPDS_ListIteratorOfListOfPaveBlock aIt;
412 const BOPDS_PDS& pDS = theDSFiller->PDS();
413 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
416 for (i = 0; i < aNb; ++i) {
417 BOPDS_InterfFF& aFF=aFFs(i);
419 const BOPDS_VectorOfCurve& aVC = aFF.Curves();
421 for (j = 0; j < aNbC; ++j) {
422 const BOPDS_Curve& aNC = aVC(j);
423 const BOPDS_ListOfPaveBlock& aLPB = aNC.PaveBlocks();
424 aIt.Initialize(aLPB);
425 for (; aIt.More(); aIt.Next()) {
426 const Handle(BOPDS_PaveBlock)& aPB = aIt.Value();
428 const TopoDS_Shape& aE = pDS->Shape(nE);
429 if (theEdge.IsSame(aE)) {
430 aFF.Indices(nF1, nF2);
431 theFace1 = pDS->Shape(nF1);
432 theFace2 = pDS->Shape(nF2);
433 return Standard_True;
439 return Standard_False;
442 // ========================================================================================
443 // function: EdgeSectionAncestors
445 // ========================================================================================
446 Standard_Boolean QANewModTopOpe_Tools::EdgeSectionAncestors(const BOPAlgo_PPaveFiller& theDSFiller,
447 const TopoDS_Shape& theEdge,
448 TopTools_ListOfShape& LF1,
449 TopTools_ListOfShape& LF2,
450 TopTools_ListOfShape& LE1,
451 TopTools_ListOfShape& LE2)
453 if(theEdge.ShapeType() != TopAbs_EDGE)
454 return Standard_False;
456 const BOPDS_PDS& pDS = theDSFiller->PDS();
457 Standard_Integer i = 0, nb = 0, nF, nE, nEOr;
458 BOPCol_MapOfInteger aMIF;
459 nb = pDS->NbSourceShapes();
461 nE = pDS->Index(theEdge);
462 const BOPDS_ListOfPaveBlock& aLPB1 = pDS->PaveBlocks(nE);
463 if (!aLPB1.Extent()) {
464 return Standard_False;
467 const Handle(BOPDS_PaveBlock)& aPB1 = aLPB1.First();
468 const Handle(BOPDS_CommonBlock)& aCB=pDS->CommonBlock(aPB1);
470 return Standard_False;
473 const BOPCol_ListOfInteger& aLIF = aCB->Faces();
474 BOPCol_ListIteratorOfListOfInteger aItLI;
475 aItLI.Initialize(aLIF);
476 for ( ; aItLI.More(); aItLI.Next()) {
478 if(pDS->Rank(nF) == 0)
479 LF1.Append(pDS->Shape(nF));
481 LF2.Append(pDS->Shape(nF));
486 const BOPDS_ListOfPaveBlock& aLPB = aCB->PaveBlocks();
487 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
488 aItPB.Initialize(aLPB);
489 for (; aItPB.More(); aItPB.Next()) {
490 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
491 nEOr = aPB->OriginalEdge();
493 if(pDS->Rank(nEOr) == 0)
494 LE1.Append(pDS->Shape(nEOr));
496 LE2.Append(pDS->Shape(nEOr));
498 //find edge ancestors
499 for(i = 0; i < nb; ++i) {
500 const BOPDS_ShapeInfo& aSI = pDS->ShapeInfo(i);
501 if(aSI.ShapeType() != TopAbs_FACE) {
504 const BOPCol_ListOfInteger& aSubShapes = aSI.SubShapes();
505 aItLI.Initialize(aSubShapes);
506 for (; aItLI.More(); aItLI.Next()) {
507 if (nEOr == aItLI.Value()) {
509 if(pDS->Rank(i) == 0) LF1.Append(pDS->Shape(i));
510 else LF2.Append(pDS->Shape(i));
511 }//if (aMIF.Add(i)) {
512 }//if (nEOr == aItLI.Value()) {
513 }//for (; aItLI.More(); aItLI.Next()) {
514 }//for(i = 0; i < nb; ++i) {
517 Standard_Boolean r = (!LF1.IsEmpty() && !LF2.IsEmpty());
518 r = r && (!LE1.IsEmpty() || !LE2.IsEmpty());
522 // ========================================================================================
525 // ========================================================================================
526 Standard_Boolean QANewModTopOpe_Tools::BoolOpe(const TopoDS_Shape& theFace1,
527 const TopoDS_Shape& theFace2,
528 Standard_Boolean& IsCommonFound,
529 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap)
531 IsCommonFound = Standard_False;
532 theHistoryMap.Clear();
534 Standard_Integer iSenseFlag;
536 BOPAlgo_PaveFiller aDSFiller;
537 BOPCol_ListOfShape aLS;
538 aLS.Append(theFace1);
539 aLS.Append(theFace2);
540 aDSFiller.SetArguments(aLS);
543 if (aDSFiller.ErrorStatus()) {
544 return Standard_False;
547 const BOPDS_PDS& pDS = aDSFiller.PDS();
549 Standard_Integer aNb = 0, aNbSps;
550 Standard_Integer i = 0;
551 TopTools_IndexedMapOfShape aMapV;
554 BRepAlgoAPI_Common aCommon(theFace1, theFace2, aDSFiller);
556 if(!aCommon.IsDone()) {
557 return Standard_False;
560 TopExp_Explorer anExp(aCommon.Shape(), TopAbs_FACE);
562 IsCommonFound = Standard_False;
563 return Standard_True;
566 IsCommonFound = Standard_True;
567 TopExp::MapShapes(aCommon.Shape(), TopAbs_VERTEX, aMapV);
568 // fill edge history.begin
569 FillEdgeHistoryMap(aCommon, theHistoryMap);
570 // fill edge history.end
572 // fill face history.begin
573 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
575 Standard_Boolean bReverseFlag = Standard_True;
576 Standard_Boolean fillhistory = Standard_True;
578 for (i=0; i<aNb; ++i) {
579 BOPDS_InterfFF& aFF = aFFs(i);
580 Standard_Integer nF1, nF2;
581 aFF.Indices(nF1, nF2);
583 const TopoDS_Face& aF1 = *(TopoDS_Face*)(&pDS->Shape(nF1));
584 const TopoDS_Face& aF2 = *(TopoDS_Face*)(&pDS->Shape(nF2));
586 BOPCol_ListOfInteger aLSE;
587 pDS->SharedEdges(nF1, nF2, aLSE, aDSFiller.Allocator());
588 aNbSps = aLSE.Extent();
591 fillhistory = Standard_False;
595 Standard_Integer nE = aLSE.First();
596 const TopoDS_Edge& aSpE = *(TopoDS_Edge*)(&pDS->Shape(nE));
598 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1);
599 BOPTools_AlgoTools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
600 iSenseFlag=BOPTools_AlgoTools3D::SenseFlag (aDNF1, aDNF2);
602 if(iSenseFlag == 1) {
603 fillhistory = Standard_True;
604 bReverseFlag = Standard_False;
606 else if(iSenseFlag == -1) {
607 fillhistory = Standard_True;
608 bReverseFlag = Standard_True;
611 fillhistory = Standard_False;
616 for(; anExp.More(); anExp.Next()) {
617 TopoDS_Shape aResShape = anExp.Current();
619 if(theFace1.Orientation() == aResShape.Orientation()) {
620 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
624 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
626 else if(theFace2.Orientation() == aResShape.Orientation()) {
627 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
631 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
634 aResShape.Orientation(theFace1.Orientation());
635 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
636 aResShape.Orientation(theFace2.Orientation());
640 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
644 // fill face history.end
647 BRepAlgoAPI_Cut aCut1(theFace1, theFace2, aDSFiller);
650 return Standard_False;
651 TopExp::MapShapes(aCut1.Shape(), TopAbs_VERTEX, aMapV);
652 // fill edge history.begin
653 FillEdgeHistoryMap(aCut1, theHistoryMap);
654 // fill edge history.end
656 // fill face history.begin
657 TopExp_Explorer anExp(aCut1.Shape(), TopAbs_FACE);
659 for(; anExp.More(); anExp.Next()) {
660 TopoDS_Shape aResShape = anExp.Current();
661 aResShape.Orientation(theFace1.Orientation());
662 AddShapeToHistoryMap(theFace1, aResShape, theHistoryMap);
664 // fill face history.end
668 BRepAlgoAPI_Cut aCut2(theFace1, theFace2, aDSFiller, Standard_False);
671 return Standard_False;
672 TopExp::MapShapes(aCut2.Shape(), TopAbs_VERTEX, aMapV);
673 // fill edge history.begin
674 FillEdgeHistoryMap(aCut2, theHistoryMap);
675 // fill edge history.end
677 // fill face history.begin
678 TopExp_Explorer anExp(aCut2.Shape(), TopAbs_FACE);
680 for(; anExp.More(); anExp.Next()) {
681 TopoDS_Shape aResShape = anExp.Current();
682 aResShape.Orientation(theFace2.Orientation());
683 AddShapeToHistoryMap(theFace2, aResShape, theHistoryMap);
685 // fill face history.end
688 // fill vertex history.begin
689 BOPDS_VectorOfInterfVV& aVVs = pDS->InterfVV();
692 for (i = 0; i < aNb; ++i) {
693 BOPDS_InterfVV& aVVi = aVVs(i);
694 if (!aVVi.HasIndexNew()) {
697 Standard_Integer aNewShapeIndex = aVVi.IndexNew();
699 const TopoDS_Shape& aNewVertex = pDS->Shape(aNewShapeIndex);
701 if(!aMapV.Contains(aNewVertex)) {
705 const TopoDS_Shape& aV1 = pDS->Shape(aVVi.Index1());
706 const TopoDS_Shape& aV2 = pDS->Shape(aVVi.Index2());
707 AddShapeToHistoryMap(aV1, aNewVertex, theHistoryMap);
708 AddShapeToHistoryMap(aV2, aNewVertex, theHistoryMap);
711 BOPDS_VectorOfInterfVE& aVEs = pDS->InterfVE();
714 for (i = 0; i < aNb; ++i) {
715 BOPDS_InterfVE& aVEi = aVEs(i);
717 Standard_Integer anIndex = aVEi.Index1();
718 const TopoDS_Shape& aNewVertex = pDS->Shape(anIndex);
720 if(!aMapV.Contains(aNewVertex))
723 AddShapeToHistoryMap(aNewVertex, aNewVertex, theHistoryMap);
726 BOPDS_VectorOfInterfVF& aVSs = pDS->InterfVF();
729 for (i = 0; i < aNb; ++i) {
730 BOPDS_InterfVF& aVSi = aVSs(i);
732 Standard_Integer anIndex = aVSi.Index1();
733 const TopoDS_Shape& aNewVertex = pDS->Shape(anIndex);
735 if(!aMapV.Contains(aNewVertex))
738 AddShapeToHistoryMap(aNewVertex, aNewVertex, theHistoryMap);
740 // fill vertex history.end
741 return Standard_True;
744 // -----------------------------------------------------------------
745 // static function: CheckSameDomainFaceInside
746 // purpose: Check if distance between several points of theFace1 and
747 // theFace2 is not more than sum of maximum of tolerances of
748 // theFace1's edges and tolerance of theFace2
749 // -----------------------------------------------------------------
750 Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
751 const TopoDS_Face& theFace2) {
753 Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
754 BRepTools::UVBounds(theFace1, umin, umax, vmin, vmax);
755 Handle(BOPInt_Context) aContext;
756 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace1);
757 Standard_Real aTolerance = BRep_Tool::Tolerance(theFace1);
759 aContext = new BOPInt_Context;
760 TopExp_Explorer anExpE(theFace1, TopAbs_EDGE);
762 for(; anExpE.More(); anExpE.Next()) {
763 const TopoDS_Edge& anEdge = TopoDS::Edge(anExpE.Current());
764 Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
765 aTolerance = (aTolerance < anEdgeTol) ? anEdgeTol : aTolerance;
767 aTolerance += BRep_Tool::Tolerance(theFace2);
769 Standard_Integer nbpoints = 5;
770 Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
771 Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
772 Standard_Real U = umin + adeltau;
773 GeomAPI_ProjectPointOnSurf& aProjector = aContext->ProjPS(theFace2);
775 for(Standard_Integer i = 1; i <= nbpoints; i++, U+=adeltau) {
776 Standard_Real V = vmin + adeltav;
778 for(Standard_Integer j = 1; j <= nbpoints; j++, V+=adeltav) {
779 gp_Pnt2d aPoint(U,V);
781 if(aContext->IsPointInFace(theFace1, aPoint)) {
782 gp_Pnt aP3d = aSurface->Value(U, V);
783 aProjector.Perform(aP3d);
785 if(aProjector.IsDone()) {
787 if(aProjector.LowerDistance() > aTolerance)
788 return Standard_False;
794 return Standard_True;
797 // --------------------------------------------------------------------------------------------
798 // static function: AddShapeToHistoryMap
800 // --------------------------------------------------------------------------------------------
801 Standard_Boolean AddShapeToHistoryMap(const TopoDS_Shape& theOldShape,
802 const TopoDS_Shape& theNewShape,
803 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) {
805 if(!theHistoryMap.Contains(theOldShape)) {
806 TopTools_ListOfShape aList;
807 aList.Append(theNewShape);
808 theHistoryMap.Add(theOldShape, aList);
809 return Standard_True;
812 Standard_Boolean found = Standard_False;
813 TopTools_ListOfShape& aList = theHistoryMap.ChangeFromKey(theOldShape);
814 TopTools_ListIteratorOfListOfShape aVIt(aList);
816 for(; aVIt.More(); aVIt.Next()) {
817 if(theNewShape.IsSame(aVIt.Value())) {
818 found = Standard_True;
824 aList.Append(theNewShape);
829 // --------------------------------------------------------------------------------------------
830 // static function: FillEdgeHistoryMap
832 // --------------------------------------------------------------------------------------------
833 void FillEdgeHistoryMap(BRepAlgoAPI_BooleanOperation& theBOP,
834 TopTools_IndexedDataMapOfShapeListOfShape& theHistoryMap) {
836 TopExp_Explorer anExp;
837 anExp.Init(theBOP.Shape1(), TopAbs_EDGE);
839 for(; anExp.More(); anExp.Next()) {
840 const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current());
841 TopTools_ListIteratorOfListOfShape anIt(aList);
843 for(; anIt.More(); anIt.Next()) {
844 AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap);
848 anExp.Init(theBOP.Shape2(), TopAbs_EDGE);
850 for(; anExp.More(); anExp.Next()) {
851 const TopTools_ListOfShape& aList = theBOP.Modified(anExp.Current());
852 TopTools_ListIteratorOfListOfShape anIt(aList);
854 for(; anIt.More(); anIt.Next()) {
855 AddShapeToHistoryMap(anExp.Current(), anIt.Value(), theHistoryMap);
860 // --------------------------------------------------------------------------------------------
861 // static function: SortVertexOnEdge
863 // --------------------------------------------------------------------------------------------
864 void SortVertexOnEdge(const TopoDS_Edge& theEdge,
865 const TopTools_ListOfShape& theListOfVertex,
866 TopTools_ListOfShape& theListOfVertexSorted) {
868 TopTools_DataMapOfIntegerShape mapiv;// mapiv.Find(iV) = V
869 TColStd_IndexedMapOfReal mappar; // mappar.FindIndex(parV) = iV
870 TopTools_ListIteratorOfListOfShape itlove(theListOfVertex);
872 for (; itlove.More(); itlove.Next()){
873 const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value());
874 Standard_Real par = BRep_Tool::Parameter(v, theEdge);
875 Standard_Integer iv = mappar.Add(par);
878 Standard_Integer nv = mapiv.Extent();
879 TColStd_Array1OfReal tabpar(1,nv);
880 Standard_Integer i = 0;
882 for ( i = 1; i <= nv; i++) {
883 Standard_Real p = mappar.FindKey(i);
884 tabpar.SetValue(i,p);
886 theListOfVertexSorted.Clear();
887 TCollection_CompareOfReal compare;
888 SortTools_QuickSortOfReal::Sort(tabpar, compare);
890 for (i = 1; i <= nv; i++) {
891 Standard_Real par = tabpar.Value(i);
892 Standard_Integer iv = mappar.FindIndex(par);
893 const TopoDS_Shape& v = mapiv.Find(iv);
894 theListOfVertexSorted.Append(v);
898 // --------------------------------------------------------------------------------------------
899 // static function: GetEdgeState
901 // --------------------------------------------------------------------------------------------
902 static TopAbs_State GetEdgeState(const BOPDS_PDS& pDS,
903 const Handle(BOPDS_PaveBlock)& aPB)
905 Standard_Integer j, aNbFI;
906 Standard_Boolean bIn;
907 TopAbs_State aState = TopAbs_ON;
909 const BOPDS_VectorOfFaceInfo& aVFI = pDS->FaceInfoPool();
910 aNbFI = aVFI.Extent();
912 for (j = 0; j < aNbFI; ++j) {
913 const BOPDS_FaceInfo& aFI = aVFI(j);
914 bIn = aFI.PaveBlocksIn().Contains(aPB);