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:
parent
c7a422d893
commit
bb58e462ad
@ -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);
|
||||
|
29
tests/bugs/modalg_5/bug24154
Normal file
29
tests/bugs/modalg_5/bug24154
Normal 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
|
Loading…
x
Reference in New Issue
Block a user