#include "SketchPlugin_Constraint.h"
+#include <ModelAPI_Data.h>
+#include <SketchPlugin_Sketch.h>
+
+const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Constraint::preview()
+{
+ return getPreview();
+}
+
void SketchPlugin_Constraint::addConstrainedObject(
+ const std::string& theAttrID,
const boost::shared_ptr<ModelAPI_AttributeReference>& theReference)
{
+ if (!data()->attribute(theAttrID).get())
+ data()->addAttribute(theAttrID, theReference->type());
+ boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ data()->attribute(theAttrID))->setValue(theReference->value());
}
void SketchPlugin_Constraint::addConstrainedObject(
+ const std::string& theAttrID,
const boost::shared_ptr<ModelAPI_AttributeRefAttr>& theReference)
{
+ if (!data()->attribute(theAttrID).get())
+ data()->addAttribute(theAttrID, theReference->type());
+ boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ data()->attribute(theAttrID))->setValue(theReference->value());
+}
+
+void SketchPlugin_Constraint::getSketchParameters(
+ std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams)
+{
+ theParams.push_back(sketch()->data()->attribute(SKETCH_ATTR_ORIGIN));
+ theParams.push_back(sketch()->data()->attribute(SKETCH_ATTR_DIRX));
+ theParams.push_back(sketch()->data()->attribute(SKETCH_ATTR_DIRY));
+ theParams.push_back(sketch()->data()->attribute(SKETCH_ATTR_NORM));
}
SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
{static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+ /// Returns the sketch preview
+ /// \param theSketch the owner of this feature
+ /// \return the built preview
+ SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
/** \brief Adds sub-feature of the higher level feature (sub-element of the sketch)
* \param theFeature sub-feature
*/
const boost::shared_ptr<ModelAPI_Feature>& theFeature) {}
/** \brief Adds an object of the constraint. The object added by the reference.
- * \param theReference reference to the feature, which will be constrained
+ * \param[in] theAttrID identifier of the attribute
+ * \param[in] theReference reference to the feature, which will be constrained
*/
SKETCHPLUGIN_EXPORT virtual void addConstrainedObject(
+ const std::string& theAttrID,
const boost::shared_ptr<ModelAPI_AttributeReference>& theReference);
/** \brief Adds an object of the constraint. The object added by the reference to its attribute.
- * \param theReference reference to the attribute feature, which will be constrained
+ * \param[in] theAttrID identifier of the attribute
+ * \param[in] theReference reference to the attribute feature, which will be constrained
*/
SKETCHPLUGIN_EXPORT virtual void addConstrainedObject(
+ const std::string& theAttrID,
const boost::shared_ptr<ModelAPI_AttributeRefAttr>& theReference);
+ /** \brief Prepares list of attributes of current sketch workplane
+ * \param[out] theParams list of attributes
+ */
+ SKETCHPLUGIN_EXPORT void getSketchParameters(
+ std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams);
+
/// \brief Use plugin manager for features creation
SketchPlugin_Constraint() {}
{ /* do nothing */ }
/// \brief Use plugin manager for features creation
- SketchPlugin_ConstraintDistance();
+ SKETCHPLUGIN_EXPORT SketchPlugin_ConstraintDistance();
/** \brief Initializes the attributes of the constraint
*
SketchPlugin
)
-SET(INCLUDE_DIRECTORIES
+INCLUDE_DIRECTORIES(
../SketchPlugin
+ ../ModelAPI
+ ../GeomAPI
)
+ADD_DEFINITIONS(-DSKETCHSOLVER_EXPORTS ${BOOST_DEFINITIONS})
+
ADD_LIBRARY(SketchSolver SHARED
${PROJECT_SOURCES}
${PROJECT_HEADERS}
// Author: Artem ZHIDKOV
#include "SketchSolver_ConstraintManager.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <SketchPlugin_Constraint.h>
+#include <SketchPlugin_ConstraintDistance.h>
+#include <SketchPlugin_Line.h>
+
+
+/// This value is used to give unique index to the groups
+static Slvs_hGroup myGroupIndexer = 0;
+
+// ========================================================
+// ========= SketchSolver_ConstraintManager ===============
+// ========================================================
+SketchSolver_ConstraintManager::SketchSolver_ConstraintManager()
+{
+ myGroups.clear();
+}
+
+SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager()
+{
+ myGroups.clear();
+}
+
+void SketchSolver_ConstraintManager::findGroups(
+ boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
+ std::vector<Slvs_hGroup>& theGroupIDs) const
+{
+ std::vector<SketchSolver_ConstraintGroup>::const_iterator aGroupIter;
+ for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
+ if (aGroupIter->isInteract(theConstraint))
+ theGroupIDs.push_back(aGroupIter->getId());
+}
+
+
+// ========================================================
+// ========= SketchSolver_ConstraintGroup ===============
+// ========================================================
+
+SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::SketchSolver_ConstraintGroup()
+ : myID(++myGroupIndexer),
+ myParamMaxID(0),
+ myEntityMaxID(0),
+ myConstrMaxID(0),
+ myConstraintMap()
+{
+ myParams.clear();
+ 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;
+}
+
+SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup()
+{
+ myParams.clear();
+ myEntities.clear();
+ myConstraints.clear();
+ myConstraintMap.clear();
+
+ if (myConstrSet.param)
+ delete [] myConstrSet.param;
+ if (myConstrSet.entity)
+ delete [] myConstrSet.entity;
+ if (myConstrSet.constraint)
+ delete [] myConstrSet.constraint;
+ if (myConstrSet.failed)
+ delete [] myConstrSet.failed;
+}
+
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isInteract(
+ boost::shared_ptr<SketchPlugin_Constraint> theConstraint) const
+{
+ /// \todo Should be implemented
+ return false;
+}
+
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addConstraint(
+ boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
+{
+ if (myWorkplane.h == 0)
+ {
+ // Create workplane when first constraint is added
+ std::list< boost::shared_ptr<ModelAPI_Attribute> > aWPAttr;
+ theConstraint->getSketchParameters(aWPAttr);
+ if (!addWorkplane(aWPAttr))
+ return false;
+ }
+
+ // Create constraint parameters
+ double aDistance = 0.0; // scalar value of the constraint
+ boost::shared_ptr<ModelAPI_AttributeDouble> aDistAttr =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theConstraint->data()->attribute(CONSTRAINT_ATTR_VALUE));
+ if (aDistAttr.get())
+ aDistance = aDistAttr->value();
+
+ Slvs_hEntity aPtA, aPtB, aEntityA, aEntityB; // parameters of the constraint
+ boost::shared_ptr<ModelAPI_Attribute> aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_POINT_A);
+ aPtA = addEntity(aEntAttr);
+ if (aPtA == 0) return false;
+ aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_POINT_B);
+ aPtB = addEntity(aEntAttr);
+ if (aPtB == 0) return false;
+ aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_A);
+ aEntityA = addEntity(aEntAttr);
+ if (aEntityA == 0) return false;
+ aEntAttr = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_B);
+ aEntityB = addEntity(aEntAttr);
+ if (aEntityB == 0) return false;
+
+ // Constraint type
+ int aConstrType = getConstraintType(theConstraint);
+ if (aConstrType == 0) return false;
+
+ // Create SolveSpace constraint structure
+ Slvs_Constraint aConstraint =
+ Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType, myWorkplane.h,
+ aDistance, aPtA, aPtB, aEntityA, aEntityB);
+ myConstraints.push_back(aConstraint);
+ myConstraintMap[theConstraint] = *(myConstraints.rbegin());
+
+ return true;
+}
+
+Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addEntity(
+ boost::shared_ptr<ModelAPI_Attribute> theEntity)
+{
+ /// \todo Should be implemented
+ return 0;
+}
+
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addWorkplane(
+ std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams)
+{
+ /// \todo Should be implemented
+ return false;
+}
+
+int SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::getConstraintType(
+ const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint) const
+{
+ if (theConstraint->getKind() == SketchPlugin_ConstraintDistance().getKind())
+ {
+ boost::shared_ptr<ModelAPI_Attribute> aPtA = theConstraint->data()->attribute(CONSTRAINT_ATTR_POINT_A);
+ boost::shared_ptr<ModelAPI_Attribute> aPtB = theConstraint->data()->attribute(CONSTRAINT_ATTR_POINT_B);
+ boost::shared_ptr<ModelAPI_Attribute> aEntA = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_A);
+ boost::shared_ptr<ModelAPI_Attribute> aEntB = theConstraint->data()->attribute(CONSTRAINT_ATTR_ENTITY_B);
+ boost::shared_ptr<ModelAPI_AttributeDouble> aDistance =
+ boost::shared_dynamic_cast<ModelAPI_AttributeDouble>(theConstraint->data()->attribute(CONSTRAINT_ATTR_VALUE));
+ if (aPtA.get()) // ptA is an attribute of the constraint
+ {
+// if (aEntA.get()) // entityA is an attribute of the constraint
+// {
+// if (aEntA->feature()->getKind() == SketchPlugin_Line().getKind()) // entityA is a line
+// {
+// if (aEntB.get() && aEntB->feature()->getKind() == SketchPlugin_Line().getKind()) // entityB is a line too
+// return SLVS_C_ANGLE;
+// else if (aPtB.get()) // ptB is also an attribute of the constraint
+// return SLVS_C_PROJ_PT_DISTANCE;
+// else
+// return SLVS_C_PT_LINE_DISTANCE;
+// }
+// /// \todo Implement other point-entity distances
+// }
+// else
+ if (aPtB.get()) // ptB is an attribute of the constrtaint => point-point distance
+ {
+ if (aDistance->value() == 0.0)
+ return SLVS_C_POINTS_COINCIDENT;
+ else
+ return SLVS_C_PT_PT_DISTANCE;
+ }
+ }
+ else if (aEntA.get() && !aEntB.get() && !aPtB.get())
+ return SLVS_C_DIAMETER;
+ return SLVS_C_UNKNOWN;
+ }
+ /// \todo Implement other kind of constrtaints
+
+ return SLVS_C_UNKNOWN;
+}
#include "SketchSolver.h"
+#include <SketchPlugin_Constraint.h>
+
+// Need to be defined before including SolveSpace to avoid additional dependances on Windows platform
+#if defined(WIN32) && !defined(HAVE_C99_INTEGER_TYPES)
+typedef unsigned int UINT32;
+#endif
+#include <string.h>
+#include <slvs.h>
+
+#include <map>
+#include <vector>
+
+
+// Unknown constraint (for error reporting)
+#define SLVS_C_UNKNOWN 0
+
/** \class SketchSolver_ConstraintManager
* \ingroup DataModel
* \brief Transforms the Constraint feature into the format understandable by SolveSpace library.
*/
class SketchSolver_ConstraintManager
{
+public:
+ SketchSolver_ConstraintManager();
+ ~SketchSolver_ConstraintManager();
+
+ /** \brief Adds a constraint into the manager
+ * \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);
+
+ /** \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);
+
private:
class SketchSolver_ConstraintGroup;
+
+ /** \brief Searches list of groups which interact with specified constraint
+ * \param[in] theConstraint constraint to be found
+ * \param[out] theGroups list of group indexes interacted with constraint
+ */
+ void findGroups(boost::shared_ptr<SketchPlugin_Constraint> theConstraint,
+ std::vector<Slvs_hGroup>& theGroupIDs) const;
+
+private:
+ std::vector<SketchSolver_ConstraintGroup> myGroups; ///< groups of constraints
};
+
+/** \class SketchSolver_ConstraintGroup
+ * \ingroup DataModel
+ * \brief Keeps the group of constraints which based on the same entities
+ */
class SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup
{
+public:
+ SketchSolver_ConstraintGroup();
+ ~SketchSolver_ConstraintGroup();
+
+ /// \brief Returns group's unique identifier
+ const Slvs_hGroup& getId() const
+ {return myID;}
+
+ /** \brief Adds a constraint into the group
+ * \param[in] theConstraint constraint to be added
+ * \return \c true if the constraint added successfully
+ */
+ bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+ /** \brief Removes a constraint into the group
+ * \param[in] theConstraint constraint to be removed
+ * \return \c true if the constraint removed successfully
+ */
+ bool removeConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+
+ /** \brief Verifies the constraint uses the objects from this group
+ * \param[in] theConstraint constraint for verification of interaction
+ * \return \c true if the constrained objects are used in current group
+ */
+ 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
+ */
+ bool addWorkplane(std::list< boost::shared_ptr<ModelAPI_Attribute> >& theParams);
+
+ /** \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
+ */
+ Slvs_hEntity addEntity(boost::shared_ptr<ModelAPI_Attribute> theEntity);
+
+ /** \brief Adds a parameter into the group
+ * \param[in] theParam parameter to be added
+ * \return identifier of created parameter or 0 if it was not added
+ */
+ Slvs_hParam addParameter(double theParam);
+
+ /** \brief Compute constraint type according to SolveSpace identifiers
+ * \param[in] theConstraint constraint which type should be determined
+ * \return identifier of constraint type
+ */
+ int getConstraintType(const boost::shared_ptr<SketchPlugin_Constraint>& theConstraint) const;
+
+private:
+ 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
+ std::vector<Slvs_Entity> myEntities; ///< List of entities of the constaints
+ Slvs_hEntity myEntityMaxID; ///< Actual maximal ID of entities
+ std::vector<Slvs_Constraint> myConstraints; ///< List of constraints in SolveSpace format
+ Slvs_hConstraint myConstrMaxID; ///< Actual maximal ID of constraints
+ Slvs_System myConstrSet; ///< SolveSpace's set of equations obtained by constraints
+ std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_Constraint>
+ myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints
};
#endif