Salome HOME
fast algorithm of altitude computing on plane edge/wire
authorasl <asl@opencascade.com>
Wed, 2 Sep 2015 05:43:36 +0000 (08:43 +0300)
committerasl <asl@opencascade.com>
Wed, 2 Sep 2015 05:43:36 +0000 (08:43 +0300)
src/HYDROData/HYDROData_Tool.cxx
src/HYDROData/HYDROData_Tool.h

index b9b0dcdbb67ab2780523f69d853b0ef7903b6493..b7d734df59125fda15b34a66960c2ce18ac2418e 100644 (file)
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
 #include <BRep_Tool.hxx>
+#include <Geom_Curve.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopExp_Explorer.hxx>
 
 static int aMaxNameId = std::numeric_limits<int>::max();
 
@@ -194,4 +198,68 @@ TopAbs_State HYDROData_Tool::ComputePointState( const gp_XY& theXY, const TopoDS
   BRepTopAdaptor_FClass2d aClassifier( theFace, toluv ); 
   aState = aClassifier.Perform( gp_Pnt2d(aU1, aV1), Standard_False );
   return aState;
-}
\ No newline at end of file
+}
+
+double HYDROData_Tool::GetAltitudeForEdge( const TopoDS_Edge& theEdge,
+                                           const gp_XY& thePoint,
+                                           double theParameterTolerance,
+                                           double theSquareDistanceTolerance,
+                                           double theInvalidAltitude )
+{
+  double aFirst, aLast;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theEdge, aFirst, aLast );
+  if( aCurve.IsNull() )
+    return theInvalidAltitude;
+
+  gp_Pnt aFirstPnt, aLastPnt;
+
+  aCurve->D0( aFirst, aFirstPnt );
+  aCurve->D0( aLast, aLastPnt );
+
+  gp_Pnt2d aFirstPnt2d( aFirstPnt.X(), aFirstPnt.Y() );
+  gp_Pnt2d aLastPnt2d( aLastPnt.X(), aLastPnt.Y() );
+
+  double aFirstDist = 0;
+  double aLastDist = aFirstPnt2d.SquareDistance( thePoint );
+  double aNecDist = aFirstPnt2d.SquareDistance( thePoint );
+
+  while( fabs( aLast - aFirst ) > theParameterTolerance )
+  {
+    double aMid = ( aFirst + aLast ) / 2;
+    gp_Pnt aMidPnt;
+    aCurve->D0( aMid, aMidPnt );
+    double aDist = aFirstPnt2d.SquareDistance( gp_Pnt2d( aMidPnt.X(), aMidPnt.Y() ) );
+
+    if( aDist > aNecDist )
+      aFirst = aMid;
+    else
+      aLast = aMid;
+  }
+
+  double aMid = ( aFirst + aLast ) / 2;
+  gp_Pnt aMidPnt;
+  aCurve->D0( aMid, aMidPnt );
+
+  gp_Pnt2d aMidPnt2d( aMidPnt.X(), aMidPnt.Y() );
+  if( aMidPnt2d.SquareDistance( thePoint ) < theSquareDistanceTolerance )
+    return aMidPnt.Z();
+  else
+    return theInvalidAltitude;
+}
+
+double HYDROData_Tool::GetAltitudeForWire( const TopoDS_Wire& theWire,
+                                           const gp_XY& thePoint,
+                                           double theParameterTolerance,
+                                           double theSquareDistanceTolerance,
+                                           double theInvalidAltitude )
+{
+  TopExp_Explorer anExp( theWire, TopAbs_EDGE );
+  for( ; anExp.More(); anExp.Next() )
+  {
+    double anAltitude = GetAltitudeForEdge( TopoDS::Edge( anExp.Current() ), thePoint,
+      theParameterTolerance, theSquareDistanceTolerance, theInvalidAltitude );
+    if( anAltitude != theInvalidAltitude )
+      return anAltitude;
+  }
+  return theInvalidAltitude;
+}
index 83b1c0421ca439e37739500e4b43971b0d2564d0..a3b129ecf1c5a257a8bf26d4ab11934aa613c944 100644 (file)
@@ -35,6 +35,8 @@ class QFile;
 class TopoDS_Shape;
 class TopTools_SequenceOfShape;
 class Handle(HYDROData_Document);
+class TopoDS_Edge;
+class TopoDS_Wire;
 
 class HYDRODATA_EXPORT HYDROData_Tool {
 
@@ -95,6 +97,17 @@ public:
 
  static TopAbs_State                    ComputePointState( const gp_XY& thePnt2d, 
                                                               const TopoDS_Face& theFace );
+
+  static double GetAltitudeForEdge( const TopoDS_Edge& theEdge,
+                                    const gp_XY& thePoint,
+                                    double theParameterTolerance,
+                                    double theSquareDistanceTolerance,
+                                    double theInvalidAltitude );
+  static double GetAltitudeForWire( const TopoDS_Wire& theWire,
+                                    const gp_XY& thePoint,
+                                    double theParameterTolerance,
+                                    double theSquareDistanceTolerance,
+                                    double theInvalidAltitude );
 };
 
 inline bool ValuesEquals( const double& theFirst, const double& theSecond )