From 206c16c4f6765e5d4027e8bb19125fb25ed59a1f Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 13 May 2014 18:18:20 +0400 Subject: [PATCH] Constraint manager is an event listener now --- src/SketchSolver/CMakeLists.txt | 9 +- .../SketchSolver_ConstraintManager.cpp | 109 +++++++++++++++++- .../SketchSolver_ConstraintManager.h | 91 ++++++++++++--- 3 files changed, 186 insertions(+), 23 deletions(-) diff --git a/src/SketchSolver/CMakeLists.txt b/src/SketchSolver/CMakeLists.txt index 5d04a4a95..974e46481 100644 --- a/src/SketchSolver/CMakeLists.txt +++ b/src/SketchSolver/CMakeLists.txt @@ -15,12 +15,15 @@ SET(PROJECT_SOURCES SET(PROJECT_LIBRARIES ${SLVS_LIBRARIES} SketchPlugin + Events ) INCLUDE_DIRECTORIES( - ../SketchPlugin - ../ModelAPI - ../GeomAPI + ${PROJECT_SOURCE_DIR}/src/SketchPlugin + ${PROJECT_SOURCE_DIR}/src/ModelAPI + ${PROJECT_SOURCE_DIR}/src/Model + ${PROJECT_SOURCE_DIR}/src/GeomAPI + ${PROJECT_SOURCE_DIR}/src/Events ) ADD_DEFINITIONS(-DSKETCHSOLVER_EXPORTS ${BOOST_DEFINITIONS}) diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index 7984b031c..3251a2af3 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -4,12 +4,19 @@ #include "SketchSolver_ConstraintManager.h" +#include #include #include +#include #include #include #include +#include +SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::_self = 0; + +/// Global constaint manager object +SketchSolver_ConstraintManager* myManager = SketchSolver_ConstraintManager::Instance(); /// This value is used to give unique index to the groups static Slvs_hGroup myGroupIndexer = 0; @@ -17,9 +24,21 @@ static Slvs_hGroup myGroupIndexer = 0; // ======================================================== // ========= SketchSolver_ConstraintManager =============== // ======================================================== +SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::Instance() +{ + if (!_self) + _self = new SketchSolver_ConstraintManager(); + return _self; +} + SketchSolver_ConstraintManager::SketchSolver_ConstraintManager() { myGroups.clear(); + + // Register in event loop + Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED)); + Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED)); + Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED)); } SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager() @@ -27,6 +46,78 @@ SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager() myGroups.clear(); } +void SketchSolver_ConstraintManager::processEvent(const Events_Message* theMessage) +{ + if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED)) + { + const Model_FeatureUpdatedMessage* aCreateMsg = dynamic_cast(theMessage); + + // Only sketches and constraints can be added by Create event + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(aCreateMsg->feature()); + if (aSketch) + { + addWorkplane(aSketch); + return ; + } + boost::shared_ptr aConstraint = + boost::dynamic_pointer_cast(aCreateMsg->feature()); + if (aConstraint) + { + addConstraint(aConstraint); + return ; + } + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED)) + { + const Model_FeatureDeletedMessage* aDeleteMsg = dynamic_cast(theMessage); + /// \todo Implement deleting objects on event + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED)) + { + const Model_FeatureUpdatedMessage* aUpdateMsg = dynamic_cast(theMessage); + + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(aUpdateMsg->feature()); + if (aSketch) + { + updateWorkplane(aSketch); + return ; + } + + boost::shared_ptr aConstraint = + boost::dynamic_pointer_cast(aUpdateMsg->feature()); + if (aConstraint) + { + updateConstraint(aConstraint); + return ; + } + + boost::shared_ptr aFeature = + boost::dynamic_pointer_cast(aUpdateMsg->feature()); + if (aFeature) + updateEntity(aFeature); + } +} + + +bool SketchSolver_ConstraintManager::addWorkplane(boost::shared_ptr theSketch) +{ + // Check the specified workplane is already used + std::vector::const_iterator aGroupIter; + for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) + if (aGroupIter->isBaseWorkplane(theSketch)) + return true; + // Create new group for workplane + SketchSolver_ConstraintGroup aNewGroup(theSketch); + // Verify that the group is created successfully + if (!aNewGroup.isBaseWorkplane(theSketch)) + return false; + myGroups.push_back(aNewGroup); + return true; +} + + void SketchSolver_ConstraintManager::findGroups( boost::shared_ptr theConstraint, std::vector& theGroupIDs) const @@ -42,7 +133,8 @@ void SketchSolver_ConstraintManager::findGroups( // ========= SketchSolver_ConstraintGroup =============== // ======================================================== -SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::SketchSolver_ConstraintGroup() +SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup:: + SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane) : myID(++myGroupIndexer), myParamMaxID(0), myEntityMaxID(0), @@ -53,14 +145,15 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::SketchSolver_Const myEntities.clear(); myConstraints.clear(); - // The workplane will be initialized on first constraint, so its handle is NULL meanwhile - myWorkplane.h = 0; - // Nullify all elements of the set of equations myConstrSet.param = 0; myConstrSet.entity = 0; myConstrSet.constraint = 0; myConstrSet.failed = 0; + + // Initialize workplane + mySketch = theWorkplane; + addWorkplane(theWorkplane); } SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup() @@ -80,6 +173,12 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_Cons delete [] myConstrSet.failed; } +bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isBaseWorkplane( + boost::shared_ptr theWorkplane) const +{ + return theWorkplane == mySketch; +} + bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isInteract( boost::shared_ptr theConstraint) const { @@ -143,7 +242,7 @@ Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addEn } bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addWorkplane( - std::list< boost::shared_ptr >& theParams) + boost::shared_ptr theParams) { /// \todo Should be implemented return false; diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.h b/src/SketchSolver/SketchSolver_ConstraintManager.h index 7bd108df6..07699e723 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.h +++ b/src/SketchSolver/SketchSolver_ConstraintManager.h @@ -7,6 +7,7 @@ #include "SketchSolver.h" +#include #include // Need to be defined before including SolveSpace to avoid additional dependances on Windows platform @@ -25,15 +26,29 @@ typedef unsigned int UINT32; /** \class SketchSolver_ConstraintManager * \ingroup DataModel - * \brief Transforms the Constraint feature into the format understandable by SolveSpace library. + * \brief Listens the changes of SketchPlugin features and transforms the Constraint + * feature into the format understandable by SolveSpace library. * - * Constraints created for SolveSpace library will be divided into the groups. + * Constraints created for SolveSpace library are divided into the groups. * The division order based on connectedness of the features by the constraints. * The groups may be fused or separated according to the new constraints. + * + * \remark This is a singleton. */ -class SketchSolver_ConstraintManager +class SketchSolver_ConstraintManager : public Events_Listener { public: + /** \brief Main method to create constraint manager + * \return pointer to the singleton + */ + static SketchSolver_ConstraintManager* Instance(); + + /** \brief Implementation of Event Listener method + * \param[in] theMessage the data of the event + */ + virtual void processEvent(const Events_Message* theMessage); + +protected: SketchSolver_ConstraintManager(); ~SketchSolver_ConstraintManager(); @@ -41,13 +56,44 @@ public: * \param[in] theConstraint constraint to be added * \return \c true if the constraint added successfully */ - SKETCHSOLVER_EXPORT bool addConstraint(boost::shared_ptr theConstraint); + bool addConstraint(boost::shared_ptr theConstraint); /** \brief Removes a constraint from the manager * \param[in] theConstraint constraint to be removed * \return \c true if the constraint removed successfully */ - SKETCHSOLVER_EXPORT bool removeConstraint(boost::shared_ptr theConstraint); + bool removeConstraint(boost::shared_ptr theConstraint); + + /** \brief Updates a constraint + * \param[in] theConstraint constraint to be updated + * \return \c true if the constraint was updated + */ + bool updateConstraint(boost::shared_ptr theConstraint); + + /** \brief Adds a workplane into the manager + * \param[in] theSketch the feature to create workplane + * \return \c true if the workplane added successfully + */ + bool addWorkplane(boost::shared_ptr theSketch); + + /** \brief Removes a workplane from the manager. + * All groups based on such workplane will be removed too. + * \param[in] theSketch the feature to be removed + * \return \c true if the workplane removed successfully + */ + bool removeWorkplane(boost::shared_ptr theSketch); + + /** \brief Updates a workplane + * \param[in] theSketch workplane to be updated + * \return \c true if the workplane was updated + */ + bool updateWorkplane(boost::shared_ptr theSketch); + + /** \brief Updates entity which is neither workplane nor constraint + * \param[in] theFeature entity to be updated + * \return \c true if the entity updated successfully + */ + bool updateEntity(boost::shared_ptr theFeature); private: class SketchSolver_ConstraintGroup; @@ -60,7 +106,8 @@ private: std::vector& theGroupIDs) const; private: - std::vector myGroups; ///< groups of constraints + static SketchSolver_ConstraintManager* _self; ///< Self pointer to implement singleton functionality + std::vector myGroups; ///< Groups of constraints }; @@ -71,7 +118,10 @@ private: class SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup { public: - SketchSolver_ConstraintGroup(); + /** \brief New group based on specified workplane + */ + SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane); + ~SketchSolver_ConstraintGroup(); /// \brief Returns group's unique identifier @@ -96,13 +146,13 @@ public: */ bool isInteract(boost::shared_ptr theConstraint) const; -protected: - /** \brief Creates a workplane from the sketch parameters - * \param[in] theParams list of the basic parameters of the workplane - * \return \c true if success + /** \brief Verifies the specified workplane is the same as a base workplane for this group + * \param[in] theWorkplane workplane to be compared + * \return \c true if workplanes are the same */ - bool addWorkplane(std::list< boost::shared_ptr >& theParams); + bool isBaseWorkplane(boost::shared_ptr theWorkplane) const; +protected: /** \brief Adds an entity into the group * \param[in] theEntity the object of constraint * \return identifier of created entity or 0 if entity was not added @@ -122,15 +172,26 @@ protected: int getConstraintType(const boost::shared_ptr& theConstraint) const; private: + /** \brief Creates a workplane from the sketch parameters + * \param[in] theSketch parameters of workplane are the attributes of this sketch + * \return \c true if success + */ + bool addWorkplane(boost::shared_ptr theSketch); + +private: + // SolveSpace entities Slvs_hGroup myID; ///< the index of the group Slvs_Entity myWorkplane; ///< Workplane for the current group std::vector myParams; ///< List of parameters of the constraints - Slvs_hParam myParamMaxID; ///< Actual maximal ID of parameters + Slvs_hParam myParamMaxID; ///< Actual maximal ID of parameters (not equal to myParams size) std::vector myEntities; ///< List of entities of the constaints - Slvs_hEntity myEntityMaxID; ///< Actual maximal ID of entities + Slvs_hEntity myEntityMaxID; ///< Actual maximal ID of entities (not equal to myEntities size) std::vector myConstraints; ///< List of constraints in SolveSpace format - Slvs_hConstraint myConstrMaxID; ///< Actual maximal ID of constraints + Slvs_hConstraint myConstrMaxID; ///< Actual maximal ID of constraints (not equal to myConstraints size) Slvs_System myConstrSet; ///< SolveSpace's set of equations obtained by constraints + + // SketchPlugin entities + boost::shared_ptr mySketch; ///< Equivalent to workplane std::map, Slvs_Constraint> myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints }; -- 2.39.2