1 // File: BOPTools_Tools3D.cxx
2 // Created: Mon Apr 5 12:29:22 2001
3 // Author: Peter KURNEV
6 #include <BOPTools_Tools3D.ixx>
9 #include <TopExp_Explorer.hxx>
12 #include <TopoDS_Shape.hxx>
13 #include <TopoDS_Edge.hxx>
14 #include <TopoDS_Face.hxx>
15 #include <TopoDS_Vertex.hxx>
17 #include <TopTools_MapOfShape.hxx>
18 #include <TopTools_MapIteratorOfMapOfShape.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopTools_ListIteratorOfListOfShape.hxx>
21 #include <TopTools_IndexedMapOfShape.hxx>
22 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
24 #include <BRep_Builder.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepTools.hxx>
27 #include <BRepAdaptor_Surface.hxx>
29 #include <gp_Vec2d.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <gp_Lin2d.hxx>
32 #include <gp_Dir2d.hxx>
37 #include <Geom2d_Curve.hxx>
38 #include <Geom2d_TrimmedCurve.hxx>
39 #include <Geom2d_Line.hxx>
41 #include <Geom_Curve.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_BSplineSurface.hxx>
44 #include <Geom_BezierSurface.hxx>
46 #include <GeomAdaptor_Surface.hxx>
48 #include <IntTools_Tools.hxx>
50 #include <BOPTools_Tools2D.hxx>
52 #include <GProp_GProps.hxx>
53 #include <BRepGProp.hxx>
54 #include <BRepBndLib.hxx>
55 #include <Bnd_Box.hxx>
60 void PointNearE (const TopoDS_Edge& aE,
61 const TopoDS_Face& aF,
62 const Standard_Real aT,
64 const Standard_Boolean aSt);
66 static Standard_Boolean CheckKeepArguments(const TopoDS_Face& F1,
67 const TopoDS_Face& F2,
68 const TopoDS_Face& F3);
70 //=======================================================================
71 //function : RemoveSims
73 //=======================================================================
74 void BOPTools_Tools3D::RemoveSims (const TopoDS_Shape& aS,
75 const Handle(IntTools_Context)& aContext)
77 TopExp_Explorer anExp(aS, TopAbs_FACE);
78 for (; anExp.More(); anExp.Next()) {
79 const TopoDS_Face& aF=TopoDS::Face(anExp.Current());
81 BOPTools_Tools3D::RemoveSims (aF, aContext);
85 //=======================================================================
86 //function : RemoveSims
88 //=======================================================================
89 void BOPTools_Tools3D::RemoveSims (const TopoDS_Face& aFF,
90 const Handle(IntTools_Context)& aContext)
92 Standard_Boolean anIsClosed, anIsPointInFace1, anIsPointInFace2;
93 Standard_Real aT1, aT2, aT, aX, aY, dt=1.e-7, aTol;
97 TopAbs_Orientation anOri;
98 Handle(Geom2d_Curve) aC2Dx;
101 aF.Orientation(TopAbs_FORWARD);
103 TopExp_Explorer anExpW (aF, TopAbs_WIRE);
104 for (; anExpW.More(); anExpW.Next()) {
106 TopTools_MapOfShape aMap, aMapToAdd, aMapToRemove;
107 const TopoDS_Shape& aW=anExpW.Current();
109 TopExp_Explorer anExp(aW, TopAbs_EDGE);
110 for (; anExp.More(); anExp.Next()) {
111 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
113 if (BRep_Tool::Degenerated(aE)){
117 anIsClosed=BRep_Tool::IsClosed(aE, aF);
119 if (aMap.Contains(aE)) {
123 aTol=BRep_Tool::Tolerance(aE);
125 Handle(Geom2d_Curve) aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
126 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
127 aC2D-> D1(aT, aP2D, aV2D);
129 anOri=aE.Orientation();
130 if (anOri==TopAbs_REVERSED) {
137 aV2Dx.SetCoord(-aY, aX);
139 aP2Dx.SetX(aP2D.X()+dt*aV2Dx.X());
140 aP2Dx.SetY(aP2D.Y()+dt*aV2Dx.Y());
142 anIsPointInFace1=aContext->IsPointInFace(aF, aP2Dx);
144 aP2Dx.SetX(aP2D.X()-dt*aV2Dx.X());
145 aP2Dx.SetY(aP2D.Y()-dt*aV2Dx.Y());
147 anIsPointInFace2=aContext->IsPointInFace(aF, aP2Dx);
150 if (anIsPointInFace1 && anIsPointInFace2) {
157 TopExp_Explorer anExpV(aE, TopAbs_VERTEX);
158 for (; anExpV.More(); anExpV.Next()) {
159 const TopoDS_Shape& aVx=anExpV.Current();
163 BB.UpdateEdge(aEx, aTol);
165 if (anIsPointInFace1) {
166 if (anOri==TopAbs_REVERSED) {
168 BB.UpdateEdge(aEx, aC2Dx, aF, aTol);
169 BB.UpdateEdge(aEx, aC2D , aF, aTol);
170 aEx.Orientation(TopAbs_REVERSED);
174 BB.UpdateEdge(aEx, aC2Dx, aF, aTol);
175 BB.UpdateEdge(aEx, aC2D , aF, aTol);
176 aEx.Orientation(TopAbs_FORWARD);
179 aMapToRemove.Add(aE);
184 TopoDS_Shape* pW= (TopoDS_Shape*)&aW;
185 pW->Free(Standard_True);
187 TopTools_MapIteratorOfMapOfShape anIt(aMapToRemove);
188 for (; anIt.More(); anIt.Next()) {
189 const TopoDS_Shape& aSR=anIt.Key();
192 anIt.Initialize(aMapToAdd);
193 for (; anIt.More(); anIt.Next()) {
194 const TopoDS_Shape& aSA=anIt.Key();
201 //=======================================================================
202 //function : SubShapesAmount
204 //=======================================================================
205 Standard_Integer BOPTools_Tools3D::SubShapesAmount (const TopoDS_Shape& aS,
206 const TopAbs_ShapeEnum aType)
208 Standard_Integer aNb;
209 TopTools_IndexedMapOfShape aM;
210 TopExp::MapShapes(aS, aType, aM);
215 //=======================================================================
216 //function : IsConvexWire
218 //=======================================================================
219 Standard_Boolean BOPTools_Tools3D::IsConvexWire (const TopoDS_Wire& aW)
221 Standard_Boolean aFlag;
222 Standard_Integer aNbV, aNbE;
224 aNbV=BOPTools_Tools3D::SubShapesAmount(aW, TopAbs_VERTEX);
225 aNbE=BOPTools_Tools3D::SubShapesAmount(aW, TopAbs_EDGE);
230 //=======================================================================
231 //function : DoSplitSEAMOnFace
233 //=======================================================================
234 void BOPTools_Tools3D::DoSplitSEAMOnFace (const TopoDS_Edge& aSplit,
235 const TopoDS_Face& aF)
237 Standard_Boolean bIsUPeriodic, bIsLeft;
238 Standard_Real aTol, a, b, anUPeriod, aT, anU, dU=1.e-7, anU1;
242 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
243 Handle(Geom2d_Curve) C2D1;
244 Handle(Geom2d_Line) aLD1;
245 Handle(Geom_Surface) aS;
250 aSp.Orientation(TopAbs_FORWARD);
252 aTol=BRep_Tool::Tolerance(aSp);
254 aS=BRep_Tool::Surface(aF);
255 bIsUPeriodic=aS->IsUPeriodic();
259 anUPeriod=aS->UPeriod();
262 //modified by NIZNHY-PKV Fri Jul 11 09:54:43 2008f
263 Standard_Boolean bIsUClosed;
264 Standard_Real aUmin, aUmax, aVmin, aVmax;
265 Handle(Geom_BSplineSurface) aBS;
266 Handle(Geom_BezierSurface) aBZ;
268 bIsUClosed=Standard_False;
269 aBS=Handle(Geom_BSplineSurface)::DownCast(aS);
270 aBZ=Handle(Geom_BezierSurface) ::DownCast(aS);
273 bIsUClosed=aBS->IsUClosed();
274 aBS->Bounds(aUmin, aUmax, aVmin, aVmax);
276 else if (!aBZ.IsNull()) {
277 bIsUClosed=aBZ->IsUClosed();
278 aBZ->Bounds(aUmin, aUmax, aVmin, aVmax);
284 anUPeriod=aUmax-aUmin;
285 //modified by NIZNHY-PKV Fri Jul 11 09:54:49 2008t
288 C2D1=BRep_Tool::CurveOnSurface(aSp, aF, a, b);
289 //modified by NIZNHY-PKV Fri Jul 11 09:55:10 2008f
291 aLD1=Handle(Geom2d_Line)::DownCast(C2D1);
296 //modified by NIZNHY-PKV Fri Jul 11 09:55:14 2008t
298 aT=BOPTools_Tools2D::IntermediatePoint(a, b);
299 C2D1->D1(aT, aP2D, aVec2D);
300 gp_Dir2d aDir2D1(aVec2D);
303 gp_Dir2d aDOY(0.,1.);
308 if (fabs (anU) < dU) {
309 bIsLeft=Standard_True;
312 else if (fabs (anU-anUPeriod) < dU) {
313 bIsLeft=Standard_False;
322 aTmpC1=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
323 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, a, b);
325 aTmpC2=Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
326 Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, a, b);
327 gp_Vec2d aTrV(anU1-anU, 0.);
328 aC2->Translate(aTrV);
332 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
335 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
340 BB.UpdateEdge(aSp, aC1, aC2, aF, aTol);
343 BB.UpdateEdge(aSp, aC2, aC1, aF, aTol);
348 //=======================================================================
349 //function : DoSplitSEAMOnFace
351 //=======================================================================
352 Standard_Boolean BOPTools_Tools3D::DoSplitSEAMOnFace(const TopoDS_Edge& theSplit,
353 const TopoDS_Edge& theSeam,
354 const TopoDS_Face& theFace,
355 Standard_Boolean& IsReversed)
357 Standard_Real aTol, f, l, a, b, aPeriod, aT, aParTolerance = 1.e-07;
358 Standard_Boolean bIsUPeriodic = Standard_False;
359 Standard_Boolean bIsVPeriodic = Standard_False;
365 TopoDS_Edge aSp = theSplit;
366 aSp.Orientation(TopAbs_FORWARD);
367 TopoDS_Edge aSeamF = theSeam;
368 aSeamF.Orientation(TopAbs_FORWARD);
369 TopoDS_Edge aSeamR = theSeam;
370 aSeamR.Orientation(TopAbs_REVERSED);
372 aTol=BRep_Tool::Tolerance(aSp);
374 Handle(Geom2d_Curve) C2D1 = BRep_Tool::CurveOnSurface(aSp, theFace, f, l);
375 Handle(Geom2d_Curve) C2D2 = BRep_Tool::CurveOnSurface(aSeamF, theFace, a, b);
376 Handle(Geom2d_Curve) C2D3 = BRep_Tool::CurveOnSurface(aSeamR, theFace, a, b);
378 Handle(Geom2d_TrimmedCurve) atr = Handle(Geom2d_TrimmedCurve)::DownCast(C2D1);
379 Handle(Geom2d_Line) aLD1;
382 aLD1 = Handle(Geom2d_Line)::DownCast(atr->BasisCurve());
385 aLD1 = Handle(Geom2d_Line)::DownCast(C2D1);
389 return Standard_False;
391 aT = BOPTools_Tools2D::IntermediatePoint(f, l);
392 C2D1->D1(aT, aP2D, aVec2D);
393 gp_Dir2d aDir2D(aVec2D);
395 gp_Vec2d aVec2D1, aVec2D2;
396 gp_Pnt2d aP2D1, aP2D2;
397 C2D2->D1(((a+b) * 0.5), aP2D1, aVec2D1);
398 C2D3->D1(((a+b) * 0.5), aP2D2, aVec2D2);
400 Handle(Geom_Surface) aS=BRep_Tool::Surface(theFace);
401 bIsUPeriodic = aS->IsUPeriodic();
402 bIsVPeriodic = aS->IsVPeriodic();
404 for(Standard_Integer i = 0; i < 2; i++) {
405 Standard_Boolean bIsPeriodic = (i == 0) ? bIsUPeriodic : bIsVPeriodic;
410 aPeriod = (i == 0) ? aS->UPeriod() : aS->VPeriod();
412 Standard_Real aParameter = (i == 0) ? aP2D.X() : aP2D.Y();
413 Standard_Real aParameter1 = (i == 0) ? aP2D1.X() : aP2D1.Y();
414 Standard_Real aParameter2 = (i == 0) ? aP2D2.X() : aP2D2.Y();
416 Standard_Boolean bIsLower = Standard_False, found = Standard_False;
417 Standard_Boolean bIsFirst = Standard_False;
418 Standard_Real aScPr = 0.;
420 if (fabs (aParameter - aParameter1) < aParTolerance) {
421 bIsLower = (aParameter < aParameter2);
422 bIsFirst = Standard_True;
423 aScPr = aDir2D * aVec2D1;
425 else if (fabs (aParameter - aParameter2) < aParTolerance) {
426 bIsLower = (aParameter < aParameter1);
427 bIsFirst = Standard_False;
428 aScPr = aDir2D * aVec2D2;
430 found = (fabs(aScPr) > aParTolerance);
433 Handle(Geom2d_Curve) aTmpC1, aTmpC2;
435 aTmpC1 = Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
436 Handle(Geom2d_TrimmedCurve) aC1 = new Geom2d_TrimmedCurve(aTmpC1, f, l);
438 aTmpC2 = Handle(Geom2d_Curve)::DownCast(C2D1->Copy());
439 Handle(Geom2d_TrimmedCurve) aC2 = new Geom2d_TrimmedCurve(aTmpC2, f, l);
456 aC2->Translate(aTrV);
458 IsReversed = (aScPr < 0.);
459 Standard_Boolean bIsReverseOrder = (!IsReversed) ? !bIsFirst : bIsFirst;
461 if(bIsReverseOrder) {
462 BB.UpdateEdge(aSp, aC2, aC1, theFace, aTol);
465 BB.UpdateEdge(aSp, aC1, aC2, theFace, aTol);
467 return Standard_True;
470 return Standard_False;
472 //=======================================================================
473 //function :IsSplitToReverse1
475 //=======================================================================
476 Standard_Boolean BOPTools_Tools3D::IsSplitToReverse1 (const TopoDS_Edge& aEF1,
477 const TopoDS_Edge& aEF2,
478 const Handle(IntTools_Context)& aContext)
480 Standard_Boolean aFlag;
481 Standard_Real aT1, aT2, aScPr, a, b;
486 Handle(Geom_Curve)aC1=BRep_Tool::Curve(aEF1, a, b);
487 aT1=BOPTools_Tools2D::IntermediatePoint(a, b);
489 aFlag=BOPTools_Tools2D::EdgeTangent(aEF1, aT1, aV1);
492 return Standard_False;
497 aFlag=aContext->ProjectPointOnEdge(aP, aEF2, aT2);
499 aFlag=BOPTools_Tools2D::EdgeTangent(aEF2, aT2, aV2);
501 return Standard_False;
511 //=======================================================================
512 //function : EdgeOrientation
514 //=======================================================================
515 TopAbs_Orientation BOPTools_Tools3D::EdgeOrientation (const TopoDS_Edge& aE,
516 const TopoDS_Face& aF1,
517 const TopoDS_Face& aF2)
520 gp_Dir aDTE, aDNF1, aDNF2, aDTN;
522 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF1, aDNF1);
523 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF2, aDNF2);
527 BOPTools_Tools2D::TangentOnEdge(aE, aDTE);
531 TopAbs_Orientation anOr;
535 anOr=TopAbs_REVERSED;
539 //=======================================================================
540 //function : IsTouchCase
542 //=======================================================================
543 Standard_Boolean BOPTools_Tools3D::IsTouchCase(const TopoDS_Edge& aE,
544 const TopoDS_Face& aF1,
545 const TopoDS_Face& aF2)
550 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF1, aDNF1);
551 BOPTools_Tools3D::GetNormalToFaceOnEdge(aE, aF2, aDNF2);
553 Standard_Boolean bIsDirsCoinside;
554 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
555 return bIsDirsCoinside;
557 //=======================================================================
558 //function : GetNormalToFaceOnEdge
560 //=======================================================================
561 void BOPTools_Tools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
562 const TopoDS_Face& aF,
565 Standard_Real aT, aT1, aT2;
567 BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
568 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
570 BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
572 if (aF.Orientation()==TopAbs_REVERSED){
577 //=======================================================================
578 //function : GetNormalToFaceOnEdge
580 //=======================================================================
581 void BOPTools_Tools3D::GetNormalToFaceOnEdge (const TopoDS_Edge& aE,
582 const TopoDS_Face& aF1,
583 const Standard_Real aT,
586 Standard_Real U, V, aTolPC;
591 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
593 Handle(Geom2d_Curve)aC2D1;
594 BOPTools_Tools2D::CurveOnSurface(aE, aF1, aC2D1, aTolPC, Standard_True);
600 aS1->D1(U, V, aP, aD1U, aD1V);
607 //=======================================================================
608 //function : GetBiNormal
610 //=======================================================================
611 void BOPTools_Tools3D::GetBiNormal(const TopoDS_Edge& aE,
612 const TopoDS_Face& aF,
613 const Standard_Real aT,
618 // Normal to the face aF at parameter aT
619 BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNF);
620 if (aF.Orientation()==TopAbs_REVERSED){
624 // Split tangent on aF at parameter aT
625 BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDT);
627 if (aF.Orientation()==TopAbs_REVERSED){
634 //=======================================================================
635 //function : :GetBiNormal
637 //=======================================================================
638 void BOPTools_Tools3D::GetBiNormal(const TopoDS_Edge& aSp,
639 const TopoDS_Face& aF,
644 // Normal to the face aF at parameter aT
645 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSp, aF, aDNF);
647 // Split tangent on aF at parameter aT
648 BOPTools_Tools3D::GetTangentToEdge(aSp, aDD1Sp);
650 if (aF.Orientation()==TopAbs_REVERSED){
656 //=======================================================================
657 //function : GetTangentToEdge
659 //=======================================================================
660 Standard_Boolean BOPTools_Tools3D::GetTangentToEdge(const TopoDS_Edge& anEdge,
663 Standard_Boolean isdgE;
665 Standard_Real aT1, aT2, aT;
667 isdgE = BRep_Tool::Degenerated(anEdge);
669 return Standard_False;
672 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, aT1, aT2);
673 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
675 BOPTools_Tools3D::GetTangentToEdge(anEdge, aT, aDT);
677 return Standard_True;
679 //=======================================================================
680 //function : GetTangentToEdge
682 //=======================================================================
683 Standard_Boolean BOPTools_Tools3D::GetTangentToEdge(const TopoDS_Edge& anEdge,
684 const Standard_Real aT,
687 Standard_Boolean isdgE;
688 Standard_Real first, last;
690 isdgE = BRep_Tool::Degenerated(anEdge);
692 return Standard_False;
695 Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
698 aC->D1(aT, aP, aTau);
700 if (anEdge.Orientation() == TopAbs_REVERSED){
705 return Standard_True;
707 //=======================================================================
708 //function : :IsSplitToReverse
710 //=======================================================================
711 Standard_Boolean BOPTools_Tools3D:: IsSplitToReverse(const TopoDS_Edge& aE,
712 const TopoDS_Edge& aSp)
714 Standard_Real t1, t2, aT;
716 Handle(Geom_Curve)aCE=BRep_Tool::Curve(aE, t1, t2);
717 Handle(Geom_Curve)aCSp=BRep_Tool::Curve(aSp,t1, t2);
719 aT=BOPTools_Tools2D::IntermediatePoint(t1, t2);
724 aCE->D1 (aT, aP, aD1E);
725 aCSp->D1(aT, aP, aD1Sp);
728 gp_Dir aDD1Sp(aD1Sp);
730 if (aE.Orientation()==TopAbs_REVERSED) {
733 if (aSp.Orientation()==TopAbs_REVERSED) {
742 //=======================================================================
743 //function : GetAdjacentFace
745 //=======================================================================
746 Standard_Boolean BOPTools_Tools3D::GetAdjacentFace(const TopoDS_Face& aFaceObj,
747 const TopoDS_Edge& anEObj,
748 const TopTools_IndexedDataMapOfShapeListOfShape& anEdgeFaceMap,
751 const TopTools_ListOfShape& aListOfAdjFaces=anEdgeFaceMap.FindFromKey(anEObj);
752 TopTools_ListIteratorOfListOfShape anIt(aListOfAdjFaces);
753 TopoDS_Shape anAdjShape;
754 for (; anIt.More(); anIt.Next()) {
755 if (anIt.Value()!=aFaceObj) {
756 anAdjShape=anIt.Value();
761 if (!anAdjShape.IsNull()) {
762 anAdjF=TopoDS::Face(anAdjShape);
763 return Standard_True;
766 return Standard_False;
769 //=======================================================================
770 //function : IsKeepTwice
772 //=======================================================================
773 Standard_Boolean BOPTools_Tools3D::IsKeepTwice(const TopoDS_Face& aF1,
774 const TopoDS_Face& aF2,
775 const TopoDS_Face& aF2Adj,
776 const TopoDS_Edge& aSpEF2)
778 if( !CheckKeepArguments(aF1, aF2, aF2Adj) ) {
779 return Standard_False;
782 Standard_Real aT1, aT2, aT, dt=1.e-7, A, B, C, D, d2, d2Adj;
783 gp_Dir aDNF1, aDNF2, DBF2, aDNF2Adj, DBF2Adj;
785 gp_Pnt aP, aPF2, aPF2Adj;
787 Handle(Geom_Curve) aC3D=BRep_Tool::Curve(aSpEF2, aT1, aT2);
788 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
789 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF1, aT, aDNF1);
792 // Split tangent on F2
793 aC3D->D1(aT, aP, aD1Sp);
794 gp_Dir aDD1Sp(aD1Sp);
796 if (aSpEF2.Orientation()==TopAbs_REVERSED) {
799 // Split Normal on F2
800 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2, aT, aDNF2);
801 if (aF2.Orientation()==TopAbs_REVERSED) {
808 aPF2.SetCoord(aP.X()+dt*DBF2.X(),
814 // Split tangent on F2Adj
816 // Split Normal on F2Adj
817 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpEF2, aF2Adj, aT, aDNF2Adj);
818 if (aF2Adj.Orientation()==TopAbs_REVERSED) {
822 DBF2Adj=aDNF2Adj^aDD1Sp;
825 aPF2Adj.SetCoord(aP.X()+dt*DBF2Adj.X(),
826 aP.Y()+dt*DBF2Adj.Y(),
827 aP.Z()+dt*DBF2Adj.Z());
829 // Tangent Plane on F1
830 gp_Pln aPlnN1(aP, aDNF1);
831 aPlnN1.Coefficients(A, B, C, D);
833 d2 = A*aPF2.X() + B*aPF2.Y() + C*aPF2.Z() + D;
834 d2Adj= A*aPF2Adj.X() + B*aPF2Adj.Y()+ C*aPF2Adj.Z() + D;
836 if (fabs(d2)<1.e-10) {
839 if (fabs(d2Adj)<1.e-10) {
848 //=======================================================================
849 //function : SenseFlag
851 //=======================================================================
852 Standard_Integer BOPTools_Tools3D::SenseFlag (const gp_Dir& aDNF1,
855 Standard_Boolean bIsDirsCoinside;
856 bIsDirsCoinside=IntTools_Tools::IsDirsCoinside(aDNF1, aDNF2);
857 if (!bIsDirsCoinside) {
873 //=======================================================================
874 //function : GetNormalToSurface
876 //=======================================================================
877 Standard_Boolean BOPTools_Tools3D::GetNormalToSurface (const Handle(Geom_Surface)& aS,
878 const Standard_Real U,
879 const Standard_Real V,
882 Standard_Boolean bFlag;
887 aS->D1(U, V, aP, aD1U, aD1V);
892 bFlag=IntTools_Tools::IsDirsCoinside(aDD1U, aDD1U);
901 //=======================================================================
902 //function : GetNormalToSurface
903 //purpose : local modification
904 //=======================================================================
906 static void GetApproxNormalToFaceOnEdgeEx(const TopoDS_Edge& aE,
907 const TopoDS_Face& aF,
908 const Standard_Real aT,
909 const Standard_Real aDT,
913 Standard_Real aFirst, aLast;
914 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
922 BOPTools_Tools3D::PointNearEdge (aE, aF, aT, aDT, aPx2DNear, aPNear);
924 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
926 BOPTools_Tools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
928 if (aF.Orientation()==TopAbs_REVERSED){
933 //=======================================================================
934 //function : GetPlanes
936 //=======================================================================
937 void BOPTools_Tools3D::GetPlanes (const TopoDS_Edge& aSpx,
938 const TopoDS_Edge& anEx,
939 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
940 const TopoDS_Edge& anE1,
941 const TopoDS_Face& aF1,
942 TopAbs_State& aStPF1,
943 const Handle(IntTools_Context)& aContext)
945 Standard_Boolean bIsAdjExists;
947 Standard_Real aT, aT1, aT2;
948 gp_Dir aDNFx1, aDNFx2;
949 gp_Pnt aPx, aPx1, aPx2, aPF1;
950 TopoDS_Face aFx1, aFx2;
953 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpx, aT1, aT2);
954 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
958 // 1.1. Fx1, Fx2 and theirs normals
959 TopAbs_Orientation anOrEx, anOr;
960 anOrEx=anEx.Orientation();
962 TopoDS_Edge aSpxSimm=anEx;
963 if (anOrEx==TopAbs_FORWARD) {
964 aSpxSimm.Orientation(TopAbs_REVERSED);
966 else if (anOrEx==TopAbs_REVERSED){
967 aSpxSimm.Orientation(TopAbs_FORWARD);
971 const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx);
972 TopTools_ListIteratorOfListOfShape anIt(aLF);
974 for (; anIt.More(); anIt.Next()) {
975 const TopoDS_Shape& aFE=anIt.Value();
976 aFx1=TopoDS::Face(aFE);
977 anOr=BOPTools_Tools3D::Orientation(anEx, aFx1);
984 Standard_Boolean aMoreShift = Standard_False;
985 Standard_Real aF2Tol = BRep_Tool::Tolerance(aFx1);
986 Standard_Real aF1Tol = BRep_Tool::Tolerance(aF1);
987 Standard_Real aETol = BRep_Tool::Tolerance(anEx);
988 if( aETol > 1.e-5 && (aF2Tol > 1.e-5 && aF1Tol > 1.e-5) )
989 aMoreShift = Standard_True;
990 Standard_Real aDT = 9.1e-5;
992 GetApproxNormalToFaceOnEdgeEx(anEx, aFx1, aT, aDT, aPx1, aDNFx1);
996 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1);
999 bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2);
1001 if (!bIsAdjExists) {
1004 GetApproxNormalToFaceOnEdgeEx(aSpxSimm, aFx1, aT, aDT, aPx2, aDNFx2);
1008 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2);
1011 aContext->ProjectPointOnEdge(aPx, anE1, aT1);
1012 PointNearE (anE1, aF1, aT1, aPF1, aMoreShift);
1015 else {// if (bIsAdjExists)
1016 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2);
1018 aContext->ProjectPointOnEdge(aPx, anE1, aT1);
1019 PointNearE (anE1, aF1, aT1, aPF1, aMoreShift);
1023 Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI;
1025 aTwoPI = M_PI + M_PI;
1027 gp_Vec aVx1(aPx, aPx1);
1028 gp_Dir aDBx1 (aVx1);
1029 gp_Pln aPlnToCompare (aPx, aDNFx1);
1031 gp_Vec aVx2(aPx, aPx2);
1032 gp_Dir aDBx2 (aVx2);
1034 anAlfa12=aDBx1.Angle(aDBx2);
1035 d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare);
1037 anAlfa12=aTwoPI-anAlfa12;
1040 gp_Vec aVF1(aPx, aPF1);
1041 gp_Dir aDBF1 (aVF1);
1042 anAlfa1=aDBx1.Angle(aDBF1);
1043 d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare);
1045 anAlfa1=aTwoPI-anAlfa1;
1049 if (anAlfa1 > anAlfa12) {
1055 //=======================================================================
1056 //function : Orientation
1058 //=======================================================================
1059 TopAbs_Orientation BOPTools_Tools3D::Orientation(const TopoDS_Edge& anE,
1060 const TopoDS_Face& aF)
1062 TopAbs_Orientation anOr=TopAbs_INTERNAL;
1064 TopExp_Explorer anExp;
1065 anExp.Init(aF, TopAbs_EDGE);
1066 for (; anExp.More(); anExp.Next()) {
1067 const TopoDS_Edge& anEF1=TopoDS::Edge(anExp.Current());
1068 if (anEF1.IsEqual(anE)) {
1069 anOr=anEF1.Orientation();
1076 //=======================================================================
1077 //function : SignDistance
1079 //=======================================================================
1080 Standard_Real BOPTools_Tools3D::SignDistance(const gp_Pnt& aP,
1083 Standard_Real A, B, C, D, d;
1084 aPln.Coefficients(A, B, C, D);
1086 d = A*aP.X() + B*aP.Y() + C*aP.Z() + D;
1091 //=======================================================================
1092 // function: IsValidArea
1094 //=======================================================================
1095 Standard_Boolean BOPTools_Tools3D::IsValidArea (const TopoDS_Face& aF,
1096 Standard_Boolean& bNegativeFlag)
1099 Standard_Boolean bFlag;
1100 Standard_Real aMass, dM=1.e-16;
1102 BRepGProp::SurfaceProperties(aF,G);
1105 bFlag=(fabs(aMass)-dM > 0.);
1106 bNegativeFlag=(aMass < dM);
1108 if( bNegativeFlag ) {
1110 BRepBndLib::AddClose(aF, boxF);
1111 Standard_Real aXmin = 0, aYmin = 0., aZmin = 0., aXmax = 0., aYmax = 0., aZmax = 0.;
1112 boxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1113 Standard_Boolean bigX = (fabs(aXmax-aXmin) >= 1.e+10);
1114 Standard_Boolean bigY = (fabs(aYmax-aYmin) >= 1.e+10);
1115 Standard_Boolean bigZ = (fabs(aZmax-aZmin) >= 1.e+10);
1116 if( !bigX && (!bigY && !bigZ) ) {
1117 TopExp_Explorer anExp;
1118 Standard_Integer nbW = 0;
1119 for(anExp.Init(aF, TopAbs_WIRE); anExp.More(); anExp.Next()) {
1120 const TopoDS_Wire& aW = TopoDS::Wire(anExp.Current());
1124 TopTools_IndexedDataMapOfShapeListOfShape mapVE;
1126 TopExp::MapShapesAndAncestors(aF,TopAbs_VERTEX,TopAbs_EDGE,mapVE);
1127 Standard_Integer nbKeys = mapVE.Extent(), iKey = 0;
1128 Standard_Boolean changeFlag = Standard_True;
1129 for( iKey = 1; iKey <= nbKeys; iKey++ ) {
1130 const TopoDS_Vertex& iV = TopoDS::Vertex(mapVE.FindKey(iKey));
1131 if( iV.IsNull() ) continue;
1132 Standard_Real TolV = BRep_Tool::Tolerance(iV);
1133 const TopTools_ListOfShape& iLE = mapVE.FindFromIndex(iKey);
1134 Standard_Integer nbE = iLE.Extent();
1136 changeFlag = Standard_False;
1139 const TopoDS_Edge& iE1 = TopoDS::Edge(iLE.First());
1140 const TopoDS_Edge& iE2 = TopoDS::Edge(iLE.Last());
1141 if(BRep_Tool::Degenerated(iE1) ||
1142 BRep_Tool::Degenerated(iE2) ) continue;
1143 Standard_Real iPE1 = BRep_Tool::Parameter(iV,iE1);
1144 Standard_Real iPE2 = BRep_Tool::Parameter(iV,iE2);
1145 Standard_Real pF1 = 0., pL1 = 0., pF2 = 0., pL2 = 0.;
1146 Handle(Geom_Curve) aC3D1 = BRep_Tool::Curve(iE1,pF1,pL1);
1147 Handle(Geom_Curve) aC3D2 = BRep_Tool::Curve(iE2,pF2,pL2);
1148 if( aC3D1.IsNull() || aC3D2.IsNull() ) {
1149 changeFlag = Standard_False;
1152 if( Abs(Abs(pL1-pF1)-Abs(pL2-pF2)) <= 1.e-10 ) {
1153 changeFlag = Standard_False;
1156 gp_Pnt aPnt1 = aC3D1->Value(iPE1);
1157 gp_Pnt aPnt2 = aC3D2->Value(iPE2);
1158 Standard_Real dist = aPnt1.Distance(aPnt2);
1159 Standard_Real TolE1 = BRep_Tool::Tolerance(iE1);
1160 Standard_Real TolE2 = BRep_Tool::Tolerance(iE2);
1161 if( dist > (/*TolV+*/TolE1+TolE2) ) {
1162 changeFlag = Standard_False;
1166 if( changeFlag ) bNegativeFlag = 0;
1175 //=======================================================================
1176 // function: PointNearE
1178 //=======================================================================
1179 void PointNearE (const TopoDS_Edge& aE,
1180 const TopoDS_Face& aF,
1181 const Standard_Real aT,
1183 const Standard_Boolean aSt)
1185 Standard_Real aT1, aT2;
1187 // 1. a Point on Edge aPOnEdge
1188 Handle(Geom_Curve)aC=BRep_Tool::Curve(aE, aT1, aT2);
1190 gp_Pnt2d aPInFace2D;
1192 aC->D0 (aT, aPOnEdge);
1194 // 2. a Point inside Face near aPOnEdge aPInFace;
1196 TopoDS_Edge aERight;
1197 aFF.Orientation(TopAbs_FORWARD);
1198 BOPTools_Tools3D::OrientEdgeOnFace (aE, aFF, aERight);
1201 Standard_Real aTolE, aDt2D;
1202 GeomAbs_SurfaceType aType;
1204 aDt2D=BOPTools_Tools3D::MinStepIn2d();
1206 Handle(Geom_Surface) aS=BRep_Tool::Surface(aFF);
1207 GeomAdaptor_Surface aGASF(aS);
1208 aType=aGASF.GetType();
1209 if (aType==GeomAbs_Plane) {
1210 aTolE=BRep_Tool::Tolerance(aE);
1225 BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aDt2D, aPInFace2D, aPInFace);
1227 if (BRep_Tool::IsClosed(aE, aF)) {
1228 Standard_Real X, Y, UMin, UMax, VMin, VMax;
1231 BRepTools::UVBounds(aF, UMin, UMax, VMin, VMax);
1232 if (!(X >= UMin && X <= UMax && Y >= VMin && Y <= VMax)) {
1234 BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace);
1240 static Standard_Boolean PseudoSDFaces(const BRepAdaptor_Surface& BS1,
1241 const BRepAdaptor_Surface& BS2)
1243 Standard_Real TolF1 = BS1.Tolerance();
1244 Standard_Real TolF2 = BS2.Tolerance();
1246 gp_Pln Pln1 = BS1.Plane();
1247 gp_Pln Pln2 = BS2.Plane();
1249 TopExp_Explorer anExpE;
1250 Standard_Real pF = 0., pL = 0.;
1253 const TopoDS_Face& aF1 = BS1.Face();
1254 Standard_Real maxTolE1 = 1.e-7, maxTolV1 = 1.e-7;
1255 Standard_Integer nbE1 = 0, nbOnE1 = 0;
1256 for(anExpE.Init(aF1, TopAbs_EDGE); anExpE.More(); anExpE.Next()) {
1257 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
1259 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
1260 if( aTolE > maxTolE1 ) maxTolE1 = aTolE;
1261 Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, pF, pL);
1262 if( !aC3D.IsNull() ) {
1263 Standard_Real pM = BOPTools_Tools2D::IntermediatePoint(pF, pL);
1264 gp_Pnt mPnt = aC3D->Value(pM);
1265 Standard_Real distMP = Pln2.Distance(mPnt);
1267 if( distMP <= aTolE )
1270 TopoDS_Vertex Vf, Vl;
1271 TopExp::Vertices(aE,Vf,Vl);
1272 if( !Vf.IsNull() && !Vl.IsNull() ) {
1273 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1274 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1275 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1276 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1277 Standard_Real distF = Pln2.Distance(aPntF);
1278 Standard_Real distL = Pln2.Distance(aPntL);
1279 if( distF <= aTolVf && distL <= aTolVl )
1282 else if( !Vf.IsNull() && Vl.IsNull() ) {
1283 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1284 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1285 Standard_Real distF = Pln2.Distance(aPntF);
1286 if( distF <= aTolVf )
1289 else if( Vf.IsNull() && !Vl.IsNull() ) {
1290 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1291 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1292 Standard_Real distL = Pln2.Distance(aPntL);
1293 if( distL <= aTolVl )
1302 Standard_Boolean procF1 = ((maxTolE1/TolF1) >= 1000. ||
1303 (TolF1/maxTolE1) >= 1000.) ? Standard_True : Standard_False;
1304 procF1 = (procF1 && (nbE1 > 1 && nbOnE1 > 1) );
1307 return Standard_False;
1309 const TopoDS_Face& aF2 = BS1.Face();
1310 Standard_Real maxTolE2 = 1.e-7, maxTolV2 = 1.e-7;
1311 Standard_Integer nbE2 = 0, nbOnE2 = 0;
1312 for(anExpE.Init(aF2, TopAbs_EDGE); anExpE.More(); anExpE.Next()) {
1313 const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
1315 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
1316 if( aTolE > maxTolE2 ) maxTolE2 = aTolE;
1317 Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, pF, pL);
1318 if( !aC3D.IsNull() ) {
1319 Standard_Real pM = BOPTools_Tools2D::IntermediatePoint(pF, pL);
1320 gp_Pnt mPnt = aC3D->Value(pM);
1321 Standard_Real distMP = Pln1.Distance(mPnt);
1322 if( distMP <= aTolE )
1325 TopoDS_Vertex Vf, Vl;
1326 TopExp::Vertices(aE,Vf,Vl);
1327 if( !Vf.IsNull() && !Vl.IsNull() ) {
1328 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1329 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1330 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1331 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1332 Standard_Real distF = Pln1.Distance(aPntF);
1333 Standard_Real distL = Pln1.Distance(aPntL);
1334 if( distF <= aTolVf && distL <= aTolVl )
1337 else if( !Vf.IsNull() && Vl.IsNull() ) {
1338 Standard_Real aTolVf = BRep_Tool::Tolerance(Vf);
1339 gp_Pnt aPntF = BRep_Tool::Pnt(Vf);
1340 Standard_Real distF = Pln1.Distance(aPntF);
1341 if( distF <= aTolVf )
1344 else if( Vf.IsNull() && !Vl.IsNull() ) {
1345 Standard_Real aTolVl = BRep_Tool::Tolerance(Vl);
1346 gp_Pnt aPntL = BRep_Tool::Pnt(Vl);
1347 Standard_Real distL = Pln1.Distance(aPntL);
1348 if( distL <= aTolVl )
1357 Standard_Boolean procF2 = ((maxTolE2/TolF2) >= 1000. ||
1358 (TolF2/maxTolE2) >= 1000.) ? Standard_True : Standard_False;
1359 procF2 = (procF2 && (nbE2 > 1 && nbOnE2 > 1) );
1361 return (procF1 && procF2);
1365 Standard_Boolean CheckKeepArguments(const TopoDS_Face& F1,
1366 const TopoDS_Face& F2,
1367 const TopoDS_Face& F3)
1369 BRepAdaptor_Surface aBS1(F1);
1370 BRepAdaptor_Surface aBS2(F2);
1371 BRepAdaptor_Surface aBS3(F3);
1373 GeomAbs_SurfaceType aT1 = aBS1.GetType();
1374 GeomAbs_SurfaceType aT2 = aBS2.GetType();
1375 GeomAbs_SurfaceType aT3 = aBS3.GetType();
1377 if(aT1 == GeomAbs_Cylinder ||
1378 aT1 == GeomAbs_Cone ||
1379 aT1 == GeomAbs_Sphere ||
1380 aT1 == GeomAbs_Torus ) return Standard_True;
1382 if(aT2 == GeomAbs_Cylinder ||
1383 aT2 == GeomAbs_Cone ||
1384 aT3 == GeomAbs_Sphere ||
1385 aT3 == GeomAbs_Torus ) return Standard_True;
1387 if(aT3 == GeomAbs_Cylinder ||
1388 aT3 == GeomAbs_Cone ||
1389 aT3 == GeomAbs_Sphere ||
1390 aT3 == GeomAbs_Torus ) return Standard_True;
1392 if( aT1 == GeomAbs_Plane && aT2 == GeomAbs_Plane ) {
1393 if( PseudoSDFaces(aBS1, aBS2) )
1394 return Standard_False;
1396 else if( aT1 == GeomAbs_Plane && aT3 == GeomAbs_Plane ) {
1397 if( PseudoSDFaces(aBS1, aBS3) )
1398 return Standard_False;
1400 else if( aT2 == GeomAbs_Plane && aT3 == GeomAbs_Plane ) {
1401 if( PseudoSDFaces(aBS2, aBS3) )
1402 return Standard_False;
1405 return Standard_True;
1406 return Standard_True;