#include <GeomDataAPI_Point2D.h>
#include <SketchPlugin_Feature.h>
-/// \brief Get list of parameters of current entity
+#include <cmath>
+
+// Verify the points are equal
+static bool isEqual(const GCS::Point& thePoint1, const GCS::Point& thePoint2);
+// 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);
myType = CONSTRAINT_FIXED;
}
+SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
+ : SketchSolver_Constraint(),
+ myBaseFeature(theFeature)
+{
+ myType = CONSTRAINT_FIXED;
+}
+
void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
{
- SketchSolver_Constraint::blockEvents(isBlocked);
+ if (myBaseFeature)
+ myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
+ if (myBaseConstraint)
+ SketchSolver_Constraint::blockEvents(isBlocked);
}
void SketchSolver_ConstraintFixed::process()
{
cleanErrorMsg();
- if (!myBaseConstraint || !myStorage) {
+ if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
// Not enough parameters are assigned
return;
}
- EntityWrapperPtr aBaseEntity = entityToFix();
- if (!aBaseEntity)
+ EntityWrapperPtr aBaseEntity;
+ getAttributes(aBaseEntity, myFixedEntity);
+ if (!aBaseEntity) {
+ moveFeature(); // remove myFixed entity
myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
+ }
if (!myErrorMsg.empty())
return;
- ConstraintWrapperPtr aConstraint = fixFeature(aBaseEntity);
- myStorage->addConstraint(myBaseConstraint, aConstraint);
+ fixFeature(aBaseEntity);
}
-ConstraintWrapperPtr SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
+void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
{
GCS::VEC_pD aParameters = toParameters(theFeature);
GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt)));
}
- return ConstraintWrapperPtr(
+ myConstraint = ConstraintWrapperPtr(
new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
+
+ if (myBaseConstraint)
+ myStorage->addConstraint(myBaseConstraint, myConstraint);
+ else
+ myStorage->addTemporaryConstraint(myConstraint);
+}
+
+void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
+ EntityWrapperPtr& theFixedEntity)
+{
+ if (myBaseFeature) {
+ // if the feature is copy, do not move it
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
+ if (aSketchFeature && aSketchFeature->isCopy()) {
+ myStorage->setNeedToResolve(true);
+ return;
+ }
+
+ bool fixFullFeature = false;
+ theBaseEntity = EntityWrapperPtr();
+ theFixedEntity = EntityWrapperPtr();
+
+ // The feature is fixed.
+ PlaneGCSSolver_FeatureBuilder aBuilder;
+ std::list<AttributePtr> aBaseAttr = myBaseFeature->data()->attributes(std::string());
+ std::list<AttributePtr>::const_iterator anIt = aBaseAttr.begin();
+ for (; anIt != aBaseAttr.end(); ++anIt) {
+ EntityWrapperPtr anEntity = aBuilder.createAttribute(*anIt);
+ EntityWrapperPtr aBaseEntity = myStorage->entity(*anIt);
+ if (!anEntity || !aBaseEntity)
+ continue;
+
+ if (!fixFullFeature && anEntity->type() == ENTITY_POINT &&
+ !isEqual(anEntity, aBaseEntity)) {
+ if (theFixedEntity)
+ fixFullFeature = true;
+ theFixedEntity = anEntity;
+ theBaseEntity = aBaseEntity;
+ }
+ }
+
+ if (fixFullFeature) {
+ theFixedEntity = aBuilder.createFeature(myBaseFeature);
+ theBaseEntity = myStorage->entity(myBaseFeature);
+ if (isEqual(theBaseEntity, theFixedEntity))
+ theBaseEntity = EntityWrapperPtr(); // do not want to fix already fixed entity
+ }
+
+ } else if (myBaseConstraint) {
+ // Constraint Fixed is added by user.
+ // Get the attribute of constraint (it should be alone in the list of constraints).
+ EntityWrapperPtr aValue;
+ std::vector<EntityWrapperPtr> anAttributes;
+ SketchSolver_Constraint::getAttributes(aValue, anAttributes);
+ std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
+ for (; anIt != anAttributes.end(); ++anIt)
+ if (*anIt)
+ theBaseEntity = *anIt;
+ } else
+ myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
}
-EntityWrapperPtr SketchSolver_ConstraintFixed::entityToFix()
+void SketchSolver_ConstraintFixed::moveFeature()
{
- // Constraint Fixed is added by user.
- // Get the attribute of constraint (it should be alone in the list of constraints).
- EntityWrapperPtr aValue;
- std::vector<EntityWrapperPtr> anAttributes;
- SketchSolver_Constraint::getAttributes(aValue, anAttributes);
- std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
- for (; anIt != anAttributes.end(); ++anIt)
- if (*anIt)
- return *anIt;
- return EntityWrapperPtr();
+ if (!myFixedEntity)
+ return;
+
+ GCS::VEC_pD aFixedParams = toParameters(myFixedEntity);
+ for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
+ myFixedValues[i] = *(aFixedParams[i]);
+
+ // Remove fixed entity due to its parameters already copied into the constraint
+ PlaneGCSSolver_EntityDestroyer aDestroyer;
+ aDestroyer.remove(myFixedEntity);
+ std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage)->removeParameters(
+ aDestroyer.parametersToRemove());
+
+ myFixedEntity = EntityWrapperPtr();
}
-// ================== Auxiliary functions ==================
+// ==================== Auxiliary functions ===============================
GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
{
GCS::VEC_pD aParameters;
return aParameters;
}
+
+bool isEqual(const GCS::Point& thePoint1, const GCS::Point& thePoint2)
+{
+ return fabs((*thePoint1.x) - (*thePoint2.x)) <= tolerance &&
+ fabs((*thePoint1.y) - (*thePoint2.y)) <= tolerance;
+}
+
+bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
+{
+ GCS::VEC_pD aParamList1 = toParameters(theEntity1);
+ GCS::VEC_pD aParamList2 = toParameters(theEntity2);
+
+ GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin();
+ GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin();
+ for (; anIt1 != aParamList1.end() && anIt2 != aParamList2.end(); ++anIt1, ++anIt2)
+ if (fabs((**anIt1) - (**anIt2)) > tolerance)
+ return false;
+
+ return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();
+}