1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0026556: Infinite calculations of BRepOffset_MakeOffset

Method for pre-analysis of input data added (CheckInputData).
Now it is possible to work with Error() function, which return error code.

Tests corrected according to changed error appearance.
This commit is contained in:
aml 2015-08-20 10:24:00 +03:00 committed by abv
parent a2361eda86
commit 574ea6faba
8 changed files with 234 additions and 30 deletions

View File

@ -72,7 +72,11 @@ is
UnCorrectClosingFace,
ExtentFaceFailed,
RadiusEqualOffset,
UnknownError
UnknownError,
BadNormalsOnGeometry,
C0Geometry,
NullOffset,
NotConnectedShell
end Error;
class MakeOffset;

View File

@ -136,6 +136,19 @@ is
returns IndexedMapOfShape from TopTools
is static;
CheckInputData(me: in out) returns Boolean;
---Purpose: Makes pre analysis of possibility offset perform. Use method Error() to get more information.
--- Finds first error. List of checks:
--- 1) Check for existence object with non-null offset.
--- 2) Check for connectivity in offset shell.
--- 3) Check continuity of input surfaces.
--- 4) Check for normals existence on grid.
--- @return 1 if possible make computations and 0 if not possible.
GetBadShape (me) returns Shape from TopoDS;
---Purpose: Return bad shape, which obtained in CheckInputData.
---C++: return const &
---Category: private methods
BuildOffsetByArc ( me : in out )
@ -224,5 +237,6 @@ fields
myError : Error from BRepOffset;
myMakeLoops : MakeLoops from BRepOffset;
myBadShape : Shape from TopoDS;
end MakeOffset;

View File

@ -118,6 +118,7 @@
#include <BRepGProp.hxx>
// POP for NT
#include <stdio.h>
#include <NCollection_Vector.hxx>
#ifdef DRAW
@ -682,29 +683,12 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
RemoveCorks (myShape,myFaces);
}
if (! IsConnectedShell(myShape))
Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
if (Abs(myOffset) <= myTol)
if (!CheckInputData())
{
// Check for face with non-null offset value.
Standard_Boolean isFound = Standard_False;
TopTools_DataMapIteratorOfDataMapOfShapeReal anIter(myFaceOffset);
for( ; anIter.More(); anIter.Next())
{
if (Abs(anIter.Value()) > myTol)
{
isFound = Standard_True;
break;
}
}
if (!isFound)
{
// No face with non-null offset found.
// There is error in input data.
// Check Error() method.
return;
}
}
TopAbs_State Side = TopAbs_IN;
if (myOffset < 0.) Side = TopAbs_OUT;
@ -3400,3 +3384,176 @@ void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList)
}
theSol = aNewSol;
}
//=======================================================================
//function : CheckInputData
//purpose : Check input data for possiblity of offset perform.
//=======================================================================
Standard_Boolean BRepOffset_MakeOffset::CheckInputData()
{
// Set initial error state.
myError = BRepOffset_NoError;
TopoDS_Shape aTmpShape;
myBadShape = aTmpShape;
// Non-null offset.
if (Abs(myOffset) <= myTol)
{
Standard_Boolean isFound = Standard_False;
TopTools_DataMapIteratorOfDataMapOfShapeReal anIter(myFaceOffset);
for( ; anIter.More(); anIter.Next())
{
if (Abs(anIter.Value()) > myTol)
{
isFound = Standard_True;
break;
}
}
if (!isFound)
{
// No face with non-null offset found.
myError = BRepOffset_NullOffset;
return Standard_False;
}
}
// Connectivity of input shape.
if (!IsConnectedShell(myShape))
{
myError = BRepOffset_NotConnectedShell;
return Standard_False;
}
// Normals check and continuity check.
const Standard_Integer aPntPerDim = 20; // 21 points on each dimension.
Standard_Real aUmin, aUmax, aVmin, aVmax;
TopExp_Explorer anExpSF(myShape, TopAbs_FACE);
TopLoc_Location L;
gp_Pnt2d aPnt2d;
gp_Pnt aPnt;
gp_Vec aD1U, aD1V;
for( ; anExpSF.More(); anExpSF.Next())
{
const TopoDS_Face& aF = TopoDS::Face(anExpSF.Current());
const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aF, L);
BRepTools::UVBounds(aF, aUmin, aUmax, aVmin, aVmax);
// Continuity check.
if (aSurf->Continuity() == GeomAbs_C0)
{
myError = BRepOffset_C0Geometry;
return Standard_False;
}
// Get degenerated points, to avoid check them.
NCollection_Vector<gp_Pnt> aBad3dPnts;
TopExp_Explorer anExpFE(aF, TopAbs_EDGE);
for( ; anExpFE.More(); anExpFE.Next())
{
const TopoDS_Edge &aE = TopoDS::Edge(anExpFE.Current());
if (BRep_Tool::Degenerated(aE))
{
aBad3dPnts.Append(BRep_Tool::Pnt((TopExp::FirstVertex(aE))));
}
}
// Geometry grid check.
for(Standard_Integer i = 0; i <= aPntPerDim; i++)
{
Standard_Real aUParam = aUmin + (aUmax - aUmin) * i / aPntPerDim;
for(Standard_Integer j = 0; j <= aPntPerDim; j++)
{
Standard_Real aVParam = aVmin + (aVmax - aVmin) * j / aPntPerDim;
aSurf->D1(aUParam, aVParam, aPnt, aD1U, aD1V);
if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
aD1V.SquareMagnitude() < Precision::SquareConfusion() )
{
Standard_Boolean isKnownBadPnt = Standard_False;
for(Standard_Integer anIdx = aBad3dPnts.Lower();
anIdx <= aBad3dPnts.Upper();
++anIdx)
{
if (aPnt.SquareDistance(aBad3dPnts(anIdx)) < Precision::SquareConfusion())
{
isKnownBadPnt = Standard_True;
break;
}
} // for(Standard_Integer anIdx = aBad3dPnts.Lower();
if (!isKnownBadPnt)
{
myError = BRepOffset_BadNormalsOnGeometry;
return Standard_False;
}
else
continue;
} // if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
Standard_Real anAngle = aD1U.Angle(aD1V);
if (Abs (anAngle) < Precision::Confusion())
{
myError = BRepOffset_BadNormalsOnGeometry;
return Standard_False;
}
}
}
// Vertex list check.
TopExp_Explorer anExpFV(aF, TopAbs_VERTEX);
for( ; anExpFV.More(); anExpFV.Next())
{
const TopoDS_Vertex &aV = TopoDS::Vertex(anExpFV.Current());
aPnt2d = BRep_Tool::Parameters(aV, aF);
aSurf->D1(aPnt2d.X(), aPnt2d.Y(), aPnt, aD1U, aD1V);
if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
aD1V.SquareMagnitude() < Precision::SquareConfusion() )
{
Standard_Boolean isKnownBadPnt = Standard_False;
for(Standard_Integer anIdx = aBad3dPnts.Lower();
anIdx <= aBad3dPnts.Upper();
++anIdx)
{
if (aPnt.SquareDistance(aBad3dPnts(anIdx)) < Precision::SquareConfusion())
{
isKnownBadPnt = Standard_True;
break;
}
} // for(Standard_Integer anIdx = aBad3dPnts.Lower();
if (!isKnownBadPnt)
{
myError = BRepOffset_BadNormalsOnGeometry;
return Standard_False;
}
else
continue;
} // if (aD1U.SquareMagnitude() < Precision::SquareConfusion() ||
Standard_Real anAngle = aD1U.Angle(aD1V);
if ( Abs (anAngle) < Precision::Confusion())
{
myError = BRepOffset_BadNormalsOnGeometry;
return Standard_False;
}
}
}
return Standard_True;
}
//=======================================================================
//function : CheckInputData
//purpose : Check input data for possiblity of offset perform.
//=======================================================================
const TopoDS_Shape& BRepOffset_MakeOffset::GetBadShape() const
{
return myBadShape;
}

View File

@ -1031,7 +1031,38 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands,
}
else
{
theCommands << "ERROR. offsetperform operation not done.";
// Return state of problem.
BRepOffset_Error anError = TheOffset.Error();
switch(anError)
{
case BRepOffset_BadNormalsOnGeometry:
{
theCommands << "ERROR. Degenerated normal on input data.";
break;
}
case BRepOffset_C0Geometry:
{
theCommands << "ERROR. C0 continuity of input data.";
break;
}
case BRepOffset_NullOffset:
{
theCommands << "ERROR. Null offset of all faces.";
break;
}
case BRepOffset_NotConnectedShell:
{
theCommands << "ERROR. Incorrect set of faces to remove, the remaining shell is not connected.";
break;
}
default:
{
theCommands << "ERROR. offsetperform operation not done.";
break;
}
}
return 1;
}

View File

@ -1,5 +1,5 @@
puts "TODO OCC25916 ALL: \\*\\* Exception"
puts "TODO OCC25916 ALL: An exception was caught"
puts "TODO OCC25916 ALL: result is not a topological shape!!!"
puts "TODO OCC25916 ALL: Error: object with name 'result' does not exist!"
puts "TODO OCC25916 ALL: TEST INCOMPLETE"
puts "========"
puts "OCC21261"

View File

@ -1,5 +1,5 @@
puts "TODO OCC25916 ALL: \\*\\* Exception"
puts "TODO OCC25916 ALL: An exception was caught"
puts "TODO OCC25916 ALL: result is not a topological shape!!!"
puts "TODO OCC25916 ALL: Error: object with name 'result' does not exist!"
puts "TODO OCC25916 ALL: TEST INCOMPLETE"
puts "========"
puts "OCC21261"

View File

@ -1,5 +1,4 @@
puts "TODO OCC23190 ALL: An exception was caugh.*Offset with no C1 Surface"
puts "TODO OCC23190 ALL: \\*\\* Exception \\*\\*.*Offset with no C1 Surface"
puts "TODO OCC23190 ALL: result is not a topological shape!!!"
puts "TODO OCC23068 ALL: TEST INCOMPLETE"
# Original bug : hkg60144/pro15325
# Date : 17Juillet98

View File

@ -1,5 +1,4 @@
puts "TODO OCC23190 ALL: An exception was caught.*Offset with no C1 Surface"
puts "TODO OCC23190 ALL: \\*\\* Exception \\*\\*.*Offset with no C1 Surface"
puts "TODO OCC23190 ALL: result is not a topological shape!!!"
puts "TODO OCC23068 ALL: TEST INCOMPLETE"
# Original bug : cts21271
# Date : 11Sept98