1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0024154: Wrong result of CUT operation

Rebuild normal for the face if the method FindPointInFace fails (unable to find point in the face in bi-normal direction).
Adding test case for issue CR24154
This commit is contained in:
emv 2013-09-19 16:41:32 +04:00 committed by bugmaster
parent c7a422d893
commit bb58e462ad
2 changed files with 162 additions and 130 deletions

View File

@ -39,7 +39,6 @@
#include <Geom_Curve.hxx> #include <Geom_Curve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx> #include <GeomAPI_ProjectPointOnSurf.hxx>
#include <Geom2dInt_Geom2dCurveTool.hxx> #include <Geom2dInt_Geom2dCurveTool.hxx>
#include <GeomAdaptor_Surface.hxx>
// //
#include <TopAbs_Orientation.hxx> #include <TopAbs_Orientation.hxx>
// //
@ -53,6 +52,7 @@
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <BRepLib.hxx> #include <BRepLib.hxx>
#include <BRepAdaptor_Curve2d.hxx> #include <BRepAdaptor_Curve2d.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepClass3d_SolidClassifier.hxx> #include <BRepClass3d_SolidClassifier.hxx>
#include <TopExp.hxx> #include <TopExp.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
@ -95,16 +95,16 @@ static
const gp_Dir& aDTgt, const gp_Dir& aDTgt,
gp_Dir& aDN, gp_Dir& aDN,
gp_Dir& aDB, gp_Dir& aDB,
Handle(BOPInt_Context)& theContext); Handle(BOPInt_Context)& theContext,
GeomAPI_ProjectPointOnSurf& aProjPL);
static static
Standard_Boolean FindPointInFace(const TopoDS_Edge& aE, Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
const TopoDS_Face& aF, const TopoDS_Face& aF,
const gp_Pnt& aP, const gp_Pnt& aP,
const Standard_Real aT,
gp_Dir& aDB, gp_Dir& aDB,
gp_Pnt& aPOut, gp_Pnt& aPOut,
Handle(BOPInt_Context)& theContext, Handle(BOPInt_Context)& theContext,
const GeomAdaptor_Surface& aGAS); GeomAPI_ProjectPointOnSurf& aProjPL);
//======================================================================= //=======================================================================
// function: MakeConnexityBlocks // function: MakeConnexityBlocks
@ -495,7 +495,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
// function: ComputeState // function: ComputeState
// purpose: // purpose:
//======================================================================= //=======================================================================
TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Vertex& theV, TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Vertex& theV,
const TopoDS_Solid& theRef, const TopoDS_Solid& theRef,
const Standard_Real theTol, const Standard_Real theTol,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
@ -511,7 +511,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
// function: ComputeState // function: ComputeState
// purpose: // purpose:
//======================================================================= //=======================================================================
TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE, TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
const TopoDS_Solid& theRef, const TopoDS_Solid& theRef,
const Standard_Real theTol, const Standard_Real theTol,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
@ -561,7 +561,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
// function: ComputeState // function: ComputeState
// purpose: // purpose:
//======================================================================= //=======================================================================
TopAbs_State BOPTools_AlgoTools::ComputeState(const gp_Pnt& theP, TopAbs_State BOPTools_AlgoTools::ComputeState(const gp_Pnt& theP,
const TopoDS_Solid& theRef, const TopoDS_Solid& theRef,
const Standard_Real theTol, const Standard_Real theTol,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
@ -795,12 +795,15 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
{ {
Standard_Boolean bRet; Standard_Boolean bRet;
Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin; Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
Standard_Real aUmin, aUsup, aVmin, aVsup;
gp_Pnt aPn1, aPn2, aPx; gp_Pnt aPn1, aPn2, aPx;
gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF; gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
gp_Vec aVTgt; gp_Vec aVTgt;
TopAbs_Orientation aOr; TopAbs_Orientation aOr;
Handle(Geom_Curve)aC3D; Handle(Geom_Curve)aC3D;
Handle(Geom_Plane) aPL;
BOPTools_ListIteratorOfListOfCoupleOfShape aIt; BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
GeomAPI_ProjectPointOnSurf aProjPL;
// //
aAngleMin=100.; aAngleMin=100.;
aTwoPI=M_PI+M_PI; aTwoPI=M_PI+M_PI;
@ -812,7 +815,11 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
gp_Dir aDTgt(aVTgt), aDTgt2; gp_Dir aDTgt(aVTgt), aDTgt2;
aOr = theE1.Orientation(); aOr = theE1.Orientation();
// //
GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext); aPL = new Geom_Plane(aPx, aDTgt);
aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
//
GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, aProjPL);
// //
aDTF=aDN1^aDBF; aDTF=aDN1^aDBF;
// //
@ -824,7 +831,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2())); const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
// //
aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed(); aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext); GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, aProjPL);
//Angle //Angle
aAngle=AngleWithRef(aDBF, aDBF2, aDTF); aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
// //
@ -856,7 +863,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function : GetEdgeOff //function : GetEdgeOff
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1, Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
const TopoDS_Face& theF2, const TopoDS_Face& theF2,
TopoDS_Edge& theE2) TopoDS_Edge& theE2)
{ {
@ -887,7 +894,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function : AreFacesSameDomain //function : AreFacesSameDomain
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1, Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1,
const TopoDS_Face& theF2, const TopoDS_Face& theF2,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
{ {
@ -933,7 +940,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function : CheckSameGeom //function : CheckSameGeom
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::CheckSameGeom(const TopoDS_Face& theF1, Standard_Boolean BOPTools_AlgoTools::CheckSameGeom(const TopoDS_Face& theF1,
const TopoDS_Face& theF2, const TopoDS_Face& theF2,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
{ {
@ -962,7 +969,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: Sense // function: Sense
// purpose: // purpose:
//======================================================================= //=======================================================================
Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1, Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
const TopoDS_Face& theF2) const TopoDS_Face& theF2)
{ {
Standard_Integer iSense=0; Standard_Integer iSense=0;
@ -1008,7 +1015,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: IsSplitToReverse // function: IsSplitToReverse
// purpose: // purpose:
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp, Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp,
const TopoDS_Shape& theSr, const TopoDS_Shape& theSr,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
{ {
@ -1042,7 +1049,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function :IsSplitToReverse //function :IsSplitToReverse
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp, Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
const TopoDS_Face& theFSr, const TopoDS_Face& theFSr,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
{ {
@ -1131,7 +1138,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function :IsSplitToReverse //function :IsSplitToReverse
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Edge& aEF1, Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Edge& aEF1,
const TopoDS_Edge& aEF2, const TopoDS_Edge& aEF2,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext)
{ {
@ -1182,7 +1189,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function : IsHole //function : IsHole
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW, Standard_Boolean BOPTools_AlgoTools::IsHole(const TopoDS_Shape& aW,
const TopoDS_Shape& aFace) const TopoDS_Shape& aFace)
{ {
Standard_Boolean bIsHole; Standard_Boolean bIsHole;
@ -1255,7 +1262,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: MakeContainer // function: MakeContainer
// purpose: // purpose:
//======================================================================= //=======================================================================
void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType, void BOPTools_AlgoTools::MakeContainer(const TopAbs_ShapeEnum theType,
TopoDS_Shape& theC) TopoDS_Shape& theC)
{ {
BRep_Builder aBB; BRep_Builder aBB;
@ -1305,7 +1312,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: MakePCurve // function: MakePCurve
// purpose: // purpose:
//======================================================================= //=======================================================================
void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE, void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
const TopoDS_Face& aF1, const TopoDS_Face& aF1,
const TopoDS_Face& aF2, const TopoDS_Face& aF2,
const IntTools_Curve& aIC, const IntTools_Curve& aIC,
@ -1366,7 +1373,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: MakeEdge // function: MakeEdge
// purpose: // purpose:
//======================================================================= //=======================================================================
void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC, void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
const TopoDS_Vertex& theV1, const TopoDS_Vertex& theV1,
const Standard_Real theT1, const Standard_Real theT1,
const TopoDS_Vertex& theV2, const TopoDS_Vertex& theV2,
@ -1395,7 +1402,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: ComputeVV // function: ComputeVV
// purpose: // purpose:
//======================================================================= //=======================================================================
Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1, Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
const gp_Pnt& aP2, const gp_Pnt& aP2,
const Standard_Real aTolP2) const Standard_Real aTolP2)
{ {
@ -1419,7 +1426,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: ComputeVV // function: ComputeVV
// purpose: // purpose:
//======================================================================= //=======================================================================
Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1, Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
const TopoDS_Vertex& aV2) const TopoDS_Vertex& aV2)
{ {
Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2; Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
@ -1443,7 +1450,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
// function: MakeVertex // function: MakeVertex
// purpose : // purpose :
//======================================================================= //=======================================================================
void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV, void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
TopoDS_Vertex& aVnew) TopoDS_Vertex& aVnew)
{ {
Standard_Integer aNb; Standard_Integer aNb;
@ -1487,7 +1494,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
//function : GetEdgeOnFace //function : GetEdgeOnFace
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1, Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1,
const TopoDS_Face& theF2, const TopoDS_Face& theF2,
TopoDS_Edge& theE2) TopoDS_Edge& theE2)
{ {
@ -1660,7 +1667,7 @@ Standard_Real fsqrt(Standard_Real val)
// function: IsBlockInOnFace // function: IsBlockInOnFace
// purpose: // purpose:
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR, Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR,
const TopoDS_Face& aF, const TopoDS_Face& aF,
const TopoDS_Edge& aE1, const TopoDS_Edge& aE1,
Handle(BOPInt_Context)& aContext) Handle(BOPInt_Context)& aContext)
@ -1750,7 +1757,7 @@ Standard_Real fsqrt(Standard_Real val)
//function : IsMicroEdge //function : IsMicroEdge
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE, Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE,
const Handle(BOPInt_Context)& aCtx) const Handle(BOPInt_Context)& aCtx)
{ {
Standard_Boolean bRet; Standard_Boolean bRet;
@ -1788,14 +1795,15 @@ Standard_Real fsqrt(Standard_Real val)
//function : GetFaceDir //function : GetFaceDir
//purpose : Get binormal direction for the face in the point aP //purpose : Get binormal direction for the face in the point aP
//======================================================================= //=======================================================================
void GetFaceDir(const TopoDS_Edge& aE, void GetFaceDir(const TopoDS_Edge& aE,
const TopoDS_Face& aF, const TopoDS_Face& aF,
const gp_Pnt& aP, const gp_Pnt& aP,
const Standard_Real aT, const Standard_Real aT,
const gp_Dir& aDTgt, const gp_Dir& aDTgt,
gp_Dir& aDN, gp_Dir& aDN,
gp_Dir& aDB, gp_Dir& aDB,
Handle(BOPInt_Context)& theContext) Handle(BOPInt_Context)& theContext,
GeomAPI_ProjectPointOnSurf& aProjPL)
{ {
BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN); BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
if (aF.Orientation()==TopAbs_REVERSED){ if (aF.Orientation()==TopAbs_REVERSED){
@ -1803,64 +1811,56 @@ Standard_Real fsqrt(Standard_Real val)
} }
aDB = aDN^aDTgt; aDB = aDN^aDTgt;
// //
Handle(Geom_Surface) aS = BRep_Tool::Surface(aF);
GeomAdaptor_Surface aGAS(aS);
if (aGAS.GetType()!=GeomAbs_Plane) {
gp_Pnt aPx; gp_Pnt aPx;
if (!FindPointInFace(aE, aF, aP, aT, aDB, aPx, theContext, aGAS)) { if (!FindPointInFace(aE, aF, aP, aDB, aPx, theContext, aProjPL)) {
gp_Pnt2d aPx2D; BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, aDN, theContext);
Handle(Geom_Plane) aPL; aProjPL.Perform(aPx);
GeomAPI_ProjectPointOnSurf aProj; aPx = aProjPL.NearestPoint();
//
BOPTools_AlgoTools3D::PointNearEdge(aE, aF, aT, aPx2D, aPx, theContext);
aPL = new Geom_Plane(aP, aDTgt);
aProj.Init(aPx, aPL);
aPx = aProj.NearestPoint();
gp_Vec aVec(aP, aPx); gp_Vec aVec(aP, aPx);
aDB.SetXYZ(aVec.XYZ()); aDB.SetXYZ(aVec.XYZ());
} }
}
} }
//======================================================================= //=======================================================================
//function : FindPointInFace //function : FindPointInFace
//purpose : Find a point in the face in direction of <aDB> //purpose : Find a point in the face in direction of <aDB>
//======================================================================= //=======================================================================
Standard_Boolean FindPointInFace(const TopoDS_Edge& aE, Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
const TopoDS_Face& aF, const TopoDS_Face& aF,
const gp_Pnt& aP, const gp_Pnt& aP,
const Standard_Real /*aT*/,
gp_Dir& aDB, gp_Dir& aDB,
gp_Pnt& aPOut, gp_Pnt& aPOut,
Handle(BOPInt_Context)& theContext, Handle(BOPInt_Context)& theContext,
const GeomAdaptor_Surface& aGAS) GeomAPI_ProjectPointOnSurf& aProjPL)
{ {
Standard_Integer aNbItMax; Standard_Integer aNbItMax;
Standard_Real aDt, aDtMin, aTolE, aTolF, aDist; Standard_Real aDt, aDtMin, aTolE, aTolF, aDist;
Standard_Boolean bRet; Standard_Boolean bRet;
gp_Pnt aP1; gp_Pnt aP1;
BRepAdaptor_Surface aBAS;
// //
bRet = Standard_False; bRet = Standard_False;
aTolE = BRep_Tool::Tolerance(aE); aTolE = BRep_Tool::Tolerance(aE);
aTolF = BRep_Tool::Tolerance(aF); aTolF = BRep_Tool::Tolerance(aF);
aDt = 2*(aTolE+aTolF); aDt = 2*(aTolE+aTolF);
aBAS.Initialize(aF, Standard_False);
// //
aDtMin=5.e-4; aDtMin=5.e-4;
if (aDt < aDtMin) { if (aDt < aDtMin) {
Standard_Real aR; Standard_Real aR;
GeomAbs_SurfaceType aSType=aGAS.GetType(); GeomAbs_SurfaceType aSType=aBAS.GetType();
switch (aSType) { switch (aSType) {
case GeomAbs_Cylinder: case GeomAbs_Cylinder:
aR = aGAS.Cylinder().Radius(); aR = aBAS.Cylinder().Radius();
break; break;
case GeomAbs_Cone: case GeomAbs_Cone:
aR = aGAS.Cone().RefRadius(); aR = aBAS.Cone().RefRadius();
break; break;
case GeomAbs_Sphere: case GeomAbs_Sphere:
aR = aGAS.Sphere().Radius(); aR = aBAS.Sphere().Radius();
break; break;
case GeomAbs_Torus: case GeomAbs_Torus:
aR = aGAS.Torus().MinorRadius(); aR = aBAS.Torus().MinorRadius();
break; break;
case GeomAbs_SurfaceOfRevolution: case GeomAbs_SurfaceOfRevolution:
aR=1.; aR=1.;
@ -1894,6 +1894,9 @@ Standard_Real fsqrt(Standard_Real val)
aPOut = aProj.NearestPoint(); aPOut = aProj.NearestPoint();
aDist = aProj.LowerDistance(); aDist = aProj.LowerDistance();
// //
aProjPL.Perform(aPOut);
aPOut = aProjPL.NearestPoint();
//
gp_Vec aV(aP, aPOut); gp_Vec aV(aP, aPOut);
aDB.SetXYZ(aV.XYZ()); aDB.SetXYZ(aV.XYZ());
} while (aDist>Precision::Angular() && --aNbItMax); } while (aDist>Precision::Angular() && --aNbItMax);

View File

@ -0,0 +1,29 @@
puts "============"
puts "OCC24154"
puts "============"
puts ""
######################################################
# Wrong result of CUT operation
######################################################
restore [locate_data_file bug24154_t.brep] b1
restore [locate_data_file bug24154_b.brep] b2
bop b1 b2
bopcut result
set square 2.68434e+06
set volume 7.35468e+07
# Analysis of "nbshapes res"
set nb_v_good 18
set nb_e_good 27
set nb_w_good 11
set nb_f_good 11
set nb_sh_good 1
set nb_sol_good 1
set nb_compsol_good 0
set nb_compound_good 1
set nb_shape_good 70
set 2dviewer 1