From: azv Date: Fri, 28 Apr 2017 14:58:33 +0000 (+0300) Subject: Task 2.4. Ability to modify the radius of circles and arcs of circle with the mouse X-Git-Tag: V_2.7.1.1~3^2~8 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=449bcc64cb436f1ccf664236f431600b30ce84b4;p=modules%2Fshaper.git Task 2.4. Ability to modify the radius of circles and arcs of circle with the mouse Redesign of the movement processing in the PlaneGCSSolver plugin. --- diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index fea8bb975..f6eb37c9e 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -94,6 +94,7 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES Config + GeomAPI ) SET(CMAKE_SWIG_FLAGS -threads -Wall) ADD_DEFINITIONS(-DMODELAPI_EXPORTS) diff --git a/src/ModelAPI/ModelAPI_Events.cpp b/src/ModelAPI/ModelAPI_Events.cpp index 00c74c8df..2a4665d4b 100644 --- a/src/ModelAPI/ModelAPI_Events.cpp +++ b/src/ModelAPI/ModelAPI_Events.cpp @@ -10,6 +10,8 @@ #include #include +#include + ModelAPI_ObjectUpdatedMessage::ModelAPI_ObjectUpdatedMessage(const Events_ID theID, const void* theSender) : Events_MessageGroup(theID, theSender) @@ -328,3 +330,41 @@ const std::set& ModelAPI_SolverFailedMessage::objects() const return myObjects; } + +// ===== ModelAPI_ObjectMovedMessage ===== +ModelAPI_ObjectMovedMessage::ModelAPI_ObjectMovedMessage(const void* theSender) + : Events_Message(Events_Loop::eventByName(EVENT_OBJECT_MOVED), theSender) +{ +} + +void ModelAPI_ObjectMovedMessage::setMovedObject(const ObjectPtr& theMovedObject) +{ + myMovedObject = theMovedObject; + myMovedAttribute = AttributePtr(); +} + +void ModelAPI_ObjectMovedMessage::setMovedAttribute(const AttributePtr& theMovedAttribute) +{ + myMovedAttribute = theMovedAttribute; + myMovedObject = ObjectPtr(); +} + +void ModelAPI_ObjectMovedMessage::setOriginalPosition(double theX, double theY) +{ + myOriginalPosition = std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); +} + +void ModelAPI_ObjectMovedMessage::setOriginalPosition(const std::shared_ptr& thePoint) +{ + myOriginalPosition = thePoint; +} + +void ModelAPI_ObjectMovedMessage::setCurrentPosition(double theX, double theY) +{ + myCurrentPosition = std::shared_ptr(new GeomAPI_Pnt2d(theX, theY)); +} + +void ModelAPI_ObjectMovedMessage::setCurrentPosition(const std::shared_ptr& thePoint) +{ + myCurrentPosition = thePoint; +} diff --git a/src/ModelAPI/ModelAPI_Events.h b/src/ModelAPI/ModelAPI_Events.h index bbe18f7b6..f0c3b7761 100644 --- a/src/ModelAPI/ModelAPI_Events.h +++ b/src/ModelAPI/ModelAPI_Events.h @@ -22,6 +22,7 @@ class ModelAPI_Document; class ModelAPI_ResultParameter; +class GeomAPI_Pnt2d; /// Event ID that feature is created (comes with ModelAPI_ObjectUpdatedMessage) static const char * EVENT_OBJECT_CREATED = "ObjectCreated"; @@ -453,4 +454,46 @@ private: int myDOF; }; +/// Message sent when feature or attrubute has been moved. +/// Stores the moving object/attribute, original and new positions of mouse. +class ModelAPI_ObjectMovedMessage : public Events_Message +{ + ObjectPtr myMovedObject; + AttributePtr myMovedAttribute; + + std::shared_ptr myOriginalPosition; + std::shared_ptr myCurrentPosition; + +public: + MODELAPI_EXPORT ModelAPI_ObjectMovedMessage(const void* theSender = 0); + + /// Set object which is being moved (if the message already contains attribute it will be cleared) + MODELAPI_EXPORT void setMovedObject(const ObjectPtr& theMovedObject); + /// Set attribute which is being moved (if the message already contains object it will be cleared) + MODELAPI_EXPORT void setMovedAttribute(const AttributePtr& theMovedAttribute); + + /// Return moved object + ObjectPtr movedObject() const + { return myMovedObject; } + /// Return moved attribute + AttributePtr movedAttribute() const + { return myMovedAttribute; } + + /// Set original mouse position + MODELAPI_EXPORT void setOriginalPosition(double theX, double theY); + /// Set original mouse position + MODELAPI_EXPORT void setOriginalPosition(const std::shared_ptr& thePoint); + /// Return original mouse position + const std::shared_ptr& originalPosition() const + { return myOriginalPosition; } + + /// Set current mouse position + MODELAPI_EXPORT void setCurrentPosition(double theX, double theY); + /// Set current mouse position + MODELAPI_EXPORT void setCurrentPosition(const std::shared_ptr& thePoint); + /// Return current mouse position + const std::shared_ptr& currentPosition() const + { return myCurrentPosition; } +}; + #endif diff --git a/src/SketchSolver/CMakeLists.txt b/src/SketchSolver/CMakeLists.txt index 776221aa0..737934c91 100644 --- a/src/SketchSolver/CMakeLists.txt +++ b/src/SketchSolver/CMakeLists.txt @@ -37,6 +37,7 @@ SET(SKETCHSOLVER_CONSTRAINT_HEADERS SketchSolver_ConstraintMulti.h SketchSolver_ConstraintMultiRotation.h SketchSolver_ConstraintMultiTranslation.h + SketchSolver_ConstraintMovement.h ) SET(SKETCHSOLVER_SOURCES @@ -60,6 +61,7 @@ SET(SKETCHSOLVER_CONSTRAINT_SOURCES SketchSolver_ConstraintMulti.cpp SketchSolver_ConstraintMultiRotation.cpp SketchSolver_ConstraintMultiTranslation.cpp + SketchSolver_ConstraintMovement.cpp ) SET(SKETCHSOLVER_LIBRARIES diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp index 64d9c7fb5..8640e513a 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.cpp @@ -51,7 +51,7 @@ void PlaneGCSSolver_Storage::addConstraint( constraintsToSolver(theSolverConstraint, mySketchSolver); } -void PlaneGCSSolver_Storage::addTemporaryConstraint( +void PlaneGCSSolver_Storage::addMovementConstraint( const ConstraintWrapperPtr& theSolverConstraint) { if (myConstraintMap.empty()) diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h index c7e1d1eda..6b6f034be 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Storage.h @@ -30,10 +30,10 @@ public: virtual void addConstraint(ConstraintPtr theConstraint, ConstraintWrapperPtr theSolverConstraint); - /// \brief Add list of temporary constraints which will be destroyed + /// \brief Add a movement constraint which will be destroyed /// after the next solving of the set of constraints. /// \param theSolverConstraint [in] solver's constraint - virtual void addTemporaryConstraint(const ConstraintWrapperPtr& theSolverConstraint); + virtual void addMovementConstraint(const ConstraintWrapperPtr& theSolverConstraint); /// \brief Convert feature to the form applicable for specific solver and map it diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp index 63813ba75..0e609ceee 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.cpp @@ -123,12 +123,28 @@ SolverConstraintPtr PlaneGCSSolver_Tools::createConstraint(ConstraintPtr theCons return SolverConstraintPtr(new SketchSolver_Constraint(theConstraint)); } +#ifdef SUPPORT_NEW_MOVE +std::shared_ptr PlaneGCSSolver_Tools::createMovementConstraint( + FeaturePtr theMovedFeature) +{ + return std::shared_ptr( + new SketchSolver_ConstraintMovement(theMovedFeature)); +} + +std::shared_ptr PlaneGCSSolver_Tools::createMovementConstraint( + AttributePtr theMovedAttribute) +{ + return std::shared_ptr( + new SketchSolver_ConstraintMovement(theMovedAttribute)); +} +#else std::shared_ptr PlaneGCSSolver_Tools::createMovementConstraint( FeaturePtr theMovedFeature) { return std::shared_ptr( new SketchSolver_ConstraintFixed(theMovedFeature)); } +#endif diff --git a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.h b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.h index 4e43206c1..dc520695f 100644 --- a/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.h +++ b/src/SketchSolver/PlaneGCSSolver/PlaneGCSSolver_Tools.h @@ -8,7 +8,7 @@ #define PlaneGCSSolver_Tools_H_ #include -#include +#include #include #include @@ -24,9 +24,18 @@ namespace PlaneGCSSolver_Tools /// or returns empty pointer if not all attributes are correct SolverConstraintPtr createConstraint(ConstraintPtr theConstraint); +#ifdef SUPPORT_NEW_MOVE + /// \brief Creates temporary constraint to fix the feature after movement + std::shared_ptr + createMovementConstraint(FeaturePtr theMovedFeature); + /// \brief Creates temporary constraint to fix the attribute after movement + std::shared_ptr + createMovementConstraint(AttributePtr theMovedAttribute); +#else /// \brief Creates temporary constraint to fix the feature after movement std::shared_ptr createMovementConstraint(FeaturePtr theMovedFeature); +#endif /// \brief Creates new constraint using given parameters /// \param theConstraint [in] original constraint diff --git a/src/SketchSolver/SketchSolver_ConstraintFixed.cpp b/src/SketchSolver/SketchSolver_ConstraintFixed.cpp index 9c4f23330..5ea432915 100644 --- a/src/SketchSolver/SketchSolver_ConstraintFixed.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintFixed.cpp @@ -16,8 +16,6 @@ // Verify the entities are equal static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2); -// Convert entity to the list of parameters -static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity); SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint) @@ -26,42 +24,65 @@ SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theCons myType = CONSTRAINT_FIXED; } +#ifndef SUPPORT_NEW_MOVE SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature) : SketchSolver_Constraint(), myBaseFeature(theFeature) { myType = CONSTRAINT_FIXED; } +#endif void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked) { +#ifndef SUPPORT_NEW_MOVE if (myBaseFeature) myBaseFeature->data()->blockSendAttributeUpdated(isBlocked); if (myBaseConstraint) - SketchSolver_Constraint::blockEvents(isBlocked); +#endif + SketchSolver_Constraint::blockEvents(isBlocked); } void SketchSolver_ConstraintFixed::process() { cleanErrorMsg(); +#ifdef SUPPORT_NEW_MOVE + if (!myBaseConstraint || !myStorage) { +#else if ((!myBaseConstraint && !myBaseFeature) || !myStorage) { +#endif // Not enough parameters are assigned return; } +#ifdef SUPPORT_NEW_MOVE + EntityWrapperPtr aBaseEntity = entityToFix(); + if (!aBaseEntity) + myErrorMsg = SketchSolver_Error::ALREADY_FIXED(); +#else EntityWrapperPtr aBaseEntity; getAttributes(aBaseEntity, myFixedEntity); if (!aBaseEntity) { moveFeature(); // remove myFixed entity myErrorMsg = SketchSolver_Error::ALREADY_FIXED(); } +#endif if (!myErrorMsg.empty()) return; - fixFeature(aBaseEntity); +#ifdef SUPPORT_NEW_MOVE + ConstraintWrapperPtr aConstraint = fixFeature(aBaseEntity); + myStorage->addConstraint(myBaseConstraint, aConstraint); +#else + myConstraint = fixFeature(aBaseEntity); + if (myBaseConstraint) + myStorage->addConstraint(myBaseConstraint, myConstraint); + else + myStorage->addMovementConstraint(myConstraint); +#endif } -void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature) +ConstraintWrapperPtr SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature) { GCS::VEC_pD aParameters = toParameters(theFeature); @@ -75,15 +96,25 @@ void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature) GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt))); } - myConstraint = ConstraintWrapperPtr( + return ConstraintWrapperPtr( new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType())); - - if (myBaseConstraint) - myStorage->addConstraint(myBaseConstraint, myConstraint); - else - myStorage->addTemporaryConstraint(myConstraint); } +#ifdef SUPPORT_NEW_MOVE +EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix() +{ + // Constraint Fixed is added by user. + // Get the attribute of constraint (it should be alone in the list of constraints). + EntityWrapperPtr aValue; + std::vector anAttributes; + SketchSolver_Constraint::getAttributes(aValue, anAttributes); + std::vector::const_iterator anIt = anAttributes.begin(); + for (; anIt != anAttributes.end(); ++anIt) + if (*anIt) + return *anIt; + return EntityWrapperPtr(); +} +#else void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity, EntityWrapperPtr& theFixedEntity) { @@ -139,12 +170,9 @@ void SketchSolver_ConstraintFixed::moveFeature() myFixedEntity = EntityWrapperPtr(); } +#endif - - - -// ==================== Auxiliary functions =============================== -GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity) +GCS::VEC_pD SketchSolver_ConstraintFixed::toParameters(const EntityWrapperPtr& theEntity) { GCS::VEC_pD aParameters; if (!theEntity) @@ -175,16 +203,20 @@ GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity) std::dynamic_pointer_cast(anEntity->entity()); aParameters.push_back(aCircle->center.x); aParameters.push_back(aCircle->center.y); +#ifndef SUPPORT_NEW_MOVE aParameters.push_back(aCircle->rad); +#endif break; } case ENTITY_ARC: { std::shared_ptr anArc = std::dynamic_pointer_cast(anEntity->entity()); aParameters.push_back(anArc->center.x); aParameters.push_back(anArc->center.y); +#ifndef SUPPORT_NEW_MOVE aParameters.push_back(anArc->rad); aParameters.push_back(anArc->startAngle); aParameters.push_back(anArc->endAngle); +#endif break; } default: @@ -194,10 +226,12 @@ GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity) return aParameters; } +#ifndef SUPPORT_NEW_MOVE +// ==================== Auxiliary functions =============================== bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2) { - GCS::VEC_pD aParamList1 = toParameters(theEntity1); - GCS::VEC_pD aParamList2 = toParameters(theEntity2); + GCS::VEC_pD aParamList1 = SketchSolver_ConstraintFixed::toParameters(theEntity1); + GCS::VEC_pD aParamList2 = SketchSolver_ConstraintFixed::toParameters(theEntity2); GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin(); GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin(); @@ -207,3 +241,4 @@ bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEnti return anIt1 == aParamList1.end() && anIt2 == aParamList2.end(); } +#endif diff --git a/src/SketchSolver/SketchSolver_ConstraintFixed.h b/src/SketchSolver/SketchSolver_ConstraintFixed.h index 7fc02b203..13ec1d160 100644 --- a/src/SketchSolver/SketchSolver_ConstraintFixed.h +++ b/src/SketchSolver/SketchSolver_ConstraintFixed.h @@ -12,45 +12,68 @@ /** \class SketchSolver_ConstraintFixed * \ingroup Plugins * \brief Stores data of the Fixed constraint - * - * Fixed constraint may have NULL basic SketchPlugin constraint, - * because the Fixed constraint may be temporary for correct moving of objects. */ class SketchSolver_ConstraintFixed : public SketchSolver_Constraint { public: /// Creates constraint to manage the given constraint from plugin SketchSolver_ConstraintFixed(ConstraintPtr theConstraint); +#ifndef SUPPORT_NEW_MOVE /// Creates temporary constraint based on feature (useful while the feature is being moved) SketchSolver_ConstraintFixed(FeaturePtr theFeature); +#endif /// \brief Block or unblock events from this constraint virtual void blockEvents(bool isBlocked); +#ifndef SUPPORT_NEW_MOVE /// \brief Set coordinates of fixed feature to the values where it has been dragged. /// Useful when the feature is being moved. void moveFeature(); +#endif 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 constraints + /// \param[out] theValue numerical characteristic of constraint (e.g. distance) + /// \param[out] theAttributes list of attributes to be filled + virtual void getAttributes(EntityWrapperPtr& , std::vector& ) + {} + +#ifdef SUPPORT_NEW_MOVE + /// \brief Obtain entity to be fixed + virtual EntityWrapperPtr entityToFix(); +#else /// \brief Generate list of attributes of constraint in order useful for constraints /// \param[out] theBaseEntity the entity which coordinates should be fixed /// \param[out] theFixedEntity the entity containing fixed values virtual void getAttributes(EntityWrapperPtr& theBaseEntity, EntityWrapperPtr& theFixedEntity); +#endif - /// \brief Fixed feature basing on its type + /// \brief Create Fixed constraint for the feature basing on its type /// \param theFeature [in] feature, converted to solver specific format - virtual void fixFeature(EntityWrapperPtr theFeature); + /// \return Fixed constraint + virtual ConstraintWrapperPtr fixFeature(EntityWrapperPtr theFeature); + +#ifndef SUPPORT_NEW_MOVE +public: +#endif + /// \brief Get list of parameters of current entity + static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity); +#ifdef SUPPORT_NEW_MOVE +protected: +#else private: FeaturePtr myBaseFeature; ///< fixed feature (when it is set, myBaseConstraint should be NULL) ConstraintWrapperPtr myConstraint; - std::vector myFixedValues; EntityWrapperPtr myFixedEntity; +#endif + std::vector myFixedValues; }; #endif diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.cpp b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp new file mode 100644 index 000000000..59dcac14a --- /dev/null +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.cpp @@ -0,0 +1,85 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + + +SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(FeaturePtr theFeature) + : SketchSolver_ConstraintFixed(ConstraintPtr()), + myMovedFeature(theFeature) +{ +} + +SketchSolver_ConstraintMovement::SketchSolver_ConstraintMovement(AttributePtr thePoint) + : SketchSolver_ConstraintFixed(ConstraintPtr()), + myDraggedPoint(thePoint) +{ + myMovedFeature = ModelAPI_Feature::feature(thePoint->owner()); +} + +void SketchSolver_ConstraintMovement::blockEvents(bool isBlocked) +{ + if (myMovedFeature) + myMovedFeature->data()->blockSendAttributeUpdated(isBlocked); +} + +void SketchSolver_ConstraintMovement::process() +{ + cleanErrorMsg(); + if (!myMovedFeature || !myStorage) { + // Not enough parameters are initialized + return; + } + + EntityWrapperPtr aMovedEntity = entityToFix(); + if (!myErrorMsg.empty() || !aMovedEntity) { + // Nothing to move, clear the feature to avoid changing its group + // after removing the Movement constraint. + myMovedFeature = FeaturePtr(); + return; + } + + ConstraintWrapperPtr aConstraint = fixFeature(aMovedEntity); + myStorage->addMovementConstraint(aConstraint); +} + + +EntityWrapperPtr SketchSolver_ConstraintMovement::entityToFix() +{ + // if the feature is copy, do not move it + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(myMovedFeature); + if (!aSketchFeature || aSketchFeature->isCopy()) { + myStorage->setNeedToResolve(true); + return EntityWrapperPtr(); + } + + return myStorage->entity(myMovedFeature); +} + +void SketchSolver_ConstraintMovement::moveTo(const std::shared_ptr& theDestinationPoint) +{ +#ifdef SUPPORT_NEW_MOVE + EntityWrapperPtr aMovedEntity = myStorage->entity(myMovedFeature); + if (!aMovedEntity) + return; + + double aDelta[2] = { theDestinationPoint->x() - myStartPoint->x(), + theDestinationPoint->y() - myStartPoint->y() }; + + GCS::VEC_pD aFixedParams = toParameters(aMovedEntity); + for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i) + myFixedValues[i] = *(aFixedParams[i]) + aDelta[i % 2]; + +#endif +} diff --git a/src/SketchSolver/SketchSolver_ConstraintMovement.h b/src/SketchSolver/SketchSolver_ConstraintMovement.h new file mode 100644 index 000000000..42d3f3982 --- /dev/null +++ b/src/SketchSolver/SketchSolver_ConstraintMovement.h @@ -0,0 +1,55 @@ +// Copyright (C) 2015-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 + +class GeomAPI_Pnt2d; + +/** \class SketchSolver_ConstraintMovement + * \ingroup Plugins + * \brief Stores data to the Fixed constraint for the moved feature only + */ +class SketchSolver_ConstraintMovement : public SketchSolver_ConstraintFixed +{ +public: + /// Creates movement constraint based on feature + SketchSolver_ConstraintMovement(FeaturePtr theFeature); + + /// Creates movement constraint based on point + SketchSolver_ConstraintMovement(AttributePtr thePoint); + + /// \brief Set coordinates of the start point of the movement + void startPoint(const std::shared_ptr& theStartPoint) + { myStartPoint = theStartPoint; } + + /// \brief Set coordinates of fixed feature to the values where it has been dragged. + /// Useful when the feature is being moved. + void moveTo(const std::shared_ptr& theDestinationPoint); + + /// \brief Block or unblock events from this constraint + virtual void blockEvents(bool isBlocked); + + /// \brief Returns moved feature + FeaturePtr movedFeature() const + { return myMovedFeature; } + +protected: + /// \brief Converts SketchPlugin constraint to a list of SolveSpace constraints + virtual void process(); + + /// \brief Obtain entity to be fixed + virtual EntityWrapperPtr entityToFix(); + +private: + FeaturePtr myMovedFeature; ///< fixed feature (when it is set, myBaseConstraint should be NULL) + AttributePtr myDraggedPoint; ///< one of the feature points which has been moved + std::shared_ptr myStartPoint; ///< start point of the movement +}; + +#endif diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index a0a7d3624..6f855c976 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -56,7 +56,7 @@ static void sendMessage(const char* theMessageName, // ======================================================== -// ========= SketchSolver_Group =============== +// ========= SketchSolver_Group =============== // ======================================================== SketchSolver_Group::SketchSolver_Group(const CompositeFeaturePtr& theWorkplane) @@ -115,6 +115,62 @@ bool SketchSolver_Group::updateFeature(FeaturePtr theFeature) return myStorage->update(theFeature); } +#ifdef SUPPORT_NEW_MOVE +template +static SolverConstraintPtr move(StoragePtr theStorage, + SolverPtr theSketchSolver, + int theSketchDOF, + bool theEventsBlocked, + Type theFeatureOrPoint, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + bool isEntityExists = (theStorage->entity(theFeatureOrPoint).get() != 0); + if (theSketchDOF == 0 && isEntityExists) { + // avoid moving elements of fully constrained sketch + theStorage->refresh(); + return SolverConstraintPtr(); + } + + // Create temporary Fixed constraint + std::shared_ptr aConstraint = + PlaneGCSSolver_Tools::createMovementConstraint(theFeatureOrPoint); + if (aConstraint) { + SolverConstraintPtr(aConstraint)->process(theStorage, theEventsBlocked); + if (aConstraint->error().empty()) { + if (!theStorage->isEmpty()) + theStorage->setNeedToResolve(true); + + theSketchSolver->initialize(); + aConstraint->startPoint(theFrom); + aConstraint->moveTo(theTo); + } else + theStorage->notify(aConstraint->movedFeature()); + } + + return aConstraint; +} + +bool SketchSolver_Group::moveFeature(FeaturePtr theFeature, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + SolverConstraintPtr aConstraint = + move(myStorage, mySketchSolver, myDOF, myIsEventsBlocked, theFeature, theFrom, theTo); + setTemporary(aConstraint); + return true; +} + +bool SketchSolver_Group::movePoint(AttributePtr theAttribute, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + SolverConstraintPtr aConstraint = + move(myStorage, mySketchSolver, myDOF, myIsEventsBlocked, theAttribute, theFrom, theTo); + setTemporary(aConstraint); + return true; +} +#else bool SketchSolver_Group::moveFeature(FeaturePtr theFeature) { bool isFeatureExists = (myStorage->entity(theFeature).get() != 0); @@ -142,6 +198,7 @@ bool SketchSolver_Group::moveFeature(FeaturePtr theFeature) return true; } +#endif // ============================================================================ // Function: resolveConstraints @@ -357,7 +414,8 @@ void SketchSolver_Group::removeConstraint(ConstraintPtr theConstraint) // ============================================================================ void SketchSolver_Group::setTemporary(SolverConstraintPtr theConstraint) { - myTempConstraints.insert(theConstraint); + if (theConstraint) + myTempConstraints.insert(theConstraint); } // ============================================================================ diff --git a/src/SketchSolver/SketchSolver_Group.h b/src/SketchSolver/SketchSolver_Group.h index fa5902664..ae10ff58b 100644 --- a/src/SketchSolver/SketchSolver_Group.h +++ b/src/SketchSolver/SketchSolver_Group.h @@ -17,6 +17,8 @@ #include #include +class GeomAPI_Pnt2d; + typedef std::map ConstraintConstraintMap; /** \class SketchSolver_Group @@ -57,12 +59,35 @@ class SketchSolver_Group */ bool updateFeature(FeaturePtr theFeature); +#ifdef SUPPORT_NEW_MOVE + /** \brief Updates the data corresponding the specified feature moved in GUI. + * Special kind of Fixed constraints is created. + * \param[in] theFeature the feature to be updated + * \param[in] theFrom start point of the movement + * \param[in] theTo final point of the movement + * \return \c true, if the feature is really moved + */ + bool moveFeature(FeaturePtr theFeature, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo); + /** \brief Updates the data corresponding the specified point moved in GUI. + * Special kind of Fixed constraints is created. + * \param[in] thePoint the attribute to be updated + * \param[in] theFrom start point of the movement + * \param[in] theTo final point of the movement + * \return \c true, if the attribute is really moved + */ + bool movePoint(AttributePtr thePoint, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo); +#else /** \brief Updates the data corresponding the specified feature moved in GUI. * Additional Fixed constraints are created. * \param[in] theFeature the feature to be updated * \return \c true, if the feature is moved */ bool moveFeature(FeaturePtr theFeature); +#endif /// Returns the current workplane inline const CompositeFeaturePtr& getWorkplane() const diff --git a/src/SketchSolver/SketchSolver_Manager.cpp b/src/SketchSolver/SketchSolver_Manager.cpp index 849c95b0c..f0d6eb210 100644 --- a/src/SketchSolver/SketchSolver_Manager.cpp +++ b/src/SketchSolver/SketchSolver_Manager.cpp @@ -8,10 +8,12 @@ #include "SketchSolver_Error.h" #include +#include #include #include #include #include +#include #include /// Global constraint manager object @@ -52,8 +54,6 @@ SketchSolver_Manager::SketchSolver_Manager() Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED)); Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_MOVED)); - ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_FAILED)); - ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)); Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_PREPARED)); } @@ -91,20 +91,27 @@ void SketchSolver_Manager::processEvent( return; myIsComputed = true; +#ifdef SUPPORT_NEW_MOVE + if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED) + || theMessage->eventID() == anUpdateEvent) { +#else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED) || theMessage->eventID() == anUpdateEvent || theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) { +#endif std::shared_ptr anUpdateMsg = std::dynamic_pointer_cast(theMessage); std::set aFeatures = anUpdateMsg->objects(); isUpdateFlushed = stopSendUpdate(); +#ifndef SUPPORT_NEW_MOVE isMovedEvt = theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED); // Shows that the message has at least one feature applicable for solver bool hasProperFeature = false; +#endif // update sketch features only std::set::iterator aFeatIter; @@ -114,12 +121,39 @@ void SketchSolver_Manager::processEvent( if (!aFeature || aFeature->isMacro()) continue; +#ifdef SUPPORT_NEW_MOVE + updateFeature(aFeature); +#else hasProperFeature = updateFeature(aFeature, isMovedEvt) || hasProperFeature; +#endif } +#ifndef SUPPORT_NEW_MOVE if (isMovedEvt && hasProperFeature) needToResolve = true; +#else + } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) { + std::shared_ptr aMoveMsg = + std::dynamic_pointer_cast(theMessage); + + ObjectPtr aMovedObject = aMoveMsg->movedObject(); + std::shared_ptr aMovedPoint = + std::dynamic_pointer_cast(aMoveMsg->movedAttribute()); + + const std::shared_ptr& aFrom = aMoveMsg->originalPosition(); + const std::shared_ptr& aTo = aMoveMsg->currentPosition(); + + if (aMovedObject) { + FeaturePtr aMovedFeature = ModelAPI_Feature::feature(aMovedObject); + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(aMovedFeature); + if (aSketchFeature && !aSketchFeature->isMacro()) + needToResolve = moveFeature(aSketchFeature, aFrom, aTo); + } else if (aMovedPoint) + needToResolve = moveAttribute(aMovedPoint, aFrom, aTo); + +#endif } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { std::shared_ptr aDeleteMsg = std::dynamic_pointer_cast(theMessage); @@ -165,11 +199,15 @@ void SketchSolver_Manager::processEvent( } // ============================================================================ -// Function: changeConstraintOrEntity -// Purpose: create/update the constraint or the feature and place it into appropriate group +// Function: updateFeature +// Purpose: create/update constraint or feature in appropriate group // ============================================================================ +#ifdef SUPPORT_NEW_MOVE +bool SketchSolver_Manager::updateFeature(const std::shared_ptr& theFeature) +#else bool SketchSolver_Manager::updateFeature(std::shared_ptr theFeature, bool theMoved) +#endif { // Check feature validity and find a group to place it. // If the feature is not valid, the returned group will be empty. @@ -185,13 +223,56 @@ bool SketchSolver_Manager::updateFeature(std::shared_ptr t bool isOk = false; if (aConstraint) isOk = aGroup->changeConstraint(aConstraint); +#ifndef SUPPORT_NEW_MOVE else if (theMoved) isOk = aGroup->moveFeature(theFeature); +#endif else isOk = aGroup->updateFeature(theFeature); return isOk; } +#ifdef SUPPORT_NEW_MOVE +// ============================================================================ +// Function: moveFeature +// Purpose: move given feature in appropriate group +// ============================================================================ +bool SketchSolver_Manager::moveFeature( + const std::shared_ptr& theMovedFeature, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + SketchGroupPtr aGroup = findGroup(theMovedFeature); + if (!aGroup) + return false; + + aGroup->blockEvents(true); + return aGroup->moveFeature(theMovedFeature, theFrom, theTo); +} + +// ============================================================================ +// Function: moveAttribute +// Purpose: move given attribute in appropriate group +// ============================================================================ +bool SketchSolver_Manager::moveAttribute( + const std::shared_ptr& theMovedAttribute, + const std::shared_ptr& theFrom, + const std::shared_ptr& theTo) +{ + FeaturePtr anOwner = ModelAPI_Feature::feature(theMovedAttribute->owner()); + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(anOwner); + SketchGroupPtr aGroup; + if (aSketchFeature) + aGroup = findGroup(aSketchFeature); + if (!aGroup) + return false; + + aGroup->blockEvents(true); + return aGroup->movePoint(theMovedAttribute, theFrom, theTo); +} +#endif + // ============================================================================ // Function: findGroup // Purpose: search groups of entities interacting with given feature diff --git a/src/SketchSolver/SketchSolver_Manager.h b/src/SketchSolver/SketchSolver_Manager.h index fc1b42229..f88e92a3a 100644 --- a/src/SketchSolver/SketchSolver_Manager.h +++ b/src/SketchSolver/SketchSolver_Manager.h @@ -10,11 +10,14 @@ #include #include -#include #include #include +class GeomAPI_Pnt2d; +class GeomDataAPI_Point2D; +class SketchPlugin_Constraint; + /** \class SketchSolver_Manager * \ingroup Plugins * \brief Listens the changes of SketchPlugin features and transforms the Constraint @@ -45,12 +48,40 @@ protected: SketchSolver_Manager(); ~SketchSolver_Manager(); +#ifdef SUPPORT_NEW_MOVE + /** \brief Adds or updates a constraint or an entity in the suitable group + * \param[in] theFeature sketch feature to be changed + * \return \c true if the feature changed successfully + */ + bool updateFeature(const std::shared_ptr& theFeature); + + /** \brief Move feature + * \param[in] theMovedFeature dragged sketch feature + * \param[in] theFromPoint original position of the feature + * \param[in] theToPoint prefereble position of the feature (current position of the mouse) + * \return \c true if the feature has been changed successfully + */ + bool moveFeature(const std::shared_ptr& theMovedFeature, + const std::shared_ptr& theFromPoint, + const std::shared_ptr& theToPoint); + + /** \brief Move feature using its moved attribute + * \param[in] theMovedAttribute dragged point attribute of sketch feature + * \param[in] theFromPoint original position of the moved point + * \param[in] theToPoint prefereble position (current position of the mouse) + * \return \c true if the attribute owner has been changed successfully + */ + bool moveAttribute(const std::shared_ptr& theMovedAttribute, + const std::shared_ptr& theFromPoint, + const std::shared_ptr& theToPoint); +#else /** \brief Adds or updates a constraint or an entity in the suitable group * \param[in] theFeature sketch feature to be changed * \param[in] theMoved \c true if the feature has been moved in the viewer * \return \c true if the feature changed successfully */ bool updateFeature(std::shared_ptr theFeature, bool theMoved = false); +#endif /** \brief Removes a constraint from the manager * \param[in] theConstraint constraint to be removed diff --git a/src/SketchSolver/SketchSolver_Storage.h b/src/SketchSolver/SketchSolver_Storage.h index 6ef8d08b5..99ddc6098 100644 --- a/src/SketchSolver/SketchSolver_Storage.h +++ b/src/SketchSolver/SketchSolver_Storage.h @@ -43,10 +43,10 @@ public: virtual void addConstraint(ConstraintPtr theConstraint, ConstraintWrapperPtr theSolverConstraint); - /// \brief Add list of temporary constraints which will be destroyed + /// \brief Add a movement constraint which will be destroyed /// after the next solving of the set of constraints. /// \param theSolverConstraint [in] solver's constraint - virtual void addTemporaryConstraint(const ConstraintWrapperPtr& theSolverConstraint) = 0; + virtual void addMovementConstraint(const ConstraintWrapperPtr& theSolverConstraint) = 0; /// \brief Change mapping feature from SketchPlugin and /// the entity applicable for corresponding solver.