0026681: BRepPrimAPI_MakeRevol creates faulty shape
authorjgv <jgv@opencascade.com>
Tue, 10 Nov 2015 11:25:56 +0000 (14:25 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 Nov 2015 11:22:54 +0000 (14:22 +0300)
Correction according to remarks

More precise processing of non-SameParameter edges

Correction of mistake

Test cases for issue CR26681

src/BRepLib/BRepLib.cxx
src/BRepLib/BRepLib.hxx
src/BRepPrimAPI/BRepPrimAPI_MakeRevol.cxx
tests/bugs/modalg_6/bug26681 [new file with mode: 0644]

index ecd0eb9..98e3e0c 100644 (file)
@@ -33,6 +33,7 @@
 #include <BRep_TFace.hxx>
 #include <BRep_Tool.hxx>
 #include <BRep_TVertex.hxx>
+#include <BRepAdaptor_HCurve.hxx>
 #include <BRepAdaptor_HCurve2d.hxx>
 #include <BRepAdaptor_HSurface.hxx>
 #include <BRepAdaptor_Surface.hxx>
@@ -1457,6 +1458,99 @@ void  BRepLib::UpdateTolerances(const TopoDS_Shape& aShape,
 }
 
 //=======================================================================
+//function : UpdateInnerTolerances
+//purpose  : 
+//=======================================================================
+void  BRepLib::UpdateInnerTolerances(const TopoDS_Shape& aShape)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape EFmap;
+  TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
+  BRep_Builder BB;
+  for (Standard_Integer i = 1; i <= EFmap.Extent(); i++)
+  {
+    TopoDS_Edge anEdge = TopoDS::Edge(EFmap.FindKey(i));
+    TopoDS_Vertex V1, V2;
+    TopExp::Vertices(anEdge, V1, V2);
+    Standard_Real fpar, lpar;
+    BRep_Tool::Range(anEdge, fpar, lpar);
+    Standard_Real TolEdge = BRep_Tool::Tolerance(anEdge);
+    gp_Pnt Pnt1, Pnt2;
+    Handle(BRepAdaptor_HCurve) anHCurve = new BRepAdaptor_HCurve();
+    anHCurve->ChangeCurve().Initialize(anEdge);
+    if (!V1.IsNull())
+      Pnt1 = BRep_Tool::Pnt(V1);
+    if (!V2.IsNull())
+      Pnt2 = BRep_Tool::Pnt(V2);
+    
+    if (!BRep_Tool::Degenerated(anEdge) &&
+        EFmap(i).Extent() > 0)
+    {
+      NCollection_Sequence<Handle(Adaptor3d_HCurve)> theRep;
+      theRep.Append(anHCurve);
+      TopTools_ListIteratorOfListOfShape itl(EFmap(i));
+      for (; itl.More(); itl.Next())
+      {
+        const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
+        Handle(BRepAdaptor_HCurve) anHCurvOnSurf = new BRepAdaptor_HCurve();
+        anHCurvOnSurf->ChangeCurve().Initialize(anEdge, aFace);
+        theRep.Append(anHCurvOnSurf);
+      }
+      
+      const Standard_Integer NbSamples = (BRep_Tool::SameParameter(anEdge))? 23 : 2;
+      Standard_Real delta = (lpar - fpar)/(NbSamples-1);
+      Standard_Real MaxDist = 0.;
+      for (Standard_Integer j = 2; j <= theRep.Length(); j++)
+      {
+        for (Standard_Integer k = 0; k <= NbSamples; k++)
+        {
+          Standard_Real ParamOnCenter = (k == NbSamples)? lpar :
+            fpar + k*delta;
+          gp_Pnt Center = theRep(1)->Value(ParamOnCenter);
+          Standard_Real ParamOnCurve = (BRep_Tool::SameParameter(anEdge))? ParamOnCenter
+            : ((k == 0)? theRep(j)->FirstParameter() : theRep(j)->LastParameter());
+          gp_Pnt aPoint = theRep(j)->Value(ParamOnCurve);
+          Standard_Real aDist = Center.Distance(aPoint);
+          //aDist *= 1.1;
+          aDist += 2.*Epsilon(aDist);
+          if (aDist > MaxDist)
+            MaxDist = aDist;
+
+          //Update tolerances of vertices
+          if (k == 0 && !V1.IsNull())
+          {
+            Standard_Real aDist1 = Pnt1.Distance(aPoint);
+            aDist1 += 2.*Epsilon(aDist1);
+            BB.UpdateVertex(V1, aDist1);
+          }
+          if (k == NbSamples && !V2.IsNull())
+          {
+            Standard_Real aDist2 = Pnt2.Distance(aPoint);
+            aDist2 += 2.*Epsilon(aDist2);
+            BB.UpdateVertex(V2, aDist2);
+          }
+        }
+      }
+      BB.UpdateEdge(anEdge, MaxDist);
+    }
+    TolEdge = BRep_Tool::Tolerance(anEdge);
+    if (!V1.IsNull())
+    {
+      gp_Pnt End1 = anHCurve->Value(fpar);
+      Standard_Real dist1 = Pnt1.Distance(End1);
+      dist1 += 2.*Epsilon(dist1);
+      BB.UpdateVertex(V1, Max(dist1, TolEdge));
+    }
+    if (!V2.IsNull())
+    {
+      gp_Pnt End2 = anHCurve->Value(lpar);
+      Standard_Real dist2 = Pnt2.Distance(End2);
+      dist2 += 2.*Epsilon(dist2);
+      BB.UpdateVertex(V2, Max(dist2, TolEdge));
+    }
+  }
+}
+
+//=======================================================================
 //function : OrientClosedSolid
 //purpose  : 
 //=======================================================================
index a1e8788..7e44fdf 100644 (file)
@@ -147,6 +147,10 @@ public:
   //! SameParameter. (called in)
   Standard_EXPORT static void UpdateTolerances (const TopoDS_Shape& S, const Standard_Boolean verifyFaceTolerance = Standard_False);
   
+  //! Checks tolerances of edges (including inner points) and vertices
+  //! of a shape and updates them to satisfy "SameParameter" condition
+  Standard_EXPORT static void UpdateInnerTolerances (const TopoDS_Shape& S);
+  
   //! Orients the solid forward  and the  shell with the
   //! orientation to have  matter in the solid. Returns
   //! False if the solid is unOrientable (open or incoherent)
index c92acc8..0cdce67 100644 (file)
@@ -80,6 +80,8 @@ const BRepSweep_Revol&  BRepPrimAPI_MakeRevol::Revol() const
 void  BRepPrimAPI_MakeRevol::Build()
 {
   myShape = myRevol.Shape();
+  BRepLib::UpdateInnerTolerances(myShape);
+  
   Done();
 // Modified by skv - Fri Mar  4 15:50:09 2005 Begin
   myDegenerated.Clear();
diff --git a/tests/bugs/modalg_6/bug26681 b/tests/bugs/modalg_6/bug26681
new file mode 100644 (file)
index 0000000..4e4ee6c
--- /dev/null
@@ -0,0 +1,19 @@
+puts "========"
+puts "OCC26681"
+puts "========"
+puts ""
+#############################################################
+# BRepPrimAPI_MakeRevol creates faulty shape
+#############################################################
+
+smallview
+
+restore [locate_data_file bug26681_ab.brep] aB
+
+revol aR aB 0 0 0 0 1 0 75
+
+checkshape aR
+
+donly aR
+fit
+set only_screen_axo 1