1 // Created on: 2001-06-18
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.
21 #include <BOPTools_Tools3D.ixx>
25 #include <gp_Cylinder.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <gp_Vec2d.hxx>
28 #include <gp_Dir2d.hxx>
33 #include <Geom2d_Curve.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_Surface.hxx>
37 #include <GeomAdaptor_Surface.hxx>
38 #include <GeomAPI_ProjectPointOnSurf.hxx>
40 #include <BRepTools.hxx>
41 #include <BRepClass3d_SolidClassifier.hxx>
43 #include <BRep_Tool.hxx>
44 #include <BRepAdaptor_Surface.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopExp_Explorer.hxx>
49 #include <TopTools_ListOfShape.hxx>
51 #include <BOPTools_Tools2D.hxx>
53 static Standard_Boolean CheckPointInside(BRepClass3d_SolidClassifier& aSolidClassifier,
55 const Standard_Real aTolerance,
56 const Handle(IntTools_Context)& theContext,
58 Standard_Boolean& bFoundInFacePoint);
60 //=======================================================================
61 //function : GetApproxNormalToFaceOnEdge
63 //=======================================================================
64 void BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE,
65 const TopoDS_Face& aF,
66 const Standard_Real aT,
70 Standard_Real aFirst, aLast;
71 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
78 BOPTools_Tools3D::PointNearEdge (aE, aF, aT, aPx2DNear, aPNear);
80 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
82 BOPTools_Tools3D::GetNormalToSurface (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF);
84 if (aF.Orientation()==TopAbs_REVERSED){
88 //=======================================================================
89 //function : PointNearEdge
91 //=======================================================================
92 void BOPTools_Tools3D::PointNearEdge (const TopoDS_Edge& aE,
93 const TopoDS_Face& aF,
94 const Standard_Real aT,
95 const Standard_Real aDt2D,
99 Standard_Real aFirst, aLast, aETol, aFTol, transVal;
100 GeomAbs_SurfaceType aTS;
101 Handle(Geom2d_Curve) aC2D;
102 Handle(Geom_Surface) aS;
104 aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast);
106 aPx2DNear.SetCoord (99., 99);
110 aS=BRep_Tool::Surface(aF);
114 aC2D->D1 (aT, aPx2D, aVx2D);
115 gp_Dir2d aDx2D(aVx2D);
118 aDP.SetCoord (-aDx2D.Y(), aDx2D.X());
120 if (aE.Orientation()==TopAbs_REVERSED){
124 if (aF.Orientation()==TopAbs_REVERSED) {
128 aETol = BRep_Tool::Tolerance(aE);
129 aFTol = BRep_Tool::Tolerance(aF);
131 GeomAdaptor_Surface aGAS(aS);
133 if (aTS==GeomAbs_BSplineSurface) {
138 //modified by NIZNHY-PKV Thu Mar 19 14:15:15 2009f
139 if( aETol > 1.e-5 || aFTol > 1.e-5 ) {
140 //if( aETol > 1.e-5 && aFTol > 1.e-5 ) {
141 //modified by NIZNHY-PKV Thu Mar 19 14:15:24 2009t
143 if(aTS!=GeomAbs_Sphere) {
144 gp_Vec2d transVec( aDP );
145 transVal = aDt2D + aETol + aFTol;
146 if (aTS==GeomAbs_Cylinder) {// pkv/909/F8
147 Standard_Real aR, dT;
149 gp_Cylinder aCyl=aGAS.Cylinder();
156 transVec.Multiply(transVal);
158 aPx2DNear = aPx2D.Translated( transVec );
161 aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
165 aPx2DNear.SetCoord (aPx2D.X()+aDt2D*aDP.X(), aPx2D.Y()+aDt2D*aDP.Y());
168 aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
171 //=======================================================================
172 //function : PointNearEdge
174 //=======================================================================
175 void BOPTools_Tools3D::PointNearEdge (const TopoDS_Edge& aE,
176 const TopoDS_Face& aF,
177 const Standard_Real aT,
181 Standard_Real dt2D=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
183 BOPTools_Tools3D::PointNearEdge (aE, aF, aT, dt2D, aPx2DNear, aPxNear);
186 //=======================================================================
187 // function: PointNearEdge
189 //=======================================================================
190 void BOPTools_Tools3D::PointNearEdge (const TopoDS_Edge& aE,
191 const TopoDS_Face& aF,
192 gp_Pnt2d& aPInFace2D,
196 Standard_Real aT, aT1, aT2;
199 BRep_Tool::Range(aE, aT1, aT2);
200 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
202 // 2. a Point inside Face near aPOnEdge aPInFace;
205 aFF.Orientation(TopAbs_FORWARD);
206 BOPTools_Tools3D::OrientEdgeOnFace (aE, aFF, aERight);
208 BOPTools_Tools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace);
212 //=======================================================================
213 //function : PointToCompare
215 //=======================================================================
216 void BOPTools_Tools3D::PointToCompare (const gp_Pnt& aP1,
218 const TopoDS_Face& aF,
220 const Handle(IntTools_Context)& aContext)
222 Standard_Boolean bFlag;
223 Standard_Real aD, aTolF, U, V;
225 Handle(Geom_Surface) aS=BRep_Tool::Surface(aF);
227 aTolF=BRep_Tool::Tolerance(aF);
229 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF);
231 aProjector.Perform(aP1);
233 bFlag=aProjector.IsDone();
236 aD=aProjector.LowerDistance();
238 aProjector.LowerDistanceParameters (U, V);
244 aProjector.Perform(aP2);
246 bFlag=aProjector.IsDone();
249 aD=aProjector.LowerDistance();
251 aProjector.LowerDistanceParameters (U, V);
260 //=======================================================================
261 //function : GetPlane
263 //=======================================================================
264 void BOPTools_Tools3D::GetPlane (const TopoDS_Edge& aSpEF1,
265 const TopoDS_Edge& aEF1,
266 const TopoDS_Face& aF1,
267 const TopoDS_Face& aF2,
269 const Handle(IntTools_Context)& aContext)
271 Standard_Real aT1, aT2, aT, aTolF2, aDt2D;
273 gp_Pnt aPxNear, aPxF2;
276 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpEF1, aT1, aT2);
277 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
279 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aEF1, aF1, aT1, aT2);
283 aDt2D=BOPTools_Tools3D::MinStepIn2d();//~1.e-5;
284 aTolF2=BRep_Tool::Tolerance(aF2);
287 GeomAbs_SurfaceType aType1;
289 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
290 GeomAdaptor_Surface aGASF1(aS1);
291 aType1=aGASF1.GetType();
293 if (aType1==GeomAbs_Cylinder) {
294 Standard_Real aCT, aDt2Dx, aPC=0.99;
296 aCT=1.-aGASF1.UResolution(aTolF2);
297 aDt2Dx=aPC*acos(aCT);
304 BOPTools_Tools3D::PointNearEdge (aEF1, aF1, aT, aDt2D, aPx2DNear, aPxNear);
308 Standard_Boolean isIn = aContext->IsPointInFace(aF1,aPx2DNear);
310 Standard_Real aEF1Tol = BRep_Tool::Tolerance(aEF1);
311 Standard_Real aF1Tol = BRep_Tool::Tolerance(aF1);
312 if( aEF1Tol > 1.e-5 || ( aF1Tol > 1.e-5 || aTolF2 > 1.e-5 ) ) {
314 aC2D->D0(aT, aP2DOnC);
315 gp_Vec2d aP2Dir( aPx2DNear, aP2DOnC );
316 Standard_Real transVal = aP2Dir.Magnitude();
317 gp_Vec2d aP2DirN = aP2Dir.Normalized();
318 if( aF1Tol > 1.e-5 && aTolF2 > 1.e-5 ) {
319 transVal = 2.*transVal +aEF1Tol + aF1Tol + aTolF2;
324 aPx2DNear.Translate( (transVal*aP2DirN) );
325 Handle(Geom_Surface) aS1 = BRep_Tool::Surface(aF1);
326 aS1->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear);
332 Standard_Boolean bFlag;
333 Standard_Real aD, U, V;
335 GeomAPI_ProjectPointOnSurf& aProjector=aContext->ProjPS(aF2);
337 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
339 aProjector.Perform(aPxNear);
341 bFlag=aProjector.IsDone();
347 aD=aProjector.LowerDistance();
349 // aPxF2, aDNF2, aPlnF2
350 aProjector.LowerDistanceParameters (U, V);
351 aS2->D0(U, V, aPxF2);
353 BOPTools_Tools3D::GetNormalToSurface (aS2, U, V, aDNF2);
355 if (aF2.Orientation()==TopAbs_REVERSED){
359 gp_Pln aPlnF2(aPxF2, aDNF2);
361 aD=BOPTools_Tools3D::SignDistance(aPxNear, aPlnF2);
369 //=======================================================================
370 //function : GetPointState
372 //=======================================================================
373 void BOPTools_Tools3D::GetPointState (const TopoDS_Edge& aSpEF2,
374 const TopoDS_Edge& aEF2,
375 const TopoDS_Face& aF2adj,
376 const TopoDS_Face& aF1,
379 Standard_Real aT1, aT2, aT, aTolEF2;
381 gp_Pnt2d aPxOnF1, aPxOnF2;
383 TopoDS_Face aF2adjF=aF2adj;
384 aF2adjF.Orientation(TopAbs_FORWARD);
386 aTolEF2=BRep_Tool::Tolerance(aEF2);
390 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpEF2, aT1, aT2);
391 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
393 // 2D-curves of aSpEF2 for aF1, aF2adj
394 Handle(Geom2d_Curve) aC2DF1= BRep_Tool::CurveOnSurface (aSpEF2, aF1, aT1, aT2);
395 aC2DF1->D0(aT, aPxOnF1);
397 Handle(Geom2d_Curve) aC2DF2= BRep_Tool::CurveOnSurface (aSpEF2, aF2adjF, aT1, aT2);
398 aC2DF2->D0(aT, aPxOnF2);
401 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
402 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2adjF);
406 Standard_Real aDt2D, aDt2dMin, aURes, aVRes;
408 GeomAdaptor_Surface aGASF2adjF(aS2);
410 aURes=aGASF2adjF.UResolution(aTolEF2);
411 aVRes=aGASF2adjF.VResolution(aTolEF2);
412 aDt2D=(aURes>aVRes) ? aURes : aVRes;
414 aDt2dMin=BOPTools_Tools3D::MinStepIn2d();
416 if (aDt2D < aDt2dMin) {
420 // Point aPxNear on aF2adjF that is Near Edge aEF2Right at parameter aT
423 TopoDS_Edge aEF2Right;
425 BOPTools_Tools3D::OrientEdgeOnFace (aEF2, aF2adjF, aEF2Right);
427 BOPTools_Tools3D::PointNearEdge (aEF2Right, aF2adjF, aT, aDt2D, aPx2DNear, aPxNear);
429 // Normal to the face aF1 at the point aPxOnF1
430 BOPTools_Tools3D::GetNormalToSurface (aS1, aPxOnF1.X(), aPxOnF1.Y(), aDNF1);
431 if (aF1.Orientation()==TopAbs_REVERSED){
435 // Plane to compare aPlnF1
438 aS1->D0(aPxOnF1.X(), aPxOnF1.Y(), aPxF1);
440 gp_Pln aPlnF1(aPxF1, aDNF1);
442 // Correction on shifting vector aVx
444 Standard_Real aX, aY, aZ;
446 aS2->D0(aPxOnF2.X(), aPxOnF2.Y(), aPxF2);
447 gp_Vec aVx(aPxF2, aPxF1);
449 aX=aPxNear.X()+aVx.X();
450 aY=aPxNear.Y()+aVx.Y();
451 aZ=aPxNear.Z()+aVx.Z();
453 aPxNear.SetCoord(aX, aY, aZ);
456 // Signed Distance between aPxNear, aPlnF1
458 aD=BOPTools_Tools3D::SignDistance(aPxNear, aPlnF1);
464 //=======================================================================
465 //function : OrientEdgeOnFace
467 //=======================================================================
468 void BOPTools_Tools3D::OrientEdgeOnFace (const TopoDS_Edge& aE,
469 const TopoDS_Face& aF,
470 TopoDS_Edge& aERight)
472 if (BRep_Tool::IsClosed(aE, aF)) {
474 aERight.Orientation(aE.Orientation());
476 Standard_Integer iFoundCount = 0;
477 TopoDS_Edge anEdge = aE;
478 TopExp_Explorer anExp(aF, TopAbs_EDGE);
480 for (; anExp.More(); anExp.Next()) {
481 const TopoDS_Shape& aSS=anExp.Current();
483 if (aSS.IsSame(aE)) {
484 anEdge = TopoDS::Edge(aSS);
489 if(iFoundCount == 1) {
495 TopExp_Explorer anExp(aF, TopAbs_EDGE);
496 for (; anExp.More(); anExp.Next()) {
497 const TopoDS_Shape& aSS=anExp.Current();
498 if (aSS.IsSame(aE)) {
500 aERight.Orientation(aSS.Orientation());
505 aERight.Orientation(aE.Orientation());
507 //=======================================================================
508 //function : OrientTouchEdgeOnF1
510 //=======================================================================
511 TopAbs_Orientation BOPTools_Tools3D::OrientTouchEdgeOnF1 (const TopoDS_Edge& aSpEF2,
512 const TopoDS_Edge& aEF2,
513 const TopoDS_Face& aF2adj,
514 const TopoDS_Face& aF1)
516 Standard_Real aT1, aT2, aT;
518 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(aSpEF2, aT1, aT2);
520 // point on edge aEF2 inside range of aSpEF2:
522 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
527 Handle(Geom2d_Curve) aC2DF1= BRep_Tool::CurveOnSurface (aSpEF2, aF1, aT1, aT2);
529 aC2DF1->D0(aT, aPxOnF1);
531 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
532 BOPTools_Tools3D::GetNormalToSurface (aS1, aPxOnF1.X(), aPxOnF1.Y(), aDNF1);
534 if (aF1.Orientation()==TopAbs_REVERSED){
538 // Point aPxNear that is ON F2adj and near Px
542 Handle(Geom2d_Curve) aC2D= BRep_Tool::CurveOnSurface (aEF2, aF2adj, aT1, aT2);
544 TopoDS_Face aF2adjF=aF2adj;
545 aF2adjF.Orientation(TopAbs_FORWARD);
546 TopoDS_Edge aEF2Right;
547 BOPTools_Tools3D::OrientEdgeOnFace (aEF2, aF2adjF, aEF2Right);
548 BOPTools_Tools3D::PointNearEdge (aEF2Right, aF2adjF, aT, aPx2DNear, aPxNear);
552 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2adj);
553 BOPTools_Tools3D::GetNormalToSurface (aS2, aPx2DNear.X(), aPx2DNear.Y(), aDNF2);
555 if (aF2adj.Orientation()==TopAbs_REVERSED){
560 gp_Dir aDTN=aDNF1^aDNF2;
563 BOPTools_Tools2D::TangentOnEdge(aT, aSpEF2, aTE);
569 TopAbs_Orientation anOr;
572 anOr=TopAbs_REVERSED;
577 //=======================================================================
578 // function: GetSeams
580 //=======================================================================
581 void BOPTools_Tools3D::GetSeams (const TopoDS_Face& aF,
585 TopTools_ListOfShape aLS;
586 TopExp_Explorer anExpEdges (aF, TopAbs_EDGE);
587 for (; anExpEdges.More(); anExpEdges.Next()) {
588 const TopoDS_Edge& aE= TopoDS::Edge(anExpEdges.Current());
589 if (BRep_Tool::IsClosed(aE, aF)) {
593 aSim1=TopoDS::Edge(aLS.First());
594 aSim2=TopoDS::Edge(aLS.Last ());
597 //=======================================================================
600 //=======================================================================
601 void BOPTools_Tools3D::GetSeam (const TopoDS_Face& aF,
602 const TopoDS_Edge& aSim1,
605 TopExp_Explorer anExpEdges (aF, TopAbs_EDGE);
606 for (; anExpEdges.More(); anExpEdges.Next()) {
607 const TopoDS_Edge& aE= TopoDS::Edge(anExpEdges.Current());
608 if (BRep_Tool::IsClosed(aE, aF)) {
609 if (aE.IsSame(aSim1)) {
619 //=======================================================================
620 //function : MinStepIn2d
622 //=======================================================================
623 Standard_Real BOPTools_Tools3D::MinStepIn2d()
625 Standard_Real dt=1.e-5;
630 #include <TopTools_IndexedMapOfShape.hxx>
631 #include <TopoDS_Iterator.hxx>
632 #include <BRep_TVertex.hxx>
633 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
634 #include <BRep_PointRepresentation.hxx>
635 #include <BRep_TEdge.hxx>
636 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
637 #include <BRep_CurveRepresentation.hxx>
638 #include <BRep_TFace.hxx>
639 #include <Poly_Triangulation.hxx>
640 #include <BRep_Builder.hxx>
643 Standard_Boolean HasGeometry(const TopoDS_Shape& aS);
646 void Add(const TopoDS_Shape& aS,
647 TopTools_IndexedMapOfShape& myShapes,
648 Standard_Boolean& bHasGeometry);
650 //=======================================================================
651 //function : IsEmptyShape
653 //=======================================================================
654 Standard_Boolean BOPTools_Tools3D::IsEmptyShape(const TopoDS_Shape& aS)
656 Standard_Boolean bHasGeometry=Standard_False;
658 TopTools_IndexedMapOfShape myShapes;
660 Add(aS, myShapes, bHasGeometry);
662 return !bHasGeometry;
664 //=======================================================================
667 //=======================================================================
668 void Add(const TopoDS_Shape& aS,
669 TopTools_IndexedMapOfShape& myShapes,
670 Standard_Boolean& bHasGeometry)
672 Standard_Integer anIndex;
682 TopoDS_Shape aSx = aS;
684 anIndex=myShapes.FindIndex(aSx);
686 bHasGeometry=HasGeometry (aSx);
691 TopoDS_Iterator anIt(aSx, Standard_False, Standard_False);
692 for(; anIt.More(); anIt.Next()) {
693 const TopoDS_Shape& aSy=anIt.Value();
694 Add(aSy, myShapes, bHasGeometry);
704 //=======================================================================
705 //function : HasGeometry
707 //=======================================================================
708 Standard_Boolean HasGeometry(const TopoDS_Shape& aS)
710 Standard_Boolean bHasGeometry=Standard_True;
711 TopAbs_ShapeEnum aType= aS.ShapeType();
713 if (aType == TopAbs_VERTEX) {
715 Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(aS.TShape());
716 BRep_ListIteratorOfListOfPointRepresentation itrp(TV->Points());
718 while (itrp.More()) {
719 const Handle(BRep_PointRepresentation)& PR = itrp.Value();
721 if (PR->IsPointOnCurve()) {
725 else if (PR->IsPointOnCurveOnSurface()) {
729 else if (PR->IsPointOnSurface()) {
737 else if (aType == TopAbs_EDGE) {
738 Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(aS.TShape());
739 BRep_ListIteratorOfListOfCurveRepresentation itrc(TE->Curves());
741 while (itrc.More()) {
742 const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
743 if (CR->IsCurve3D()) {
744 if (!CR->Curve3D().IsNull()) {
748 else if (CR->IsCurveOnSurface()) {
751 else if (CR->IsRegularity()) {
754 else if (!CR->Polygon3D().IsNull()) {
757 else if (CR->IsPolygonOnTriangulation()) {
760 else if (CR->IsPolygonOnSurface()) {
767 else if (aType == TopAbs_FACE) {
768 Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(aS.TShape());
769 if (!TF->Surface().IsNull()) {
772 Handle(Poly_Triangulation) Tr = TF->Triangulation();
778 return !bHasGeometry;
781 //=======================================================================
782 // function: InvertShape
784 //=======================================================================
785 void BOPTools_Tools3D::InvertShape(const TopoDS_Shape& aS,
786 TopoDS_Shape& aSInvert)
790 aSInvert=aS.EmptyCopied();
792 TopoDS_Iterator anIt(aS);
794 while (anIt.More()) {
795 aBB.Add(aSInvert, anIt.Value().Reversed());
800 //=======================================================================
801 // function: GetStatePartIN2D
803 //=======================================================================
804 TopAbs_State BOPTools_Tools3D::GetStatePartIN2D(const TopoDS_Edge& aSp,
805 const TopoDS_Edge& aEF1,
806 const TopoDS_Face& aF1,
807 const TopoDS_Face& aF2,
808 const Handle(IntTools_Context)& aContext)
813 BOPTools_Tools3D::GetBiNormal (aSp, aF1, aDBF1);
814 BOPTools_Tools3D::GetNormalToFaceOnEdge (aSp, aF2, aDNF2);
816 Standard_Real aTolScPr, aScPr;
822 BRepAdaptor_Surface aBAS1, aBAS2;
823 GeomAbs_SurfaceType aType1, aType2;
825 aBAS1.Initialize (aF1, Standard_False);
826 aBAS2.Initialize (aF2, Standard_False);
827 aType1=aBAS1.GetType();
828 aType2=aBAS2.GetType();
830 if (aType1==GeomAbs_BSplineSurface
832 aType2==GeomAbs_BSplineSurface) {
838 if (fabs(aScPr) < aTolScPr) {
841 BOPTools_Tools3D::GetPlane(aSp, aEF1, aF1, aF2, aStPF, aContext);
843 if (aStPF==TopAbs_IN) {
854 // ===========================================================================================
855 // function: ComputeFaceState
857 // ===========================================================================================
858 Standard_Boolean BOPTools_Tools3D::ComputeFaceState(const TopoDS_Face& theFace,
859 const TopoDS_Solid& theRef,
860 const Handle(IntTools_Context)& theContext,
861 TopAbs_State& theState)
863 TopAbs_State aState = TopAbs_ON;
865 Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
866 BRepTools::UVBounds(theFace, umin, umax, vmin, vmax);
867 Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace);
868 Standard_Real aTolerance = BRep_Tool::Tolerance(theFace);
870 Standard_Integer nbpoints = 5;
871 Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
872 Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
873 Standard_Real U = umin + adeltau;
874 Standard_Boolean bFoundValidPoint = Standard_False;
875 Standard_Boolean bFoundInFacePoint = Standard_False;
876 BRepClass3d_SolidClassifier& aSolidClassifier = theContext->SolidClassifier(theRef);
877 Standard_Integer i = 0, j = 0;
879 for(i = 1; !bFoundValidPoint && (i <= nbpoints); i++, U+=adeltau) {
880 Standard_Real V = vmin + adeltav;
882 for(j = 1; !bFoundValidPoint && (j <= nbpoints); j++, V+=adeltav) {
883 gp_Pnt2d aPoint(U,V);
885 if(theContext->IsPointInFace(theFace, aPoint)) {
886 bFoundInFacePoint = Standard_True;
887 gp_Pnt aP3d = aSurface->Value(U, V);
889 aSolidClassifier.Perform(aP3d, aTolerance);
890 aState = aSolidClassifier.State();
892 if(aState != TopAbs_ON) {
894 if(!aSolidClassifier.Rejected()) {
895 TopoDS_Face aFace2 = aSolidClassifier.Face();
897 if(!aFace2.IsNull()) {
898 if(BOPTools_Tools3D::CheckSameDomainFaceInside(theFace, aFace2, theContext))
910 if(!bFoundInFacePoint) {
911 U = (umin + umax) * 0.5;
914 for(i = 1; !bFoundValidPoint && (i <= nbpoints); i++, U+=adeltau) {
915 Standard_Real V = (vmin + vmax) * 0.5;
917 for(j = 1; !bFoundValidPoint && (j <= nbpoints); j++, V+=adeltav) {
918 gp_Pnt2d aPoint(U,V);
920 if(theContext->IsPointInOnFace(theFace, aPoint)) {
921 bFoundInFacePoint = Standard_True;
922 gp_Pnt aP3d = aSurface->Value(U, V);
924 bFoundValidPoint = CheckPointInside(aSolidClassifier, aP3d, aTolerance, theContext,
925 aState, bFoundInFacePoint);
926 if (bFoundValidPoint) {
933 //emv for salome bug 23160
934 if(!bFoundInFacePoint) {
935 TopExp_Explorer aExp;
936 Standard_Real aT1, aT2, aT, aDt2D;
939 aExp.Init(theFace, TopAbs_EDGE);
940 for(; aExp.More(); aExp.Next()) {
941 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
942 if (aE.Orientation()==TopAbs_INTERNAL) {
946 if (BRep_Tool::Degenerated(aE)){
950 //get point inside face
951 Handle(Geom_Curve)aC3D = BRep_Tool::Curve(aE, aT1, aT2);
952 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
954 aDt2D = BOPTools_Tools3D::MinStepIn2d();
955 aDt2D += 2*BRep_Tool::Tolerance(aE);
956 BOPTools_Tools3D::PointNearEdge (aE, theFace, aT, aDt2D, aPoint, aP3d);
958 if (theContext->IsPointInOnFace(theFace, aPoint)) {
959 bFoundInFacePoint = Standard_True;
961 bFoundValidPoint = CheckPointInside(aSolidClassifier, aP3d, aTolerance, theContext,
962 aState, bFoundInFacePoint);
963 if (bFoundValidPoint) {
970 if(!bFoundInFacePoint)
971 return Standard_False;
975 return Standard_True;
978 //modified by NIZNHY-PKV Thu Sep 22 10:55:14 2011f
979 // ===========================================================================================
980 // function: CheckSameDomainFaceInside
981 // purpose: Check if distance between several points of theFace1 and
983 // ===========================================================================================
984 Standard_Boolean BOPTools_Tools3D::CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
985 const TopoDS_Face& theFace2,
986 const Handle(IntTools_Context)& theContext)
988 Standard_Boolean bFoundON, bPointInFace;
989 Standard_Integer nbpoints, i, j;
990 Standard_Real umin, umax, vmin, vmax, aTol, adeltau, adeltav, U, V, U2, V2, aD, aTolE;
993 TopExp_Explorer aExp;
995 BRepTools::UVBounds(theFace1, umin, umax, vmin, vmax);
996 Handle(Geom_Surface) aS1=BRep_Tool::Surface(theFace1);
998 aTol=BRep_Tool::Tolerance(theFace1);
999 aExp.Init(theFace1, TopAbs_EDGE);
1000 for(; aExp.More(); aExp.Next()) {
1001 const TopoDS_Edge& aE = TopoDS::Edge(aExp.Current());
1002 aTolE = BRep_Tool::Tolerance(aE);
1003 aTol=(aTol < aTolE) ? aTolE : aTol;
1005 aTol=aTol+BRep_Tool::Tolerance(theFace2);
1008 adeltau=(umax - umin) / (nbpoints + 1);
1009 adeltav=(vmax - vmin) / (nbpoints + 1);
1010 bFoundON = Standard_False;
1012 GeomAPI_ProjectPointOnSurf& aProjector = theContext->ProjPS(theFace2);
1014 for(i=1; i<=nbpoints; ++i){
1016 for(j=1; j<=nbpoints; ++j) {
1019 bPointInFace=theContext->IsPointInFace(theFace1, aP2D);
1021 aP3D=aS1->Value(U, V);
1022 aProjector.Perform(aP3D);
1023 if(aProjector.IsDone()) {
1024 aProjector.LowerDistanceParameters(U2, V2);
1025 aP2D.SetCoord(U2, V2);
1027 aD=aProjector.LowerDistance();
1029 return Standard_False;
1032 bPointInFace=theContext->IsPointInFace(theFace2, aP2D);
1034 bFoundON = Standard_True;
1042 //modified by NIZNHY-PKV Thu Sep 22 10:55:19 2011t
1044 // ===========================================================================================
1045 // function: CheckPointInside
1047 // ===========================================================================================
1048 Standard_Boolean CheckPointInside(BRepClass3d_SolidClassifier& aSolidClassifier,
1050 const Standard_Real aTolerance,
1051 const Handle(IntTools_Context)& theContext,
1052 TopAbs_State& aState,
1053 Standard_Boolean& bFoundInFacePoint)
1055 Standard_Boolean bFoundValidPoint;
1057 bFoundValidPoint = Standard_False;
1059 aSolidClassifier.Perform(aP3d, aTolerance);
1060 aState = aSolidClassifier.State();
1062 if(aState != TopAbs_ON) {
1064 if(!aSolidClassifier.Rejected()) {
1065 TopoDS_Face aFace2 = aSolidClassifier.Face();
1067 if(!aFace2.IsNull()) {
1068 GeomAPI_ProjectPointOnSurf& aProjector = theContext->ProjPS(aFace2);
1069 aProjector.Perform(aP3d);
1071 if(aProjector.IsDone()) {
1072 Standard_Real U2 = 0., V2 = 0.;
1073 aProjector.LowerDistanceParameters(U2, V2);
1074 gp_Pnt2d aPoint2(U2, V2);
1076 if(aProjector.LowerDistance() < aTolerance) {
1077 if(theContext->IsPointInFace(aFace2, aPoint2)) {
1082 bFoundValidPoint = Standard_True;
1086 bFoundInFacePoint = Standard_False;
1090 return bFoundValidPoint;