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
@ -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);
//
@ -1795,7 +1802,8 @@ Standard_Real fsqrt(Standard_Real val)
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,24 +1811,15 @@ 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
@ -1829,38 +1828,39 @@ Standard_Real fsqrt(Standard_Real val)
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