]> OCCT Git - occt-copy.git/commitdiff
0028346: Function ProjectOnSegments of ShapeAnalysis_Curve returns only single soluti...
authorifv <ifv@opencascade.com>
Thu, 16 Mar 2017 08:02:12 +0000 (11:02 +0300)
committerifv <ifv@opencascade.com>
Thu, 16 Mar 2017 08:02:12 +0000 (11:02 +0300)
src/Extrema/Extrema_Curve2dTool.cxx [new file with mode: 0644]
src/Extrema/Extrema_Curve2dTool.hxx
src/Extrema/Extrema_CurveTool.cxx
src/Extrema/Extrema_CurveTool.hxx
src/Extrema/Extrema_GExtPC.gxx
src/Extrema/FILES
src/GeomFill/GeomFill_SnglrFunc.cxx
src/SWDRAW/SWDRAW_ShapeAnalysis.cxx

diff --git a/src/Extrema/Extrema_Curve2dTool.cxx b/src/Extrema/Extrema_Curve2dTool.cxx
new file mode 100644 (file)
index 0000000..aae6482
--- /dev/null
@@ -0,0 +1,74 @@
+// Created on: 1995-07-18
+// Created by: Modelistation
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Extrema_Curve2dTool.hxx>
+#include <Adaptor2d_Curve2d.hxx>
+#include <TColStd_HArray1OfReal.hxx>
+#include <Precision.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
+
+//=======================================================================
+//function : DeflCurvIntervals
+//purpose  : 
+//=======================================================================
+Handle(TColStd_HArray1OfReal) 
+  Extrema_Curve2dTool::DeflCurvIntervals(const Adaptor2d_Curve2d& C)
+{
+  const Standard_Real epsd = 1.e-3;
+  const Standard_Real maxdefl = 1.e3;
+  const Standard_Real mindefl = 1.e-3;
+  Handle(TColStd_HArray1OfReal) Intervals;
+  Standard_Integer nbpnts = 23, i;
+  Standard_Real L = 0.;
+  Standard_Real tf = C.FirstParameter(), tl = C.LastParameter();
+  gp_Pnt2d aP = C.Value(tf);
+  for (i = 2; i <= nbpnts; ++i)
+  {
+    Standard_Real t = (tf * (nbpnts - i) + (i - 1) * tl) / (nbpnts - 1);
+    gp_Pnt2d aP1 = C.Value(t);
+    L += aP.Distance(aP1);
+  }
+  //
+  Standard_Real dLdt = L / (tl - tf);
+  if (L <= Precision::Confusion() || dLdt < epsd || (tl - tf) > 10000.)
+  {
+    nbpnts = 2;
+    Intervals = new TColStd_HArray1OfReal(1, nbpnts);
+    Intervals->SetValue(1, tf);
+    Intervals->SetValue(nbpnts, tl);
+    return Intervals;
+  }
+  //
+  Standard_Real aDefl = Max(0.01 * L / (2. * M_PI), mindefl);
+  if (aDefl > maxdefl)
+  {
+    nbpnts = 2;
+    Intervals = new TColStd_HArray1OfReal(1, nbpnts);
+    Intervals->SetValue(1, tf);
+    Intervals->SetValue(nbpnts, tl);
+    return Intervals;
+  }
+  Standard_Real aMinLen = Max(.00001*L, Precision::Confusion());
+  Standard_Real aTol = Max(0.00001*(tl - tf), Precision::PConfusion());
+  GCPnts_TangentialDeflection aPntGen(C, M_PI / 6, aDefl, 2, aTol, aMinLen);
+  nbpnts = aPntGen.NbPoints();
+  Intervals = new TColStd_HArray1OfReal(1, nbpnts);
+  for (i = 1; i <= nbpnts; ++i)
+  {
+    Intervals->SetValue(i, aPntGen.Parameter(i));
+  }
+  return Intervals;
+}
index 8e89a95a74bfd651bd25750429aaceabbcfaf30d..b4497dcc2499ed13b938c72483f0505665bd81ee 100644 (file)
@@ -25,6 +25,7 @@
 #include <GeomAbs_Shape.hxx>
 #include <Standard_Integer.hxx>
 #include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfReal.hxx>
 #include <Standard_Boolean.hxx>
 #include <gp_Pnt2d.hxx>
 #include <gp_Vec2d.hxx>
@@ -63,7 +64,12 @@ public:
   //! Stores in <T> the  parameters bounding the intervals
   //! of continuity <S>.
     static void Intervals (const Adaptor2d_Curve2d& C, TColStd_Array1OfReal& T, const GeomAbs_Shape S);
-  
+
+  //! Returns the parameters bounding the intervals of subdivision of curve
+  //! according to Curvature deflection. Value of deflection is defined in method.
+  //!
+    Standard_EXPORT static Handle(TColStd_HArray1OfReal) DeflCurvIntervals(const Adaptor2d_Curve2d& C);
+
     static Standard_Boolean IsClosed (const Adaptor2d_Curve2d& C);
   
     static Standard_Boolean IsPeriodic (const Adaptor2d_Curve2d& C);
index 2e43311759efa9f27108e984f6d08f13f50956ee..995e311ce017b3335a002d0d91cc327332bb8a9b 100644 (file)
@@ -21,6 +21,7 @@
 #include <Geom_BSplineCurve.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Vec.hxx>
+#include <GCPnts_TangentialDeflection.hxx>
 
 //=======================================================================
 //function : IsPeriodic
@@ -36,4 +37,57 @@ Standard_Boolean Extrema_CurveTool::IsPeriodic(const Adaptor3d_Curve& C)
     return C.IsPeriodic();
 }
 
-
+//=======================================================================
+//function : DeflCurvIntervals
+//purpose  : 
+//=======================================================================
+Handle(TColStd_HArray1OfReal) 
+Extrema_CurveTool::DeflCurvIntervals(const Adaptor3d_Curve& C)
+{
+  const Standard_Real epsd = 1.e-3;
+  const Standard_Real maxdefl = 1.e3;
+  const Standard_Real mindefl = 1.e-3;
+  Handle(TColStd_HArray1OfReal) Intervals;
+  Standard_Integer nbpnts = 23, i;
+  Standard_Real L = 0.;
+  Standard_Real tf = C.FirstParameter(), tl = C.LastParameter();
+  gp_Pnt aP = C.Value(tf);
+  for (i = 2; i <= nbpnts; ++i)
+  {
+    Standard_Real t = (tf * (nbpnts - i) + (i - 1) * tl) / (nbpnts - 1);
+    gp_Pnt aP1 = C.Value(t);
+    L += aP.Distance(aP1);
+  }
+  //
+  Standard_Real dLdt = L / (tl - tf);
+  if (L <= Precision::Confusion() || dLdt < epsd || (tl - tf) > 10000.) // To avoid problemwith GCPnts
+  {
+    nbpnts = 2;
+    Intervals = new TColStd_HArray1OfReal(1, nbpnts);
+    Intervals->SetValue(1, tf);
+    Intervals->SetValue(nbpnts, tl);
+    return Intervals;
+  }
+  //
+  Standard_Real aDefl = Max(0.01 * L / (2. * M_PI), mindefl);
+  if (aDefl > maxdefl)
+  {
+    nbpnts = 2;
+    Intervals = new TColStd_HArray1OfReal(1, nbpnts);
+    Intervals->SetValue(1, tf);
+    Intervals->SetValue(nbpnts, tl);
+    return Intervals;
+  }
+  //
+  Standard_Real aMinLen = Max(.00001*L, Precision::Confusion());
+  Standard_Real aTol = Max(0.00001*(tl - tf), Precision::PConfusion());
+  //
+  GCPnts_TangentialDeflection aPntGen(C, M_PI / 6, aDefl, 2, aTol, aMinLen);
+  nbpnts = aPntGen.NbPoints();
+  Intervals = new TColStd_HArray1OfReal(1, nbpnts);
+  for (i = 1; i <= nbpnts; ++i)
+  {
+    Intervals->SetValue(i, aPntGen.Parameter(i));
+  }
+  return Intervals;
+}
index 8dd3077c8fd5c730877828e970fe1c3671877997..163b1550e906ee7535492b25a24b899b8e2655b0 100644 (file)
@@ -25,6 +25,7 @@
 #include <GeomAbs_Shape.hxx>
 #include <Standard_Integer.hxx>
 #include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfReal.hxx>
 #include <Standard_Boolean.hxx>
 #include <GeomAbs_CurveType.hxx>
 #include <gp_Pnt.hxx>
@@ -65,8 +66,13 @@ public:
   //! The array must provide  enough room to  accomodate
   //! for the parameters. i.e. T.Length() > NbIntervals()
     static void Intervals (Adaptor3d_Curve& C, TColStd_Array1OfReal& T, const GeomAbs_Shape S);
-  
-  Standard_EXPORT static Standard_Boolean IsPeriodic (const Adaptor3d_Curve& C);
+
+  //! Returns the parameters bounding the intervals of subdivision of curve
+  //! according to Curvature deflection. Value of deflection is defined in method.
+  //!
+    Standard_EXPORT static Handle(TColStd_HArray1OfReal) DeflCurvIntervals(const Adaptor3d_Curve& C);
+
+    Standard_EXPORT static Standard_Boolean IsPeriodic (const Adaptor3d_Curve& C);
   
     static Standard_Real Period (const Adaptor3d_Curve& C);
   
index 2ed746dac7d35c33aebb4b89a44251d24d304673..d69b0464b297532c09351421693d588c84d21d3c 100644 (file)
@@ -28,6 +28,7 @@
 #include <Precision.hxx>
 #include <ElCLib.hxx>
 #include <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfReal.hxx>
 #include <NCollection_Array1.hxx>
 
 
@@ -260,13 +261,32 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
     }
   default:
     {
+      const Standard_Integer aMaxSample = 17;
       Standard_Boolean IntExtIsDone = Standard_False;
       Standard_Boolean IntIsNotValid;
+      Handle(TColStd_HArray1OfReal) theHInter;
       n = TheCurveTool::NbIntervals(aCurve, GeomAbs_C2);
-      TColStd_Array1OfReal theInter(1, n+1);
+      if (n > 1)
+      {
+        theHInter = new TColStd_HArray1OfReal(1, n + 1);
+        TheCurveTool::Intervals(aCurve, theHInter->ChangeArray1(), GeomAbs_C2);
+      }
+      else
+      {
+        theHInter = TheCurveTool::DeflCurvIntervals(aCurve);
+        n = theHInter->Length() - 1;
+      }
+      mysample = Max(mysample / n, aMaxSample);
+      Standard_Real maxint = 0.;
+      for (i = 1; i <= n; ++i)
+      {
+        Standard_Real dt = theHInter->Value(i + 1) - theHInter->Value(i);
+        if (maxint < dt)
+        {
+          maxint = dt;
+        }
+      }
       Standard_Boolean isPeriodic = TheCurveTool::IsPeriodic(aCurve);
-      TheCurveTool::Intervals(aCurve, theInter, GeomAbs_C2);
-      mysample = Max(mysample/n, 17);
       TheVector V1;
       ThePoint PP;
       Standard_Real s1 = 0.0 ;
@@ -274,8 +294,9 @@ void Extrema_GExtPC::Perform(const ThePoint& P)
       myExtPC.Initialize(aCurve);
       for (i = 1; i <= n; i++)
       {
-        myintuinf = theInter(i);
-        myintusup = theInter(i+1);
+        myintuinf = theHInter->Value(i);
+        myintusup = theHInter->Value(i+1);
+        mysample = Max(RealToInt(aMaxSample*(myintusup - myintuinf) / maxint), 3);
         
         Standard_Real anInfToCheck = myintuinf;
         Standard_Real aSupToCheck = myintusup;
@@ -509,8 +530,8 @@ Standard_Boolean Extrema_GExtPC::IsDone() const
 
 Standard_Real Extrema_GExtPC::SquareDistance(const Standard_Integer N) const 
 {
-  if(!mydone) StdFail_NotDone::Raise();
-  if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
+  if(!mydone) throw StdFail_NotDone();
+  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
   return mySqDist.Value(N);
 }
 
@@ -522,7 +543,7 @@ Standard_Real Extrema_GExtPC::SquareDistance(const Standard_Integer N) const
 
 Standard_Integer Extrema_GExtPC::NbExt() const
 {
-  if(!mydone) StdFail_NotDone::Raise();
+  if(!mydone) throw StdFail_NotDone();
   return mySqDist.Length();
 }
 
@@ -534,8 +555,8 @@ Standard_Integer Extrema_GExtPC::NbExt() const
 
 Standard_Boolean Extrema_GExtPC::IsMin(const Standard_Integer N) const
 {
-  if(!mydone) StdFail_NotDone::Raise();
-  if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
+  if(!mydone) throw StdFail_NotDone();
+  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
   return myismin.Value(N);
 }
 
@@ -548,8 +569,8 @@ Standard_Boolean Extrema_GExtPC::IsMin(const Standard_Integer N) const
 
 const ThePOnC & Extrema_GExtPC::Point(const Standard_Integer N) const
 {
-  if(!mydone) StdFail_NotDone::Raise();
-  if ((N < 1) || (N > mySqDist.Length())) Standard_OutOfRange::Raise();
+  if(!mydone) throw StdFail_NotDone();
+  if ((N < 1) || (N > mySqDist.Length())) throw Standard_OutOfRange();
   return mypoint.Value(N);
 }
 
index 1156af9202cd25ebbb8d61e6673a749c6fef1e0f..34ec6a72e08fc73e91d04faa45f751a11340858e 100644 (file)
@@ -9,6 +9,7 @@ Extrema_CCLocFOfLocECC.hxx
 Extrema_CCLocFOfLocECC2d.hxx
 Extrema_CCLocFOfLocECC2d_0.cxx
 Extrema_CCLocFOfLocECC_0.cxx
+Extrema_Curve2dTool.cxx
 Extrema_Curve2dTool.hxx
 Extrema_Curve2dTool.lxx
 Extrema_CurveLocator.gxx
index bfaeb2f2826612b5f6aa51c229a06b3a3c2c875c..07ecd327cfe8340ceffdd9930b782422c513f954 100644 (file)
@@ -47,11 +47,17 @@ void GeomFill_SnglrFunc::SetRatio(const Standard_Real Ratio)
  Standard_Integer GeomFill_SnglrFunc::NbIntervals(const GeomAbs_Shape S) const
 {
   GeomAbs_Shape HCS=GeomAbs_C0;
-  switch(S) {
-  case GeomAbs_C0: HCS = GeomAbs_C2; break;
-  case GeomAbs_C1: HCS = GeomAbs_C3; break;
-  case GeomAbs_C2: HCS = GeomAbs_CN; break;
-  default: Standard_DomainError::Raise();
+  if (S == GeomAbs_C0)
+  {
+    HCS = GeomAbs_C2;
+  }
+  else if (S == GeomAbs_C1)
+  {
+    HCS = GeomAbs_C3;
+  }
+  else if (S >= GeomAbs_C2)
+  {
+    HCS = GeomAbs_CN;
   }
   return myHCurve->NbIntervals(HCS);
 }
@@ -59,11 +65,17 @@ void GeomFill_SnglrFunc::SetRatio(const Standard_Real Ratio)
  void GeomFill_SnglrFunc::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
 {
   GeomAbs_Shape HCS=GeomAbs_C0;
-  switch(S) {
-  case GeomAbs_C0: HCS = GeomAbs_C2; break;
-  case GeomAbs_C1: HCS = GeomAbs_C3; break;
-  case GeomAbs_C2: HCS = GeomAbs_CN; break;
-  default: Standard_DomainError::Raise();
+  if (S == GeomAbs_C0)
+  {
+    HCS = GeomAbs_C2;
+  }
+  else if (S == GeomAbs_C1)
+  {
+    HCS = GeomAbs_C3;
+  }
+  else if (S >= GeomAbs_C2)
+  {
+    HCS = GeomAbs_CN;
   }
   myHCurve->Intervals(T, HCS);
 }
@@ -153,12 +165,9 @@ gp_Vec GeomFill_SnglrFunc::DN(const Standard_Real U,const Standard_Integer N) co
       D3(U,C,D1C,D2C,D3C);
       return D3C;
     default:
-      Standard_NotImplemented::Raise("Exception: Derivative order is greater than 3. "
+      throw Standard_NotImplemented("Exception: Derivative order is greater than 3. "
         "Cannot compute of derivative.");
     }
-   
-  return gp_Vec();
-
   }
 
  Standard_Real GeomFill_SnglrFunc::Resolution(const Standard_Real R3D) const
index 71282904912e359c79174ec47de2fd230b55dac7..7c449e34f9617c2a9fd66cc9ed5c025cfd3952ab 100644 (file)
@@ -60,6 +60,9 @@
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
 #include <TopTools_HSequenceOfShape.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <BRepAdaptor_HCurve2d.hxx>
+#include <BRepAdaptor_HSurface.hxx>
 
 #include <stdio.h>
 static Standard_Integer tolerance
@@ -227,6 +230,50 @@ static Standard_Integer projcurve
   di<<"Result : "<<X<<"  "<<Y<<"  "<<Z<<"\nParam = "<<param<<"  Gap = "<<dist<<"\n";
   return 0;
 }
+static Standard_Integer projpcurve
+(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+{
+  //  admet une EDGE ou une CURVE
+  if (argc < 7)
+  {
+    di << "Give : projpcurve edge face tol X Y Z\n";
+    return 1;
+  }
+
+  TopoDS_Edge aEdge = TopoDS::Edge(DBRep::Get(argv[1]));
+  if (aEdge.IsNull())
+  {
+    di << "SHAPE " << argv[1] << " is not an EDGE\n"; return 1 /* Error */;
+  }
+  TopoDS_Face aFace = TopoDS::Face(DBRep::Get(argv[2]));
+  if (aFace.IsNull())
+  {
+    di << "SHAPE " << argv[2] << " is not a FACE\n"; return 1 /* Error */;
+  }
+
+  Standard_Real aTol = Draw::Atof(argv[3]);
+
+
+  Standard_Real X = Draw::Atof(argv[4]);
+  Standard_Real Y = Draw::Atof(argv[5]);
+  Standard_Real Z = Draw::Atof(argv[6]);
+
+  gp_Pnt aP3D(X, Y, Z);
+
+  Adaptor3d_CurveOnSurface aCOnS =
+    Adaptor3d_CurveOnSurface(new BRepAdaptor_HCurve2d(BRepAdaptor_Curve2d(aEdge, aFace)),
+    new BRepAdaptor_HSurface(BRepAdaptor_Surface(aFace, Standard_False)));
+
+  gp_Pnt aPnt;
+  Standard_Real aParam;
+  ShapeAnalysis_Curve aTool;
+  Standard_Real aDist = aTool.Project(aCOnS, aP3D, aTol, aPnt, aParam, Standard_False);
+
+  di << "Point:" << "\n" << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n";
+  di << "Param: " << aParam << "\n";
+  di << "Dist: " << aDist << "\n";
+  return 0;
+}
 
 static Standard_Integer anaface
   (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
@@ -983,7 +1030,9 @@ static Standard_Integer checkedge(Draw_Interpretor& di, Standard_Integer argc, c
   theCommands.Add ("projface","nom_face X Y [Z]", __FILE__,projface,g);
   theCommands.Add ("projcurve","nom_edge | curve3d | curve3d first last + X Y Z",
                   __FILE__,projcurve,g);
-  theCommands.Add ("anaface","nomface",__FILE__,anaface,g);
+  theCommands.Add("projpcurve", "edge face tol x y z",
+    __FILE__, projpcurve, g);
+  theCommands.Add("anaface", "nomface", __FILE__, anaface, g);
   theCommands.Add ("statshape","shape [particul] : stats/particularites",
                   __FILE__,XSHAPE_statshape,g);
   theCommands.Add ("comptol","shape [nbpoints]",__FILE__,XSHAPE_comptoledge,g);