diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx index 85be6dac95..21b71a82d4 100644 --- a/src/BOPTools/BOPTools_AlgoTools.cxx +++ b/src/BOPTools/BOPTools_AlgoTools.cxx @@ -84,16 +84,17 @@ static const TopoDS_Face& aF); static - void GetFaceDir(const TopoDS_Edge& aE, - const TopoDS_Face& aF, - const gp_Pnt& aP, - const Standard_Real aT, - const gp_Dir& aDTgt, - gp_Dir& aDN, - gp_Dir& aDB, - Handle(IntTools_Context)& theContext, - GeomAPI_ProjectPointOnSurf& aProjPL, - const Standard_Real aDt); + Standard_Boolean GetFaceDir(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const gp_Pnt& aP, + const Standard_Real aT, + const gp_Dir& aDTgt, + const Standard_Boolean theSmallFaces, + gp_Dir& aDN, + gp_Dir& aDB, + Handle(IntTools_Context)& theContext, + GeomAPI_ProjectPointOnSurf& aProjPL, + const Standard_Real aDt); static Standard_Boolean FindPointInFace(const TopoDS_Face& aF, const gp_Pnt& aP, @@ -107,7 +108,9 @@ static Standard_Real MinStep3D(const TopoDS_Edge& theE1, const TopoDS_Face& theF1, const BOPTools_ListOfCoupleOfShape& theLCS, - const gp_Pnt& aP); + const gp_Pnt& aP, + Handle(IntTools_Context)& theContext, + Standard_Boolean& theSmallFaces); @@ -899,7 +902,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff TopoDS_Face& theFOff, Handle(IntTools_Context)& theContext) { - Standard_Boolean bRet; + Standard_Boolean bRet, bIsComputed; Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D; Standard_Real aUmin, aUsup, aVmin, aVsup, aPA; gp_Pnt aPn1, aPn2, aPx; @@ -926,9 +929,15 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff aPL->Bounds(aUmin, aUsup, aVmin, aVsup); aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup); // - aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx); - GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, - aProjPL, aDt3D); + Standard_Boolean bSmallFaces = Standard_False; + aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx, theContext, bSmallFaces); + bIsComputed = GetFaceDir(theE1, theF1, aPx, aT, aDTgt, bSmallFaces, + aDN1, aDBF, theContext, aProjPL, aDt3D); + if (!bIsComputed) { +#ifdef OCCT_DEBUG + cout << "BOPTools_AlgoTools::GetFaceOff(): incorrect computation of bi-normal direction." << endl; +#endif + } // aDTF=aDN1^aDBF; // @@ -940,8 +949,13 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2())); // aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed(); - GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, - aProjPL, aDt3D); + bIsComputed = GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, bSmallFaces, aDN2, + aDBF2, theContext, aProjPL, aDt3D); + if (!bIsComputed) { +#ifdef OCCT_DEBUG + cout << "BOPTools_AlgoTools::GetFaceOff(): incorrect computation of bi-normal direction." << endl; +#endif + } //Angle aAngle=AngleWithRef(aDBF, aDBF2, aDTF); // @@ -1887,16 +1901,17 @@ Standard_Boolean BOPTools_AlgoTools::IsMicroEdge //function : GetFaceDir //purpose : Get binormal direction for the face in the point aP //======================================================================= -void GetFaceDir(const TopoDS_Edge& aE, - const TopoDS_Face& aF, - const gp_Pnt& aP, - const Standard_Real aT, - const gp_Dir& aDTgt, - gp_Dir& aDN, - gp_Dir& aDB, - Handle(IntTools_Context)& theContext, - GeomAPI_ProjectPointOnSurf& aProjPL, - const Standard_Real aDt) +Standard_Boolean GetFaceDir(const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const gp_Pnt& aP, + const Standard_Real aT, + const gp_Dir& aDTgt, + const Standard_Boolean theSmallFaces, + gp_Dir& aDN, + gp_Dir& aDB, + Handle(IntTools_Context)& theContext, + GeomAPI_ProjectPointOnSurf& aProjPL, + const Standard_Real aDt) { Standard_Real aTolE; gp_Pnt aPx; @@ -1906,21 +1921,31 @@ void GetFaceDir(const TopoDS_Edge& aE, aDN.Reverse(); } // - aTolE=BRep_Tool::Tolerance(aE); + aTolE=BRep_Tool::Tolerance(aE); aDB = aDN^aDTgt; // - if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE)) { - BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, - aDN, theContext); + // do not try to look for the point in the small face by intersecting + // it with the circle because, most likely, the intersection point will + // be out of the face + Standard_Boolean bFound = !theSmallFaces && + FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE); + if (!bFound) { + // if the first method did not succeed, try to use hatcher to find the point + bFound = BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge + (aE, aF, aT, aDt, aPx, aDN, theContext); aProjPL.Perform(aPx); aPx = aProjPL.NearestPoint(); gp_Vec aVec(aP, aPx); aDB.SetXYZ(aVec.XYZ()); } + // + return bFound; } //======================================================================= //function : FindPointInFace -//purpose : Find a point in the face in direction of +//purpose : Find a point in the face in direction of . +// To get this point the method intersects the circle with radius +// built in point with normal perpendicular to . //======================================================================= Standard_Boolean FindPointInFace(const TopoDS_Face& aF, const gp_Pnt& aP, @@ -1995,33 +2020,38 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF, Standard_Real MinStep3D(const TopoDS_Edge& theE1, const TopoDS_Face& theF1, const BOPTools_ListOfCoupleOfShape& theLCS, - const gp_Pnt& aP) + const gp_Pnt& aP, + Handle(IntTools_Context)& theContext, + Standard_Boolean& theSmallFaces) { - Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR; - BOPTools_CoupleOfShape aCS1; - BOPTools_ListOfCoupleOfShape aLCS; - BOPTools_ListIteratorOfListOfCoupleOfShape aIt; - BRepAdaptor_Surface aBAS; + Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin; // - aLCS = theLCS; + // add the current pair of edge/face for checking as well + BOPTools_CoupleOfShape aCS1; aCS1.SetShape1(theE1); aCS1.SetShape2(theF1); + // + BOPTools_ListOfCoupleOfShape aLCS = theLCS; aLCS.Append(aCS1); // aTolE = BRep_Tool::Tolerance(theE1); aDtMax = -1.; aDtMin = 5.e-6; // - aIt.Initialize(aLCS); + BOPTools_ListIteratorOfListOfCoupleOfShape aIt(aLCS); for (; aIt.More(); aIt.Next()) { const BOPTools_CoupleOfShape& aCS = aIt.Value(); const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2())); // aTolF = BRep_Tool::Tolerance(aF); aDt = 2*(aTolE + aTolF); + if (aDt > aDtMax) { + aDtMax = aDt; + } // - aR = 0.; - aBAS.Initialize(aF, Standard_False); + // try to compute the minimal 3D step + const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(aF); + Standard_Real aR = 0.; GeomAbs_SurfaceType aSType = aBAS.GetType(); switch (aSType) { case GeomAbs_Cylinder: { @@ -2051,16 +2081,42 @@ Standard_Real MinStep3D(const TopoDS_Edge& theE1, Standard_Real d = 10*Precision::PConfusion(); aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR)); } - // - if (aDt > aDtMax) { - aDtMax = aDt; - } } // if (aDtMax < aDtMin) { aDtMax = aDtMin; } // + // check if the computed 3D step is too big for any of the faces in the list + aIt.Initialize(aLCS); + for (; aIt.More(); aIt.Next()) { + const BOPTools_CoupleOfShape& aCS = aIt.Value(); + const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2())); + // + const BRepAdaptor_Surface& aBAS = theContext->SurfaceAdaptor(aF); + // + Standard_Real aUMin, aUMax, aVMin, aVMax; + theContext->UVBounds(aF, aUMin, aUMax, aVMin, aVMax); + // + Standard_Real aDU = aUMax - aUMin; + if (aDU > 0.) { + Standard_Real aURes = aBAS.UResolution(aDtMax); + if (2*aURes > aDU) { + break; + } + } + // + Standard_Real aDV = aVMax - aVMin; + if (aDV > 0.) { + Standard_Real aVRes = aBAS.VResolution(aDtMax); + if (2*aVRes > aDV) { + break; + } + } + } + // + theSmallFaces = aIt.More(); + // return aDtMax; } //======================================================================= diff --git a/src/BOPTools/BOPTools_AlgoTools3D.cxx b/src/BOPTools/BOPTools_AlgoTools3D.cxx index bb1a3d19b9..b5b7fe8c46 100644 --- a/src/BOPTools/BOPTools_AlgoTools3D.cxx +++ b/src/BOPTools/BOPTools_AlgoTools3D.cxx @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -332,7 +331,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetNormalToSurface //function : GetApproxNormalToFaceOnEdge //purpose : //======================================================================= -void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge +Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aT, @@ -340,29 +339,27 @@ void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge gp_Dir& aDNF, Standard_Real aDt2D) { - Standard_Real aFirst, aLast; - Handle(Geom2d_Curve) aC2D= - BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); - - if (aC2D.IsNull()) { - return; - } gp_Pnt2d aPx2DNear; - PointNearEdge (aE, aF, aT, aDt2D, aPx2DNear, aPNear); - Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); + Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge + (aE, aF, aT, aDt2D, aPx2DNear, aPNear); + if (iErr != 1) { + Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); - BOPTools_AlgoTools3D::GetNormalToSurface - (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); + BOPTools_AlgoTools3D::GetNormalToSurface + (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); - if (aF.Orientation()==TopAbs_REVERSED){ - aDNF.Reverse(); + if (aF.Orientation()==TopAbs_REVERSED){ + aDNF.Reverse(); + } } + // + return (iErr == 0); } //======================================================================= //function : GetApproxNormalToFaceOnEdge //purpose : //======================================================================= -void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge +Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aT, @@ -370,37 +367,62 @@ void BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge gp_Dir& aDNF, Handle(IntTools_Context)& theContext) { - Standard_Real aFirst, aLast; - Handle(Geom2d_Curve) aC2D= - BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); - - if (aC2D.IsNull()) { - return; - } - //gp_Pnt aPNear; gp_Pnt2d aPx2DNear; - BOPTools_AlgoTools3D::PointNearEdge + Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, aPx2DNear, aPNear, theContext); + if (iErr != 1) { + Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); - Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); + BOPTools_AlgoTools3D::GetNormalToSurface + (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); - BOPTools_AlgoTools3D::GetNormalToSurface - (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); - - if (aF.Orientation()==TopAbs_REVERSED){ - aDNF.Reverse(); + if (aF.Orientation()==TopAbs_REVERSED){ + aDNF.Reverse(); + } } + // + return (iErr == 0); +} +//======================================================================= +//function : GetApproxNormalToFaceOnEdge +//purpose : +//======================================================================= +Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge + (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + const Standard_Real theStep, + gp_Pnt& aPNear, + gp_Dir& aDNF, + Handle(IntTools_Context)& theContext) +{ + gp_Pnt2d aPx2DNear; + Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge + (aE, aF, aT, theStep, aPx2DNear, aPNear, theContext); + if (iErr != 1) { + Handle(Geom_Surface) aS=BRep_Tool::Surface(aF); + + BOPTools_AlgoTools3D::GetNormalToSurface + (aS, aPx2DNear.X(), aPx2DNear.Y(), aDNF); + + if (aF.Orientation()==TopAbs_REVERSED){ + aDNF.Reverse(); + } + } + // + return (iErr == 0); } //======================================================================= //function : PointNearEdge //purpose : //======================================================================= -void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, - const TopoDS_Face& aF, - const Standard_Real aT, - const Standard_Real aDt2D, - gp_Pnt2d& aPx2DNear, - gp_Pnt& aPxNear) +Standard_Integer BOPTools_AlgoTools3D::PointNearEdge + (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + const Standard_Real aDt2D, + gp_Pnt2d& aPx2DNear, + gp_Pnt& aPxNear) { Standard_Real aFirst, aLast, aETol, aFTol, transVal; GeomAbs_SurfaceType aTS; @@ -408,9 +430,9 @@ void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, Handle(Geom_Surface) aS; // aC2D= BRep_Tool::CurveOnSurface (aE, aF, aFirst, aLast); - if (aC2D.IsNull()) { - aPx2DNear.SetCoord (99., 99); - return; + Standard_Integer iErr = aC2D.IsNull() ? 1 : 0; + if (iErr) { + return iErr; } // aS=BRep_Tool::Surface(aF); @@ -472,12 +494,13 @@ void BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, } // aS->D0(aPx2DNear.X(), aPx2DNear.Y(), aPxNear); + return iErr; } //======================================================================= //function : PointNearEdge //purpose : //======================================================================= -void BOPTools_AlgoTools3D::PointNearEdge +Standard_Integer BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aT, @@ -496,7 +519,7 @@ void BOPTools_AlgoTools3D::PointNearEdge if (aGAS.GetType()==GeomAbs_Cylinder || aGAS.GetType()==GeomAbs_Sphere) { dT2D=10.*dT2D; - } + } // aTolE = BRep_Tool::Tolerance(aE); aTolF = BRep_Tool::Tolerance(aF); @@ -505,44 +528,63 @@ void BOPTools_AlgoTools3D::PointNearEdge dT2D=dTx; } // - BOPTools_AlgoTools3D::PointNearEdge + Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge (aE, aF, aT, dT2D, aPx2DNear, aPxNear); - if (!theContext->IsPointInOnFace(aF, aPx2DNear)) { - Standard_Integer iErr; - Standard_Real aU1, aU2, aV1, aV2, dV, dU, dTresh; + if ((iErr != 1) && !theContext->IsPointInOnFace(aF, aPx2DNear)) { gp_Pnt aP; gp_Pnt2d aP2d; // - if (theContext.IsNull()) { - BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2); + iErr = BOPTools_AlgoTools3D::PointInFace + (aF, aE, aT, dT2D, aP, aP2d, theContext); + if (iErr == 0) { + aPxNear = aP; + aPx2DNear = aP2d; } else { - theContext->UVBounds(aF, aU1, aU2, aV1, aV2); - } - // - dU=aU2-aU1; - dV=aV2-aV1; - // - dTresh=1.e-4; - if (dT2D > dTresh) { - dTresh=dT2D; - } - // - if (dU < dTresh || dV < dTresh) { - iErr = BOPTools_AlgoTools3D::PointInFace - (aF, aP, aP2d, theContext); - if (!iErr) { - aPxNear = aP; - aPx2DNear = aP2d; - } + iErr = 2; // point is out of the face } } + // + return iErr; +} + +//======================================================================= +//function : PointNearEdge +//purpose : +//======================================================================= +Standard_Integer BOPTools_AlgoTools3D::PointNearEdge + (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + const Standard_Real theStep, + gp_Pnt2d& aPx2DNear, + gp_Pnt& aPxNear, + Handle(IntTools_Context)& theContext) +{ + Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge + (aE, aF, aT, theStep, aPx2DNear, aPxNear); + if ((iErr != 1) && !theContext->IsPointInOnFace(aF, aPx2DNear)) { + gp_Pnt aP; + gp_Pnt2d aP2d; + // + iErr = BOPTools_AlgoTools3D::PointInFace + (aF, aE, aT, theStep, aP, aP2d, theContext); + if (iErr == 0) { + aPxNear = aP; + aPx2DNear = aP2d; + } + else { + iErr = 2; // point is out of the face + } + } + // + return iErr; } //======================================================================= // function: PointNearEdge // purpose: //======================================================================= -void BOPTools_AlgoTools3D::PointNearEdge +Standard_Integer BOPTools_AlgoTools3D::PointNearEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, gp_Pnt2d& aPInFace2D, @@ -551,18 +593,20 @@ void BOPTools_AlgoTools3D::PointNearEdge { Standard_Real aT, aT1, aT2; // - // 1. + // 1. compute parameter on edge BRep_Tool::Range(aE, aT1, aT2); aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2); // - // 2. a Point inside Face near aPOnEdge aPInFace; + // 2. compute point inside the face near the edge TopoDS_Face aFF=aF; TopoDS_Edge aERight; aFF.Orientation(TopAbs_FORWARD); BOPTools_AlgoTools3D::OrientEdgeOnFace (aE, aFF, aERight); - - BOPTools_AlgoTools3D::PointNearEdge + // + Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge (aERight, aFF, aT, aPInFace2D, aPInFace, theContext); + // + return iErr; } //======================================================================= //function : MinStepIn2d @@ -732,108 +776,158 @@ void BOPTools_AlgoTools3D::OrientEdgeOnFace (const TopoDS_Edge& aE, //purpose : //======================================================================= Standard_Integer BOPTools_AlgoTools3D::PointInFace - (const TopoDS_Face& aF, + (const TopoDS_Face& theF, gp_Pnt& theP, gp_Pnt2d& theP2D, Handle(IntTools_Context)& theContext) { - Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; - Standard_Integer iErr, aIx = 0, aNbDomains = 0; - Standard_Real aUMin, aUMax, aVMin, aVMax; - Standard_Real aVx = 0., aUx, aV1, aV2; - gp_Dir2d aD2D (0., 1.); - gp_Pnt2d aP2D; - gp_Pnt aPx; - Handle(Geom2d_Curve) aC2D; - Handle(Geom2d_Line) aL2D; - Handle(Geom_Surface) aS; - TopoDS_Face aFF; + Standard_Integer i, iErr = 1; + Standard_Real aUMin, aUMax, aVMin, aVMax, aUx; // - Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(aF); + theContext->UVBounds(theF, aUMin, aUMax, aVMin, aVMax); // - iErr=0; + gp_Dir2d aD2D(0. , 1.); + aUx = IntTools_Tools::IntermediatePoint(aUMin, aUMax); // - aFF=aF; - aFF.Orientation (TopAbs_FORWARD); - // - aS=BRep_Tool::Surface(aFF); - if (theContext.IsNull()) { - BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); - } - else { - theContext->UVBounds(aFF, aUMin, aUMax, aVMin, aVMax); - } - // - aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax); - Standard_Integer i; - for(i = 1; i <= 2; ++i) - { - aP2D.SetCoord(aUx, 0.); - aL2D=new Geom2d_Line (aP2D, aD2D); - Geom2dAdaptor_Curve aHCur(aL2D); - // - aIx=aHatcher.AddHatching(aHCur) ; - // - aHatcher.Trim(aIx); - bIsDone=aHatcher.TrimDone(aIx); - if (!bIsDone) { - iErr=1; - return iErr; - } - // - if(aHatcher.NbPoints(aIx) > 1) - { - aHatcher.ComputeDomains(aIx); - bIsDone=aHatcher.IsDone(aIx); - if (!bIsDone) { - iErr=2; - return iErr; - } + for (i = 0; i < 2; ++i) { + gp_Pnt2d aP2D(aUx, 0.); + Handle(Geom2d_Line) aL2D = new Geom2d_Line (aP2D, aD2D); + iErr = BOPTools_AlgoTools3D::PointInFace + (theF, aL2D, theP, theP2D, theContext); + if (iErr == 0) { + // done break; } - else - { + else { + // possible reason - incorrect computation of the 2d box of the face. + // try to compute the point with the translated line. aUx = aUMax - (aUx - aUMin); } } // - if(!aHatcher.IsDone(aIx)) - { - iErr=2; - return iErr; - } - - aNbDomains=aHatcher.NbDomains(aIx); - if (aNbDomains > 0) { - const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, 1); - bHasFirstPoint=aDomain.HasFirstPoint(); - if (!bHasFirstPoint) { - iErr=3; - return iErr; - } - // - aV1=aDomain.FirstPoint().Parameter(); - // - bHasSecondPoint=aDomain.HasSecondPoint(); - if (!bHasSecondPoint) { - iErr=4; - return iErr; - } - // - aV2=aDomain.SecondPoint().Parameter(); - // - aVx=IntTools_Tools::IntermediatePoint(aV1, aV2); - // - } - else { - iErr=2; + return iErr; +} +//======================================================================= +//function : PointInFace +//purpose : +//======================================================================= +Standard_Integer BOPTools_AlgoTools3D::PointInFace + (const TopoDS_Face& theF, + const TopoDS_Edge& theE, + const Standard_Real theT, + const Standard_Real theDt2D, + gp_Pnt& theP, + gp_Pnt2d& theP2D, + Handle(IntTools_Context)& theContext) +{ + Standard_Integer iErr; + Standard_Real f, l; + Handle(Geom2d_Curve) aC2D; + // + iErr = 0; + aC2D = BRep_Tool::CurveOnSurface (theE, theF, f, l); + if (aC2D.IsNull()) { + iErr = 5; return iErr; } // - aS->D0(aUx, aVx, aPx); + gp_Pnt2d aP2D; + gp_Vec2d aV2D; // - theP2D.SetCoord(aUx, aVx); - theP=aPx; + aC2D->D1(theT, aP2D, aV2D); + gp_Dir2d aD2Dx(aV2D); + // + gp_Dir2d aD2D; + aD2D.SetCoord (-aD2Dx.Y(), aD2Dx.X()); + // + if (theE.Orientation()==TopAbs_REVERSED){ + aD2D.Reverse(); + } + // + if (theF.Orientation()==TopAbs_REVERSED) { + aD2D.Reverse(); + } + // + Handle(Geom2d_Line) aL2D = new Geom2d_Line(aP2D, aD2D); + Handle(Geom2d_TrimmedCurve) aL2DTrim = + new Geom2d_TrimmedCurve(aL2D, 0., Precision::Infinite()); + // + iErr = BOPTools_AlgoTools3D::PointInFace + (theF, aL2DTrim, theP, theP2D, theContext, theDt2D); // return iErr; } +//======================================================================= +//function : PointInFace +//purpose : +//======================================================================= +Standard_Integer BOPTools_AlgoTools3D::PointInFace + (const TopoDS_Face& theF, + const Handle(Geom2d_Curve)& theL2D, + gp_Pnt& theP, + gp_Pnt2d& theP2D, + Handle(IntTools_Context)& theContext, + const Standard_Real theDt2D) +{ + Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint; + Standard_Integer iErr, aIH, aNbDomains; + Standard_Real aVx, aV1, aV2; + // + Geom2dHatch_Hatcher& aHatcher = theContext->Hatcher(theF); + // + Geom2dAdaptor_Curve aHCur(theL2D); + // + aHatcher.ClrHatchings(); + aIH = aHatcher.AddHatching(aHCur); + // + iErr = 0; + for (;;) { + aHatcher.Trim(); + bIsDone = aHatcher.TrimDone(aIH); + if (!bIsDone) { + iErr = 1; + break; + } + // + aHatcher.ComputeDomains(aIH); + bIsDone = aHatcher.IsDone(aIH); + if (!bIsDone) { + iErr = 2; + break; + } + // + aNbDomains = aHatcher.NbDomains(aIH); + if (aNbDomains == 0) { + iErr = 2; + break; + } + // + const HatchGen_Domain& aDomain = aHatcher.Domain (aIH, 1); + bHasFirstPoint = aDomain.HasFirstPoint(); + if (!bHasFirstPoint) { + iErr = 3; + break; + } + // + bHasSecondPoint = aDomain.HasSecondPoint(); + if (!bHasSecondPoint) { + iErr = 4; + break; + } + // + aV1 = aDomain.FirstPoint().Parameter(); + aV2 = aDomain.SecondPoint().Parameter(); + // + aVx = (theDt2D > 0. && (aV2 - aV1) > theDt2D) ? (aV1 + theDt2D) : + IntTools_Tools::IntermediatePoint(aV1, aV2); + // + Handle(Geom_Surface) aS = BRep_Tool::Surface(theF); + // + theL2D->D0(aVx, theP2D); + aS->D0(theP2D.X(), theP2D.Y(), theP); + break; + } + // + aHatcher.RemHatching(aIH); + return iErr; +} diff --git a/src/BOPTools/BOPTools_AlgoTools3D.hxx b/src/BOPTools/BOPTools_AlgoTools3D.hxx index c57a2722fc..a9567b779a 100644 --- a/src/BOPTools/BOPTools_AlgoTools3D.hxx +++ b/src/BOPTools/BOPTools_AlgoTools3D.hxx @@ -26,6 +26,7 @@ class TopoDS_Edge; class TopoDS_Face; class gp_Dir; class Geom_Surface; +class Geom2d_Curve; class gp_Pnt; class IntTools_Context; class gp_Pnt2d; @@ -45,8 +46,8 @@ public: //! Make the edge seam edge for the face - Standard_EXPORT static void DoSplitSEAMOnFace (const TopoDS_Edge& aSp, const TopoDS_Face& aF); - + Standard_EXPORT static void DoSplitSEAMOnFace (const TopoDS_Edge& aSp, + const TopoDS_Face& aF); //! Computes normal to the face for the point on the edge //! at parameter .
@@ -67,51 +68,147 @@ public: const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)()); - //! Returns 1 if scalar product aNF1* aNF2>0. - //! Returns 0 if directions aNF1 aNF2 coinside + //! Returns 1 if scalar product aNF1* aNF2>0.
+ //! Returns 0 if directions aNF1 aNF2 coincide
//! Returns -1 if scalar product aNF1* aNF2<0. - Standard_EXPORT static Standard_Integer SenseFlag (const gp_Dir& aNF1, const gp_Dir& aNF2); - + Standard_EXPORT static Standard_Integer SenseFlag (const gp_Dir& aNF1, + const gp_Dir& aNF2); //! Compute normal to surface in point (U,V) - //! Returns TRUE if directions aD1U, aD1V coinside - Standard_EXPORT static Standard_Boolean GetNormalToSurface (const Handle(Geom_Surface)& aS, const Standard_Real U, const Standard_Real V, gp_Dir& aD); - + //! Returns TRUE if directions aD1U, aD1V coincide + Standard_EXPORT static Standard_Boolean GetNormalToSurface (const Handle(Geom_Surface)& aS, + const Standard_Real U, + const Standard_Real V, + gp_Dir& aD); //! Computes normal to the face for the 3D-point that - //! belonds to the edge at parameter . - //! Output: - //! aPx - the 3D-point where the normal computed - //! aD - the normal; - //! - //! Warning: + //! belongs to the edge at parameter .
+ //! Output:
+ //! aPx - the 3D-point where the normal computed
+ //! aD - the normal;
+ //! Warning:
//! The normal is computed not exactly in the point on the //! edge, but in point that is near to the edge towards to - //! the face material (so, we'll have approx. normal) - Standard_EXPORT static void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aT, gp_Pnt& aPx, gp_Dir& aD, Handle(IntTools_Context)& theContext); + //! the face material (so, we'll have approx. normal);
+ //! The point is computed using PointNearEdge function, + //! with the shifting value BOPTools_AlgoTools3D::MinStepIn2d(), + //! from the edge, but if this value is too big, + //! the point will be computed using Hatcher (PointInFace function).
+ //! Returns TRUE in case of success. + Standard_EXPORT static Standard_Boolean GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + gp_Pnt& aPx, + gp_Dir& aD, + Handle(IntTools_Context)& theContext); - Standard_EXPORT static void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& theE, const TopoDS_Face& theF, const Standard_Real aT, gp_Pnt& aP, gp_Dir& aDNF, const Standard_Real aDt2D); + //! Computes normal to the face for the 3D-point that + //! belongs to the edge at parameter .
+ //! Output:
+ //! aPx - the 3D-point where the normal computed
+ //! aD - the normal;
+ //! Warning:
+ //! The normal is computed not exactly in the point on the + //! edge, but in point that is near to the edge towards to + //! the face material (so, we'll have approx. normal);
+ //! The point is computed using PointNearEdge function + //! with the shifting value from the edge;
+ //! No checks on this value will be done.
+ //! Returns TRUE in case of success. + Standard_EXPORT static Standard_Boolean GetApproxNormalToFaceOnEdge (const TopoDS_Edge& theE, + const TopoDS_Face& theF, + const Standard_Real aT, + gp_Pnt& aP, + gp_Dir& aDNF, + const Standard_Real aDt2D); + //! Computes normal to the face for the 3D-point that + //! belongs to the edge at parameter .
+ //! Output:
+ //! aPx - the 3D-point where the normal computed
+ //! aD - the normal;
+ //! Warning:
+ //! The normal is computed not exactly in the point on the + //! edge, but in point that is near to the edge towards to + //! the face material (so, we'll have approx. normal);
+ //! The point is computed using PointNearEdge function + //! with the shifting value from the edge, + //! but if this value is too big the point will be + //! computed using Hatcher (PointInFace function).
+ //! Returns TRUE in case of success. + Standard_EXPORT static Standard_Boolean GetApproxNormalToFaceOnEdge (const TopoDS_Edge& theE, + const TopoDS_Face& theF, + const Standard_Real aT, + const Standard_Real aDt2D, + gp_Pnt& aP, + gp_Dir& aDNF, + Handle(IntTools_Context)& theContext); //! Compute the point , () that is near to //! the edge at parameter towards to the //! material of the face . The value of shifting in - //! 2D is - Standard_EXPORT static void PointNearEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aT, const Standard_Real aDt2D, gp_Pnt2d& aP2D, gp_Pnt& aPx); - + //! 2D is
+ //! If the value of shifting is too big the point + //! will be computed using Hatcher (PointInFace function).
+ //! Returns error status:
+ //! 0 - in case of success;
+ //! 1 - does not have 2d curve on the face ;
+ //! 2 - the computed point is out of the face. + Standard_EXPORT static Standard_Integer PointNearEdge (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + const Standard_Real aDt2D, + gp_Pnt2d& aP2D, + gp_Pnt& aPx, + Handle(IntTools_Context)& theContext); + + //! Compute the point , () that is near to + //! the edge at parameter towards to the + //! material of the face . The value of shifting in + //! 2D is . No checks on this value will be done.
+ //! Returns error status:
+ //! 0 - in case of success;
+ //! 1 - does not have 2d curve on the face . + Standard_EXPORT static Standard_Integer PointNearEdge (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + const Standard_Real aDt2D, + gp_Pnt2d& aP2D, + gp_Pnt& aPx); //! Computes the point , () that is near to //! the edge at parameter towards to the //! material of the face . The value of shifting in - //! 2D is dt2D=BOPTools_AlgoTools3D::MinStepIn2d() - Standard_EXPORT static void PointNearEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, const Standard_Real aT, gp_Pnt2d& aP2D, gp_Pnt& aPx, Handle(IntTools_Context)& theContext); + //! 2D is dt2D=BOPTools_AlgoTools3D::MinStepIn2d()
+ //! If the value of shifting is too big the point will be computed + //! using Hatcher (PointInFace function).
+ //! Returns error status:
+ //! 0 - in case of success;
+ //! 1 - does not have 2d curve on the face ;
+ //! 2 - the computed point is out of the face. + Standard_EXPORT static Standard_Integer PointNearEdge (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + const Standard_Real aT, + gp_Pnt2d& aP2D, + gp_Pnt& aPx, + Handle(IntTools_Context)& theContext); //! Compute the point , () that is near to //! the edge at arbitrary parameter towards to the //! material of the face . The value of shifting in - //! 2D is dt2D=BOPTools_AlgoTools3D::MinStepIn2d() - Standard_EXPORT static void PointNearEdge (const TopoDS_Edge& aE, const TopoDS_Face& aF, gp_Pnt2d& aP2D, gp_Pnt& aPx, Handle(IntTools_Context)& theContext); + //! 2D is dt2D=BOPTools_AlgoTools3D::MinStepIn2d().
+ //! If the value of shifting is too big the point will be computed + //! using Hatcher (PointInFace function).
+ //! Returns error status:
+ //! 0 - in case of success;
+ //! 1 - does not have 2d curve on the face ;
+ //! 2 - the computed point is out of the face. + Standard_EXPORT static Standard_Integer PointNearEdge (const TopoDS_Edge& aE, + const TopoDS_Face& aF, + gp_Pnt2d& aP2D, + gp_Pnt& aPx, + Handle(IntTools_Context)& theContext); //! Returns simple step value that is used in 2D-computations @@ -128,33 +225,49 @@ public: //! the edge Standard_EXPORT static void OrientEdgeOnFace (const TopoDS_Edge& aE, const TopoDS_Face& aF, TopoDS_Edge& aER); - //! Computes a point inside the face .
- //! - 2D representation of
- //! on the surface of
- //! Returns 0 in case of success.
- Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, gp_Pnt& theP, gp_Pnt2d& theP2D, Handle(IntTools_Context)& theContext); + //! Computes arbitrary point inside the face .
+ //! - 2D representation of + //! on the surface of
+ //! Returns 0 in case of success. + Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, + gp_Pnt& theP, + gp_Pnt2d& theP2D, + Handle(IntTools_Context)& theContext); + //! Computes a point inside the face + //! using starting point taken by the parameter + //! from the 2d curve of the edge on the face + //! in the direction perpendicular to the tangent vector + //! of the 2d curve of the edge.
+ //! The point will be distanced on from the 2d curve. + //! - 2D representation of + //! on the surface of
+ //! Returns 0 in case of success. + Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, + const TopoDS_Edge& theE, + const Standard_Real theT, + const Standard_Real theDt2D, + gp_Pnt& theP, + gp_Pnt2d& theP2D, + Handle(IntTools_Context)& theContext); + //! Computes a point inside the face + //! using the line so that 2D point + //! , 2D representation of + //! on the surface of , lies on that line.
+ //! Returns 0 in case of success. + Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, + const Handle(Geom2d_Curve)& theL, + gp_Pnt& theP, + gp_Pnt2d& theP2D, + Handle(IntTools_Context)& theContext, + const Standard_Real theDt2D = 0.0); protected: - - - - private: - - - - }; - - - - - - #endif // _BOPTools_AlgoTools3D_HeaderFile diff --git a/src/ShapeFix/ShapeFix_Solid.lxx b/src/ShapeFix/ShapeFix_Solid.lxx deleted file mode 100644 index 7048ecd09c..0000000000 --- a/src/ShapeFix/ShapeFix_Solid.lxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -//======================================================================= -//function : FixShellTool -//purpose : -//======================================================================= - -inline Handle(ShapeFix_Shell) ShapeFix_Solid::FixShellTool() const -{ - return myFixShell; -} - -//======================================================================= -//function : FixShellMode -//purpose : -//======================================================================= - -inline Standard_Integer& ShapeFix_Solid::FixShellMode() -{ - return myFixShellMode; -} -//======================================================================= -//function : CreateOpenSolidMode -//purpose : -//======================================================================= - -inline Standard_Boolean& ShapeFix_Solid::CreateOpenSolidMode() -{ - return myCreateOpenSolidMode; -} diff --git a/tests/boolean/bopcommon_complex/J1 b/tests/boolean/bopcommon_complex/J1 index 4b63ff3a86..cff26c5499 100755 --- a/tests/boolean/bopcommon_complex/J1 +++ b/tests/boolean/bopcommon_complex/J1 @@ -1,6 +1,3 @@ -puts "TODO #22911 ALL: Error : The command is not valid. The area is" -puts "TODO #22911 ALL: Error : The area of result shape is" - restore [locate_data_file a158] a restore [locate_data_file b148] b diff --git a/tests/bugs/modalg_6/bug27182 b/tests/bugs/modalg_6/bug27182 new file mode 100644 index 0000000000..fe687370e5 --- /dev/null +++ b/tests/bugs/modalg_6/bug27182 @@ -0,0 +1,33 @@ +puts "========" +puts "OCC27182" +puts "========" +puts "" +################################# +# Wrong result of General Fuse operation for two spheres +################################# + + +restore [locate_data_file bug27182_Solid_417.brep] b1 +restore [locate_data_file bug27182_Solid_420.brep] b2 +bclearobjects +bcleartools +baddobjects b1 b2 +bfillds +bbuild result + +checkprops result -s 5.69241e-005 + +set nbshapes_expected " +Number of shapes in shape + VERTEX : 5 + EDGE : 7 + WIRE : 6 + FACE : 4 + SHELL : 3 + SOLID : 3 + COMPSOLID : 0 + COMPOUND : 1 + SHAPE : 29 +" + +checknbshapes result -ref ${nbshapes_expected} -t diff --git a/tests/offset/shape_type_i_c/XJ2 b/tests/offset/shape_type_i_c/XJ2 index f4e41e7175..2c97a2c0ce 100755 --- a/tests/offset/shape_type_i_c/XJ2 +++ b/tests/offset/shape_type_i_c/XJ2 @@ -1,7 +1,3 @@ -puts "TODO OCC27414 ALL: Error: The command cannot be built" -puts "TODO OCC27414 ALL: Tcl Exception" -puts "TODO OCC27414 ALL: TEST INCOMPLETE" - restore [locate_data_file bug26917_dom-8092.t6c1_with_faces.brep] c # get the shape @@ -21,9 +17,9 @@ foreach f [explode c_3 f] { offsetperform result -checkprops result -v 0 -s 0 +checkprops result -v 6.99508e+007 -s 5.03259e+006 unifysamedom result_unif result -checknbshapes result_unif -face 1 -shell 1 +checknbshapes result_unif -face 613 -shell 1 checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XJ4 b/tests/offset/shape_type_i_c/XJ4 index eaca5c36d9..4239290f89 100644 --- a/tests/offset/shape_type_i_c/XJ4 +++ b/tests/offset/shape_type_i_c/XJ4 @@ -1,7 +1,3 @@ -puts "TODO OCC27414 ALL: Error: The command cannot be built" -puts "TODO OCC27414 ALL: Tcl Exception" -puts "TODO OCC27414 ALL: TEST INCOMPLETE" - restore [locate_data_file bug26917_dom-8092.t6c1_trim2_with_faces.brep] c # get the shape @@ -21,9 +17,9 @@ foreach f [explode c_3 f] { offsetperform result -checkprops result -v 0 -s 0 +checkprops result -v 3.87575e+007 -s 2.82699e+006 unifysamedom result_unif result -checknbshapes result_unif -face 1 -shell 1 +checknbshapes result_unif -face 335 -shell 1 checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XJ5 b/tests/offset/shape_type_i_c/XJ5 index 33b7be9df0..62118a64bd 100644 --- a/tests/offset/shape_type_i_c/XJ5 +++ b/tests/offset/shape_type_i_c/XJ5 @@ -1,7 +1,3 @@ -puts "TODO OCC27414 ALL: Error: The command cannot be built" -puts "TODO OCC27414 ALL: Tcl Exception" -puts "TODO OCC27414 ALL: TEST INCOMPLETE" - restore [locate_data_file bug26917_dom-8092.t6c1_trim3_with_faces.brep] c # get the shape @@ -21,9 +17,9 @@ foreach f [explode c_3 f] { offsetperform result -checkprops result -v 0 -s 0 +checkprops result -v 2.13551e+007 -s 1.52076e+006 unifysamedom result_unif result -checknbshapes result_unif -face 1 -shell 1 +checknbshapes result_unif -face 184 -shell 1 checkview -display result_unif -2d -path ${imagedir}/${test_image}.png diff --git a/tests/offset/shape_type_i_c/XJ6 b/tests/offset/shape_type_i_c/XJ6 index 78b3de4b84..3c983a96fa 100644 --- a/tests/offset/shape_type_i_c/XJ6 +++ b/tests/offset/shape_type_i_c/XJ6 @@ -1,7 +1,3 @@ -puts "TODO OCC27414 ALL: Error: The command cannot be built" -puts "TODO OCC27414 ALL: Tcl Exception" -puts "TODO OCC27414 ALL: TEST INCOMPLETE" - restore [locate_data_file bug26917_dom-8092.t6c1_trim4_with_faces.brep] c # get the shape @@ -21,9 +17,9 @@ foreach f [explode c_3 f] { offsetperform result -checkprops result -v 0 -s 0 +checkprops result -v 5.87244e+006 -s 429300 unifysamedom result_unif result -checknbshapes result_unif -face 1 -shell 1 +checknbshapes result_unif -face 66 -shell 1 checkview -display result_unif -2d -path ${imagedir}/${test_image}.png