Salome HOME
Improvement #651: Arc direction must be flexible
authordbv <dbv@opencascade.com>
Tue, 8 Sep 2015 12:44:11 +0000 (15:44 +0300)
committerdbv <dbv@opencascade.com>
Tue, 8 Sep 2015 12:45:10 +0000 (15:45 +0300)
src/GeomAPI/CMakeLists.txt
src/GeomAPI/GeomAPI.i
src/GeomAPI/GeomAPI_Ax2.cpp [new file with mode: 0644]
src/GeomAPI/GeomAPI_Ax2.h [new file with mode: 0644]
src/GeomAPI/GeomAPI_Circ.cpp
src/GeomAPI/GeomAPI_Circ.h
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Arc.h

index 888da4512967b46e44dd90b78344360d07cc0a06..b258cb54a3904a30162f6c03a0f1aaabfa221ac4 100644 (file)
@@ -32,6 +32,7 @@ SET(PROJECT_HEADERS
     GeomAPI_ICustomPrs.h
     GeomAPI_Vertex.h
     GeomAPI_Ax1.h
+    GeomAPI_Ax2.h
     GeomAPI_Ax3.h
     GeomAPI_Trsf.h
 )
@@ -61,6 +62,7 @@ SET(PROJECT_SOURCES
     GeomAPI_Vertex.cpp
     GeomAPI_ICustomPrs.cpp
     GeomAPI_Ax1.cpp
+    GeomAPI_Ax2.cpp
     GeomAPI_Ax3.cpp
     GeomAPI_IPresentable.cpp
     GeomAPI_Trsf.cpp
index 2bd0b7857eb3d04e9de18299fd1efe734f74d732..41f79de25f0ec12ea8328195655105abbcda61d9 100644 (file)
@@ -4,6 +4,7 @@
   #include "GeomAPI.h"
   #include "GeomAPI_AISObject.h"
   #include "GeomAPI_Ax1.h"
+  #include "GeomAPI_Ax2.h"
   #include "GeomAPI_Ax3.h"
   #include "GeomAPI_Circ.h"
   #include "GeomAPI_Circ2d.h"
@@ -45,6 +46,7 @@
 // shared pointers
 %shared_ptr(GeomAPI_AISObject)
 %shared_ptr(GeomAPI_Ax1)
+%shared_ptr(GeomAPI_Ax2)
 %shared_ptr(GeomAPI_Ax3)
 %shared_ptr(GeomAPI_Circ)
 %shared_ptr(GeomAPI_Circ2d)
@@ -77,6 +79,7 @@
 %include "GeomAPI_Shape.h"
 %include "GeomAPI_AISObject.h"
 %include "GeomAPI_Ax1.h"
+%include "GeomAPI_Ax2.h"
 %include "GeomAPI_Ax3.h"
 %include "GeomAPI_Circ.h"
 %include "GeomAPI_Circ2d.h"
diff --git a/src/GeomAPI/GeomAPI_Ax2.cpp b/src/GeomAPI/GeomAPI_Ax2.cpp
new file mode 100644 (file)
index 0000000..7daff46
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Ax2.cpp
+// Created:     08 September 2015
+// Author:      Dmitry Bobylev
+
+#include <GeomAPI_Ax2.h>
+
+#include <gp_Ax2.hxx>
+
+#define MY_AX1 implPtr<gp_Ax2>()
+
+//=================================================================================================
+GeomAPI_Ax2::GeomAPI_Ax2()
+: GeomAPI_Interface(new gp_Ax2())
+{
+}
+
+//=================================================================================================
+GeomAPI_Ax2::GeomAPI_Ax2(std::shared_ptr<GeomAPI_Pnt> theOrigin,
+                         std::shared_ptr<GeomAPI_Dir> theN,
+                         std::shared_ptr<GeomAPI_Dir> theVX)
+: GeomAPI_Interface(new gp_Ax2(theOrigin->impl<gp_Pnt>(),
+                               theN->impl<gp_Dir>(),
+                               theVX->impl<gp_Dir>()))
+{
+}
+
+//=================================================================================================
+GeomAPI_Ax2::GeomAPI_Ax2(std::shared_ptr<GeomAPI_Pnt> theOrigin,
+                         std::shared_ptr<GeomAPI_Dir> theDir)
+: GeomAPI_Interface(new gp_Ax2(theOrigin->impl<gp_Pnt>(),
+                               theDir->impl<gp_Dir>()))
+{
+}
+
+//=================================================================================================
+void GeomAPI_Ax2::setOrigin(const std::shared_ptr<GeomAPI_Pnt>& theOrigin)
+{
+  MY_AX1->SetLocation(theOrigin->impl<gp_Pnt>());
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Pnt> GeomAPI_Ax2::origin() const
+{
+  gp_Pnt aPnt = MY_AX1->Location();
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aPnt.X(),aPnt.Y(),aPnt.Z()));
+}
+
+//=================================================================================================
+void GeomAPI_Ax2::setDir(const std::shared_ptr<GeomAPI_Dir>& theDir)
+{
+  MY_AX1->SetDirection(theDir->impl<gp_Dir>());
+}
+
+//=================================================================================================
+std::shared_ptr<GeomAPI_Dir> GeomAPI_Ax2::dir() const
+{
+  gp_Dir aDir = MY_AX1->Direction();
+  return std::shared_ptr<GeomAPI_Dir>(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z()));
+}
diff --git a/src/GeomAPI/GeomAPI_Ax2.h b/src/GeomAPI/GeomAPI_Ax2.h
new file mode 100644 (file)
index 0000000..7db04e8
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        GeomAPI_Ax2.h
+// Created:     12 May 2015
+// Author:      Dmitry Bobylev
+
+#ifndef GeomAPI_Ax2_H_
+#define GeomAPI_Ax2_H_
+
+#include <GeomAPI.h>
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Dir.h>
+
+/** \ingroup DataModel
+ *  \brief The class represents an axis in 3D space.
+ */
+class GeomAPI_Ax2 : public GeomAPI_Interface
+{
+public:
+  /// Default constructor.
+  GEOMAPI_EXPORT 
+  GeomAPI_Ax2();
+
+  /** \brief Ñonstructor.
+   *  \param[in] theOrigin point of origin.
+   *  \param[in] theN direction of axis.
+   *  \param[in] theVX x direction of axis.
+   */
+  GEOMAPI_EXPORT 
+  GeomAPI_Ax2(std::shared_ptr<GeomAPI_Pnt> theOrigin,
+              std::shared_ptr<GeomAPI_Dir> theN,
+              std::shared_ptr<GeomAPI_Dir> theVX);
+
+  /** \brief Ñonstructor.
+   *  \param[in] theOrigin point of origin.
+   *  \param[in] theDir direction of axis.
+   */
+  GEOMAPI_EXPORT 
+  GeomAPI_Ax2(std::shared_ptr<GeomAPI_Pnt> theOrigin,
+              std::shared_ptr<GeomAPI_Dir> theDir);
+
+  /// Sets origin point.
+  GEOMAPI_EXPORT 
+  void setOrigin(const std::shared_ptr<GeomAPI_Pnt>& theOrigin);
+
+  /// \return the plane origin point.
+  GEOMAPI_EXPORT 
+  std::shared_ptr<GeomAPI_Pnt> origin() const;
+
+  /// Sets direction vector.
+  GEOMAPI_EXPORT 
+  void setDir(const std::shared_ptr<GeomAPI_Dir>& theDir);
+
+  /// \return direction vector.
+  GEOMAPI_EXPORT 
+  std::shared_ptr<GeomAPI_Dir> dir() const;
+};
+
+#endif
index 34332272cc421ed08741b2b1cad5c50c7cd33f94..56a7b6d024a45ec1df6874142b62cd71829b54fe 100644 (file)
@@ -5,6 +5,8 @@
 // Author:      Artem ZHIDKOV
 
 #include <GeomAPI_Circ.h>
+
+#include <GeomAPI_Ax2.h>
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Dir.h>
 
@@ -15,6 +17,7 @@
 
 #include <Geom_Circle.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomLib_Tool.hxx>
 
 #define MY_CIRC implPtr<gp_Circ>()
 
@@ -23,12 +26,36 @@ static gp_Circ* newCirc(const gp_Pnt& theCenter, const gp_Dir& theDir, const dou
   return new gp_Circ(gp_Ax2(theCenter, theDir), theRadius);
 }
 
+//=================================================================================================
+GeomAPI_Circ::GeomAPI_Circ(const std::shared_ptr<GeomAPI_Ax2> theAx2,
+                           const double theRadius)
+: GeomAPI_Interface(new gp_Circ(theAx2->impl<gp_Ax2>(), theRadius))
+{
+
+}
+
+
+//=================================================================================================
 GeomAPI_Circ::GeomAPI_Circ(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
                            const std::shared_ptr<GeomAPI_Dir>& theDir, double theRadius)
     : GeomAPI_Interface(newCirc(theCenter->impl<gp_Pnt>(), theDir->impl<gp_Dir>(), theRadius))
 {
 }
 
+//=================================================================================================
+const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Circ::center() const
+{
+  const gp_Pnt& aCenter = MY_CIRC->Location();
+  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z()));
+}
+
+//=================================================================================================
+double GeomAPI_Circ::radius() const
+{
+  return MY_CIRC->Radius();
+}
+
+//=================================================================================================
 const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Circ::project(
     const std::shared_ptr<GeomAPI_Pnt>& thePoint) const
 {
@@ -57,13 +84,11 @@ const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Circ::project(
   return aResult;
 }
 
-const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Circ::center() const
-{
-  const gp_Pnt& aCenter = MY_CIRC->Location();
-  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z()));
-}
-
-double GeomAPI_Circ::radius() const
+//=================================================================================================
+const bool GeomAPI_Circ::parameter(const std::shared_ptr<GeomAPI_Pnt> thePoint,
+                                   const double theTolerance,
+                                   double& theParameter) const
 {
-  return MY_CIRC->Radius();
+  Handle(Geom_Circle) aCurve = new Geom_Circle(*MY_CIRC);
+  return GeomLib_Tool::Parameter(aCurve, thePoint->impl<gp_Pnt>(), theTolerance, theParameter);
 }
index 71ede7631191fcebb7cafe906944a10eb8ecc64b..3791071dd0e35890be5ba40bfa916de0294b32cc 100644 (file)
@@ -10,6 +10,7 @@
 #include <GeomAPI_Interface.h>
 #include <memory>
 
+class GeomAPI_Ax2;
 class GeomAPI_Pnt;
 class GeomAPI_Dir;
 
@@ -21,6 +22,16 @@ class GeomAPI_Dir;
 class GeomAPI_Circ : public GeomAPI_Interface
 {
  public:
+
+  /** \brief Constructs a circle of radius Radius, where theAx2 locates the circle and defines its orientation in 3D space such that:\n
+   *  - the center of the circle is the origin of theAx2;\n
+   *  - the origin, "X Direction" and "Y Direction" of theAx2 define the plane of the circle;\n
+   *  - theAx2 is the local coordinate system of the circle.\n
+   *    Note: It is possible to create a circle where Radius is equal to 0.0. raised if Radius < 0.
+   */
+  GEOMAPI_EXPORT GeomAPI_Circ(const std::shared_ptr<GeomAPI_Ax2> theAx2,
+                              const double theRadius);
+
   /// Creation of circle defined by center point, direction and circle radius
   GEOMAPI_EXPORT GeomAPI_Circ(const std::shared_ptr<GeomAPI_Pnt>& theCenter,
                const std::shared_ptr<GeomAPI_Dir>& theDir, double theRadius);
@@ -34,6 +45,18 @@ class GeomAPI_Circ : public GeomAPI_Interface
   /// Project point on circle
   GEOMAPI_EXPORT const std::shared_ptr<GeomAPI_Pnt> project(
       const std::shared_ptr<GeomAPI_Pnt>& thePoint) const;
+
+  /** \brief Computes the parameter of a given point on a circle. The point must be
+   *         located either on the circle itself or relatively to the latter
+   *         at a distance less than the tolerance value. Return FALSE if the point
+   *         is beyond the tolerance limit or if computation fails.
+   *         Max Tolerance value is currently limited to 1.e-4
+   *  \param[in] theOrigin point of origin.
+   *  \param[in] theDir direction of axis.
+   */
+  GEOMAPI_EXPORT const bool parameter(const std::shared_ptr<GeomAPI_Pnt> thePoint,
+                                      const double theTolerance,
+                                      double& theParameter) const;
 };
 
 #endif
index 04f2c922babe98d54245f40d28f4b9569af2c29f..9de0fc49b97dc5851cf50f116c523120b22ac3af 100644 (file)
@@ -12,6 +12,7 @@
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Session.h>
 
+#include <GeomAPI_Ax2.h>
 #include <GeomAPI_Circ2d.h>
 #include <GeomAPI_Circ.h>
 #include <GeomAPI_Pnt2d.h>
@@ -24,6 +25,8 @@
 #include <math.h>
 
 const double tolerance = 1e-7;
+const double paramTolerance = 1.e-4;
+const double PI =3.141592653589793238463;
 
 SketchPlugin_Arc::SketchPlugin_Arc()
     : SketchPlugin_SketchEntity()
@@ -33,6 +36,9 @@ SketchPlugin_Arc::SketchPlugin_Arc()
   // default values
   myXEndBefore = 0;
   myYEndBefore = 0;
+
+  myForwardDirection = true;
+  myParamBefore = 0;
 }
 
 void SketchPlugin_Arc::initAttributes()
@@ -93,8 +99,28 @@ void SketchPlugin_Arc::execute()
     */
     std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
 
-    std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
-        aCenter, aStartPoint, aEndPoint, aNormal);
+    std::shared_ptr<GeomAPI_Dir> anXDir(new GeomAPI_Dir(aStartPoint->xyz()->decreased(aCenter->xyz())));
+    std::shared_ptr<GeomAPI_Ax2> anAx2(new GeomAPI_Ax2(aCenter, aNormal, anXDir));
+    std::shared_ptr<GeomAPI_Circ> aCirc(new GeomAPI_Circ(anAx2, aCenter->distance(aStartPoint)));
+    double aParameterNew = 0.0;
+    if(aCirc->parameter(aEndPoint, paramTolerance, aParameterNew)) {
+      if(0 < myParamBefore && myParamBefore <= PI / 2.0
+        && PI * 1.5 < aParameterNew && aParameterNew <= PI * 2.0) {
+          myForwardDirection = false;
+      } else if(PI * 1.5 < myParamBefore && myParamBefore <= PI * 2.0
+        && 0 < aParameterNew && aParameterNew <= PI / 2.0) {
+          myForwardDirection = true;
+      }
+    }
+    myParamBefore = aParameterNew;
+
+    std::shared_ptr<GeomAPI_Shape> aCircleShape;
+    if(myForwardDirection) {
+      aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStartPoint, aEndPoint, aNormal);
+    } else {
+      aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aEndPoint, aStartPoint, aNormal);
+    }
+
     if (aCircleShape) {
       std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
           data(), 1);
index 4d2df1417c024db8c8dafe54bb1c7410d830033a..d3d9e597d29940e5f175ba04eb8b6a88e8d739de 100644 (file)
@@ -27,6 +27,10 @@ class SketchPlugin_Arc : public SketchPlugin_SketchEntity, public GeomAPI_IPrese
   /// to avoid (if possible) additional modification of changed coordinate (issue #855)
   double myXEndBefore, myYEndBefore;
 
+  /// to define in which direction draw arc
+  bool myForwardDirection;
+  double myParamBefore;
+
  public:
   /// Arc feature kind
   inline static const std::string& ID()