0024910: Offset of solid is not created
authorjgv <jgv@opencascade.com>
Thu, 25 Sep 2014 09:41:27 +0000 (13:41 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 25 Sep 2014 11:58:13 +0000 (15:58 +0400)
Optimization of local function

Test case for issue #24910

src/BRepOffset/BRepOffset_Analyse.cxx
src/BRepOffset/BRepOffset_Offset.cxx
src/GeomFill/GeomFill_CircularBlendFunc.cxx
tests/bugs/modalg_5/bug24910 [new file with mode: 0644]

index 4b57f8f..5fc6f1c 100644 (file)
 #include <gp.hxx>
 
 
+static void CorrectOrientationOfTangent(gp_Vec& TangVec,
+                                        const TopoDS_Vertex& aVertex,
+                                        const TopoDS_Edge& anEdge)
+{
+  TopoDS_Vertex Vlast = TopExp::LastVertex(anEdge);
+  if (aVertex.IsSame(Vlast))
+    TangVec.Reverse();
+}
+
 //=======================================================================
 //function : BRepOffset_Analyse
 //purpose  : 
@@ -367,6 +376,7 @@ void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge&    Edge  ,
   URef   = BRep_Tool::Parameter(Vertex,Edge);
   C3dRef = BRepAdaptor_Curve(Edge);
   VRef   = C3dRef.DN(URef,1);
+  CorrectOrientationOfTangent(VRef, Vertex, Edge);
   if (VRef.SquareMagnitude() < gp::Resolution()) return;
 
   Edges.Clear();
@@ -379,8 +389,9 @@ void BRepOffset_Analyse::TangentEdges(const TopoDS_Edge&    Edge  ,
     U   = BRep_Tool::Parameter(Vertex,CurE);
     C3d = BRepAdaptor_Curve(CurE);
     V   = C3d.DN(U,1);
+    CorrectOrientationOfTangent(V, Vertex, CurE);
     if (V.SquareMagnitude() < gp::Resolution()) continue;
-    if (V.IsParallel(VRef,angle)) {
+    if (V.IsOpposite(VRef,angle)) {
       Edges.Append(CurE);
     }
   }
index cbfce6b..17e0708 100644 (file)
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomLib.hxx>
 
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <BRepLib_MakeWire.hxx>
+#include <gce_MakePln.hxx>
+#include <ShapeFix_Shape.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
+
 #ifdef DEB
 static Standard_Boolean Affich = Standard_False;
 static Standard_Integer NbOFFSET = 0;
@@ -83,6 +90,32 @@ static Standard_Integer NbOFFSET = 0;
 #endif
 #include <stdio.h>
 
+
+static gp_Pnt GetFarestCorner(const TopoDS_Wire& aWire)
+{
+  TopTools_IndexedMapOfShape Vertices;
+  TopExp::MapShapes(aWire, TopAbs_VERTEX, Vertices);
+
+  Standard_Real MaxDist = 0.;
+  gp_Pnt thePoint;
+  for (Standard_Integer i = 1; i <= Vertices.Extent(); i++)
+    for (Standard_Integer j = 1; j <= Vertices.Extent(); j++)
+    {
+      const TopoDS_Vertex& V1 = TopoDS::Vertex(Vertices(i));
+      const TopoDS_Vertex& V2 = TopoDS::Vertex(Vertices(j));
+      gp_Pnt P1 = BRep_Tool::Pnt(V1);
+      gp_Pnt P2 = BRep_Tool::Pnt(V2);
+      Standard_Real aDist = P1.SquareDistance(P2);
+      if (aDist > MaxDist)
+      {
+        MaxDist = aDist;
+        thePoint = P1;
+      }
+    }
+
+  return thePoint;
+}
+
 //=======================================================================
 //function : UpdateEdge
 //purpose  : 
@@ -1316,29 +1349,29 @@ void BRepOffset_Offset::Init(const TopoDS_Vertex&        Vertex,
   }
 #endif
 
+  gp_Pnt Origin = BRep_Tool::Pnt(Vertex);
 
-  it.Initialize(LEdge);
-  TopExp::Vertices(TopoDS::Edge(it.Value()), V1, V2);
-  P1 = BRep_Tool::Pnt(V1);
-  P2 = BRep_Tool::Pnt(V2);
+  //// Find the axis of the sphere to exclude
+  //// degenerated and seam edges from the face under construction
+  BRepLib_MakeWire MW;
+  MW.Add(LEdge);
+  TopoDS_Wire theWire = MW.Wire();
 
-  if ( !it.More()) {
-    Standard_ConstructionError::Raise("BRepOffset_Sphere");
-  }
-  it.Next();
-  TopExp::Vertices(TopoDS::Edge(it.Value()), V3, V4);
+  ShapeFix_Shape Fixer(theWire);
+  Fixer.Perform();
+  theWire = TopoDS::Wire(Fixer.Shape());
 
-  P3 = BRep_Tool::Pnt(V3);
-  Standard_Real eps = 1.e-8;
-  if ( P1.Distance(P3) < eps || P2.Distance(P3) < eps)
-    P3 = BRep_Tool::Pnt(V4);
-  
-  P = BRep_Tool::Pnt(Vertex);
-  
-  gp_Vec X = gp_Vec(P1,P2) ^ gp_Vec(P1,P3);
-  if ( X * gp_Vec(P1,P) < 0.) X.Reverse();
+  GProp_GProps GlobalProps;
+  BRepGProp::LinearProperties(theWire, GlobalProps);
+  gp_Pnt BaryCenter = GlobalProps.CentreOfMass();
+  gp_Vec Xdir(BaryCenter, Origin);
+
+  gp_Pnt FarestCorner = GetFarestCorner(theWire);
+  gp_Pln thePlane = gce_MakePln(Origin, BaryCenter, FarestCorner);
+  gp_Dir Vdir = thePlane.Axis().Direction();
 
-  gp_Ax3 Axis( P, gp_Dir(gp_Vec(P1,P2)), gp_Dir(X));
+  gp_Ax3 Axis(Origin, Vdir, Xdir);
+  
   Handle(Geom_Surface) S 
     = new Geom_SphericalSurface( Axis, Abs(Offset));
 
index 498000d..1aae632 100644 (file)
@@ -31,6 +31,8 @@
 static Standard_Integer NbSections = 0;
 #endif
 
+const Standard_Real TolAng = 1.e-6;
+
 GeomAbs_Shape GeomFillNextShape(const GeomAbs_Shape S)
 {
   switch (S) {
@@ -228,7 +230,8 @@ void GeomFill_CircularBlendFunc::Discret()
   ns1.SetXYZ( Center.XYZ() - P1.XYZ());
   ns2.SetXYZ( Center.XYZ() - P2.XYZ());     
 
-  myreverse = (DCenter.Dot(ns1.Crossed(ns2)) < 0);    
+  //myreverse = (DCenter.Dot(ns1.Crossed(ns2)) < 0);
+  myreverse = Standard_False;
 }
 
 
@@ -250,7 +253,7 @@ Standard_Boolean GeomFill_CircularBlendFunc::D0(const Standard_Real Param,
   myTCurve2->D0(Param, P2);
   ns1.SetXYZ( Center.XYZ() - P1.XYZ());
   ns2.SetXYZ( Center.XYZ() - P2.XYZ());
-  if (!ns1.IsParallel(ns2,1.e-9))  nplan = ns1.Crossed(ns2);
+  if (!ns1.IsParallel(ns2, TolAng))  nplan = ns1.Crossed(ns2);
   else {
     myTPath->D1(Param, Center, nplan);
     if (myreverse) nplan.Reverse();
@@ -316,7 +319,7 @@ Standard_Boolean GeomFill_CircularBlendFunc::D1(const Standard_Real Param,
   Dns1 = DCenter - DP1;
   Dns2 = DCenter - DP2;
  
-  if (!ns1.IsParallel(ns2,1.e-9)) {
+  if (!ns1.IsParallel(ns2, TolAng)) {
     nplan = ns1.Crossed(ns2);
     dnplan =  Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2));
   }
@@ -404,7 +407,7 @@ Standard_Boolean GeomFill_CircularBlendFunc::D2(const Standard_Real Param,
   Dns2 = DCenter - DP2;
   D2ns2 =  D2Center - D2P2;
 
-  if (!ns1.IsParallel(ns2,1.e-9)) {
+  if (!ns1.IsParallel(ns2, TolAng)) {
     nplan = ns1.Crossed(ns2);
     dnplan = Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2));
     d2nplan.SetLinearForm(1, D2ns1.Crossed(ns2),
diff --git a/tests/bugs/modalg_5/bug24910 b/tests/bugs/modalg_5/bug24910
new file mode 100644 (file)
index 0000000..82ebd17
--- /dev/null
@@ -0,0 +1,20 @@
+puts "================"
+puts "OCC24910"
+puts "================"
+puts ""
+##################################
+# Offset of solid is not created
+##################################
+
+restore [locate_data_file bug24910_Solid_4.brep] a
+offsetshape result a 1
+
+set nb_v_good 46
+set nb_e_good 88
+set nb_w_good 44
+set nb_f_good 44
+set nb_sh_good 1
+set nb_sol_good 1
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 224