From 9b159dad1e76cd9671e776be60fc63663835b49c Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 25 Aug 2015 08:25:08 +0300 Subject: [PATCH] Update calculation of angle value (issue #788) --- .../SketchPlugin_ConstraintAngle.cpp | 63 ++++++++++++++++--- src/SketchSolver/CMakeLists.txt | 2 + src/SketchSolver/SketchSolver_Builder.cpp | 1 + src/SketchSolver/SketchSolver_Constraint.h | 23 ------- .../SketchSolver_ConstraintAngle.cpp | 36 +++++++++++ .../SketchSolver_ConstraintAngle.h | 40 ++++++++++++ 6 files changed, 132 insertions(+), 33 deletions(-) create mode 100644 src/SketchSolver/SketchSolver_ConstraintAngle.cpp create mode 100644 src/SketchSolver/SketchSolver_ConstraintAngle.h diff --git a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp index 03c840b27..693fa9c84 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintAngle.cpp @@ -23,6 +23,9 @@ const double tolerance = 1.e-7; #define PI 3.1415926535897932 +/// \brief Calculate intersection point of two lines +static std::shared_ptr intersect(FeaturePtr theLine1, FeaturePtr theLine2); + SketchPlugin_ConstraintAngle::SketchPlugin_ConstraintAngle() { @@ -102,6 +105,22 @@ void SketchPlugin_ConstraintAngle::attributeChanged(const std::string& theID) // coordinates are calculated according to the center of shapes intersection std::shared_ptr aFlyoutAttr = std::dynamic_pointer_cast(attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); + + std::shared_ptr aData = data(); + std::shared_ptr aPlane = SketchPlugin_Sketch::plane(sketch()); + FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A()); + FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B()); + + // Intersection of lines + std::shared_ptr anInter = intersect(aLineA, aLineB); + if (!anInter) + return; + + myFlyoutUpdate = true; + std::shared_ptr aFlyoutDir = aFlyoutAttr->pnt()->xy()->decreased(anInter->xy()); + if (aFlyoutDir->dot(aFlyoutDir) < tolerance * tolerance) + aFlyoutAttr->setValue(aFlyoutAttr->x() + tolerance, aFlyoutAttr->y()); + myFlyoutUpdate = false; } } @@ -114,6 +133,11 @@ double SketchPlugin_ConstraintAngle::calculateAngle() FeaturePtr aLineA = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A()); FeaturePtr aLineB = SketcherPrs_Tools::getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B()); + // Intersection of lines + std::shared_ptr anInter = intersect(aLineA, aLineB); + if (!anInter) + return anAngle; + // Start and end points of lines std::shared_ptr aPointA1 = std::dynamic_pointer_cast( aLineA->attribute(SketchPlugin_Line::START_ID())); @@ -129,15 +153,6 @@ double SketchPlugin_ConstraintAngle::calculateAngle() std::shared_ptr aEndA = aPointA2->pnt(); std::shared_ptr aStartB = aPointB1->pnt(); std::shared_ptr aEndB = aPointB2->pnt(); - if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance) - return anAngle; - - // Lines and their intersection point - std::shared_ptr aLA(new GeomAPI_Lin2d(aStartA, aEndA)); - std::shared_ptr aLB(new GeomAPI_Lin2d(aStartB, aEndB)); - std::shared_ptr anInter = aLA->intersect(aLB); - if (!anInter) - return anAngle; // Directions of lines if (anInter->distance(aEndA) < tolerance) @@ -204,4 +219,32 @@ bool SketchPlugin_ConstraintAngle::compute(const std::string& theAttributeId) myFlyoutUpdate = false; return true; -} \ No newline at end of file +} + + +// =============== Auxiliary functions ================================== +std::shared_ptr intersect(FeaturePtr theLine1, FeaturePtr theLine2) +{ + // Start and end points of lines + std::shared_ptr aPointA1 = std::dynamic_pointer_cast( + theLine1->attribute(SketchPlugin_Line::START_ID())); + std::shared_ptr aPointA2 = std::dynamic_pointer_cast( + theLine1->attribute(SketchPlugin_Line::END_ID())); + + std::shared_ptr aPointB1 = std::dynamic_pointer_cast( + theLine2->attribute(SketchPlugin_Line::START_ID())); + std::shared_ptr aPointB2 = std::dynamic_pointer_cast( + theLine2->attribute(SketchPlugin_Line::END_ID())); + + std::shared_ptr aStartA = aPointA1->pnt(); + std::shared_ptr aEndA = aPointA2->pnt(); + std::shared_ptr aStartB = aPointB1->pnt(); + std::shared_ptr aEndB = aPointB2->pnt(); + if (aStartA->distance(aEndA) < tolerance || aStartB->distance(aEndB) < tolerance) + std::shared_ptr(); + + // Lines and their intersection point + std::shared_ptr aLA(new GeomAPI_Lin2d(aStartA, aEndA)); + std::shared_ptr aLB(new GeomAPI_Lin2d(aStartB, aEndB)); + return aLA->intersect(aLB); +} diff --git a/src/SketchSolver/CMakeLists.txt b/src/SketchSolver/CMakeLists.txt index 5b5e1dda5..eedad7a0f 100644 --- a/src/SketchSolver/CMakeLists.txt +++ b/src/SketchSolver/CMakeLists.txt @@ -8,6 +8,7 @@ SET(PROJECT_HEADERS SketchSolver_Error.h SketchSolver_Solver.h SketchSolver_Constraint.h + SketchSolver_ConstraintAngle.h SketchSolver_ConstraintCoincidence.h SketchSolver_ConstraintDistance.h SketchSolver_ConstraintEqual.h @@ -29,6 +30,7 @@ SET(PROJECT_HEADERS SET(PROJECT_SOURCES SketchSolver_Solver.cpp SketchSolver_Constraint.cpp + SketchSolver_ConstraintAngle.cpp SketchSolver_ConstraintCoincidence.cpp SketchSolver_ConstraintDistance.cpp SketchSolver_ConstraintEqual.cpp diff --git a/src/SketchSolver/SketchSolver_Builder.cpp b/src/SketchSolver/SketchSolver_Builder.cpp index 8e27a4b41..f491471df 100644 --- a/src/SketchSolver/SketchSolver_Builder.cpp +++ b/src/SketchSolver/SketchSolver_Builder.cpp @@ -6,6 +6,7 @@ #include "SketchSolver_Builder.h" #include +#include #include #include #include diff --git a/src/SketchSolver/SketchSolver_Constraint.h b/src/SketchSolver/SketchSolver_Constraint.h index 6e048ccaf..2a12fc5e9 100644 --- a/src/SketchSolver/SketchSolver_Constraint.h +++ b/src/SketchSolver/SketchSolver_Constraint.h @@ -223,27 +223,4 @@ public: } }; - -/** \class SketchSolver_ConstraintAngle - * \ingroup Plugins - * \brief Convert Agnle constraint to SolveSpace structure - */ -class SketchSolver_ConstraintAngle : public SketchSolver_Constraint -{ -public: - SketchSolver_ConstraintAngle(ConstraintPtr theConstraint) : - SketchSolver_Constraint(theConstraint) - {} - - virtual int getType() const - { return SLVS_C_ANGLE; } - - virtual void adjustConstraint() - { - Slvs_Constraint aConstraint = myStorage->getConstraint(mySlvsConstraints.front()); - aConstraint.other = aConstraint.valA >= 0.0; - myStorage->updateConstraint(aConstraint); - } -}; - #endif diff --git a/src/SketchSolver/SketchSolver_ConstraintAngle.cpp b/src/SketchSolver/SketchSolver_ConstraintAngle.cpp new file mode 100644 index 000000000..cfad93f19 --- /dev/null +++ b/src/SketchSolver/SketchSolver_ConstraintAngle.cpp @@ -0,0 +1,36 @@ +#include + +#include + +void SketchSolver_ConstraintAngle::getAttributes( + double& theValue, std::vector& theAttributes) +{ + SketchSolver_Constraint::getAttributes(theValue, theAttributes); + + myAngle = theValue; +} + + +void SketchSolver_ConstraintAngle::adjustConstraint() +{ + Slvs_Constraint aConstraint = myStorage->getConstraint(mySlvsConstraints.front()); + + double aLineDir[2][2] = { {0.0, 0.0}, {0.0, 0.0} }; + Slvs_hEntity anEnt[2] = {aConstraint.entityA, aConstraint.entityB}; + for (int i = 0; i < 2; i++) { + const Slvs_Entity& aLine = myStorage->getEntity(anEnt[i]); + double aCoef = -1.0; + for (int j = 0; j < 2; j++, aCoef += 2.0) { + const Slvs_Entity& aPoint = myStorage->getEntity(aLine.point[j]); + for (int k = 0; k < 2; k++) + aLineDir[i][k] += aCoef * myStorage->getParameter(aPoint.param[k]).val; + } + } + double aDot = aLineDir[0][0] * aLineDir[1][0] + aLineDir[0][1] * aLineDir[1][1]; + + aConstraint.other = aDot * (90.0 - fabs(aConstraint.valA)) < 0.0; + if ((90.0 - fabs(aConstraint.valA)) * (90.0 - fabs(myAngle)) < 0.0) + aConstraint.other = !aConstraint.other; + myAngle = aConstraint.valA; + myStorage->updateConstraint(aConstraint); +} diff --git a/src/SketchSolver/SketchSolver_ConstraintAngle.h b/src/SketchSolver/SketchSolver_ConstraintAngle.h new file mode 100644 index 000000000..a4a65a4a3 --- /dev/null +++ b/src/SketchSolver/SketchSolver_ConstraintAngle.h @@ -0,0 +1,40 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: SketchSolver_ConstraintAngle.h +// Created: 24 August 2015 +// Author: Artem ZHIDKOV + +#ifndef SketchSolver_ConstraintAngle_H_ +#define SketchSolver_ConstraintAngle_H_ + +#include + +/** \class SketchSolver_ConstraintAngle + * \ingroup Plugins + * \brief Convert Agnle constraint to SolveSpace structure + */ +class SketchSolver_ConstraintAngle : public SketchSolver_Constraint +{ +public: + SketchSolver_ConstraintAngle(ConstraintPtr theConstraint) : + SketchSolver_Constraint(theConstraint), + myAngle(0.0) + {} + + virtual int getType() const + { return SLVS_C_ANGLE; } + + /// \brief This method is used in derived objects to check consistence of constraint. + virtual void adjustConstraint(); + +protected: + /// \brief Generate list of attributes of constraint in order useful for SolveSpace constraints + /// \param[out] theValue numerical characteristic of constraint (e.g. distance) + /// \param[out] theAttributes list of attributes to be filled + virtual void getAttributes(double& theValue, std::vector& theAttributes); + +private: + double myAngle; +}; + +#endif -- 2.39.2