mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0028490: Point located outside the solid is classified as inside
New method for building surface polyhedron (class IntCurveSurface_Polyhedron), which takes in account intervals of discontinuity of surface is added for constructor IntCurvesFace_Intersector. Bug in methods NbU(V)Intervals and U(V)Intervals for Offset surfaces is fixed.
This commit is contained in:
parent
b80d766ab9
commit
f24f542856
@ -353,7 +353,7 @@ Standard_Integer GeomAdaptor_Surface::NbUIntervals(const GeomAbs_Shape S) const
|
|||||||
case GeomAbs_CN: break;
|
case GeomAbs_CN: break;
|
||||||
}
|
}
|
||||||
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
||||||
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
|
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
|
||||||
return Sur.NbUIntervals(BaseS);
|
return Sur.NbUIntervals(BaseS);
|
||||||
}
|
}
|
||||||
case GeomAbs_Plane:
|
case GeomAbs_Plane:
|
||||||
@ -406,7 +406,7 @@ Standard_Integer GeomAdaptor_Surface::NbVIntervals(const GeomAbs_Shape S) const
|
|||||||
case GeomAbs_CN: break;
|
case GeomAbs_CN: break;
|
||||||
}
|
}
|
||||||
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
||||||
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
|
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
|
||||||
return Sur.NbVIntervals(BaseS);
|
return Sur.NbVIntervals(BaseS);
|
||||||
}
|
}
|
||||||
case GeomAbs_Plane:
|
case GeomAbs_Plane:
|
||||||
@ -465,7 +465,7 @@ void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
|
|||||||
case GeomAbs_CN: break;
|
case GeomAbs_CN: break;
|
||||||
}
|
}
|
||||||
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
||||||
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
|
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
|
||||||
myNbUIntervals = Sur.NbUIntervals(BaseS);
|
myNbUIntervals = Sur.NbUIntervals(BaseS);
|
||||||
Sur.UIntervals(T, BaseS);
|
Sur.UIntervals(T, BaseS);
|
||||||
}
|
}
|
||||||
@ -528,7 +528,7 @@ void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
|
|||||||
case GeomAbs_CN: break;
|
case GeomAbs_CN: break;
|
||||||
}
|
}
|
||||||
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
|
||||||
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
|
GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
|
||||||
myNbVIntervals = Sur.NbVIntervals(BaseS);
|
myNbVIntervals = Sur.NbVIntervals(BaseS);
|
||||||
Sur.VIntervals(T, BaseS);
|
Sur.VIntervals(T, BaseS);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,75 @@
|
|||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||||
|
//
|
||||||
|
static void ComputeSamplePars(const Handle(Adaptor3d_HSurface)& Hsurface,
|
||||||
|
const Standard_Integer nbsu,
|
||||||
|
const Standard_Integer nbsv,
|
||||||
|
Handle(TColStd_HArray1OfReal)& UPars,
|
||||||
|
Handle(TColStd_HArray1OfReal)& VPars)
|
||||||
|
{
|
||||||
|
Standard_Integer NbUInts = Hsurface->NbUIntervals(GeomAbs_C2);
|
||||||
|
Standard_Integer NbVInts = Hsurface->NbVIntervals(GeomAbs_C2);
|
||||||
|
TColStd_Array1OfReal UInts(1, NbUInts + 1);
|
||||||
|
TColStd_Array1OfReal VInts(1, NbVInts + 1);
|
||||||
|
Hsurface->UIntervals(UInts, GeomAbs_C2);
|
||||||
|
Hsurface->VIntervals(VInts, GeomAbs_C2);
|
||||||
|
//
|
||||||
|
TColStd_Array1OfInteger NbUSubInts(1, NbUInts);
|
||||||
|
TColStd_Array1OfInteger NbVSubInts(1, NbVInts);
|
||||||
|
//
|
||||||
|
Standard_Integer i, j, ind, NbU, NbV;
|
||||||
|
Standard_Real t, dt;
|
||||||
|
t = UInts(NbUInts + 1) - UInts(1);
|
||||||
|
t = 1. / t;
|
||||||
|
NbU = 0;
|
||||||
|
for(i = 1; i <= NbUInts; ++i)
|
||||||
|
{
|
||||||
|
dt = (UInts(i+1) - UInts(i));
|
||||||
|
NbUSubInts(i) = RealToInt(nbsu * dt * t) + 1;
|
||||||
|
NbU += NbUSubInts(i);
|
||||||
|
}
|
||||||
|
t = VInts(NbVInts + 1) - VInts(1);
|
||||||
|
t = 1. / t;
|
||||||
|
NbV = 0;
|
||||||
|
for(i = 1; i <= NbVInts; ++i)
|
||||||
|
{
|
||||||
|
dt = (VInts(i+1) - VInts(i));
|
||||||
|
NbVSubInts(i) = RealToInt(nbsv * dt * t) + 1;
|
||||||
|
NbV += NbVSubInts(i);
|
||||||
|
}
|
||||||
|
UPars = new TColStd_HArray1OfReal(1, NbU + 1);
|
||||||
|
VPars = new TColStd_HArray1OfReal(1, NbV + 1);
|
||||||
|
//
|
||||||
|
ind = 1;
|
||||||
|
for(i = 1; i <= NbUInts; ++i)
|
||||||
|
{
|
||||||
|
UPars->SetValue(ind++, UInts(i));
|
||||||
|
dt = (UInts(i+1) - UInts(i)) / NbUSubInts(i);
|
||||||
|
t = UInts(i);
|
||||||
|
for(j = 1; j < NbUSubInts(i); ++j)
|
||||||
|
{
|
||||||
|
t += dt;
|
||||||
|
UPars->SetValue(ind++, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UPars->SetValue(ind, UInts(NbUInts + 1));
|
||||||
|
//
|
||||||
|
ind = 1;
|
||||||
|
for(i = 1; i <= NbVInts; ++i)
|
||||||
|
{
|
||||||
|
VPars->SetValue(ind++, VInts(i));
|
||||||
|
dt = (VInts(i+1) - VInts(i)) / NbVSubInts(i);
|
||||||
|
t = VInts(i);
|
||||||
|
for(j = 1; j < NbVSubInts(i); ++j)
|
||||||
|
{
|
||||||
|
t += dt;
|
||||||
|
VPars->SetValue(ind++, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VPars->SetValue(ind, VInts(NbVInts + 1));
|
||||||
|
}
|
||||||
|
//
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : SurfaceType
|
//function : SurfaceType
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -86,24 +155,28 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
|
|||||||
U1 = Hsurface->LastUParameter();
|
U1 = Hsurface->LastUParameter();
|
||||||
V0 = Hsurface->FirstVParameter();
|
V0 = Hsurface->FirstVParameter();
|
||||||
V1 = Hsurface->LastVParameter();
|
V1 = Hsurface->LastVParameter();
|
||||||
|
//
|
||||||
|
nbsu = myTopolTool->NbSamplesU();
|
||||||
|
nbsv = myTopolTool->NbSamplesV();
|
||||||
|
//
|
||||||
Standard_Real aURes = Hsurface->UResolution(1.0);
|
Standard_Real aURes = Hsurface->UResolution(1.0);
|
||||||
Standard_Real aVRes = Hsurface->VResolution(1.0);
|
Standard_Real aVRes = Hsurface->VResolution(1.0);
|
||||||
|
|
||||||
// Checking correlation between number of samples and length of the face along each axis
|
// Checking correlation between number of samples and length of the face along each axis
|
||||||
const Standard_Real aTresh = 100.0;
|
const Standard_Real aTresh = 100.0;
|
||||||
const Standard_Integer aMinSamples = 10;
|
Standard_Integer aMinSamples = 20;
|
||||||
const Standard_Integer aMaxSamples = 40;
|
const Standard_Integer aMaxSamples = 40;
|
||||||
const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
|
const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
|
||||||
Standard_Real dU = (U1 - U0) / aURes;
|
Standard_Real dU = (U1 - U0) / aURes;
|
||||||
Standard_Real dV = (V1 - V0) / aVRes;
|
Standard_Real dV = (V1 - V0) / aVRes;
|
||||||
nbsu = myTopolTool->NbSamplesU();
|
if (nbsu < aMinSamples) nbsu = aMinSamples;
|
||||||
nbsv = myTopolTool->NbSamplesV();
|
if (nbsv < aMinSamples) nbsv = aMinSamples;
|
||||||
if (nbsu > aMaxSamples) nbsu = aMaxSamples;
|
if (nbsu > aMaxSamples) nbsu = aMaxSamples;
|
||||||
if (nbsv > aMaxSamples) nbsv = aMaxSamples;
|
if (nbsv > aMaxSamples) nbsv = aMaxSamples;
|
||||||
|
|
||||||
if (Max(dU, dV) > Min(dU, dV) * aTresh)
|
if (Max(dU, dV) > Min(dU, dV) * aTresh)
|
||||||
{
|
{
|
||||||
|
aMinSamples = 10;
|
||||||
nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
|
nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
|
||||||
if (nbsu < aMinSamples) nbsu = aMinSamples;
|
if (nbsu < aMinSamples) nbsu = aMinSamples;
|
||||||
nbsv = aMaxSamples2 / nbsu;
|
nbsv = aMaxSamples2 / nbsu;
|
||||||
@ -113,8 +186,23 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
|
|||||||
nbsu = aMaxSamples2 / aMinSamples;
|
nbsu = aMaxSamples2 / aMinSamples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
|
|
||||||
|
Standard_Integer NbUOnS = Hsurface->NbUIntervals(GeomAbs_C2);
|
||||||
|
Standard_Integer NbVOnS = Hsurface->NbVIntervals(GeomAbs_C2);
|
||||||
|
|
||||||
|
if(NbUOnS > 1 || NbVOnS > 1)
|
||||||
|
{
|
||||||
|
Handle(TColStd_HArray1OfReal) UPars, VPars;
|
||||||
|
ComputeSamplePars(Hsurface, nbsu, nbsv, UPars, VPars);
|
||||||
|
PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
|
||||||
|
new IntCurveSurface_ThePolyhedronOfHInter(Hsurface, UPars->ChangeArray1(),
|
||||||
|
VPars->ChangeArray1());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
|
||||||
new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
|
new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
21
tests/bugs/modalg_6/bug28490_1
Normal file
21
tests/bugs/modalg_6/bug28490_1
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC28490"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
###########################################################
|
||||||
|
# Point located outside the solid is classified as inside
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
restore [locate_data_file bug28490_solid_vertex1.brep] a
|
||||||
|
explode a
|
||||||
|
mkpoint p a_2
|
||||||
|
set case_output [string trim [bclassify a_1 p]]
|
||||||
|
|
||||||
|
if {$case_output != "The point is OUT of shape"} {
|
||||||
|
puts "ERROR: OCC28490 is reproduced. Point is classified as INNER."
|
||||||
|
}
|
||||||
|
|
||||||
|
smallview
|
||||||
|
fit
|
||||||
|
|
||||||
|
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
|
21
tests/bugs/modalg_6/bug28490_2
Normal file
21
tests/bugs/modalg_6/bug28490_2
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC28490"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
###########################################################
|
||||||
|
# Point located outside the solid is classified as inside
|
||||||
|
###########################################################
|
||||||
|
|
||||||
|
restore [locate_data_file bug28490_solid_vertex2.brep] a
|
||||||
|
explode a
|
||||||
|
mkpoint p a_2
|
||||||
|
set case_output [string trim [bclassify a_1 p]]
|
||||||
|
|
||||||
|
if {$case_output != "The point is OUT of shape"} {
|
||||||
|
puts "ERROR: OCC28490 is reproduced. Point is classified as INNER."
|
||||||
|
}
|
||||||
|
|
||||||
|
smallview
|
||||||
|
fit
|
||||||
|
|
||||||
|
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
|
@ -1,5 +1,3 @@
|
|||||||
puts "TODO OCC25555 ALL: Faulty shapes in variables faulty_1 to faulty_"
|
|
||||||
|
|
||||||
puts "============"
|
puts "============"
|
||||||
puts "OCC24055"
|
puts "OCC24055"
|
||||||
puts "============"
|
puts "============"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user