mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0030433: Checkshape: bad solid, created by revolution, is reported as valid.
BRepPrimAPI_MakeRevol.cxx, hxx Insert checking of self-intersecting of generated surfaces in MakeRevol BRepTest_SweepCommands.cxx Adjusting command revol to current behavior of MakeRevol algorithm.
This commit is contained in:
parent
7dd7c146e8
commit
6f2411378b
@ -26,6 +26,13 @@
|
|||||||
#include <TopoDS_Shape.hxx>
|
#include <TopoDS_Shape.hxx>
|
||||||
#include <TopTools_DataMapOfShapeListOfShape.hxx>
|
#include <TopTools_DataMapOfShapeListOfShape.hxx>
|
||||||
#include <BRepTools_ReShape.hxx>
|
#include <BRepTools_ReShape.hxx>
|
||||||
|
#include <Geom_TrimmedCurve.hxx>
|
||||||
|
#include <GeomAdaptor_SurfaceOfRevolution.hxx>
|
||||||
|
#include <GeomAdaptor_HCurve.hxx>
|
||||||
|
#include <Extrema_ExtCC.hxx>
|
||||||
|
#include <Extrema_POnCurv.hxx>
|
||||||
|
#include <Geom_Line.hxx>
|
||||||
|
|
||||||
// perform checks on the argument
|
// perform checks on the argument
|
||||||
static const TopoDS_Shape& check(const TopoDS_Shape& S)
|
static const TopoDS_Shape& check(const TopoDS_Shape& S)
|
||||||
{
|
{
|
||||||
@ -41,10 +48,20 @@ static const TopoDS_Shape& check(const TopoDS_Shape& S)
|
|||||||
BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S,
|
BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S,
|
||||||
const gp_Ax1& A,
|
const gp_Ax1& A,
|
||||||
const Standard_Real D,
|
const Standard_Real D,
|
||||||
const Standard_Boolean Copy) :
|
const Standard_Boolean Copy) :
|
||||||
myRevol(check(S),A,D,Copy)
|
myRevol(check(S), A, D, Copy),
|
||||||
|
myIsBuild(Standard_False)
|
||||||
|
|
||||||
{
|
{
|
||||||
Build();
|
if (!CheckValidity(check(S), A))
|
||||||
|
{
|
||||||
|
myShape.Nullify();
|
||||||
|
myIsBuild = Standard_True;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,10 +72,21 @@ BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S,
|
|||||||
|
|
||||||
BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S,
|
BRepPrimAPI_MakeRevol::BRepPrimAPI_MakeRevol(const TopoDS_Shape& S,
|
||||||
const gp_Ax1& A,
|
const gp_Ax1& A,
|
||||||
const Standard_Boolean Copy) :
|
const Standard_Boolean Copy) :
|
||||||
myRevol(check(S),A,Copy)
|
|
||||||
|
myRevol(check(S), A, 2. * M_PI, Copy),
|
||||||
|
myIsBuild(Standard_False)
|
||||||
{
|
{
|
||||||
Build();
|
|
||||||
|
if (!CheckValidity(check(S), A))
|
||||||
|
{
|
||||||
|
myShape.Nullify();
|
||||||
|
myIsBuild = Standard_True;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,10 +108,16 @@ const BRepSweep_Revol& BRepPrimAPI_MakeRevol::Revol() const
|
|||||||
|
|
||||||
void BRepPrimAPI_MakeRevol::Build()
|
void BRepPrimAPI_MakeRevol::Build()
|
||||||
{
|
{
|
||||||
|
if (myIsBuild)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
myShape = myRevol.Shape();
|
myShape = myRevol.Shape();
|
||||||
BRepLib::UpdateInnerTolerances(myShape);
|
BRepLib::UpdateInnerTolerances(myShape);
|
||||||
|
|
||||||
Done();
|
Done();
|
||||||
|
myIsBuild = Standard_True;
|
||||||
|
|
||||||
myHist.Nullify();
|
myHist.Nullify();
|
||||||
myDegenerated.Clear();
|
myDegenerated.Clear();
|
||||||
TopTools_DataMapOfShapeListOfShape aDegE;
|
TopTools_DataMapOfShapeListOfShape aDegE;
|
||||||
@ -210,6 +244,98 @@ void BRepPrimAPI_MakeRevol::Build()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//=======================================================================
|
||||||
|
//function : IsIntersect
|
||||||
|
//purpose : used in CheckValidity to find out is there
|
||||||
|
// intersection between curve and axe of revolution
|
||||||
|
//=======================================================================
|
||||||
|
static Standard_Boolean IsIntersect(const Handle(Adaptor3d_HCurve)& theC,
|
||||||
|
const gp_Ax1& theAxe)
|
||||||
|
{
|
||||||
|
const Handle(Geom_Line) aL = new Geom_Line(theAxe);
|
||||||
|
const GeomAdaptor_Curve aLin(aL);
|
||||||
|
const Standard_Real aParTol = theC->Resolution(Precision::Confusion());
|
||||||
|
const Standard_Real aParF = theC->FirstParameter() + aParTol,
|
||||||
|
aParL = theC->LastParameter() - aParTol;
|
||||||
|
|
||||||
|
Extrema_ExtCC anExtr(theC->Curve(), aLin);
|
||||||
|
anExtr.Perform();
|
||||||
|
if (anExtr.IsDone() && anExtr.NbExt() > 0)
|
||||||
|
{
|
||||||
|
Extrema_POnCurv aP1, aP2;
|
||||||
|
for (Standard_Integer i = 1; i <= anExtr.NbExt(); i++)
|
||||||
|
{
|
||||||
|
if (anExtr.SquareDistance(i) > Precision::SquareConfusion())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
anExtr.Points(i, aP1, aP2);
|
||||||
|
if ((aParF < aP1.Parameter()) && (aP1.Parameter() < aParL))
|
||||||
|
{
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : CheckValidity
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
Standard_Boolean BRepPrimAPI_MakeRevol::CheckValidity(const TopoDS_Shape& theShape,
|
||||||
|
const gp_Ax1& theA)
|
||||||
|
{
|
||||||
|
TopExp_Explorer anExp(theShape, TopAbs_EDGE);
|
||||||
|
Standard_Boolean IsValid = Standard_True;
|
||||||
|
for (; anExp.More(); anExp.Next())
|
||||||
|
{
|
||||||
|
const TopoDS_Edge& anE = TopoDS::Edge(anExp.Current());
|
||||||
|
|
||||||
|
if (BRep_Tool::Degenerated(anE))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TopLoc_Location L;
|
||||||
|
Standard_Real First, Last;
|
||||||
|
Handle(Geom_Curve) C = BRep_Tool::Curve(anE, L, First, Last);
|
||||||
|
gp_Trsf Tr = L.Transformation();
|
||||||
|
C = Handle(Geom_Curve)::DownCast(C->Copy());
|
||||||
|
C = new Geom_TrimmedCurve(C, First, Last);
|
||||||
|
C->Transform(Tr);
|
||||||
|
|
||||||
|
Handle(GeomAdaptor_HCurve) HC = new GeomAdaptor_HCurve();
|
||||||
|
HC->ChangeCurve().Load(C, First, Last);
|
||||||
|
//Checking coinsidence axe of revolution and basis curve
|
||||||
|
//This code is taken directly from GeomAdaptor_SurfaceOfRevolution
|
||||||
|
Standard_Integer Ratio = 1;
|
||||||
|
Standard_Real Dist;
|
||||||
|
gp_Pnt PP;
|
||||||
|
do {
|
||||||
|
PP = HC->Value(First + (Last - First) / Ratio);
|
||||||
|
Dist = gp_Lin(theA).Distance(PP);
|
||||||
|
Ratio++;
|
||||||
|
} while (Dist < Precision::Confusion() && Ratio < 100);
|
||||||
|
//
|
||||||
|
if (Ratio >= 100) // edge coinsides with axes
|
||||||
|
{
|
||||||
|
IsValid = Standard_True; //Such edges are allowed by revol algo and treated
|
||||||
|
//by special way, so they must be concidered as valid
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IsValid = !IsIntersect(HC, theA);
|
||||||
|
}
|
||||||
|
if (!IsValid)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
return IsValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@ -351,4 +477,3 @@ const TopTools_ListOfShape& BRepPrimAPI_MakeRevol::Degenerated () const
|
|||||||
{
|
{
|
||||||
return myDegenerated;
|
return myDegenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,6 @@ class BRepPrimAPI_MakeRevol : public BRepPrimAPI_MakeSweep
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
DEFINE_STANDARD_ALLOC
|
DEFINE_STANDARD_ALLOC
|
||||||
|
|
||||||
|
|
||||||
//! Builds the Revol of base S, axis A and angle D. If C
|
//! Builds the Revol of base S, axis A and angle D. If C
|
||||||
//! is true, S is copied.
|
//! is true, S is copied.
|
||||||
@ -110,15 +109,15 @@ public:
|
|||||||
|
|
||||||
//! Check if there are degenerated edges in the result.
|
//! Check if there are degenerated edges in the result.
|
||||||
Standard_EXPORT Standard_Boolean HasDegenerated() const;
|
Standard_EXPORT Standard_Boolean HasDegenerated() const;
|
||||||
|
|
||||||
Standard_EXPORT const TopTools_ListOfShape& Degenerated() const;
|
|
||||||
|
|
||||||
|
//! Returns the list of degenerated edges
|
||||||
|
Standard_EXPORT const TopTools_ListOfShape& Degenerated() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
//! Checks possibilities of producing self-intersection surface
|
||||||
|
//! returns true if all surfaces are valid
|
||||||
|
Standard_EXPORT Standard_Boolean CheckValidity(const TopoDS_Shape& theShape, const gp_Ax1& theA);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -127,6 +126,7 @@ private:
|
|||||||
BRepSweep_Revol myRevol;
|
BRepSweep_Revol myRevol;
|
||||||
TopTools_ListOfShape myDegenerated;
|
TopTools_ListOfShape myDegenerated;
|
||||||
Handle(BRepTools_History) myHist;
|
Handle(BRepTools_History) myHist;
|
||||||
|
Standard_Boolean myIsBuild;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -114,7 +114,7 @@ static Standard_Integer prism(Draw_Interpretor&, Standard_Integer n, const char*
|
|||||||
//=======================================================================
|
//=======================================================================
|
||||||
// revol
|
// revol
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
static Standard_Integer revol(Draw_Interpretor&,
|
static Standard_Integer revol(Draw_Interpretor& di,
|
||||||
Standard_Integer n, const char** a)
|
Standard_Integer n, const char** a)
|
||||||
{
|
{
|
||||||
if (n < 10) return 1;
|
if (n < 10) return 1;
|
||||||
@ -133,14 +133,21 @@ static Standard_Integer revol(Draw_Interpretor&,
|
|||||||
|
|
||||||
BRepPrimAPI_MakeRevol Revol(base, A, angle, copy);
|
BRepPrimAPI_MakeRevol Revol(base, A, angle, copy);
|
||||||
|
|
||||||
TopoDS_Shape res = Revol.Shape();
|
if (Revol.IsDone())
|
||||||
|
{
|
||||||
|
TopoDS_Shape res = Revol.Shape();
|
||||||
|
|
||||||
DBRep::Set(a[1], res);
|
DBRep::Set(a[1], res);
|
||||||
|
|
||||||
//History
|
//History
|
||||||
TopTools_ListOfShape anArgs;
|
TopTools_ListOfShape anArgs;
|
||||||
anArgs.Append(base);
|
anArgs.Append(base);
|
||||||
BRepTest_Objects::SetHistory(anArgs, Revol);
|
BRepTest_Objects::SetHistory(anArgs, Revol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
di << "Revol not done \n";
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,11 @@ puts ""
|
|||||||
# BRepPrimAPI_MakeRevol fails to recognize a torus case
|
# BRepPrimAPI_MakeRevol fails to recognize a torus case
|
||||||
##########################################################
|
##########################################################
|
||||||
|
|
||||||
circle c_1 0 100 0 1 0 0 0 1 0 100
|
circle c_1 0 100.00001 0 1 0 0 0 1 0 100
|
||||||
circle c_2 0 100 0 1 0 0 0 0 1 100
|
circle c_2 0 100.00001 0 1 0 0 0 0 1 100
|
||||||
circle c_3 0 100 0 1 0 0 0 -1 0 100
|
circle c_3 0 100.00001 0 1 0 0 0 -1 0 100
|
||||||
circle c_4 0 100 0 1 0 0 0 0 1 10
|
circle c_4 0 100.00001 0 1 0 0 0 0 1 10
|
||||||
circle c_5 0 100 0 1 0 0 0 0 1 120
|
for { set i 1 } { $i <= 4 } { incr i } {
|
||||||
for { set i 1 } { $i <= 5 } { incr i } {
|
|
||||||
mkedge e c_$i
|
mkedge e c_$i
|
||||||
revol r e 0 0 0 0 0 1 90
|
revol r e 0 0 0 0 0 1 90
|
||||||
mksurface s_$i r
|
mksurface s_$i r
|
||||||
|
19
tests/bugs/modalg_7/bug30433
Normal file
19
tests/bugs/modalg_7/bug30433
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "0030433: Checkshape: bad solid, created by revolution, is reported as valid."
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
ellipse e1 0 0 0 200 100
|
||||||
|
mkedge ell1 e1
|
||||||
|
wire w1 ell1
|
||||||
|
plane p1
|
||||||
|
mkface fe1 p1 w1
|
||||||
|
revol rev1 fe1 0 0 0 1 0 0 180 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if { [isdraw rev1] != 1 } {
|
||||||
|
puts "OK: wrong shape is not created"
|
||||||
|
} else {
|
||||||
|
puts "Error: algorithm created wrong shape"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user