]> OCCT Git - occt.git/commitdiff
Fix of crash in "thickshell" functionality
authorjgv <jgv@opencascade.com>
Fri, 17 Sep 2021 12:16:20 +0000 (15:16 +0300)
committerjgv <jgv@opencascade.com>
Fri, 17 Sep 2021 12:16:20 +0000 (15:16 +0300)
src/BRepOffset/BRepOffset_Analyse.cxx

index 1e215a3801458426fb7e85f74357653f0764a550..edddededf68ad1a56fb556b3cb2d44c193808952 100644 (file)
 #include <Precision.hxx>
 #include <gp.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepAdaptor_HSurface.hxx>
 #include <Adaptor3d_Surface.hxx>
+#include <BRepTopAdaptor_TopolTool.hxx>
+#include <LocalAnalysis_SurfaceContinuity.hxx>
+#include <TopOpeBRepTool_TOOL.hxx>
 //
 static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d);
 //
@@ -54,10 +58,15 @@ static Standard_Real IntermediatePoint(const Standard_Real aFirst,
   const Standard_Real aLast);
 //
 static BRepOffset_Type DefineConnectType(const TopoDS_Edge&         E,
-                                                          const TopoDS_Face&         F1,
-                                                          const TopoDS_Face&         F2,
-                                                          const Standard_Real        SinTol,
+                                         const TopoDS_Face&         F1,
+                                         const TopoDS_Face&         F2,
+                                         const Standard_Real        SinTol,
                                          const Standard_Boolean     CorrectPoint);
+
+static Standard_Boolean IsTangentFaces(const TopoDS_Edge &theEdge,
+                                       const TopoDS_Face &theFace1,
+                                       const TopoDS_Face &theFace2,
+                                       const GeomAbs_Shape Order);
 //
 static void CorrectOrientationOfTangent(gp_Vec& TangVec,
                                         const TopoDS_Vertex& aVertex,
@@ -101,27 +110,37 @@ static void EdgeAnalyse(const TopoDS_Edge&         E,
                                          const Standard_Real        SinTol,
                                                BRepOffset_ListOfInterval& LI)
 {
-  
   Standard_Real   f,l;
   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) {
-      I.Type(BRepOffset_Tangent);
-      LI.Append(I);
-      return;
-    }
+  //  
+  BRepAdaptor_Surface aBAsurf1(F1, Standard_False);
+  GeomAbs_SurfaceType aSurfType1 = aBAsurf1.GetType();
+
+  BRepAdaptor_Surface aBAsurf2(F2, Standard_False);
+  GeomAbs_SurfaceType aSurfType2 = aBAsurf2.GetType();
+
+  Standard_Boolean isTwoPlanes = (aSurfType1 == GeomAbs_Plane && aSurfType2 == GeomAbs_Plane);
+
+  BRepOffset_Type ConnectType = BRepOffset_Other;
+
+  if (isTwoPlanes) //then use only strong condition
+  {
+    if (BRep_Tool::Continuity(E,F1,F2) > GeomAbs_C0)
+      ConnectType = BRepOffset_Tangent;
+    else
+      ConnectType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
   }
-  //
-  BRepOffset_Type aType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
-  if(aType != BRepOffset_Tangent)
+  else
   {
-    aType = DefineConnectType(E, F1, F2, SinTol, Standard_True);
+    if (IsTangentFaces(E, F1, F2, GeomAbs_G1)) //weak condition
+      ConnectType = BRepOffset_Tangent;
+    else
+      ConnectType = DefineConnectType(E, F1, F2, SinTol, Standard_False);
   }
-  I.Type(aType);
+   
+  I.Type(ConnectType);
   LI.Append(I);
 }
 
@@ -176,7 +195,7 @@ void BRepOffset_Analyse::Perform (const TopoDS_Shape& S,
   myShape = S;
 
   angle                = Angle;
-  Standard_Real SinTol = Abs(Sin(Angle));
+  Standard_Real SinTol = Sin(Angle);
 
   // Build ancestors.
   BuildAncestors (S,ancestors);
@@ -550,9 +569,9 @@ Standard_Real IntermediatePoint(const Standard_Real aFirst,
 //purpose  : 
 //=======================================================================
 BRepOffset_Type DefineConnectType(const TopoDS_Edge&         E,
-                                                   const TopoDS_Face&         F1,
-                                                   const TopoDS_Face&         F2,
-                                                   const Standard_Real        SinTol,
+                                  const TopoDS_Face&         F1,
+                                  const TopoDS_Face&         F2,
+                                  const Standard_Real        SinTol,
                                   const Standard_Boolean     CorrectPoint)
 {
   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1);
@@ -640,3 +659,90 @@ BRepOffset_Type DefineConnectType(const TopoDS_Edge&         E,
     }
   }
 }
+
+//=======================================================================
+//function : IsTangentFaces
+//purpose  : 
+//=======================================================================
+Standard_Boolean IsTangentFaces(const TopoDS_Edge &theEdge,
+                                const TopoDS_Face &theFace1,
+                                const TopoDS_Face &theFace2,
+                                const GeomAbs_Shape Order)
+{
+  if (Order == GeomAbs_G1 &&
+      BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
+    return Standard_True;
+
+  Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
+
+  Standard_Real aFirst;
+  Standard_Real aLast;
+    
+// Obtaining of pcurves of edge on two faces.
+  const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
+                                                (theEdge, theFace1, aFirst, aLast);
+  const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
+                                                (theEdge, theFace2, aFirst, aLast);
+  if (aC2d1.IsNull() || aC2d2.IsNull())
+    return Standard_False;
+
+// Obtaining of two surfaces from adjacent faces.
+  Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
+  Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
+
+  if (aSurf1.IsNull() || aSurf2.IsNull())
+    return Standard_False;
+
+// Computation of the number of samples on the edge.
+  BRepAdaptor_Surface              aBAS1(theFace1);
+  BRepAdaptor_Surface              aBAS2(theFace2);
+  Handle(BRepAdaptor_HSurface)     aBAHS1      = new BRepAdaptor_HSurface(aBAS1);
+  Handle(BRepAdaptor_HSurface)     aBAHS2      = new BRepAdaptor_HSurface(aBAS2);
+  Handle(BRepTopAdaptor_TopolTool) aTool1      = new BRepTopAdaptor_TopolTool(aBAHS1);
+  Handle(BRepTopAdaptor_TopolTool) aTool2      = new BRepTopAdaptor_TopolTool(aBAHS2);
+  Standard_Integer                 aNbSamples1 =     aTool1->NbSamples();
+  Standard_Integer                 aNbSamples2 =     aTool2->NbSamples();
+  Standard_Integer                 aNbSamples  =     Max(aNbSamples1, aNbSamples2);
+
+
+// Computation of the continuity.
+  Standard_Real    aPar;
+  Standard_Real    aDelta = (aLast - aFirst)/(aNbSamples - 1);
+  Standard_Integer i, nbNotDone = 0;
+
+  for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
+    if (i == aNbSamples) aPar = aLast;
+
+    LocalAnalysis_SurfaceContinuity aCont(aC2d1,  aC2d2,  aPar,
+                                         aSurf1, aSurf2, Order,
+                                         0.001, TolC0, 0.1, 0.1, 0.1);
+    if (!aCont.IsDone())
+      {
+       nbNotDone++;
+       continue;
+      }
+    
+    if (Order == GeomAbs_G1)
+    {
+      if (!aCont.IsG1())
+        return Standard_False;
+    }
+    else if (!aCont.IsG2())
+      return Standard_False;
+  }
+  
+  if (nbNotDone == aNbSamples)
+    return Standard_False;
+
+  //Compare normals of tangent faces in the middle point
+  Standard_Real MidPar = (aFirst + aLast)/2.;
+  gp_Pnt2d uv1 = aC2d1->Value(MidPar);
+  gp_Pnt2d uv2 = aC2d2->Value(MidPar);
+  gp_Dir normal1, normal2;
+  TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 );
+  TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 );
+  Standard_Real dot = normal1.Dot(normal2);
+  if (dot < 0.)
+    return Standard_False;
+  return Standard_True;
+}