1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-16 10:54:53 +03:00

0027888: Fuse of valid untouched solids leads to result with faulties

Incorrect result of classification of a point relatively a solid leads to faulty interferences between vertices/edges of one solid with another one.  Classification has been corrected by checking if an auxiliary point in face coincides with the face boundary in 3D space.

Test case has been created.
This commit is contained in:
msv 2016-09-21 11:02:25 +03:00 committed by kgv
parent c381fda2d6
commit c58b30780a
3 changed files with 48 additions and 13 deletions

View File

@ -225,6 +225,29 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
U1, V1, U2, V2, aVecD1U, aVecD1V); U1, V1, U2, V2, aVecD1U, aVecD1V);
} }
//=======================================================================
//function : ClassifyUVPoint
//purpose :
//=======================================================================
TopAbs_State BRepClass3d_SolidExplorer::ClassifyUVPoint
(const IntCurvesFace_Intersector& theIntersector,
const Handle(BRepAdaptor_HSurface)& theSurf,
const gp_Pnt2d& theP2d) const
{
// first find if the point is near an edge/vertex
gp_Pnt aP3d = theSurf->Value(theP2d.X(), theP2d.Y());
BRepClass3d_BndBoxTreeSelectorPoint aSelectorPoint(myMapEV);
aSelectorPoint.SetCurrentPoint(aP3d);
Standard_Integer aSelsVE = myTree.Select(aSelectorPoint);
if (aSelsVE > 0)
{
// The point is inside the tolerance area of vertices/edges => return ON state.
return TopAbs_ON;
}
return theIntersector.ClassifyUVPoint(theP2d);
}
//======================================================================= //=======================================================================
//function : PointInTheFace //function : PointInTheFace
//purpose : //purpose :
@ -264,7 +287,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
if(ptr) { if(ptr) {
const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr)); const IntCurvesFace_Intersector& TheIntersector = (*((IntCurvesFace_Intersector *)ptr));
// Check if the point is already in the face // Check if the point is already in the face
if(IsInside && (TheIntersector.ClassifyUVPoint(gp_Pnt2d(u_,v_))==TopAbs_IN)) { if (IsInside && (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u_, v_)) == TopAbs_IN)) {
gp_Pnt aPnt; gp_Pnt aPnt;
surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V); surf->D1(u_, v_, aPnt, theVecD1U, theVecD1V);
if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion()) if (aPnt.SquareDistance(APoint_) < Precision::Confusion() * Precision::Confusion())
@ -280,7 +303,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 X u increases for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 X u increases
for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases
if(++NbPntCalc>=IndexPoint) { if(++NbPntCalc>=IndexPoint) {
if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
u_=u; v_=v; u_=u; v_=v;
surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
IndexPoint = NbPntCalc; IndexPoint = NbPntCalc;
@ -293,7 +316,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- 0 0 u decreases
for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- X 0 v decreases
if(++NbPntCalc>=IndexPoint) { if(++NbPntCalc>=IndexPoint) {
if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
u_=u; v_=v; u_=u; v_=v;
surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
IndexPoint = NbPntCalc; IndexPoint = NbPntCalc;
@ -305,7 +328,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases for(u=-du+(U1+U2)*0.5; u>U1; u-=du) { //-- X 0 u decreases
for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases for(v=dv+(V1+V2)*0.5; v<V2; v+=dv) { //-- 0 0 v increases
if(++NbPntCalc>=IndexPoint) { if(++NbPntCalc>=IndexPoint) {
if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
u_=u; v_=v; u_=u; v_=v;
surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
IndexPoint = NbPntCalc; IndexPoint = NbPntCalc;
@ -317,7 +340,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 0 u increases for(u=du+(U1+U2)*0.5; u<U2; u+=du) { //-- 0 0 u increases
for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases for(v=-dv+(V1+V2)*0.5; v>V1; v-=dv) { //-- 0 X v decreases
if(++NbPntCalc>=IndexPoint) { if(++NbPntCalc>=IndexPoint) {
if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
u_=u; v_=v; u_=u; v_=v;
surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
IndexPoint = NbPntCalc; IndexPoint = NbPntCalc;
@ -335,7 +358,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
for(u=du+U1; u<U2; u+=du) { for(u=du+U1; u<U2; u+=du) {
for(v=dv+V1; v<V2; v+=dv) { for(v=dv+V1; v<V2; v+=dv) {
if(++NbPntCalc>=IndexPoint) { if(++NbPntCalc>=IndexPoint) {
if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
u_=u; v_=v; u_=u; v_=v;
surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
IndexPoint = NbPntCalc; IndexPoint = NbPntCalc;
@ -347,7 +370,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::PointInTheFace
u=(U1+U2)*0.5; u=(U1+U2)*0.5;
v=(V1+V2)*0.5; v=(V1+V2)*0.5;
if(++NbPntCalc>=IndexPoint) { if(++NbPntCalc>=IndexPoint) {
if(TheIntersector.ClassifyUVPoint(gp_Pnt2d(u,v))==TopAbs_IN) { if (ClassifyUVPoint(TheIntersector, surf, gp_Pnt2d(u, v)) == TopAbs_IN) {
u_=u; v_=v; u_=u; v_=v;
surf->D1 (u, v, APoint_, theVecD1U, theVecD1V); surf->D1 (u, v, APoint_, theVecD1U, theVecD1V);
IndexPoint = NbPntCalc; IndexPoint = NbPntCalc;

View File

@ -152,14 +152,12 @@ public:
Standard_EXPORT void Destroy(); Standard_EXPORT void Destroy();
protected: protected:
Standard_EXPORT TopAbs_State ClassifyUVPoint
(const IntCurvesFace_Intersector& theIntersector,
const Handle(BRepAdaptor_HSurface)& theSurf,
const gp_Pnt2d& theP2d) const;
private: private:

View File

@ -0,0 +1,14 @@
puts "============"
puts "OCC27888"
puts "============"
puts ""
######################################################
# Fuse of valid untouched solids leads to result with faulties
######################################################
binrestore [locate_data_file bug27888_cut_2_4.bin] a
explode a
bfuse r a_1 a_2
checkshape r
checknbshapes r -solid 26
checkprops r -v 1.85614e+006