0031301: Data Exchange - Export to STEP corrupts the shape IR-2020-03-20
authorgka <gka@opencascade.com>
Thu, 27 Feb 2020 12:26:42 +0000 (15:26 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 20 Mar 2020 07:24:10 +0000 (10:24 +0300)
For small edges fully covered by tolerances of vertices BSpline periodic curves are converted to not periodic BSpline curves by cutting segment before writing.
In the class TopoDSToStep_MakeStepEdge permute of edge vertices for closed curves was added for the case when the range obtained from the vertex projection contradicts the edge range in order to avoid computation of the invalid edge range after reading.

Second test script for bug 0031301

src/GeomToStep/GeomToStep_MakeCurve.cxx
src/TopoDSToStep/TopoDSToStep_MakeStepEdge.cxx
tests/bugs/step/bug31301_2 [new file with mode: 0644]
tests/de/step_4/D9
tests/de/step_4/E1
tests/de/step_4/H1
tests/de/step_5/A1

index 50275c4..6dfee4c 100644 (file)
@@ -42,6 +42,7 @@
 #include <StepGeom_Conic.hxx>
 #include <StepGeom_Curve.hxx>
 #include <StepGeom_Line.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
 
 //=============================================================================
 // Creation d' une Curve de prostep a partir d' une Curve de Geom
@@ -162,6 +163,10 @@ GeomToStep_MakeCurve::GeomToStep_MakeCurve ( const Handle(Geom2d_Curve)& C)
     GeomToStep_MakeBoundedCurve MkBoundedC(L);
     theCurve = MkBoundedC.Value();
   }
+  else if (C->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
+    GeomToStep_MakeCurve aMaker = (Handle(Geom2d_TrimmedCurve)::DownCast(C)->BasisCurve());
+    theCurve = aMaker.Value();
+  }
   else
     done = Standard_False;
 } 
index 75aa71b..3f4b415 100644 (file)
@@ -53,6 +53,8 @@
 #include <Transfer_FinderProcess.hxx>
 #include <TransferBRep.hxx>
 #include <TransferBRep_ShapeMapper.hxx>
+#include <BRepTools.hxx>
+#include <ShapeAnalysis_Curve.hxx>
 
 // Processing of non-manifold topology (ssv; 11.11.2010)
 // ----------------------------------------------------------------------------
@@ -185,6 +187,64 @@ void TopoDSToStep_MakeStepEdge::Init(const TopoDS_Edge& aEdge,
   Handle(Geom_Curve) C = CA.Curve().Curve();
   if (!C.IsNull()) {
     C = Handle(Geom_Curve)::DownCast(C->Copy());
+
+    // Special treatment is needed for very short edges based on periodic curves.
+    // Since edge in STEP does not store its parametric range, parameters are computed
+    // on import by projecting vertices on a curve, and for periodic curve this may 
+    // lead to use of wrong part of the curve if end vertices are too close to each other
+    // (often whole curve is taken instead of its very small fragment).
+    if (C->IsPeriodic())
+    {
+      Standard_Real dpar = CA.LastParameter() - CA.FirstParameter();
+      if (dpar <= 0)
+      {
+        dpar += (ceil(fabs(dpar) / C->Period()) * C->Period());
+      }
+
+      // if range obtained from projection of vertices contradicts with range
+      // of the edge tnen vertices are swapped to keep results correct after import
+      // (see test de step_5 A1)
+      gp_Pnt aP1 = BRep_Tool::Pnt(Vfirst);
+      gp_Pnt aP2 = BRep_Tool::Pnt(Vlast);
+      gp_Pnt  pproj;
+      ShapeAnalysis_Curve sac;
+      sac.Project (C, aP1, Tolerance(), pproj, U1, Standard_False);
+      sac.Project (C, aP2, Tolerance(), pproj, U2, Standard_False);
+      Standard_Real dU = U2 - U1;
+      if (dU <= 0)
+      {
+        dU += (ceil(fabs(dU) / C->Period()) * C->Period());
+      }
+      if ((dU  > Precision::PConfusion() &&  dU <= 0.1 * C->Period() && dpar > 0.5 * C->Period()) ||
+          (dpar  > Precision::PConfusion() && dpar <= 0.1 * C->Period() && dU > 0.5 * C->Period()))
+      {
+        std::swap (V1, V2);
+      }
+
+      // If vertices overlap, we cut only needed part of the BSpline curve.
+      // Note that this method cannot be used for canonic curves 
+      // (STEP does not support trimmed curves in AIC 514).
+      if (C->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
+      {
+        Standard_Real aTolV1 = BRep_Tool::Tolerance(Vfirst);
+        Standard_Real aTolV2 = BRep_Tool::Tolerance(Vlast);
+        gp_Pnt aP11 = CA.Value(CA.FirstParameter());
+        gp_Pnt aP12 = CA.Value(CA.LastParameter());
+        gp_Pnt aPm = CA.Value((CA.FirstParameter() + CA.LastParameter()) * 0.5);
+        Standard_Real aDist11 = aP11.Distance(aP12);
+        Standard_Real aDist1m = aP11.Distance(aPm);
+        Standard_Real aDist2m = aP12.Distance(aPm);
+        Standard_Real aDistMax = Max(Max(aDist1m, aDist2m), aDist11);
+        Standard_Boolean isSmallCurve = (aDistMax <= aTolV1 || aDistMax <= aTolV2);
+        if (BRepTools::Compare(Vfirst, Vlast) && isSmallCurve  && dpar > Precision::PConfusion() && dpar <= 0.1 * C->Period())
+        {
+          Handle(Geom_BSplineCurve) aBspl1 = Handle(Geom_BSplineCurve)::DownCast(C->Copy());
+          aBspl1->Segment(CA.FirstParameter(), CA.LastParameter());
+          C = aBspl1;
+        }
+      }
+    }
+
     gp_Trsf Tr1 = CA.Trsf();
     C->Transform(Tr1);
     GeomToStep_MakeCurve MkCurve(C);
diff --git a/tests/bugs/step/bug31301_2 b/tests/bugs/step/bug31301_2
new file mode 100644 (file)
index 0000000..df99f05
--- /dev/null
@@ -0,0 +1,5 @@
+restore  [locate_data_file bug31301_2.brep] s
+testwritestep bug31301_1.stp s
+testreadstep bug31301_1.stp s1
+checkshape s1 f
+checkmaxtol s1 -ref 0.000247
\ No newline at end of file
index 8bc1f9c..ed1996d 100644 (file)
@@ -6,11 +6,11 @@ set filename test-m020306-v1.stp
 
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 153  ( 114 )  Summary  = 153  ( 114 )
+TPSTAT      : Faulties = 1  ( 0 )  Warnings = 153  ( 114 )  Summary  = 154  ( 114 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 742  ( 742 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 742  ( 742 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.008481946718  (  0.01167623167 )  AvgTol   =  0.000132472064  (  0.0003097606769 )
+TOLERANCE   : MaxTol   = 0.008481946718  (  0.01167623167 )  AvgTol   =  0.0001322682241  (  0.0003097606769 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index fc7ab98..edcdbdd 100644 (file)
@@ -3,11 +3,11 @@ set filename test-m020306-v2.stp
 
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 61  ( 157 )  Summary  = 61  ( 157 )
+TPSTAT      : Faulties = 1  ( 0 )  Warnings = 63  ( 157 )  Summary  = 64  ( 157 )
 CHECKSHAPE  : Wires    = 0  ( 0 )  Faces    = 0  ( 0 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 956  ( 956 ) 
 STATSHAPE   : Solid    = 1  ( 1 )  Shell    = 1  ( 1 )  Face     = 956  ( 956 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   = 0.008481946718  (  0.05394823207 )  AvgTol   =  0.0001239210367  (  0.0004089750747 )
+TOLERANCE   : MaxTol   = 0.008481946718  (  0.01167623167 )  AvgTol   =  0.000123986292  (  0.0003770309367 )
 LABELS      : N0Labels = 1  ( 1 )  N1Labels = 0  ( 0 )  N2Labels = 0  ( 0 )   TotalLabels = 1  ( 1 )   NameLabels = 1  ( 1 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )
index 054ddf9..1dcbea7 100644 (file)
@@ -1,13 +1,16 @@
 # !!!! This file is generated automatically, do not edit manually! See end script
+puts "TODO CR23096 ALL: TPSTAT : Faulty" 
+
+
 set filename Inventor_Engine.stp
 
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 456  ( 560 )  Summary  = 456  ( 560 )
+TPSTAT      : Faulties = 1  ( 0 )  Warnings = 455  ( 560 )  Summary  = 456  ( 560 )
 CHECKSHAPE  : Wires    = 6  ( 6 )  Faces    = 6  ( 6 )  Shells   = 0  ( 0 )   Solids   = 0 ( 0 )
 NBSHAPES    : Solid    = 47  ( 47 )  Shell    = 47  ( 47 )  Face     = 4454  ( 4454 ) 
 STATSHAPE   : Solid    = 80  ( 80 )  Shell    = 80  ( 80 )  Face     = 5356  ( 5356 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =     2.37122237  (    2.449305641 )  AvgTol   =  0.002570949956  (  0.002589629313 )
+TOLERANCE   : MaxTol   =    2.371238233  (    2.449305641 )  AvgTol   =  0.001672277308  (  0.002589629313 )
 LABELS      : N0Labels = 52  ( 52 )  N1Labels = 86  ( 86 )  N2Labels = 0  ( 0 )   TotalLabels = 138  ( 138 )   NameLabels = 136  ( 136 )   ColorLabels = 47  ( 47 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 11  ( 11 )
index 9074ec2..0b490cc 100755 (executable)
@@ -7,11 +7,11 @@ set filename Z8INV5.stp
 
 set ref_data {
 DATA        : Faulties = 0  ( 0 )  Warnings = 0  ( 0 )  Summary  = 0  ( 0 )
-TPSTAT      : Faulties = 0  ( 0 )  Warnings = 120  ( 620 )  Summary  = 120  ( 620 )
-CHECKSHAPE  : Wires    = 15  ( 16 )  Faces    = 17  ( 18 )  Shells   = 1  ( 1 )   Solids   = 0 ( 0 )
-NBSHAPES    : Solid    = 22  ( 22 )  Shell    = 25  ( 24 )  Face     = 1520  ( 1519 ) 
-STATSHAPE   : Solid    = 22  ( 22 )  Shell    = 25  ( 24 )  Face     = 1520  ( 1519 )   FreeWire = 0  ( 0 ) 
-TOLERANCE   : MaxTol   =    7.499684301  (    7.499684301 )  AvgTol   =   0.03452373473  (   0.03544461059 )
+TPSTAT      : Faulties = 0  ( 0 )  Warnings = 121  ( 620 )  Summary  = 121  ( 620 )
+CHECKSHAPE  : Wires    = 15  ( 16 )  Faces    = 18  ( 18 )  Shells   = 1  ( 1 )   Solids   = 0 ( 0 )
+NBSHAPES    : Solid    = 22  ( 22 )  Shell    = 25  ( 24 )  Face     = 1521  ( 1519 ) 
+STATSHAPE   : Solid    = 22  ( 22 )  Shell    = 25  ( 24 )  Face     = 1521  ( 1519 )   FreeWire = 0  ( 0 ) 
+TOLERANCE   : MaxTol   =    7.499684301  (    7.499684301 )  AvgTol   =   0.03357316863  (   0.03544461059 )
 LABELS      : N0Labels = 25  ( 25 )  N1Labels = 23  ( 23 )  N2Labels = 0  ( 0 )   TotalLabels = 48  ( 48 )   NameLabels = 48  ( 48 )   ColorLabels = 0  ( 0 )   LayerLabels = 0  ( 0 )
 PROPS       : Centroid = 0  ( 0 )  Volume   = 0  ( 0 )  Area     = 0  ( 0 )
 NCOLORS     : NColors  = 0  ( 0 )