From: skl Date: Wed, 18 Nov 2020 08:25:19 +0000 (+0300) Subject: 0028414: Data Exchange - Step entity not correctly read X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=88f4030f0529b339d964d492b4fc69e14f6486c7;p=occt-copy.git 0028414: Data Exchange - Step entity not correctly read Fix + test. For entity FACE_BOUND if surface is torus and orientation is True temporary natural bound is created. Later in the ShapeFix_Face this bound is removed but special flag myTorusReverseFlag is activated. Value of this flag is used for decision what part of torus must be used. --- diff --git a/src/ShapeFix/ShapeFix_Face.cxx b/src/ShapeFix/ShapeFix_Face.cxx index f0ad0e3ed1..614d918593 100644 --- a/src/ShapeFix/ShapeFix_Face.cxx +++ b/src/ShapeFix/ShapeFix_Face.cxx @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,7 @@ ShapeFix_Face::ShapeFix_Face() myFwd = Standard_True; myStatus = 0; myFixWire = new ShapeFix_Wire; + myTorusReverseFlag = Standard_True; ClearModes(); } @@ -147,6 +149,7 @@ ShapeFix_Face::ShapeFix_Face(const TopoDS_Face &face) myFwd = Standard_True; myStatus = 0; myFixWire = new ShapeFix_Wire; + myTorusReverseFlag = Standard_True; ClearModes(); Init( face ); } @@ -238,6 +241,7 @@ void ShapeFix_Face::Init (const Handle(ShapeAnalysis_Surface)& surf, { myStatus = 0; mySurf = surf; + myTorusReverseFlag = Standard_True; SetPrecision ( preci ); BRep_Builder B; B.MakeFace ( myFace, mySurf->Surface(), ::Precision::Confusion() ); @@ -255,8 +259,57 @@ void ShapeFix_Face::Init (const TopoDS_Face& face) { myStatus = 0; mySurf = new ShapeAnalysis_Surface ( BRep_Tool::Surface (face) ); + myTorusReverseFlag = Standard_True; myFwd = ( face.Orientation() != TopAbs_REVERSED ); myFace = face; + + if (mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) + { + // it is needed to check if face includes temporary created natural bound. + // this bound was created in order to detect cases where face has only one + // wire and this wire is outer. it means that if material is placed out of it + // this wire haven`t be reversed - for such face must be created correct + // natural bound and existed wire becames hole. + // temporary natural bound must be removed. + TopoDS_Wire outW; + Standard_Integer nbw = 0; + for (TopExp_Explorer exp(myFace, TopAbs_WIRE); exp.More(); exp.Next()) + { + nbw++; + TopoDS_Wire aW = TopoDS::Wire(exp.Current()); + TopExp_Explorer ex(aW, TopAbs_EDGE); + Bnd_Box2d aBox; + ShapeAnalysis_Edge sae; + ShapeAnalysis_Curve sac; + for (; ex.More(); ex.Next()) { + TopoDS_Edge edge = TopoDS::Edge(ex.Current()); + Handle(Geom2d_Curve) c2d; + Standard_Real f, l; + if (!sae.PCurve(edge, myFace, c2d, f, l, Standard_False)) continue; + sac.FillBndBox(c2d, f, l, 20, Standard_True, aBox); + } + if (aBox.IsVoid()) continue; + Standard_Real UMin, VMin, UMax, VMax; + aBox.Get(UMin, VMin, UMax, VMax); + Standard_Boolean hasOutW = + fabs(UMin) < Precision::PConfusion() && fabs(2 * M_PI - UMax) < Precision::PConfusion() && + fabs(VMin) < Precision::PConfusion() && fabs(2 * M_PI - VMax) < Precision::PConfusion(); + if (hasOutW) + { + // it is a temporary added natural bound + myTorusReverseFlag = Standard_False; + outW = aW; + } + } + if (nbw==2 && !myTorusReverseFlag) + { + // remove temporary added natural bound + BRep_Builder B; + myFace.Free(Standard_True); + B.Remove(myFace, outW); + } + } + myShape = myFace; // myFace = TopoDS::Face(face.EmptyCopied()); // for (TopoDS_Iterator ws (face,Standard_False); ws.More(); ws.Next()) @@ -1098,17 +1151,36 @@ Standard_Boolean ShapeFix_Face::FixOrientation(TopTools_DataMapOfShapeListOfShap TopoDS_Face af = TopoDS::Face ( dummy ); af.Orientation ( TopAbs_FORWARD ); B.Add (af,ws.Value(1)); - + if ((myFixAddNaturalBoundMode != 1 || !IsSurfaceUVPeriodic(mySurf->Adaptor3d())) && !ShapeAnalysis::IsOuterBound(af)) { - Handle(ShapeExtend_WireData) sbdw = - new ShapeExtend_WireData(TopoDS::Wire(ws.Value(1))); - sbdw->Reverse(myFace); - ws.SetValue(1, sbdw->Wire()); - SendWarning(sbdw->Wire(), Message_Msg("FixAdvFace.FixOrientation.MSG5"));// Wire on face was reversed - done = Standard_True; + Standard_Boolean needReverse = Standard_True; + if (mySurf->Surface()->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) + { + // detect situation when we have to use special flag for decision + // what part of torus must be used + Standard_Real SUF, SUL, SVF, SVL; + mySurf->Bounds(SUF, SUL, SVF, SVL); + Standard_Real aUmin, aUmax, aVmin, aVmax; + ShapeAnalysis::GetFaceUVBounds(myFace, aUmin, aUmax, aVmin, aVmax); + Standard_Boolean isInUmin = (aUmin > (SUF - Precision::PConfusion())) && (aUmin < (SUL + Precision::PConfusion())); + Standard_Boolean isInUmax = (aUmax > (SUF - Precision::PConfusion())) && (aUmax < (SUL + Precision::PConfusion())); + if ((isInUmin && !isInUmax) || (!isInUmin && isInUmax)) + { + needReverse = myTorusReverseFlag; + } + } + if (needReverse) + { + Handle(ShapeExtend_WireData) sbdw = + new ShapeExtend_WireData(TopoDS::Wire(ws.Value(1))); + sbdw->Reverse(myFace); + ws.SetValue(1, sbdw->Wire()); + SendWarning(sbdw->Wire(), Message_Msg("FixAdvFace.FixOrientation.MSG5"));// Wire on face was reversed + done = Standard_True; + } } } // in case of several wires, perform complex analysis diff --git a/src/ShapeFix/ShapeFix_Face.hxx b/src/ShapeFix/ShapeFix_Face.hxx index 9fc7d070a6..38e0541913 100644 --- a/src/ShapeFix/ShapeFix_Face.hxx +++ b/src/ShapeFix/ShapeFix_Face.hxx @@ -280,7 +280,9 @@ private: Standard_Integer myAutoCorrectPrecisionMode; Standard_Integer myFixPeriodicDegenerated; - + // flag for manage in special cases what part of torus must be used + // if face based on such surface has one wire + Standard_Boolean myTorusReverseFlag; }; diff --git a/src/StepToTopoDS/StepToTopoDS_TranslateFace.cxx b/src/StepToTopoDS/StepToTopoDS_TranslateFace.cxx index 8bf7a3ee4f..645d506f79 100644 --- a/src/StepToTopoDS/StepToTopoDS_TranslateFace.cxx +++ b/src/StepToTopoDS/StepToTopoDS_TranslateFace.cxx @@ -317,6 +317,26 @@ void StepToTopoDS_TranslateFace::Init //:S4136 if (EL->NbEdgeList() != 1) STF.Closed() = Standard_False; //:S4136 } + if (GeomSurf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) + { + if (NbBnd == 1 && !FaceBound->IsKind(STANDARD_TYPE(StepShape_FaceOuterBound)) && FaceBound->Orientation()) + { + // Create natural bound for face based on the toroidal surface + // in order to detect such cases in ShapeFix_Face + // We suggest that existed one boundary is outer and correct => if after + // future analysis we recieve that material out of it we have to create + // correct natural bound and existed wire becames hole. + // Later in the ShapeFix_Face this temporary bound will be removed but + // special flag will be activated. + BRepBuilderAPI_MakeFace mf(GeomSurf, Precision()); + for (TopoDS_Iterator it(mf); it.More(); it.Next()) + { + TopoDS_Wire aW = TopoDS::Wire(it.Value()); + B.Add(F, aW); + } + } + } + TopoDS_Wire W; myTranEdgeLoop.SetPrecision(Precision()); //gka myTranEdgeLoop.SetMaxTol(MaxTol()); diff --git a/tests/bugs/step/bug28414 b/tests/bugs/step/bug28414 new file mode 100644 index 0000000000..a68f4e9ce3 --- /dev/null +++ b/tests/bugs/step/bug28414 @@ -0,0 +1,18 @@ +puts "===================================================================" +puts "0028414: Data Exchange - Step entity not correctly read" +puts "===================================================================" +puts "" + +stepread [locate_data_file bug28414_bug_toroidal_surface.stp] a * + +checkshape a_1 f + +checkprops a_1 -s 3593.35 + +checkgravitycenter a_1 -s -30. 0. 137.993 0.001 + +vinit +vdisplay a_1 +vfit + +vdump $imagedir/${casename}.png