]> OCCT Git - occt.git/commitdiff
Fix of bug of thickshell functionality
authorjgv <jgv@opencascade.com>
Wed, 15 Sep 2021 10:31:23 +0000 (13:31 +0300)
committerjgv <jgv@opencascade.com>
Wed, 15 Sep 2021 10:31:23 +0000 (13:31 +0300)
src/BRepOffset/BRepOffset_Analyse.cxx

index 070c38adcaa843f6268201ba243dfae07abb86d8..ae28e0de4b1022b9469c358cbabee64f91ed6fd2 100644 (file)
@@ -20,6 +20,9 @@
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepTopAdaptor_TopolTool.hxx>
+#include <LocalAnalysis_SurfaceContinuity.hxx>
 #include <BRepOffset_Analyse.hxx>
 #include <BRepOffset_Interval.hxx>
 #include <BRepOffset_ListIteratorOfListOfInterval.hxx>
@@ -44,6 +47,8 @@
 #include <TopoDS_Vertex.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopOpeBRepTool_TOOL.hxx>
+#include <IntTools_Tools.hxx>
 
 //
 static void Correct2dPoint(const TopoDS_Face& theF, gp_Pnt2d& theP2d);
@@ -53,6 +58,11 @@ static BRepOffset_Type DefineConnectType(const TopoDS_Edge&         E,
                                                           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,
@@ -96,27 +106,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);
 }
 
@@ -520,21 +540,30 @@ BRepOffset_Type DefineConnectType(const TopoDS_Edge&     E,
                                   const Standard_Real    SinTol,
                                   const Standard_Boolean CorrectPoint)
 {
-  TopLoc_Location L;
-  Standard_Real   f,l;
-  
   const Handle(Geom_Surface)& S1 = BRep_Tool::Surface(F1);
   const Handle(Geom_Surface)& S2 = BRep_Tool::Surface(F2);
   //
+  Standard_Real   f,l;
   Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
-  Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
+  //For the case of seam edge
+  TopoDS_Edge EE = E;
+  if (F1.IsSame(F2))
+    EE.Reverse();
+  Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(EE,F2,f,l);
+  if (C1.IsNull() || C2.IsNull())
+    return BRepOffset_Other;
 
   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());
+  gp_Vec T1 = C.DN(ParOnC,1);
+  if (T1.SquareMagnitude() <= gp::Resolution())
+  {
+    ParOnC = IntTools_Tools::IntermediatePoint(f,l);
+    T1 = C.DN(ParOnC,1);
+  }
   if (T1.SquareMagnitude() > gp::Resolution()) {
     T1.Normalize();
   }
@@ -567,8 +596,7 @@ BRepOffset_Type DefineConnectType(const TopoDS_Edge&     E,
 
   gp_Vec        ProVec     = DN1^DN2;
   Standard_Real NormProVec = ProVec.Magnitude(); 
-
-  if (Abs(NormProVec) < SinTol) {
+  if (NormProVec < SinTol) {
     // plane
     if (DN1.Dot(DN2) > 0) {   
       //Tangent
@@ -596,3 +624,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;
+}