mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-09-07 05:08:13 +08:00
Modeling - Fix null surface crash in fixshape (#623)
- Added null surface validation in ShapeAnalysis_Surface constructor and Init method - Added null surface checks throughout ShapeFix_Face methods to prevent crashes - Enhanced robustness by validating surface availability before performing surface-dependent operations
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
#include <GeomAdaptor_Surface.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
@@ -56,6 +57,8 @@
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(ShapeAnalysis_Surface, Standard_Transient)
|
||||
|
||||
namespace
|
||||
@@ -105,18 +108,32 @@ ShapeAnalysis_Surface::ShapeAnalysis_Surface(const Handle(Geom_Surface)& S)
|
||||
myUCloseVal(-1),
|
||||
myVCloseVal(-1)
|
||||
{
|
||||
// Bug 33895: Prevent crash when surface is null
|
||||
if (mySurf.IsNull())
|
||||
{
|
||||
Message::SendWarning("ShapeAnalysis_Surface: Cannot create with null surface");
|
||||
assert(!mySurf.IsNull());
|
||||
return;
|
||||
}
|
||||
mySurf->Bounds(myUF, myUL, myVF, myVL);
|
||||
myAdSur = new GeomAdaptor_Surface(mySurf);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void ShapeAnalysis_Surface::Init(const Handle(Geom_Surface)& S)
|
||||
void ShapeAnalysis_Surface::Init(const Handle(Geom_Surface)& theSurface)
|
||||
{
|
||||
if (mySurf == S)
|
||||
if (mySurf == theSurface)
|
||||
return;
|
||||
// Bug 33895: Prevent crash when surface is null
|
||||
if (theSurface.IsNull())
|
||||
{
|
||||
Message::SendWarning("ShapeAnalysis_Surface: Cannot initialize with null surface");
|
||||
assert(!theSurface.IsNull());
|
||||
return;
|
||||
}
|
||||
myExtOK = Standard_False; //: 30
|
||||
mySurf = S;
|
||||
mySurf = theSurface;
|
||||
myNbDeg = -1;
|
||||
myUCloseVal = myVCloseVal = -1;
|
||||
myGap = 0.;
|
||||
|
||||
@@ -150,8 +150,16 @@ void ShapeAnalysis_Wire::Load(const Handle(ShapeExtend_WireData)& sbwd)
|
||||
void ShapeAnalysis_Wire::SetFace(const TopoDS_Face& face)
|
||||
{
|
||||
myFace = face;
|
||||
if (!face.IsNull())
|
||||
mySurf = new ShapeAnalysis_Surface(BRep_Tool::Surface(myFace));
|
||||
if (myFace.IsNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Handle(Geom_Surface) aSurface = BRep_Tool::Surface(myFace);
|
||||
if (!face.IsNull() && !aSurface.IsNull())
|
||||
{
|
||||
mySurf = new ShapeAnalysis_Surface(aSurface);
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -661,7 +669,6 @@ Standard_Boolean ShapeAnalysis_Wire::CheckSmall(const Standard_Integer num,
|
||||
if (!IsLoaded() || NbEdges() <= 1)
|
||||
return Standard_False;
|
||||
|
||||
// Standard_Integer n = ( num ? num : NbEdges() ); //szv#4:S4163:12Mar99 not needed
|
||||
TopoDS_Edge E = myWire->Edge(num ? num : NbEdges());
|
||||
ShapeAnalysis_Edge sae;
|
||||
|
||||
@@ -685,35 +692,35 @@ Standard_Boolean ShapeAnalysis_Wire::CheckSmall(const Standard_Integer num,
|
||||
gp_Pnt p2 = BRep_Tool::Pnt(V2);
|
||||
Standard_Real dist = p1.Distance(p2);
|
||||
Standard_Real prec = precsmall; // Min ( myPrecision, precsmall );
|
||||
// Standard_Real prec = Min(BRep_Tool::Tolerance(V1),BRep_Tool::Tolerance(V2)); //skl
|
||||
if (dist > prec)
|
||||
return Standard_False; // pas nulle
|
||||
return Standard_False; // not small enough
|
||||
|
||||
// La courbe 3D a present : est-elle FERMEE ou DE LONGUEUR NULLE ... ???
|
||||
// Pour cela on prend le point milieu (y a-t-il mieux)
|
||||
// Si pas de C3D, on essaie la C2D ...
|
||||
// The 3D curve now: is it CLOSED or ZERO LENGTH...???
|
||||
// To do this, we take the midpoint (is there anything better?)
|
||||
// If there's no 3D curve, we try 2D...
|
||||
|
||||
gp_Pnt Pm;
|
||||
gp_Pnt aMidpoint;
|
||||
Standard_Real cf, cl;
|
||||
Handle(Geom_Curve) c3d;
|
||||
if (sae.Curve3d(E, c3d, cf, cl, Standard_False))
|
||||
Pm = c3d->Value((cf + cl) / 2.);
|
||||
{
|
||||
aMidpoint = c3d->Value((cf + cl) / 2.);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(Geom2d_Curve) c2d;
|
||||
if (!myFace.IsNull() && sae.PCurve(E, myFace, c2d, cf, cl, Standard_False))
|
||||
if (!myFace.IsNull() && !mySurf.IsNull() && sae.PCurve(E, myFace, c2d, cf, cl, Standard_False))
|
||||
{
|
||||
gp_Pnt2d p2m = c2d->Value((cf + cl) / 2.);
|
||||
Pm = mySurf->Value(p2m);
|
||||
aMidpoint = mySurf->Value(p2m);
|
||||
}
|
||||
else
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
||||
Pm = p1;
|
||||
//: n2 return Standard_False;
|
||||
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
||||
aMidpoint = p1;
|
||||
}
|
||||
}
|
||||
if (Pm.Distance(p1) > prec || Pm.Distance(p2) > prec)
|
||||
if (aMidpoint.Distance(p1) > prec || aMidpoint.Distance(p2) > prec)
|
||||
return Standard_False;
|
||||
|
||||
myStatus |= ShapeExtend::EncodeStatus(V1.IsSame(V2) ? ShapeExtend_DONE1 : ShapeExtend_DONE2);
|
||||
@@ -820,8 +827,6 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated(const Standard_Integer num
|
||||
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL2);
|
||||
return Standard_False;
|
||||
}
|
||||
//: i8 if ( BRep_Tool::Degenerated ( E1 ) ||
|
||||
//: i8 BRep_Tool::Degenerated ( E2 ) ) return Standard_False; // deja OK
|
||||
|
||||
TopoDS_Vertex Vp = sae.FirstVertex(E1); //: i9
|
||||
TopoDS_Vertex V0 = sae.LastVertex(E1);
|
||||
@@ -906,7 +911,7 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated(const Standard_Integer num
|
||||
// rln S4135 if ( prec > myPrecision ) mySurf->ComputeSingularities ( myPrecision ); //:51
|
||||
}
|
||||
|
||||
// voila, on a soit dgnr soit lack
|
||||
// there you go, we either have degenerate or lack
|
||||
if (!lack && !dgnr)
|
||||
{
|
||||
//: abv 29.08.01: if singularity not detected but edge is marked
|
||||
@@ -932,8 +937,6 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated(const Standard_Integer num
|
||||
if (sae.PCurve(E1, myFace, c2d, a, b, Standard_True))
|
||||
{
|
||||
p2d1 = c2d->Value(b);
|
||||
// #84 rln gp_Pnt2d p2d = c2d->Value ( b );
|
||||
// #84 rln par1 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY();
|
||||
}
|
||||
else
|
||||
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
||||
@@ -941,19 +944,10 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated(const Standard_Integer num
|
||||
if (sae.PCurve((dgnr ? E3 : E2), myFace, c2d, a, b, Standard_True))
|
||||
{
|
||||
p2d2 = c2d->Value(a);
|
||||
// #84 rln gp_Pnt2d p2d = c2d->Value ( a );
|
||||
// #84 rln par2 = ( p2d.XY() - aP2d.XY() ) * theDir2d.XY();
|
||||
}
|
||||
else
|
||||
myStatus |= ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
||||
}
|
||||
/*
|
||||
if ( par2 < par1 ) {
|
||||
par1 = -par1;
|
||||
par2 = -par2;
|
||||
theDir2d.Reverse();
|
||||
}
|
||||
*/
|
||||
|
||||
// #84 rln 18.03.99 if pcurve is not degenerate anymore, the fix is postponned
|
||||
// to ShapeFix_Wire::FixLacking
|
||||
@@ -974,8 +968,6 @@ Standard_Boolean ShapeAnalysis_Wire::CheckDegenerated(const Standard_Integer num
|
||||
if (p2d1.Distance(p2d2) /*Abs (par1 - par2)*/ <= max + gp::Resolution())
|
||||
return Standard_False;
|
||||
|
||||
// #84 rln p2d1 = aP2d.XY() + par1 * theDir2d.XY();
|
||||
// #84 rln p2d2 = aP2d.XY() + par2 * theDir2d.XY();
|
||||
myStatus = ShapeExtend::EncodeStatus(dgnr ? ShapeExtend_DONE2 : ShapeExtend_DONE1);
|
||||
return Standard_True;
|
||||
}
|
||||
@@ -1020,6 +1012,12 @@ Standard_Boolean ShapeAnalysis_Wire::CheckGap3d(const Standard_Integer num)
|
||||
|
||||
Standard_Boolean ShapeAnalysis_Wire::CheckGap2d(const Standard_Integer num)
|
||||
{
|
||||
if (myFace.IsNull() || mySurf.IsNull())
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_FAIL1);
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
myStatus = ShapeExtend::EncodeStatus(ShapeExtend_OK);
|
||||
// szv#4:S4163:12Mar99 optimized
|
||||
if (!IsReady() || NbEdges() < 1)
|
||||
|
||||
+39
-167
@@ -89,10 +89,6 @@
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_Face, ShapeFix_Root)
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
#define DEBUG
|
||||
#endif
|
||||
|
||||
static Standard_Boolean IsSurfaceUVInfinite(const Handle(Geom_Surface)& theSurf)
|
||||
{
|
||||
Standard_Real UMin, UMax, VMin, VMax;
|
||||
@@ -208,16 +204,18 @@ void ShapeFix_Face::Init(const Handle(ShapeAnalysis_Surface)& surf,
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
void ShapeFix_Face::Init(const TopoDS_Face& face)
|
||||
void ShapeFix_Face::Init(const TopoDS_Face& theFace)
|
||||
{
|
||||
myStatus = 0;
|
||||
mySurf = new ShapeAnalysis_Surface(BRep_Tool::Surface(face));
|
||||
myFwd = (face.Orientation() != TopAbs_REVERSED);
|
||||
myFace = face;
|
||||
myShape = myFace;
|
||||
// myFace = TopoDS::Face(face.EmptyCopied());
|
||||
// for (TopoDS_Iterator ws (face,Standard_False); ws.More(); ws.Next())
|
||||
// Add (TopoDS::Wire (ws.Value()) );
|
||||
// Check if surface is null. It doesn't make sense to create ShapeAnalysis_Surface in that case.
|
||||
const Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace);
|
||||
if (!aSurface.IsNull())
|
||||
{
|
||||
mySurf = new ShapeAnalysis_Surface(aSurface);
|
||||
}
|
||||
myFwd = (theFace.Orientation() != TopAbs_REVERSED);
|
||||
myFace = theFace;
|
||||
myShape = myFace;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -314,13 +312,6 @@ static Standard_Boolean SplitWire(const TopoDS_Face& face,
|
||||
break;
|
||||
}
|
||||
|
||||
if (aResWires.Length() > 1)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Wire was split on " << aResWires.Length() << " wires" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
@@ -363,34 +354,6 @@ Standard_Boolean ShapeFix_Face::Perform()
|
||||
TopoDS_Face tmpFace = TopoDS::Face(emptyCopied);
|
||||
tmpFace.Orientation(TopAbs_FORWARD);
|
||||
|
||||
/*
|
||||
// skl 14.05.2002 OCC55 + corrected 03.03.2004
|
||||
Standard_Real dPreci = aSavPreci*aSavPreci;
|
||||
dPreci*=4;
|
||||
Standard_Real newpreci=dPreci;
|
||||
for(TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
TopoDS_Edge edge = TopoDS::Edge ( exp.Current() );
|
||||
Standard_Real first,last;
|
||||
Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, first, last);
|
||||
if(!c3d.IsNull()) {
|
||||
Bnd_Box bb;
|
||||
bb.Add(c3d->Value(first));
|
||||
bb.Add(c3d->Value(last));
|
||||
bb.Add(c3d->Value((last+first)/2.));
|
||||
Standard_Real x1,x2,y1,y2,z1,z2,size;
|
||||
bb.Get(x1,y1,z1,x2,y2,z2);
|
||||
size = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
|
||||
if(size<newpreci) newpreci=size;
|
||||
}
|
||||
}
|
||||
newpreci=sqrt(newpreci)/2.*1.00001;
|
||||
if( aSavPreci > newpreci && newpreci > Precision::Confusion()) {
|
||||
SetPrecision(newpreci);
|
||||
theAdvFixWire->SetPrecision(newpreci);
|
||||
}
|
||||
// end skl 14.05.2002
|
||||
*/
|
||||
|
||||
// skl 29.03.2010 (OCC21623)
|
||||
if (myAutoCorrectPrecisionMode)
|
||||
{
|
||||
@@ -453,22 +416,17 @@ Standard_Boolean ShapeFix_Face::Perform()
|
||||
wire = w;
|
||||
}
|
||||
B.Add(tmpFace, wire);
|
||||
// if ( theAdvFixWire->Status ( ShapeExtend_FAIL ) )
|
||||
// myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
|
||||
}
|
||||
|
||||
theAdvFixWire->FixLackingMode() = usFixLackingMode;
|
||||
// theAdvFixWire->FixNotchedEdgesMode() = usFixNotchedEdgesMode; // CR0024983
|
||||
theAdvFixWire->FixLackingMode() = usFixLackingMode;
|
||||
theAdvFixWire->FixSelfIntersectionMode() = usFixSelfIntersectionMode;
|
||||
if (!myFwd)
|
||||
tmpFace.Orientation(TopAbs_REVERSED);
|
||||
|
||||
if (fixed)
|
||||
{
|
||||
// if ( ! myFwd ) tmpFace.Orientation ( TopAbs_REVERSED );
|
||||
if (!Context().IsNull())
|
||||
Context()->Replace(S, tmpFace);
|
||||
// myFace = tmpFace;
|
||||
isReplaced = Standard_True;
|
||||
}
|
||||
if (fixed || isfixReorder)
|
||||
@@ -738,7 +696,7 @@ Standard_Boolean ShapeFix_Face::Perform()
|
||||
static void Shift2dWire(const TopoDS_Wire& w,
|
||||
const TopoDS_Face& f,
|
||||
const gp_Vec2d vec,
|
||||
const Handle(ShapeAnalysis_Surface)& mySurf,
|
||||
const Handle(ShapeAnalysis_Surface)& theSurface,
|
||||
Standard_Boolean recompute3d = Standard_False)
|
||||
{
|
||||
gp_Trsf2d tr2d;
|
||||
@@ -759,7 +717,7 @@ static void Shift2dWire(const TopoDS_Wire& w,
|
||||
// recompute 3d curve and vertex
|
||||
sbe.RemoveCurve3d(edge);
|
||||
sbe.BuildCurve3d(edge);
|
||||
B.UpdateVertex(sae.FirstVertex(edge), mySurf->Value(C2d->Value(cf)), 0.);
|
||||
B.UpdateVertex(sae.FirstVertex(edge), theSurface->Value(C2d->Value(cf)), 0.);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -827,6 +785,11 @@ static Standard_Real FindBestInterval(TColgp_SequenceOfPnt2d& intervals)
|
||||
|
||||
Standard_Boolean ShapeFix_Face::FixAddNaturalBound()
|
||||
{
|
||||
if (mySurf.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (!Context().IsNull())
|
||||
{
|
||||
TopoDS_Shape S = Context()->Apply(myFace);
|
||||
@@ -898,10 +861,7 @@ Standard_Boolean ShapeFix_Face::FixAddNaturalBound()
|
||||
{
|
||||
Standard_Real Umin, Vmin, Umax, Vmax;
|
||||
// Bnd_Box2d B;
|
||||
TopoDS_Wire aw = TopoDS::Wire(ws.Value(i));
|
||||
// PTV 01.11.2002 ACIS907, OCC921 begin
|
||||
// BRepTools::AddUVBounds(myFace,aw,B);
|
||||
// B.Get(Umin, Vmin, Umax, Vmax);
|
||||
TopoDS_Wire aw = TopoDS::Wire(ws.Value(i));
|
||||
TopoDS_Face aWireFace = TopoDS::Face(myFace.EmptyCopied());
|
||||
BRep_Builder aB;
|
||||
aB.Add(aWireFace, aw);
|
||||
@@ -936,33 +896,6 @@ Standard_Boolean ShapeFix_Face::FixAddNaturalBound()
|
||||
}
|
||||
|
||||
// Create naturally bounded surface and add that wire to sequence
|
||||
/* variant 1
|
||||
// Create fictive grid and call ComposeShell
|
||||
Handle(Geom_RectangularTrimmedSurface) RTS =
|
||||
new Geom_RectangularTrimmedSurface ( mySurf->Surface(), SUF+shift.X(), SUL+shift.X(),
|
||||
SVF+shift.Y(), SVL+shift.Y() );
|
||||
Handle(TColGeom_HArray2OfSurface) grid = new TColGeom_HArray2OfSurface ( 1, 1, 1, 1 );
|
||||
grid->SetValue ( 1, 1, RTS );
|
||||
Handle(ShapeExtend_CompositeSurface) G = new ShapeExtend_CompositeSurface ( grid );
|
||||
TopLoc_Location L;
|
||||
|
||||
ShapeFix_ComposeShell CompShell;
|
||||
CompShell.Init ( G, L, myFace, ::Precision::Confusion() );
|
||||
CompShell.ClosedMode() = Standard_True;
|
||||
CompShell.NaturalBoundMode() = Standard_True;
|
||||
CompShell.SetContext( Context() );
|
||||
CompShell.SetMaxTolerance(MaxTolerance());
|
||||
CompShell.Perform();
|
||||
TopoDS_Shape res = CompShell.Result();
|
||||
|
||||
Context()->Replace ( myFace, res );
|
||||
for (TopExp_Explorer exp ( res, TopAbs_FACE ); exp.More(); exp.Next() ) {
|
||||
myFace = TopoDS::Face ( exp.Current() );
|
||||
BRepTools::Update(myFace); //:p4
|
||||
}
|
||||
myResult = Context()->Apply ( myResult );
|
||||
*/
|
||||
/* variant 2 */
|
||||
TopLoc_Location L;
|
||||
Handle(Geom_Surface) surf = BRep_Tool::Surface(myFace, L);
|
||||
BRepBuilderAPI_MakeFace mf(surf, Precision::Confusion());
|
||||
@@ -1039,10 +972,6 @@ Standard_Boolean ShapeFix_Face::FixAddNaturalBound()
|
||||
myFace = TopoDS::Face(S);
|
||||
BRepTools::Update(myFace);
|
||||
|
||||
/**/
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Natural bound on sphere or torus with holes added" << std::endl; // mise au point !
|
||||
#endif
|
||||
// clang-format off
|
||||
SendWarning ( myFace, Message_Msg ( "FixAdvFace.FixOrientation.MSG0" ) );// Face created with natural bounds
|
||||
// clang-format on
|
||||
@@ -1069,7 +998,7 @@ Standard_Boolean ShapeFix_Face::isNeedAddNaturalBound(
|
||||
return Standard_False;
|
||||
}
|
||||
// if surface is not double-closed
|
||||
if (!IsSurfaceUVPeriodic(mySurf->Adaptor3d()))
|
||||
if (mySurf && !IsSurfaceUVPeriodic(mySurf->Adaptor3d()))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -1204,23 +1133,18 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
|
||||
}
|
||||
}
|
||||
// in case of several wires, perform complex analysis
|
||||
// ATTENTION ESSAI
|
||||
// Plusieurs wires : orientations relatives
|
||||
// Chaque wire doit "contenir" tous les autres
|
||||
// Evidemment, en cas de peau de leopard, il peut y avoir probleme
|
||||
else
|
||||
// TEST CAUTION
|
||||
// Multiple wires: relative orientations
|
||||
// Each wire must "contain" all the others
|
||||
// Obviously, in the case of leopard skin, there may be a problem
|
||||
else if (!mySurf.IsNull())
|
||||
{
|
||||
// On prend chaque wire (NB: pcurves presentes !)
|
||||
// En principe on devrait rejeter les wires non fermes (cf couture manque ?)
|
||||
// On le classe par rapport aux autres, qui doivent tous etre, soit IN soit
|
||||
// OUT. Sinon il y a imbrication -> SDB. Si IN, OK, si OUT on inverse
|
||||
// (nb : ici pas myClos donc pas de pb de couture)
|
||||
// Si au moins une inversion, il faut refaire la face (cf myRebil)
|
||||
|
||||
//: 94 abv 30 Jan 98: calculate parametric precision
|
||||
|
||||
// GeomAdaptor_Surface& Ads = mySurf->Adaptor3d()->ChangeSurface();
|
||||
// Standard_Real toluv = Min ( Ads.UResolution(Precision()), Ads.VResolution(Precision()) );
|
||||
// Take each wire (NB: curves present!)
|
||||
// In principle, we should reject unclosed wires (see missing seam?)
|
||||
// We classify it relative to the others, which must all be either IN or
|
||||
// OUT. Otherwise, there is nesting -> SDB. If IN, OK, if OUT, we reverse
|
||||
// (NB: not myClos here, so no stitching problem)
|
||||
// If there is at least one inversion, the face must be redone (see myRebil)
|
||||
Standard_Boolean uclosed = mySurf->IsUClosed();
|
||||
Standard_Boolean vclosed = mySurf->IsVClosed();
|
||||
Standard_Real SUF, SUL, SVF, SVL;
|
||||
@@ -1295,7 +1219,6 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
|
||||
Bnd_Box2d aBox1 = aWireBoxes.Value(i);
|
||||
TopoDS_Shape dummy = myFace.EmptyCopied();
|
||||
TopoDS_Face af = TopoDS::Face(dummy);
|
||||
// B.MakeFace (af,mySurf->Surface(),::Precision::Confusion());
|
||||
af.Orientation(TopAbs_FORWARD);
|
||||
B.Add(af, aw);
|
||||
// PTV OCC945 06.11.2002 files ie_exhaust-A.stp (entities 3782, 3787)
|
||||
@@ -1519,7 +1442,7 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
|
||||
if (isAddNaturalBounds && nb == aSeqReversed.Length())
|
||||
done = Standard_False;
|
||||
|
||||
// Faut-il reconstruire ? si myRebil est mis
|
||||
// Should I rebuild? if myRebil is set
|
||||
if (done)
|
||||
{
|
||||
TopoDS_Shape S = myFace.EmptyCopied();
|
||||
@@ -1545,15 +1468,6 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap
|
||||
Context()->Replace(myFace, S);
|
||||
myFace = TopoDS::Face(S);
|
||||
BRepTools::Update(myFace);
|
||||
Standard_Integer k = 1;
|
||||
for (; k <= aSeqReversed.Length(); k++)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
// clang-format off
|
||||
std::cout<<"Wire no "<<aSeqReversed.Value(k)<<" of "<<nb<<" reversed"<<std::endl; // mise au point !
|
||||
// clang-format on
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return done;
|
||||
}
|
||||
@@ -1632,6 +1546,11 @@ static Standard_Boolean CheckWire(const TopoDS_Wire& wire,
|
||||
|
||||
Standard_Boolean ShapeFix_Face::FixMissingSeam()
|
||||
{
|
||||
if (mySurf.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Boolean uclosed = mySurf->IsUClosed();
|
||||
Standard_Boolean vclosed = mySurf->IsVClosed();
|
||||
|
||||
@@ -1745,25 +1664,12 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
|
||||
else
|
||||
{
|
||||
w2.Reverse();
|
||||
#ifdef OCCT_DEBUG
|
||||
if (!isdeg2)
|
||||
std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): wire reversed" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else
|
||||
std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): incompatible open wires"
|
||||
<< std::endl;
|
||||
#endif
|
||||
}
|
||||
// else return Standard_False; // abort
|
||||
else
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): more than two open wires detected!"
|
||||
<< std::endl;
|
||||
#endif
|
||||
//: abv 30.08.09: if more than one open wires and more than two of them are
|
||||
// completely degenerated, remove any of them
|
||||
if (isdeg || isdeg1 || isdeg2)
|
||||
@@ -1772,10 +1678,6 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
|
||||
w1.Nullify();
|
||||
w2.Nullify();
|
||||
i = 0;
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Warning: ShapeFix_Face::FixMissingSeam(): open degenerated wire removed"
|
||||
<< std::endl;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2093,8 +1995,6 @@ Standard_Boolean ShapeFix_Face::FixMissingSeam()
|
||||
B.Add(tmpF, aSeqNonManif.Value(j));
|
||||
|
||||
ShapeFix_ComposeShell CompShell;
|
||||
// TopoDS_Face tmpF = myFace;
|
||||
// tmpF.Orientation(TopAbs_FORWARD);
|
||||
CompShell.Init(G, L, tmpF, ::Precision::Confusion()); // myPrecision
|
||||
if (Context().IsNull())
|
||||
SetContext(new ShapeBuild_ReShape);
|
||||
@@ -2210,19 +2110,11 @@ Standard_Boolean ShapeFix_Face::FixSmallAreaWire(const Standard_Boolean theIsRem
|
||||
|
||||
if (nbWires <= 0)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Warning: ShapeFix_Face: All wires on a face have small area; left untouched"
|
||||
<< std::endl;
|
||||
#endif
|
||||
if (theIsRemoveSmallFace && !Context().IsNull())
|
||||
Context()->Remove(myFace);
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Warning: ShapeFix_Face: " << nbRemoved << " small area wire(s) removed"
|
||||
<< std::endl;
|
||||
#endif
|
||||
aFace.Orientation(myFace.Orientation());
|
||||
if (!Context().IsNull())
|
||||
Context()->Replace(myFace, aFace);
|
||||
@@ -2439,7 +2331,7 @@ Standard_Boolean ShapeFix_Face::FixLoopWire(TopTools_SequenceOfShape& aResWires)
|
||||
Standard_Boolean isClosed = Standard_True;
|
||||
|
||||
// checking that obtained wires is closed in 2D space
|
||||
if (mySurf->Adaptor3d()->GetType() != GeomAbs_Plane)
|
||||
if (mySurf && mySurf->Adaptor3d()->GetType() != GeomAbs_Plane)
|
||||
{
|
||||
|
||||
TopoDS_Shape emptyCopied = myFace.EmptyCopied();
|
||||
@@ -2453,15 +2345,7 @@ Standard_Boolean ShapeFix_Face::FixLoopWire(TopTools_SequenceOfShape& aResWires)
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean isDone = (aResWires.Length() && isClosed);
|
||||
if (isDone && aResWires.Length() > 1)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "Wire was split on " << aResWires.Length() << " wires" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return isDone;
|
||||
return !aResWires.IsEmpty() && isClosed;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -2490,15 +2374,6 @@ Standard_Boolean ShapeFix_Face::SplitEdge(const Handle(ShapeExtend_WireData)& se
|
||||
BRepTools::Update(E);
|
||||
}
|
||||
|
||||
// for ( Standard_Integer i=1; i <= sewd->NbEdges(); i++ ) {
|
||||
// TopoDS_Edge E = sewd->Edge(i);
|
||||
// TopoDS_Shape S = Context()->Apply ( E );
|
||||
// if ( S == E ) continue;
|
||||
// for ( TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next() )
|
||||
// sewd->Add ( exp.Current(), i++ );
|
||||
// sewd->Remove ( i-- );
|
||||
// }
|
||||
|
||||
// change sewd and boxes
|
||||
sewd->Set(newE1, num);
|
||||
if (num == sewd->NbEdges())
|
||||
@@ -2740,9 +2615,6 @@ Standard_Boolean ShapeFix_Face::FixSplitFace(const TopTools_DataMapOfShapeListOf
|
||||
V2 = sae.LastVertex(E2);
|
||||
if (!V1.IsSame(V2))
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
std::cout << "wire not closed --> stop split" << std::endl;
|
||||
#endif
|
||||
return Standard_False;
|
||||
}
|
||||
// create face
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
puts "========================================================================"
|
||||
puts "Bug 33895: fixshape crashes on tessellated geometry without surfaces"
|
||||
puts "No crash expected"
|
||||
puts "========================================================================"
|
||||
|
||||
pload XDE MODELING
|
||||
|
||||
stepread [locate_data_file gh623_tessellated_tetrahedron_ap242.step] anInputShape *
|
||||
|
||||
# Check what kind of shape we get
|
||||
checknbshapes anInputShape_1 -t
|
||||
|
||||
# Validate shape - will show BRepCheck_NoSurface errors
|
||||
puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_6"
|
||||
checkshape anInputShape_1
|
||||
|
||||
# Fix shapes. No crash expected.
|
||||
fixshape aFixed anInputShape_1
|
||||
|
||||
# Check result.
|
||||
checknbshapes aFixed -face 4 -shell 4 -compound 1 -shape 9 -t
|
||||
Reference in New Issue
Block a user