From 5634465ae5952d974470bbc741e5b4507d42b0e9 Mon Sep 17 00:00:00 2001 From: azv Date: Mon, 15 Jun 2015 16:12:34 +0300 Subject: [PATCH] Issue #601: Impossible to modify segment with constraint The procedure of movement is changed. Any part of object can be moved separately. --- src/SketchSolver/CMakeLists.txt | 2 + src/SketchSolver/SketchSolver_Builder.cpp | 9 ++ src/SketchSolver/SketchSolver_Builder.h | 3 + .../SketchSolver_ConstraintMovement.cpp | 89 +++++++++++++++++++ .../SketchSolver_ConstraintMovement.h | 40 +++++++++ .../SketchSolver_ConstraintRigid.cpp | 6 +- .../SketchSolver_ConstraintRigid.h | 9 +- src/SketchSolver/SketchSolver_Group.cpp | 2 +- 8 files changed, 155 insertions(+), 5 deletions(-) create mode 100644 src/SketchSolver/SketchSolver_ConstraintMovement.cpp create mode 100644 src/SketchSolver/SketchSolver_ConstraintMovement.h diff --git a/src/SketchSolver/CMakeLists.txt b/src/SketchSolver/CMakeLists.txt index 29e2ef1e7..9cf51643a 100644 --- a/src/SketchSolver/CMakeLists.txt +++ b/src/SketchSolver/CMakeLists.txt @@ -18,6 +18,7 @@ SET(PROJECT_HEADERS SketchSolver_ConstraintTangent.h SketchSolver_ConstraintMultiRotation.h SketchSolver_ConstraintMultiTranslation.h + SketchSolver_ConstraintMovement.h SketchSolver_Builder.h SketchSolver_Group.h SketchSolver_ConstraintManager.h @@ -38,6 +39,7 @@ SET(PROJECT_SOURCES SketchSolver_ConstraintTangent.cpp SketchSolver_ConstraintMultiRotation.cpp SketchSolver_ConstraintMultiTranslation.cpp + SketchSolver_ConstraintMovement.cpp SketchSolver_Builder.cpp SketchSolver_Group.cpp SketchSolver_ConstraintManager.cpp diff --git a/src/SketchSolver/SketchSolver_Builder.cpp b/src/SketchSolver/SketchSolver_Builder.cpp index bc992f26d..e0c6855db 100644 --- a/src/SketchSolver/SketchSolver_Builder.cpp +++ b/src/SketchSolver/SketchSolver_Builder.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -138,6 +139,14 @@ SolverConstraintPtr SketchSolver_Builder::createRigidConstraint(FeaturePtr theFi return SolverConstraintPtr(new SketchSolver_ConstraintRigid(theFixedFeature)); } +SolverConstraintPtr SketchSolver_Builder::createMovementConstraint(FeaturePtr theFixedFeature) +{ + DataPtr aData = theFixedFeature->data(); + if (!aData || !aData->isValid()) + return SolverConstraintPtr(); + return SolverConstraintPtr(new SketchSolver_ConstraintMovement(theFixedFeature)); +} + bool SketchSolver_Builder::createWorkplane( diff --git a/src/SketchSolver/SketchSolver_Builder.h b/src/SketchSolver/SketchSolver_Builder.h index e9aa10d9e..1fd353f85 100644 --- a/src/SketchSolver/SketchSolver_Builder.h +++ b/src/SketchSolver/SketchSolver_Builder.h @@ -35,6 +35,9 @@ public: /// \brief Creates temporary constraint to fix the placement of the feature SolverConstraintPtr createRigidConstraint(FeaturePtr theFixedFeature); + /// \brief Creates temporary constraint to fix the feature after movement + SolverConstraintPtr createMovementConstraint(FeaturePtr theFixedFeature); + /// \brief Converts sketch parameters to the list of SolveSpace entities. /// Identifiers of entities and parameters are local. They should be changed while adding into storage. /// The sketch entity goes last. diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp new file mode 100644 index 000000000..dfbed30fd --- /dev/null +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp @@ -0,0 +1,89 @@ +#include +#include +#include + +#include + +SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature) + : SketchSolver_ConstraintRigid(theFeature) +{ + process(); +} + +void SketchSolver_ConstraintMovement::process() +{ + cleanErrorMsg(); + if (!myBaseFeature || !myStorage || myGroup == 0) { + /// TODO: Put error message here + return; + } + if (!mySlvsConstraints.empty()) // some data is changed, update constraint + update(myBaseConstraint); + + double aValue; + std::vector anEntities; + bool isFullyMoved; + getAttributes(aValue, anEntities, isFullyMoved); + if (!myErrorMsg.empty() || (myFeatureMap.empty() && myAttributeMap.empty())) + return; + + if (isFullyMoved) + fixFeature(); + else { + std::vector::iterator anEntIt = anEntities.begin(); + for (; anEntIt != anEntities.end(); ++anEntIt) + fixPoint(*anEntIt); + } +} + + +void SketchSolver_ConstraintMovement::getAttributes( + double& theValue, + std::vector& theAttributes, + bool& theIsFullyMoved) +{ + theValue = 0.0; + theIsFullyMoved = true; + int aType = SLVS_E_UNKNOWN; // type of created entity + Slvs_hEntity anEntityID = SLVS_E_UNKNOWN; + anEntityID = myGroup->getFeatureId(myBaseFeature); + if (anEntityID == SLVS_E_UNKNOWN) { + anEntityID = changeEntity(myBaseFeature, aType); + if (anEntityID == SLVS_E_UNKNOWN) { + myErrorMsg = SketchSolver_Error::NOT_INITIALIZED(); + return; + } + + // Check the entity is complex + Slvs_Entity anEntity = myStorage->getEntity(anEntityID); + if (anEntity.point[0] != SLVS_E_UNKNOWN) { + for (int i = 0; i < 4 && anEntity.point[i]; i++) + theAttributes.push_back(anEntity.point[i]); + } else // simple entity + theAttributes.push_back(anEntityID); + } + else { + myFeatureMap[myBaseFeature] = anEntityID; + + std::list aPoints = + myBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); + std::list::iterator anIt = aPoints.begin(); + for (; anIt != aPoints.end(); ++anIt) { + Slvs_hEntity anAttr = myGroup->getAttributeId(*anIt); + + // Check the attribute changes coordinates + Slvs_Entity anAttrEnt = myStorage->getEntity(anAttr); + double aDeltaX = myStorage->getParameter(anAttrEnt.param[0]).val; + double aDeltaY = myStorage->getParameter(anAttrEnt.param[1]).val; + std::shared_ptr aPt = + std::dynamic_pointer_cast(*anIt); + aDeltaX -= aPt->x(); + aDeltaY -= aPt->y(); + if (aDeltaX * aDeltaX + aDeltaY * aDeltaY >= tolerance * tolerance) + theAttributes.push_back(anAttr); + else + theIsFullyMoved = false; + } + } +} + diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.h b/src/SketchSolver/SketchSolver_ConstraintMovement.h new file mode 100644 index 000000000..0492f5006 --- /dev/null +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.h @@ -0,0 +1,40 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: SketchSolver_ConstraintMovement.h +// Created: 15 Jun 2015 +// Author: Artem ZHIDKOV + +#ifndef SketchSolver_ConstraintMovement_H_ +#define SketchSolver_ConstraintMovement_H_ + +#include "SketchSolver.h" +#include + +/** \class SketchSolver_ConstraintMovement + * \ingroup Plugins + * \brief Stores data of Rigid (Fixed) constraint for the moved feature only + */ +class SketchSolver_ConstraintMovement : public SketchSolver_ConstraintRigid +{ +private: + /// Creates constraint to manage the given constraint from plugin + SketchSolver_ConstraintMovement(ConstraintPtr theConstraint) + : SketchSolver_ConstraintRigid(theConstraint) + {} + +public: + /// Creates temporary constraint based on feature + SketchSolver_ConstraintMovement(FeaturePtr theFeature); + +protected: + /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints + virtual void process(); + + /// \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 + /// \param[out] theIsFullyMoved shows that the feature is moved, in other case only one point of the feature is shifted + virtual void getAttributes(double& theValue, std::vector& theAttributes, bool& theIsFullyMoved); +}; + +#endif diff --git a/src/SketchSolver/SketchSolver_ConstraintRigid.cpp b/src/SketchSolver/SketchSolver_ConstraintRigid.cpp index 6082f2fd4..ff52e5774 100644 --- a/src/SketchSolver/SketchSolver_ConstraintRigid.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintRigid.cpp @@ -37,8 +37,12 @@ void SketchSolver_ConstraintRigid::process() getAttributes(aValue, anEntities); if (!myErrorMsg.empty() || (myFeatureMap.empty() && myAttributeMap.empty())) return; + fixFeature(); +} - Slvs_hEntity anEntID; +void SketchSolver_ConstraintRigid::fixFeature() +{ + Slvs_hEntity anEntID; if (!myFeatureMap.empty()) anEntID = myFeatureMap.begin()->second; else diff --git a/src/SketchSolver/SketchSolver_ConstraintRigid.h b/src/SketchSolver/SketchSolver_ConstraintRigid.h index 1fcb896e1..78b47fedd 100644 --- a/src/SketchSolver/SketchSolver_ConstraintRigid.h +++ b/src/SketchSolver/SketchSolver_ConstraintRigid.h @@ -48,6 +48,12 @@ protected: /// E.g. the distance between line and point may be signed. virtual void adjustConstraint(); + /// \brief Fixed feature basing on its type + void fixFeature(); + + /// \brief Fix given point + void fixPoint(const Slvs_hEntity& thePointID); + private: /// \brief Fixing line position (start and end points) void fixLine(const Slvs_Entity& theLine); @@ -58,9 +64,6 @@ private: /// There will be fixed start and end points and the radius of the arc. void fixArc(const Slvs_Entity& theArc); - /// \brief Fix given point - void fixPoint(const Slvs_hEntity& thePointID); - /// \brief Verifies the entity is used in any equal constraint /// \param[in] theEntity entity to be found /// \param[out] theEqual constraint, which uses the entity diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index cc24d79f2..11f334f51 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -285,7 +285,7 @@ void SketchSolver_Group::moveFeature(std::shared_ptr theFe { // Firstly, create temporary rigid constraint SolverConstraintPtr aConstraint = - SketchSolver_Builder::getInstance()->createRigidConstraint(theFeature); + SketchSolver_Builder::getInstance()->createMovementConstraint(theFeature); if (!aConstraint) return; aConstraint->setGroup(this); -- 2.30.2