#include <SketchPlugin_Line.h>
#include <SketchPlugin_Sketch.h>
+#include <math.h>
+
+/// Tolerance for value of parameters
+const double tolerance = 1.e-10;
+
+// Initialization of constraint manager self pointer
SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::_self = 0;
/// Global constaint manager object
/// This value is used to give unique index to the groups
static Slvs_hGroup myGroupIndexer = 0;
-/** \brief Makes transformation from ModelAPI_Attribute to the list of parameters' values
- * \remark Convertion of normal in 3D needs two attributes (coordinate axis of transversal plane)
- * \param[in,out] theParams list of converted values which appended to incoming list
- * \param[in] theAttr attribute to be converted
- * \param[in] theNormExtraAttr additional attribute for conversion of a normal
- */
-static void ConvertAttributeToParamList(
- std::vector<double>& theParams,
- boost::shared_ptr<ModelAPI_Attribute> theAttr,
- boost::shared_ptr<ModelAPI_Attribute> theNormExtraAttr = boost::shared_ptr<ModelAPI_Attribute>());
-
/** \brief Search the entity/parameter with specified ID in the list of elements
* \param[in] theEntityID unique ID of the element
* \param[in] theEntities list of elements
static int Search(const uint32_t& theEntityID, const std::vector<T>& theEntities);
+
// ========================================================
// ========= SketchSolver_ConstraintManager ===============
// ========================================================
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))
+ if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED) ||
+ theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED))
{
const Model_FeatureUpdatedMessage* aUpdateMsg = 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>(aUpdateMsg->feature());
if (aSketch)
{
- updateWorkplane(aSketch);
+ changeWorkplane(aSketch);
return ;
}
-
boost::shared_ptr<SketchPlugin_Constraint> aConstraint =
boost::dynamic_pointer_cast<SketchPlugin_Constraint>(aUpdateMsg->feature());
if (aConstraint)
{
-// updateConstraint(aConstraint);
+ changeConstraint(aConstraint);
return ;
}
// if (aFeature)
// updateEntity(aFeature);
}
+ 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
+ }
}
-
-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;
-}
-
-bool SketchSolver_ConstraintManager::updateWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch)
+bool SketchSolver_ConstraintManager::changeWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch)
{
bool aResult = true; // changed when a workplane wrongly updated
bool isUpdated = false;
if (aGroupIter->isBaseWorkplane(theSketch))
{
isUpdated = true;
- if (!aGroupIter->updateWorkplane(theSketch))
+ if (!aGroupIter->updateWorkplane())
aResult = false;
}
- // If the workplane is not updates, so this is a new workplane
+ // If the workplane is not updated, so this is a new workplane
if (!isUpdated)
- return addWorkplane(theSketch);
+ {
+ SketchSolver_ConstraintGroup aNewGroup(theSketch);
+ // Verify that the group is created successfully
+ if (!aNewGroup.isBaseWorkplane(theSketch))
+ return false;
+ myGroups.push_back(aNewGroup);
+ }
return aResult;
}
-bool SketchSolver_ConstraintManager::addConstraint(
+bool SketchSolver_ConstraintManager::changeConstraint(
boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
{
// Search the groups which this constraint touchs
boost::shared_ptr<SketchPlugin_Sketch> aWP = findWorkplaneForConstraint(theConstraint);
if (!aWP) return false;
SketchSolver_ConstraintGroup aGroup(aWP);
- aGroup.addConstraint(theConstraint);
+ if (!aGroup.changeConstraint(theConstraint))
+ return false;
myGroups.push_back(aGroup);
return true;
}
std::vector<SketchSolver_ConstraintGroup>::iterator aGroupIter;
for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++)
if (aGroupIter->getId() == aGroupId)
- return aGroupIter->addConstraint(theConstraint);
+ return aGroupIter->changeConstraint(theConstraint);
}
else if (aGroups.size() > 1)
{ // Several groups applicable for this constraint => need to merge them
myParamMaxID(0),
myEntityMaxID(0),
myConstrMaxID(0),
- myConstraintMap()
+ myConstraintMap(),
+ myNeedToSolve(false)
{
myParams.clear();
myEntities.clear();
return false;
}
-bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addConstraint(
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeConstraint(
boost::shared_ptr<SketchPlugin_Constraint> theConstraint)
{
// There is no workplane yet, something wrong
boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
);
- aConstrEnt[indAttr] = addEntity(aConstrAttr->attr());
+ aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
}
// Create SolveSpace constraint structure
return true;
}
-Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addEntity(
+Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeEntity(
boost::shared_ptr<ModelAPI_Attribute> theEntity)
{
+ // If the entity is already in the group, try to find it
+ std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
+ aEntIter = myEntityMap.find(theEntity);
+ std::vector<Slvs_Param>::const_iterator aParamIter; // looks at first parameter of already existent entity or at the end of vector otherwise
+ if (aEntIter == myEntityMap.end()) // no such entity => should be created
+ aParamIter = myParams.end();
+ else
+ { // the entity already exists
+ int aEntPos = Search(aEntIter->second, myEntities);
+ int aParamPos = Search(myEntities[aEntPos].param[0], myParams);
+ aParamIter = myParams.begin() + aParamPos;
+ }
+
// Look over supported types of entities
// Point in 3D
boost::dynamic_pointer_cast<GeomDataAPI_Point>(theEntity);
if (aPoint)
{
- Slvs_hParam aX = addParameter(aPoint->x());
- Slvs_hParam aY = addParameter(aPoint->y());
- Slvs_hParam aZ = addParameter(aPoint->z());
+ Slvs_hParam aX = changeParameter(aPoint->x(), aParamIter);
+ Slvs_hParam aY = changeParameter(aPoint->y(), aParamIter);
+ Slvs_hParam aZ = changeParameter(aPoint->z(), aParamIter);
+
+ if (aEntIter != myEntityMap.end()) // the entity already exists
+ return aEntIter->second;
+
+ // New entity
Slvs_Entity aPtEntity = Slvs_MakePoint3d(++myEntityMaxID, myID, aX, aY, aZ);
myEntities.push_back(aPtEntity);
+ myEntityMap[theEntity] = aPtEntity.h;
return aPtEntity.h;
}
// The 2D points are created on workplane. So, if there is no workplane yet, then error
if (myWorkplane.h == 0)
return 0;
- Slvs_hParam aU = addParameter(aPoint2D->x());
- Slvs_hParam aV = addParameter(aPoint2D->y());
+ Slvs_hParam aU = changeParameter(aPoint2D->x(), aParamIter);
+ Slvs_hParam aV = changeParameter(aPoint2D->y(), aParamIter);
+
+ if (aEntIter != myEntityMap.end()) // the entity already exists
+ return aEntIter->second;
+
+ // New entity
Slvs_Entity aPt2DEntity = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, aU, aV);
myEntities.push_back(aPt2DEntity);
+ myEntityMap[theEntity] = aPt2DEntity.h;
return aPt2DEntity.h;
}
return 0;
}
-Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addNormal(
+Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeNormal(
boost::shared_ptr<ModelAPI_Attribute> theDirX,
- boost::shared_ptr<ModelAPI_Attribute> theDirY)
+ boost::shared_ptr<ModelAPI_Attribute> theDirY,
+ boost::shared_ptr<ModelAPI_Attribute> theNorm)
{
- // Convert axes to the coordinates of normal
- std::vector<double> aNormCoord;
- ConvertAttributeToParamList(aNormCoord, theDirX, theDirY);
-
- // Create a normal
+ boost::shared_ptr<GeomDataAPI_Dir> aDirX =
+ boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theDirX);
+ boost::shared_ptr<GeomDataAPI_Dir> aDirY =
+ boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theDirY);
+ if (!aDirX || !aDirY ||
+ (fabs(aDirX->x()) + fabs(aDirX->y()) + fabs(aDirX->z()) < tolerance) ||
+ (fabs(aDirY->x()) + fabs(aDirY->y()) + fabs(aDirY->z()) < tolerance))
+ return 0;
+
+ // quaternion parameters of normal vector
+ double qw, qx, qy, qz;
+ Slvs_MakeQuaternion(aDirX->x(), aDirX->y(), aDirX->z(),
+ aDirY->x(), aDirY->y(), aDirY->z(),
+ &qw, &qx, &qy, &qz);
+ double aNormCoord[4] = {qw, qx, qy, qz};
+
+ // Try to find existent normal
+ std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
+ aEntIter = myEntityMap.find(theNorm);
+ std::vector<Slvs_Param>::const_iterator aParamIter; // looks at first parameter of already existent entity or at the end of vector otherwise
+ if (aEntIter == myEntityMap.end()) // no such entity => should be created
+ aParamIter = myParams.end();
+ else
+ { // the entity already exists, update it
+ int aEntPos = Search(aEntIter->second, myEntities);
+ int aParamPos = Search(myEntities[aEntPos].param[0], myParams);
+ aParamIter = myParams.begin() + aParamPos;
+ }
+
+ // Change parameters of the normal
Slvs_hParam aNormParams[4];
for (int i = 0; i < 4; i++)
- aNormParams[i] = addParameter(aNormCoord[i]);
+ aNormParams[i] = changeParameter(aNormCoord[i], aParamIter);
+
+ if (aEntIter != myEntityMap.end()) // the entity already exists
+ return aEntIter->second;
+
+ // Create a normal
Slvs_Entity aNormal = Slvs_MakeNormal3d(++myEntityMaxID, myID,
aNormParams[0], aNormParams[1], aNormParams[2], aNormParams[3]);
myEntities.push_back(aNormal);
+ myEntityMap[theNorm] = aNormal.h;
return aNormal.h;
}
if (myWorkplane.h)
return false; // the workplane already exists
- // Get parameters of workplane
- boost::shared_ptr<ModelAPI_Attribute> aDirX = theSketch->data()->attribute(SKETCH_ATTR_DIRX);
- boost::shared_ptr<ModelAPI_Attribute> aDirY = theSketch->data()->attribute(SKETCH_ATTR_DIRY);
- boost::shared_ptr<ModelAPI_Attribute> anOrigin = theSketch->data()->attribute(SKETCH_ATTR_ORIGIN);
- // Transform them into SolveSpace format
- Slvs_hEntity aNormalWP = addNormal(aDirX, aDirY);
- if (!aNormalWP) return false;
- Slvs_hEntity anOriginWP = addEntity(anOrigin);
- if (!anOriginWP) return false;
- // Create workplane
- myWorkplane = Slvs_MakeWorkplane(++myEntityMaxID, myID, anOriginWP, aNormalWP);
mySketch = theSketch;
- // Workplane should be added to the list of entities
- myEntities.push_back(myWorkplane);
- return true;
+ return updateWorkplane();
}
-bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateWorkplane(
- boost::shared_ptr<SketchPlugin_Sketch> theSketch)
+bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::updateWorkplane()
{
- // Renew Sketch pointer
- mySketch = theSketch;
-
// Get parameters of workplane
- boost::shared_ptr<ModelAPI_Attribute> aDirX = theSketch->data()->attribute(SKETCH_ATTR_DIRX);
- boost::shared_ptr<ModelAPI_Attribute> aDirY = theSketch->data()->attribute(SKETCH_ATTR_DIRY);
- boost::shared_ptr<ModelAPI_Attribute> anOrig = theSketch->data()->attribute(SKETCH_ATTR_ORIGIN);
- // Transform them to lists of coordinates
- std::vector<double> aNormal;
- ConvertAttributeToParamList(aNormal, aDirX, aDirY);
- std::vector<double> anOrigin;
- ConvertAttributeToParamList(anOrigin, anOrig);
-
- // Search the normal and the origin in the parameters list and update their values.
- // Remark: entities are sorted in the vector, so the most probable position
- // of the entity is equal to identifier the entity
-
- // search normal
- int aEntPos = Search(myWorkplane.normal, myEntities);
- if (aEntPos < 0) return false;
- // search first parameter of normal
- int aParamPos = Search(myEntities[aEntPos].param[0], myParams);
- if (aParamPos < 0) return false;
- std::vector<Slvs_Param>::iterator aParamIter = myParams.begin() + aParamPos;
- // change normal parameters
- std::vector<double>::iterator anIter;
- for (anIter = aNormal.begin(); anIter != aNormal.end(); anIter++, aParamIter++)
- aParamIter->val = *anIter;
-
- // search origin
- aEntPos = Search(myWorkplane.point[0], myEntities);
- if (aEntPos < 0) return false;
- // search first parameter of origin
- aParamPos = Search(myEntities[aEntPos].param[0], myParams);
- if (aParamPos < 0) return false;
- aParamIter = myParams.begin() + aParamPos;
- // change origin's parameters
- for (anIter = anOrigin.begin(); anIter != anOrigin.end(); anIter++, aParamIter++)
- aParamIter->val = *anIter;
+ boost::shared_ptr<ModelAPI_Attribute> aDirX = mySketch->data()->attribute(SKETCH_ATTR_DIRX);
+ boost::shared_ptr<ModelAPI_Attribute> aDirY = mySketch->data()->attribute(SKETCH_ATTR_DIRY);
+ boost::shared_ptr<ModelAPI_Attribute> aNorm = mySketch->data()->attribute(SKETCH_ATTR_NORM);
+ boost::shared_ptr<ModelAPI_Attribute> anOrigin = mySketch->data()->attribute(SKETCH_ATTR_ORIGIN);
+ // Transform them into SolveSpace format
+ Slvs_hEntity aNormalWP = changeNormal(aDirX, aDirY, aNorm);
+ if (!aNormalWP) return false;
+ Slvs_hEntity anOriginWP = changeEntity(anOrigin);
+ if (!anOriginWP) return false;
+ if (!myWorkplane.h)
+ {
+ // Create workplane
+ myWorkplane = Slvs_MakeWorkplane(++myEntityMaxID, myID, anOriginWP, aNormalWP);
+ // Workplane should be added to the list of entities
+ myEntities.push_back(myWorkplane);
+ }
return true;
}
-Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addParameter(double theParam)
+Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::changeParameter(
+ const double& theParam,
+ std::vector<Slvs_Param>::const_iterator& thePrmIter)
{
+ if (thePrmIter != myParams.end())
+ { // Parameter should be updated
+ if (thePrmIter->val != theParam)
+ myNeedToSolve = true; // parameter is changed, need to resolve constraints
+ int aParamPos = thePrmIter - myParams.begin();
+ myParams[aParamPos].val = theParam;
+ thePrmIter++;
+ return myParams[aParamPos].h;
+ }
+
+ // Newly created parameter
Slvs_Param aParam = Slvs_MakeParam(++myParamMaxID, myID, theParam);
myParams.push_back(aParam);
+ myNeedToSolve = true;
+ // The list of parameters is changed, move iterator to the end of the list to avoid problems
+ thePrmIter = myParams.end();
return aParam.h;
}
// ========= Auxiliary functions ===============
// ========================================================
-void ConvertAttributeToParamList(
- std::vector<double>& theParams,
- boost::shared_ptr<ModelAPI_Attribute> theAttr,
- boost::shared_ptr<ModelAPI_Attribute> theNormExtraAttr)
-{
- // Point in 3D
- boost::shared_ptr<GeomDataAPI_Point> aPoint =
- boost::dynamic_pointer_cast<GeomDataAPI_Point>(theAttr);
- if (aPoint)
- {
- theParams.push_back(aPoint->x());
- theParams.push_back(aPoint->y());
- theParams.push_back(aPoint->z());
- return ;
- }
-
- // Point in 2D
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
- boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttr);
- if (aPoint2D)
- {
- theParams.push_back(aPoint2D->x());
- theParams.push_back(aPoint2D->y());
- return ;
- }
-
- // Normal in 3D
- boost::shared_ptr<GeomDataAPI_Dir> aDirX =
- boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theAttr);
- boost::shared_ptr<GeomDataAPI_Dir> aDirY =
- boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theNormExtraAttr);
- if (aDirX && aDirY)
- {
- // quaternion parameters of normal vector
- double qw, qx, qy, qz;
- Slvs_MakeQuaternion(aDirX->x(), aDirX->y(), aDirX->z(),
- aDirY->x(), aDirY->y(), aDirY->z(),
- &qw, &qx, &qy, &qz);
- theParams.push_back(qw);
- theParams.push_back(qx);
- theParams.push_back(qy);
- theParams.push_back(qz);
- }
-
- /// \todo Other types of entities
-}
-
template <typename T>
int Search(const uint32_t& theEntityID, const std::vector<T>& theEntities)
{
return -1;
return aEntIter - theEntities.begin();
}
-
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
+ /** \brief Adds or updates a constraint in the suitable group
+ * \param[in] theConstraint constraint to be changed
+ * \return \c true if the constraint changed successfully
*/
- bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+ bool changeConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
/** \brief Removes a constraint from the manager
* \param[in] theConstraint constraint to be removed
*/
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
+ /** \brief Adds or updates a workplane in the manager
+ * \param[in] theSketch the feature to create or update workplane
+ * \return \c true if the workplane cahnged successfully
*/
- 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);
+ bool changeWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch);
/** \brief Removes a workplane from the manager.
* All groups based on such workplane will be removed too.
*/
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
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
+ /** \brief Adds or updates a constraint in the group
+ * \param[in] theConstraint constraint to be changed
+ * \return \c true if the constraint added or updated successfully
*/
- bool addConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
+ bool changeConstraint(boost::shared_ptr<SketchPlugin_Constraint> theConstraint);
/** \brief Removes a constraint into the group
* \param[in] theConstraint constraint to be removed
boost::shared_ptr<SketchPlugin_Sketch> getWorkplane() const
{ return mySketch; }
- /** \brief Update parameters of workplane. Should be called when Update event is coming
- * \param[in] theWorkplane workplane to be updated
- * \return \c true if workplane updated successfully
+ /** \brief Update parameters of workplane. Should be called when Update event is coming.
+ * \return \c true if workplane updated successfully, \c false if workplane parameters are not consistent
*/
- bool updateWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theWorkplane);
+ bool updateWorkplane();
protected:
- /** \brief Adds an entity into the group
+ /** \brief Adds or updates an entity in the group
*
* The parameters of entity will be parsed and added to the list of SolveSpace parameters.
* Parameters of certain entity will be placed sequentially in the list.
*
* \param[in] theEntity the object of constraint
- * \return identifier of created entity or 0 if entity was not added
+ * \return identifier of changed entity or 0 if entity could not be changed
*/
- Slvs_hEntity addEntity(boost::shared_ptr<ModelAPI_Attribute> theEntity);
+ Slvs_hEntity changeEntity(boost::shared_ptr<ModelAPI_Attribute> theEntity);
- /** \brief Adds a normal into the group
+ /** \brief Adds or updates a normal in the group
*
* Normal is a special entity in SolveSpace, which defines a direction in 3D and
* a rotation about this direction. So, SolveSpace represents normals as unit quaternions.
*
* \param[in] theDirX first coordinate axis of the plane
* \param[in] theDirY second coordinate axis of the plane
- * \return identifier of created normal
+ * \param[in] theNorm attribute for the normal (used to identify newly created entity)
+ * \return identifier of created or updated normal
*/
- Slvs_hEntity addNormal(boost::shared_ptr<ModelAPI_Attribute> theDirX,
- boost::shared_ptr<ModelAPI_Attribute> theDirY);
+ Slvs_hEntity changeNormal(boost::shared_ptr<ModelAPI_Attribute> theDirX,
+ boost::shared_ptr<ModelAPI_Attribute> theDirY,
+ boost::shared_ptr<ModelAPI_Attribute> theNorm);
- /** \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
+ /** \brief Adds or updates a parameter in the group
+ * \param[in] theParam the value of parameter
+ * \param[in] thePrmIter the cell in the list of parameters which should be changed
+ * (the iterator will be increased if it does not reach the end of the list)
+ * \return identifier of changed parameter; when the parameter cannot be created, returned ID is 0
*/
- Slvs_hParam addParameter(double theParam);
+ Slvs_hParam changeParameter(const double& theParam,
+ std::vector<Slvs_Param>::const_iterator& thePrmIter);
/** \brief Compute constraint type according to SolveSpace identifiers
* and verify that constraint parameters are correct
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
+ * \return \c true if success, \c false if workplane parameters are not consistent
*/
bool addWorkplane(boost::shared_ptr<SketchPlugin_Sketch> theSketch);
std::vector<Slvs_Constraint> myConstraints; ///< List of constraints in SolveSpace format
Slvs_hConstraint myConstrMaxID; ///< Actual maximal ID of constraints (not equal to myConstraints size)
Slvs_System myConstrSet; ///< SolveSpace's set of equations obtained by constraints
+ bool myNeedToSolve; ///< Indicator that something changed in the group and constraint system need to be rebuilt
// 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
+ myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints
+ std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>
+ myEntityMap; ///< The map between parameters of constraints and their equivalent SolveSpace entities
};
#endif