#include "SketchSolver_ConstraintManager.h"
+#include <Events_Loop.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_Data.h>
+#include <Model_Events.h>
#include <SketchPlugin_Constraint.h>
#include <SketchPlugin_ConstraintCoincidence.h>
#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+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;
// ========================================================
// ========= 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()
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<const Model_FeatureUpdatedMessage*>(theMessage);
+
+ // Only sketches and constraints can be added by Create event
+ boost::shared_ptr<SketchPlugin_Sketch> aSketch =
+ boost::dynamic_pointer_cast<SketchPlugin_Sketch>(aCreateMsg->feature());
+ if (aSketch)
+ {
+ addWorkplane(aSketch);
+ return ;
+ }
+ boost::shared_ptr<SketchPlugin_Constraint> aConstraint =
+ boost::dynamic_pointer_cast<SketchPlugin_Constraint>(aCreateMsg->feature());
+ if (aConstraint)
+ {
+ addConstraint(aConstraint);
+ return ;
+ }
+ }
+ else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED))
+ {
+ const Model_FeatureDeletedMessage* aDeleteMsg = dynamic_cast<const Model_FeatureDeletedMessage*>(theMessage);
+ /// \todo Implement deleting objects on event
+ }
+ else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED))
+ {
+ const Model_FeatureUpdatedMessage* aUpdateMsg = dynamic_cast<const Model_FeatureUpdatedMessage*>(theMessage);
+
+ boost::shared_ptr<SketchPlugin_Sketch> aSketch =
+ boost::dynamic_pointer_cast<SketchPlugin_Sketch>(aUpdateMsg->feature());
+ if (aSketch)
+ {
+ updateWorkplane(aSketch);
+ return ;
+ }
+
+ boost::shared_ptr<SketchPlugin_Constraint> aConstraint =
+ boost::dynamic_pointer_cast<SketchPlugin_Constraint>(aUpdateMsg->feature());
+ if (aConstraint)
+ {
+ updateConstraint(aConstraint);
+ return ;
+ }
+
+ boost::shared_ptr<SketchPlugin_Feature> aFeature =
+ boost::dynamic_pointer_cast<SketchPlugin_Feature>(aUpdateMsg->feature());
+ if (aFeature)
+ updateEntity(aFeature);
+ }
+}
+
+
+bool SketchSolver_ConstraintManager::addWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch)
+{
+ // Check the specified workplane is already used
+ std::vector<SketchSolver_ConstraintGroup>::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<SketchPlugin_Constraint> theConstraint,
std::vector<Slvs_hGroup>& theGroupIDs) const
// ========= SketchSolver_ConstraintGroup ===============
// ========================================================
-SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::SketchSolver_ConstraintGroup()
+SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::
+ SketchSolver_ConstraintGroup(boost::shared_ptr<SketchPlugin_Sketch> theWorkplane)
: myID(++myGroupIndexer),
myParamMaxID(0),
myEntityMaxID(0),
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()
delete [] myConstrSet.failed;
}
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isBaseWorkplane(
+ boost::shared_ptr<SketchPlugin_Sketch> theWorkplane) const
+{
+ return theWorkplane == mySketch;
+}
+
bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isInteract(
boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const
{
}
bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addWorkplane(
- std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams)
+ boost::shared_ptr<SketchPlugin_Sketch> theParams)
{
/// \todo Should be implemented
return false;
#include "SketchSolver.h"
+#include <Events_Listener.h>
#include <SketchPlugin_Constraint.h>
// Need to be defined before including SolveSpace to avoid additional dependances on Windows platform
/** \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();
* \param[in] theConstraint constraint to be added
* \return \c true if the constraint added successfully
*/
- SKETCHSOLVER_EXPORT bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+ bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> 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<SketchPlugin_Constraint> theConstraint);
+ bool removeConstraint(boost::shared_ptr<SketchPlugin_Constraint> 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<SketchPlugin_Constraint> 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<SketchPlugin_Sketch> 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<SketchPlugin_Sketch> 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<SketchPlugin_Sketch> 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<SketchPlugin_Feature> theFeature);
private:
class SketchSolver_ConstraintGroup;
std::vector<Slvs_hGroup>& theGroupIDs) const;
private:
- std::vector<SketchSolver_ConstraintGroup> myGroups; ///< groups of constraints
+ static SketchSolver_ConstraintManager* _self; ///< Self pointer to implement singleton functionality
+ std::vector<SketchSolver_ConstraintGroup> myGroups; ///< Groups of constraints
};
class SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup
{
public:
- SketchSolver_ConstraintGroup();
+ /** \brief New group based on specified workplane
+ */
+ SketchSolver_ConstraintGroup(boost::shared_ptr<SketchPlugin_Sketch> theWorkplane);
+
~SketchSolver_ConstraintGroup();
/// \brief Returns group's unique identifier
*/
bool isInteract(boost::shared_ptr<SketchPlugin_Constraint> 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<ModelAPI_Attribute> >& theParams);
+ bool isBaseWorkplane(boost::shared_ptr<SketchPlugin_Sketch> 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
int getConstraintType(const boost::shared_ptr<SketchPlugin_Constraint>& 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<SketchPlugin_Sketch> theSketch);
+
+private:
+ // SolveSpace entities
Slvs_hGroup myID; ///< the index of the group
Slvs_Entity myWorkplane; ///< Workplane for the current group
std::vector<Slvs_Param> 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<Slvs_Entity> 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<Slvs_Constraint> 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<SketchPlugin_Sketch> mySketch; ///< Equivalent to workplane
std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_Constraint>
myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints
};