0025729: algorith BRepOffset_MakeOffset(...) produces wrong result for join type...
authorifv <ifv@opencascade.com>
Thu, 12 Feb 2015 09:18:56 +0000 (12:18 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 12 Feb 2015 09:19:43 +0000 (12:19 +0300)
Test case for issue CR25729

src/BRepOffset/BRepOffset_Analyse.cxx
src/BRepOffset/BRepOffset_Inter2d.cxx
src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepOffset/BRepOffset_Offset.cxx
src/BiTgte/BiTgte_Blend.cxx
tests/bugs/modalg_5/bug25729 [new file with mode: 0644]

index c8fc015..a78d0b9 100644 (file)
 
 #include <Precision.hxx>
 #include <gp.hxx>
-
-
+#include <BRepAdaptor_Surface.hxx>
+#include <Adaptor3d_Surface.hxx>
+//
+static void Correct2dPoint(const Adaptor3d_Surface& theS, gp_Pnt2d& theP2d);
+//
+static BRepOffset_Type DefineConnectType(const TopoDS_Edge&         E,
+                                                          const TopoDS_Face&         F1,
+                                                          const TopoDS_Face&         F2,
+                                                          const Standard_Real        SinTol,
+                                         const Standard_Boolean     CorrectPoint);
+//
 static void CorrectOrientationOfTangent(gp_Vec& TangVec,
                                         const TopoDS_Vertex& aVertex,
                                         const TopoDS_Edge& anEdge)
@@ -55,7 +64,6 @@ static void CorrectOrientationOfTangent(gp_Vec& TangVec,
   if (aVertex.IsSame(Vlast))
     TangVec.Reverse();
 }
-
 //=======================================================================
 //function : BRepOffset_Analyse
 //purpose  : 
@@ -85,99 +93,32 @@ BRepOffset_Analyse::BRepOffset_Analyse(const TopoDS_Shape& S,
 //=======================================================================
 
 static void EdgeAnalyse(const TopoDS_Edge&         E,
-                       const TopoDS_Face&         F1,
-                       const TopoDS_Face&         F2,
-                       const Standard_Real        SinTol,
-                       BRepOffset_ListOfInterval& LI)
+                                         const TopoDS_Face&         F1,
+                                         const TopoDS_Face&         F2,
+                                         const Standard_Real        SinTol,
+                                               BRepOffset_ListOfInterval& LI)
 {
-
   
-  TopLoc_Location L;
   Standard_Real   f,l;
-  
-  Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
-  Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
-  Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
-  Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
-
-  BRepAdaptor_Curve C(E);
-  f = C.FirstParameter();
-  l = C.LastParameter();
-  
+  BRep_Tool::Range(E, F1, f, l);
+  BRepOffset_Interval I;
+  I.First(f); I.Last(l);
+  //
   // Tangent if the regularity is at least G1.
   if (BRep_Tool::HasContinuity(E,F1,F2)) {
     if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0) {
-      BRepOffset_Interval I;
-       I.First(f); I.Last(l);
       I.Type(BRepOffset_Tangent);
       LI.Append(I);
       return;
     }
   }
-  // First stage : Type determined by one of ends.
-  // Calculate normals and tangents on the curves and surface.
-  // normals are oriented outwards.
-  
-  Standard_Real ParOnC = 0.5*(f+l);
-  gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation());
-  if (T1.SquareMagnitude() > gp::Resolution()) {
-    T1.Normalize();
-  }
-  
-  if (BRepOffset_Tool::OriEdgeInFace(E,F1) == TopAbs_REVERSED) {
-    T1.Reverse();
-  }
-  if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse();
-
-  gp_Pnt2d P  = C1->Value(ParOnC);
-  gp_Pnt   P3;
-  gp_Vec   D1U,D1V;
-  
-  S1->D1(P.X(),P.Y(),P3,D1U,D1V);
-  gp_Vec DN1(D1U^D1V);
-  if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
-  
-  P = C2->Value(ParOnC);
-  S2->D1(P.X(),P.Y(),P3,D1U,D1V);
-  gp_Vec DN2(D1U^D1V);
-  if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
-
-  DN1.Normalize();
-  DN2.Normalize();
-
-  gp_Vec        ProVec     = DN1^DN2;
-  Standard_Real NormProVec = ProVec.Magnitude(); 
-
-  BRepOffset_Interval I;
-  I.First(f); I.Last(l);
-
-  if (Abs(NormProVec) < SinTol) {
-    // plane
-    if (DN1.Dot(DN2) > 0) {   
-      //Tangent
-      I.Type(BRepOffset_Tangent);
-    }
-    else  {                   
-      //Mixed not finished!
-#ifdef OCCT_DEBUG
-      cout <<" faces locally mixed"<<endl;
-#endif
-      I.Type(BRepOffset_Convex);
-    }
-  }
-  else {  
-    if (NormProVec > gp::Resolution())
-      ProVec.Normalize();
-    Standard_Real Prod  = T1.Dot(DN1^DN2);
-    if (Prod > 0.) {       
-      //
-      I.Type(BRepOffset_Convex);
-    }
-    else {                       
-      //reenters
-      I.Type(BRepOffset_Concave);
-    }
+  //
+  BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
+  if(aType != BRepOffset_Tangent)
+  {
+    aType = DefineConnectType(E, F1, F2, SinTol, Standard_True);
   }
+  I.Type(aType);
   LI.Append(I);
 }
 
@@ -540,3 +481,130 @@ void BRepOffset_Analyse::AddFaces (const TopoDS_Face&    Face,
     }
   }
 }
+
+//=======================================================================
+//function : Correct2dPoint
+//purpose  : 
+//=======================================================================
+void Correct2dPoint(const Adaptor3d_Surface& theS, gp_Pnt2d& theP2d)
+{
+  const Standard_Real coeff = 0.01;
+  Standard_Real eps;
+  Standard_Real u1, u2, v1, v2;
+  if(theS.GetType() >= GeomAbs_BezierSurface)
+  {
+    u1 = theS.FirstUParameter();
+    u2 = theS.LastUParameter();
+    v1 = theS.FirstVParameter();
+    v2 = theS.LastVParameter();
+    if(!(Precision::IsInfinite(u1) || Precision::IsInfinite(u2)))
+    {
+      eps = Max(coeff*(u2-u1), Precision::PConfusion());
+      if(Abs(theP2d.X()-u1) < eps)
+      {
+        theP2d.SetX(u1 + eps);
+      }
+      if(Abs(theP2d.X()-u2) < eps)
+      {
+        theP2d.SetX(u2 - eps);
+      }
+    }
+    if(!(Precision::IsInfinite(v1) || Precision::IsInfinite(v2)))
+    {
+      eps = Max(coeff*(v2-v1), Precision::PConfusion());
+      if(Abs(theP2d.Y()-v1) < eps)
+      {
+        theP2d.SetY(v1 + eps);
+      }
+      if(Abs(theP2d.Y()-v2) < eps)
+      {
+        theP2d.SetY(v2 - eps);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : DefineConnectType
+//purpose  : 
+//=======================================================================
+BRepOffset_Type DefineConnectType(const TopoDS_Edge&         E,
+                                                   const TopoDS_Face&         F1,
+                                                   const TopoDS_Face&         F2,
+                                                   const Standard_Real        SinTol,
+                                  const Standard_Boolean     CorrectPoint)
+{
+  TopLoc_Location L;
+  Standard_Real   f,l;
+  
+  BRepAdaptor_Surface S1(F1), S2(F2);
+  Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
+  Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
+
+  BRepAdaptor_Curve C(E);
+  f = C.FirstParameter();
+  l = C.LastParameter();
+//
+  Standard_Real ParOnC = 0.5*(f+l);
+  gp_Vec T1 = C.DN(ParOnC,1).Transformed(L.Transformation());
+  if (T1.SquareMagnitude() > gp::Resolution()) {
+    T1.Normalize();
+  }
+  
+  if (BRepOffset_Tool::OriEdgeInFace(E,F1) == TopAbs_REVERSED) {
+    T1.Reverse();
+  }
+  if (F1.Orientation() == TopAbs_REVERSED) T1.Reverse();
+
+  gp_Pnt2d P  = C1->Value(ParOnC);
+  gp_Pnt   P3;
+  gp_Vec   D1U,D1V;
+  
+  if(CorrectPoint) 
+    Correct2dPoint(S1, P);
+  //
+  S1.D1(P.X(),P.Y(),P3,D1U,D1V);
+  gp_Vec DN1(D1U^D1V);
+  if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
+  
+  P = C2->Value(ParOnC);
+  if(CorrectPoint) 
+    Correct2dPoint(S2, P);
+  S2.D1(P.X(),P.Y(),P3,D1U,D1V);
+  gp_Vec DN2(D1U^D1V);
+  if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
+
+  DN1.Normalize();
+  DN2.Normalize();
+
+  gp_Vec        ProVec     = DN1^DN2;
+  Standard_Real NormProVec = ProVec.Magnitude(); 
+
+  if (Abs(NormProVec) < SinTol) {
+    // plane
+    if (DN1.Dot(DN2) > 0) {   
+      //Tangent
+      return BRepOffset_Tangent;
+    }
+    else  {                   
+      //Mixed not finished!
+#ifdef OCCT_DEBUG
+      cout <<" faces locally mixed"<<endl;
+#endif
+      return BRepOffset_Convex;
+    }
+  }
+  else {  
+    if (NormProVec > gp::Resolution())
+      ProVec.Normalize();
+    Standard_Real Prod  = T1.Dot(DN1^DN2);
+    if (Prod > 0.) {       
+      //
+      return BRepOffset_Convex;
+    }
+    else {                       
+      //reenters
+      return BRepOffset_Concave;
+    }
+  }
+}
index 588cc13..2c6c643 100644 (file)
@@ -83,7 +83,7 @@
 
 #ifdef DRAW 
 #include <DBRep.hxx>
-Standard_IMPORT extern Standard_Boolean AffichInt2d;
+Standard_Boolean Inter2dAffichInt2d;
 static Standard_Integer NbF2d = 0;
 static Standard_Integer NbE2d = 0;
 static Standard_Integer NbNewVertices  = 0;
@@ -245,7 +245,7 @@ static void  Store (const TopoDS_Edge&       E1,
     }
     
 #ifdef DRAW
-   if (AffichInt2d) {    
+   if (Inter2dAffichInt2d) {     
      if (!OnE1 && !OnE2) {
        char name[256];
        sprintf(name,"VV_%d",NbNewVertices++);  
@@ -272,7 +272,7 @@ static void EdgeInter(const TopoDS_Face&              F,
                      Standard_Boolean                WithOri)
 {
 #ifdef DRAW
-  if (AffichInt2d) {
+  if (Inter2dAffichInt2d) {
     char name[256];
     sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
     DBRep::Set(name,E1);
@@ -543,7 +543,7 @@ static void RefEdgeInter(const TopoDS_Face&              F,
                         gp_Pnt&                         Pref)
 {
 #ifdef DRAW
-  if (AffichInt2d) {
+  if (Inter2dAffichInt2d) {
     char name[256];
     sprintf(name,"E2d_%d_%d",NbF2d,NbE2d++);
     DBRep::Set(name,E1);
index d2ff2f6..69ca982 100644 (file)
   Standard_Boolean ChronBuild  = Standard_False;
   Standard_Integer NbAE        = 0;
   Standard_Integer NbAF        = 0;  
+  Standard_Integer NVP        = 0;  
+  Standard_Integer NVM        = 0;  
+  Standard_Integer NVN        = 0;  
   static OSD_Chronometer  Clock;
   char name[100];
 
index f93e726..29fb26e 100644 (file)
@@ -1405,6 +1405,7 @@ void BRepOffset_Offset::Init(const TopoDS_Vertex&        Vertex,
     for (it.Initialize(LEdge); it.More(); it.Next()) {
       sprintf(name,"EOnSph_%d_%d",NbOFFSET,NbEdges++);
 #ifdef DRAW
+      const TopoDS_Shape& CurE = it.Value();
       DBRep::Set(name, CurE);
 #endif
     }
index e99e30b..e32cef7 100644 (file)
@@ -2342,9 +2342,6 @@ void BiTgte_Blend::ComputeShape()
   
   BRep_Builder B;
 
-#ifdef DRAW
-  Standard_Integer NbNT = 1;
-#endif
 
   // Maj of the Map of created.
   // Update edges that do not change in the resulting shape 
diff --git a/tests/bugs/modalg_5/bug25729 b/tests/bugs/modalg_5/bug25729
new file mode 100644 (file)
index 0000000..123cee6
--- /dev/null
@@ -0,0 +1,17 @@
+puts "========="
+puts "OCC25729"
+puts "========="
+puts ""
+###############################################
+# algorith BRepOffset_MakeOffset(...) produces wrong result for join type Intersection
+###############################################
+
+restore [locate_data_file bug25729_source_shape.brep] s
+
+offsetparameter 1.e-7 i i
+offsetload s 0.14
+offsetperform result
+
+checkshape result
+
+set 2dviewer 1