From caf028355772b8ed5cd35a400a879d009df7968b Mon Sep 17 00:00:00 2001 From: dbv Date: Tue, 8 Sep 2015 15:44:11 +0300 Subject: [PATCH] Improvement #651: Arc direction must be flexible --- src/GeomAPI/CMakeLists.txt | 2 + src/GeomAPI/GeomAPI.i | 3 ++ src/GeomAPI/GeomAPI_Ax2.cpp | 61 +++++++++++++++++++++++++++ src/GeomAPI/GeomAPI_Ax2.h | 59 ++++++++++++++++++++++++++ src/GeomAPI/GeomAPI_Circ.cpp | 41 ++++++++++++++---- src/GeomAPI/GeomAPI_Circ.h | 23 ++++++++++ src/SketchPlugin/SketchPlugin_Arc.cpp | 30 ++++++++++++- src/SketchPlugin/SketchPlugin_Arc.h | 4 ++ 8 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 src/GeomAPI/GeomAPI_Ax2.cpp create mode 100644 src/GeomAPI/GeomAPI_Ax2.h diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index 888da4512..b258cb54a 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -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 diff --git a/src/GeomAPI/GeomAPI.i b/src/GeomAPI/GeomAPI.i index 2bd0b7857..41f79de25 100644 --- a/src/GeomAPI/GeomAPI.i +++ b/src/GeomAPI/GeomAPI.i @@ -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 index 000000000..7daff469c --- /dev/null +++ b/src/GeomAPI/GeomAPI_Ax2.cpp @@ -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 + +#include + +#define MY_AX1 implPtr() + +//================================================================================================= +GeomAPI_Ax2::GeomAPI_Ax2() +: GeomAPI_Interface(new gp_Ax2()) +{ +} + +//================================================================================================= +GeomAPI_Ax2::GeomAPI_Ax2(std::shared_ptr theOrigin, + std::shared_ptr theN, + std::shared_ptr theVX) +: GeomAPI_Interface(new gp_Ax2(theOrigin->impl(), + theN->impl(), + theVX->impl())) +{ +} + +//================================================================================================= +GeomAPI_Ax2::GeomAPI_Ax2(std::shared_ptr theOrigin, + std::shared_ptr theDir) +: GeomAPI_Interface(new gp_Ax2(theOrigin->impl(), + theDir->impl())) +{ +} + +//================================================================================================= +void GeomAPI_Ax2::setOrigin(const std::shared_ptr& theOrigin) +{ + MY_AX1->SetLocation(theOrigin->impl()); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Ax2::origin() const +{ + gp_Pnt aPnt = MY_AX1->Location(); + return std::shared_ptr(new GeomAPI_Pnt(aPnt.X(),aPnt.Y(),aPnt.Z())); +} + +//================================================================================================= +void GeomAPI_Ax2::setDir(const std::shared_ptr& theDir) +{ + MY_AX1->SetDirection(theDir->impl()); +} + +//================================================================================================= +std::shared_ptr GeomAPI_Ax2::dir() const +{ + gp_Dir aDir = MY_AX1->Direction(); + return std::shared_ptr(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 index 000000000..7db04e814 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Ax2.h @@ -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 +#include +#include + +/** \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 theOrigin, + std::shared_ptr theN, + std::shared_ptr theVX); + + /** \brief Ñonstructor. + * \param[in] theOrigin point of origin. + * \param[in] theDir direction of axis. + */ + GEOMAPI_EXPORT + GeomAPI_Ax2(std::shared_ptr theOrigin, + std::shared_ptr theDir); + + /// Sets origin point. + GEOMAPI_EXPORT + void setOrigin(const std::shared_ptr& theOrigin); + + /// \return the plane origin point. + GEOMAPI_EXPORT + std::shared_ptr origin() const; + + /// Sets direction vector. + GEOMAPI_EXPORT + void setDir(const std::shared_ptr& theDir); + + /// \return direction vector. + GEOMAPI_EXPORT + std::shared_ptr dir() const; +}; + +#endif diff --git a/src/GeomAPI/GeomAPI_Circ.cpp b/src/GeomAPI/GeomAPI_Circ.cpp index 34332272c..56a7b6d02 100644 --- a/src/GeomAPI/GeomAPI_Circ.cpp +++ b/src/GeomAPI/GeomAPI_Circ.cpp @@ -5,6 +5,8 @@ // Author: Artem ZHIDKOV #include + +#include #include #include @@ -15,6 +17,7 @@ #include #include +#include #define MY_CIRC implPtr() @@ -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 theAx2, + const double theRadius) +: GeomAPI_Interface(new gp_Circ(theAx2->impl(), theRadius)) +{ + +} + + +//================================================================================================= GeomAPI_Circ::GeomAPI_Circ(const std::shared_ptr& theCenter, const std::shared_ptr& theDir, double theRadius) : GeomAPI_Interface(newCirc(theCenter->impl(), theDir->impl(), theRadius)) { } +//================================================================================================= +const std::shared_ptr GeomAPI_Circ::center() const +{ + const gp_Pnt& aCenter = MY_CIRC->Location(); + return std::shared_ptr(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z())); +} + +//================================================================================================= +double GeomAPI_Circ::radius() const +{ + return MY_CIRC->Radius(); +} + +//================================================================================================= const std::shared_ptr GeomAPI_Circ::project( const std::shared_ptr& thePoint) const { @@ -57,13 +84,11 @@ const std::shared_ptr GeomAPI_Circ::project( return aResult; } -const std::shared_ptr GeomAPI_Circ::center() const -{ - const gp_Pnt& aCenter = MY_CIRC->Location(); - return std::shared_ptr(new GeomAPI_Pnt(aCenter.X(), aCenter.Y(), aCenter.Z())); -} - -double GeomAPI_Circ::radius() const +//================================================================================================= +const bool GeomAPI_Circ::parameter(const std::shared_ptr 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(), theTolerance, theParameter); } diff --git a/src/GeomAPI/GeomAPI_Circ.h b/src/GeomAPI/GeomAPI_Circ.h index 71ede7631..3791071dd 100644 --- a/src/GeomAPI/GeomAPI_Circ.h +++ b/src/GeomAPI/GeomAPI_Circ.h @@ -10,6 +10,7 @@ #include #include +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 theAx2, + const double theRadius); + /// Creation of circle defined by center point, direction and circle radius GEOMAPI_EXPORT GeomAPI_Circ(const std::shared_ptr& theCenter, const std::shared_ptr& theDir, double theRadius); @@ -34,6 +45,18 @@ class GeomAPI_Circ : public GeomAPI_Interface /// Project point on circle GEOMAPI_EXPORT const std::shared_ptr project( const std::shared_ptr& 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 thePoint, + const double theTolerance, + double& theParameter) const; }; #endif diff --git a/src/SketchPlugin/SketchPlugin_Arc.cpp b/src/SketchPlugin/SketchPlugin_Arc.cpp index 04f2c922b..9de0fc49b 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.cpp +++ b/src/SketchPlugin/SketchPlugin_Arc.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,8 @@ #include 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 aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y())); - std::shared_ptr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc( - aCenter, aStartPoint, aEndPoint, aNormal); + std::shared_ptr anXDir(new GeomAPI_Dir(aStartPoint->xyz()->decreased(aCenter->xyz()))); + std::shared_ptr anAx2(new GeomAPI_Ax2(aCenter, aNormal, anXDir)); + std::shared_ptr 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 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 aConstr2 = document()->createConstruction( data(), 1); diff --git a/src/SketchPlugin/SketchPlugin_Arc.h b/src/SketchPlugin/SketchPlugin_Arc.h index 4d2df1417..d3d9e597d 100644 --- a/src/SketchPlugin/SketchPlugin_Arc.h +++ b/src/SketchPlugin/SketchPlugin_Arc.h @@ -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() -- 2.39.2