From bd18928c345d5acd6a4a4710a1587067a3b20a57 Mon Sep 17 00:00:00 2001 From: dpasukhi Date: Tue, 7 Mar 2023 13:28:47 +0000 Subject: [PATCH] 0033357: Data Exchange, Step Import - Fixing crash with corrupted edge_curve Added avoiding exception for the corrupted file. There can be generated invalid geometry --- .../StepToTopoDS_TranslateEdge.cxx | 41 +++- .../StepToTopoDS_TranslateEdgeLoop.cxx | 218 +++++++++++++----- 2 files changed, 200 insertions(+), 59 deletions(-) diff --git a/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx b/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx index cd34da906c..c0cccfd038 100644 --- a/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx +++ b/src/StepToTopoDS/StepToTopoDS_TranslateEdge.cxx @@ -161,8 +161,16 @@ static TopoDS_Edge MakeEdge TopoDS_Edge E; B.MakeEdge (E,C3D,Precision::Confusion()); B.Add (E,V1); B.Add (E,V2); - B.UpdateVertex(V1, U1, E, 0.); - B.UpdateVertex(V2, U2, E, 0.); + if (!Precision::IsPositiveInfinite(U1) && + !Precision::IsNegativeInfinite(U1)) + { + B.UpdateVertex(V1, U1, E, 0.); + } + if (!Precision::IsPositiveInfinite(U2) && + !Precision::IsNegativeInfinite(U2)) + { + B.UpdateVertex(V2, U2, E, 0.); + } return E; } @@ -308,11 +316,17 @@ void StepToTopoDS_TranslateEdge::Init(const Handle(StepShape_Edge)& aEdge, // --- * a 3D Curve // ---------------------------------------------------------- - if ( C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) { + if (C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) + { B.MakeEdge(E); -//:S4136 B.UpdateEdge (E,preci); - B.Add(E, V1); - B.Add(E, V2); + if (!V1.IsNull()) + { + B.Add(E, V1); + } + if (!V2.IsNull()) + { + B.Add(E, V2); + } } else if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve)) ) { // For SeamCurve and IntersectionCurve types @@ -385,6 +399,21 @@ void StepToTopoDS_TranslateEdge::MakeFromCurve3D myError = StepToTopoDS_TranslateEdgeOther; done = Standard_False; return; + } + BRep_Builder aBuilder; + if (V1.IsNull()) + { + TopoDS_Vertex aTmpVert; + const Standard_Real aFirst = C1->FirstParameter(); + aBuilder.MakeVertex(aTmpVert, C1->Value(aFirst), preci); + V1 = aTmpVert; + } + if (V2.IsNull()) + { + TopoDS_Vertex aTmpVert; + const Standard_Real aFirst = C1->LastParameter(); + aBuilder.MakeVertex(aTmpVert, C1->Value(aFirst), preci); + V2 = aTmpVert; } // -- Statistics -- -> No Warning message aTool.AddContinuity (C1); diff --git a/src/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx b/src/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx index 9de5910cf6..ff47e2fcd7 100644 --- a/src/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx +++ b/src/StepToTopoDS/StepToTopoDS_TranslateEdgeLoop.cxx @@ -22,6 +22,8 @@ // rln 02.06.99 removing #include // smh 31.01.01 BUC60810 : IsNull protection +#include + #include #include #include @@ -29,13 +31,15 @@ #include #include #include -#include -#include -#include +#include #include #include +#include #include #include #include +#include +#include +#include #include #include #include @@ -43,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -63,13 +68,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include @@ -86,6 +91,26 @@ #include #include +// ============================================================================ +// Method : MakeCurveFromStep +// Purpose : +// ============================================================================ +static Handle(Geom_Curve) MakeCurveFromStep (const Handle(StepGeom_Curve)& theStepCurve, + const Handle(Transfer_TransientProcess) theTP) +{ + Handle(Geom_Curve) aResCurve = Handle(Geom_Curve)::DownCast(theTP->FindTransient(theStepCurve)); + if (!aResCurve.IsNull()) + { + return aResCurve; + } + aResCurve = StepToGeom::MakeCurve(theStepCurve); + if (!aResCurve.IsNull()) + { + theTP->BindTransient(theStepCurve, aResCurve); + } + return aResCurve; +} + // ============================================================================ // Method : RemoveSinglePCurve // Purpose : @@ -232,21 +257,13 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac BRep_Builder B; Handle(Transfer_TransientProcess) TP = aTool.TransientProcess(); - Standard_Real preci = Precision(); + const Standard_Real preci = Precision(); TopoDS_Wire W; TopoDS_Edge E; - TopoDS_Vertex V; - - Standard_Boolean isSeam, isLikeSeam; - - Handle(StepShape_OrientedEdge) OrEdge1, OrEdge2; - Handle(StepGeom_Curve) StepCurve, StepCurve1, StepCurve2; - Handle(StepRepr_DefinitionalRepresentation) DRI, Dri1, Dri2; - Handle(Geom2d_Curve) C2d, C2d1, C2d2, WhichC2d1, WhichC2d2; - TopoDS_Edge suspectE; //:f1, degEdge; + Handle(Geom2d_Curve) C2d, C2d1, C2d2; - Standard_Integer j, NbEdge = EL->NbEdgeList(); + const Standard_Integer NbEdge = EL->NbEdgeList(); if (NbEdge == 0) { TP->AddWarning(EL, "Wire not done. EdgeLoop does not contain edges."); done = Standard_False; @@ -281,9 +298,8 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac // This case may not be processed, PCurves has to be recomputed from scratch // ----------------------------------------------- // Standard_Integer theSame = 1; //gka 15.12.98 - - for (j=1; j<=NbEdge; j++) { - OrEdge1 = EL->EdgeListValue(j); + for (Standard_Integer j=1; j<=NbEdge; j++) { + Handle(StepShape_OrientedEdge) OrEdge1 = EL->EdgeListValue(j); if (OrEdge1.IsNull() || OrEdge1->EdgeElement().IsNull()) { @@ -349,21 +365,38 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac StepToTopoDS_TranslateVertex myTranVertex1(Vstart, aTool, NMTool); StepToTopoDS_TranslateVertex myTranVertex2(Vend, aTool, NMTool); - if (myTranVertex1.IsDone()) { + if (myTranVertex1.IsDone()) + { V1 = TopoDS::Vertex(myTranVertex1.Value()); } - if (myTranVertex2.IsDone()) { + if (myTranVertex2.IsDone()) + { V2 = TopoDS::Vertex(myTranVertex2.Value()); - gp_Pnt p1 = BRep_Tool::Pnt(V1); - gp_Pnt p2 = BRep_Tool::Pnt(V2); - if (p1.Distance(p2) <= Precision::Confusion()) { //:S4136: preci) { - Standard_Boolean Fixed = Standard_True; - if (!iseV) aTool.Bind(Vend, V1); //gka 21.08.1998 bug PRO7656 - else if (!istV) aTool.Bind (Vstart, V2); - else aTool.Bind (Vend, V1); - if (!C1.IsNull() && !C1->IsClosed() && Fixed) + } + if (!V1.IsNull() && !V2.IsNull()) + { + gp_Pnt aPnt1 = BRep_Tool::Pnt(V1); + gp_Pnt aPnt2 = BRep_Tool::Pnt(V2); + if (aPnt1.Distance(aPnt2) <= Precision::Confusion()) + { + Standard_Boolean aIsFixed = Standard_True; + if (!iseV) + { + aTool.Bind(Vend, V1); + } + else if (!istV) + { + aTool.Bind(Vstart, V2); + } + else + { + aTool.Bind(Vend, V1); + } + if (!C1.IsNull() && !C1->IsClosed() && aIsFixed) + { TP->AddWarning(EL->EdgeListValue(j), - "Vertex of same coordinates, set confused"); + "Vertex of same coordinates, set confused"); + } } } } @@ -373,32 +406,111 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac // and make it be one vertex // NOTE: this is done only for the case if at least one of edges // was not yet translated; else nothing will help - for (j=1; j<=NbEdge; j++) { - OrEdge1 = EL->EdgeListValue (j); - OrEdge2 = EL->EdgeListValue (j < NbEdge ? j + 1 : 1); - if (OrEdge1.IsNull() || OrEdge2.IsNull()) + for (Standard_Integer anEdgeInd = 1; anEdgeInd <= NbEdge; anEdgeInd++) + { + Handle(StepShape_OrientedEdge) anOrEdge1 = + EL->EdgeListValue(anEdgeInd); + Handle(StepShape_OrientedEdge) anOrEdge2 = + EL->EdgeListValue(anEdgeInd < NbEdge ? anEdgeInd + 1 : 1); + if (anOrEdge1.IsNull() || anOrEdge2.IsNull()) continue; - Handle(StepShape_EdgeCurve) EC1 = - Handle(StepShape_EdgeCurve)::DownCast (OrEdge1->EdgeElement()); - Handle(StepShape_EdgeCurve) EC2 = - Handle(StepShape_EdgeCurve)::DownCast (OrEdge2->EdgeElement()); - if (EC1.IsNull() || EC2.IsNull()) // see #29979 + if (!anOrEdge1->EdgeElement().IsNull() && + anOrEdge1->EdgeElement()->IsKind(STANDARD_TYPE(StepShape_OrientedEdge))) + { + anOrEdge1 = Handle(StepShape_OrientedEdge)::DownCast(anOrEdge1->EdgeElement()); + } + if (!anOrEdge2->EdgeElement().IsNull() && + anOrEdge2->EdgeElement()->IsKind(STANDARD_TYPE(StepShape_OrientedEdge))) + { + anOrEdge2 = Handle(StepShape_OrientedEdge)::DownCast(anOrEdge2->EdgeElement()); + } + Handle(StepShape_EdgeCurve) aEC1 = + Handle(StepShape_EdgeCurve)::DownCast(anOrEdge1->EdgeElement()); + const Handle(StepShape_EdgeCurve) aEC2 = + Handle(StepShape_EdgeCurve)::DownCast(anOrEdge2->EdgeElement()); + if (aEC1.IsNull() || aEC2.IsNull()) // see #29979 { continue; } - Handle(StepShape_Vertex) Vs1, Vs2, Vs11, Vs22; - Vs1 = (OrEdge1->Orientation() ? EC1->EdgeEnd() : EC1->EdgeStart()); - Vs2 = (OrEdge2->Orientation() ? EC2->EdgeStart() : EC2->EdgeEnd()); - - Vs11 = (OrEdge1->Orientation() ? EC1->EdgeStart() : EC1->EdgeEnd()); - Vs22 = (OrEdge2->Orientation() ? EC2->EdgeEnd() : EC2->EdgeStart()); + Handle(StepShape_Vertex) aVs1 = anOrEdge1->Orientation() ? aEC1->EdgeEnd() : aEC1->EdgeStart(); + Handle(StepShape_Vertex) aVs2 = anOrEdge2->Orientation() ? aEC2->EdgeStart() : aEC2->EdgeEnd(); - if ((Vs1 == Vs2) || (Vs1 == Vs22) || (Vs2 == Vs11) || (Vs22 == Vs11)) continue; + Handle(StepShape_Vertex) aVs11 = anOrEdge1->Orientation() ? aEC1->EdgeStart() : aEC1->EdgeEnd(); + const Handle(StepShape_Vertex) aVs22 = anOrEdge2->Orientation() ? aEC2->EdgeEnd() : aEC2->EdgeStart(); - StepToTopoDS_TranslateVertex myTranVertex1 (Vs1, aTool, NMTool); - StepToTopoDS_TranslateVertex myTranVertex2 (Vs2, aTool, NMTool); + if (!aVs1.IsNull() && !aVs11.IsNull() && + ((aVs1 == aVs2) || (aVs1 == aVs22) || (aVs2 == aVs11) || (aVs22 == aVs11))) + { + continue; + } + if (aVs1.IsNull()) + { + if (aVs2.IsNull()) + { + Handle(Geom_Curve) aCurve; + const Handle(Geom_Curve) aCurveFirst = MakeCurveFromStep(aEC1->EdgeGeometry(), TP); + const Handle(Geom_Curve) aCurveSecond = MakeCurveFromStep(aEC2->EdgeGeometry(), TP); + Standard_Real aLast = Precision::Infinite(); + aCurve = aCurveFirst; + aLast = anOrEdge1->Orientation() ? aCurve->LastParameter() : aCurve->FirstParameter(); + if (Precision::IsPositiveInfinite(aLast) || + Precision::IsNegativeInfinite(aLast)) + { + aCurve = aCurveSecond; + aLast = anOrEdge2->Orientation() ? aCurve->FirstParameter() : aCurve->LastParameter(); + } + if (Precision::IsPositiveInfinite(aLast) || + Precision::IsNegativeInfinite(aLast)) + { + continue; + } + gp_Pnt aStartP = aCurve->Value(aLast); + GeomToStep_MakeCartesianPoint aMkPoint(aStartP); + const Handle(StepGeom_CartesianPoint) aGpms = aMkPoint.Value(); + const Handle(StepShape_VertexPoint) aVSP0 = + new StepShape_VertexPoint(); + const Handle(TCollection_HAsciiString) aName = + new TCollection_HAsciiString(""); + aVSP0->Init(aName, aGpms); + aVs2 = aVSP0; + } + if (!aVs2.IsNull()) + { + aVs1 = aVs2; + if (anOrEdge1->Orientation()) + { + aEC1->SetEdgeEnd(aVs1); + } + else + { + aEC1->SetEdgeStart(aVs1); + } + if (anOrEdge2->Orientation()) + { + aEC2->SetEdgeStart(aVs1); + } + else + { + aEC2->SetEdgeEnd(aVs1); + } + } + } + else if (aVs2.IsNull()) + { + aVs2 = aVs1; + if (anOrEdge2->Orientation()) + { + aEC2->SetEdgeStart(aVs1); + } + else + { + aEC2->SetEdgeEnd(aVs1); + } + } + StepToTopoDS_TranslateVertex myTranVertex1 (aVs1, aTool, NMTool); + StepToTopoDS_TranslateVertex myTranVertex2 (aVs2, aTool, NMTool); TopoDS_Vertex V1, V2; if (myTranVertex1.IsDone()) @@ -412,8 +524,8 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac gp_Pnt p2 = BRep_Tool::Pnt(V2); Standard_Boolean locFixed = Standard_True; if (p1.Distance(p2) <= preci) { - if (! aTool.IsBound (EC1)) aTool.Bind (Vs1, V2); - else if (! aTool.IsBound (EC2)) aTool.Bind (Vs2, V1); + if (! aTool.IsBound (aEC1)) aTool.Bind (aVs1, V2); + else if (! aTool.IsBound (aEC2)) aTool.Bind (aVs2, V1); else locFixed = Standard_False; } else locFixed = Standard_False; @@ -425,7 +537,7 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac // Iteration on each Oriented Edge of the EdgeLoop // ----------------------------------------------- - for (j=1; j<=NbEdge; j++) { + for (Standard_Integer j=1; j<=NbEdge; j++) { Standard_Boolean ThereIsLikeSeam = Standard_False; @@ -433,7 +545,7 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac std::cout << " Processing Edge :" << j << std::endl; #endif - OrEdge1 = EL->EdgeListValue(j); + Handle(StepShape_OrientedEdge) OrEdge1 = EL->EdgeListValue(j); if (OrEdge1.IsNull() || OrEdge1->EdgeElement().IsNull()) continue; @@ -470,7 +582,8 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac E.Orientation(TopAbs_FORWARD); else E.Orientation(TopAbs_REVERSED); - isSeam = isLikeSeam = Standard_False; + Standard_Boolean isSeam = Standard_False; + Standard_Boolean isLikeSeam = Standard_False; // ------------------------------------------ // Map the StepEdge parametric representation @@ -538,7 +651,6 @@ void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& Fac } if (isLikeSeam) { - suspectE = E; ThereIsLikeSeam = Standard_True; hasPcurve = Standard_True; } -- 2.39.5