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