aResult->setExternal(true);
return aResult;
}
-
-const std::list<GCSConstraintPtr>& PlaneGCSSolver_AttributeBuilder::constraints() const
-{
- static std::list<GCSConstraintPtr> aList;
- return aList;
-}
/// \brief Blank. To be defined in derived class.
virtual EntityWrapperPtr createFeature(FeaturePtr)
{ return EntityWrapperPtr(); }
-
- /// \brief Blank. To be defined in derived class.
- virtual const std::list<GCSConstraintPtr>& constraints() const;
};
#endif
/// \param theFeature [in] feature to create
virtual EntityWrapperPtr createFeature(FeaturePtr) = 0;
- /// \brief Return list of constraints necessary to fix feature's extra DoF
- virtual const std::list<GCSConstraintPtr>& constraints() const = 0;
-
protected:
PlaneGCSSolver_Storage* myStorage;
};
#include <PlaneGCSSolver_PointWrapper.h>
#include <PlaneGCSSolver_ScalarWrapper.h>
#include <PlaneGCSSolver_EdgeWrapper.h>
-
-static void destroyScalar(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
- ScalarWrapperPtr aScalar = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(theEntity);
- theParams.insert(aScalar->scalar());
-}
-
-static void destroyPoint(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
- std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
- std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
- theParams.insert(aPoint->point()->x);
- theParams.insert(aPoint->point()->y);
-}
-
-static void destroyLine(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
- std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
- std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
- std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
- theParams.insert(aLine->p1.x);
- theParams.insert(aLine->p1.y);
- theParams.insert(aLine->p2.x);
- theParams.insert(aLine->p2.y);
-}
-
-static void destroyCircle(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
- std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
- std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
- std::shared_ptr<GCS::Circle> aCirc = std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
- theParams.insert(aCirc->center.x);
- theParams.insert(aCirc->center.y);
- theParams.insert(aCirc->rad);
-}
-
-static void destroyArc(const EntityWrapperPtr& theEntity, GCS::SET_pD& theParams)
-{
- std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
- std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
- std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
- theParams.insert(anArc->center.x);
- theParams.insert(anArc->center.y);
- theParams.insert(anArc->start.x);
- theParams.insert(anArc->start.y);
- theParams.insert(anArc->end.x);
- theParams.insert(anArc->end.y);
- theParams.insert(anArc->startAngle);
- theParams.insert(anArc->endAngle);
- theParams.insert(anArc->rad);
-}
+#include <PlaneGCSSolver_Tools.h>
void PlaneGCSSolver_EntityDestroyer::remove(const EntityWrapperPtr& theEntity)
{
- GCS::SET_pD& aParamSet = theEntity->isExternal() ? myParamsOutOfStorage : myParams;
-
- switch (theEntity->type()) {
- case ENTITY_SCALAR:
- case ENTITY_ANGLE:
- destroyScalar(theEntity, aParamSet);
- break;
- case ENTITY_POINT:
- destroyPoint(theEntity, aParamSet);
- break;
- case ENTITY_LINE:
- destroyLine(theEntity, aParamSet);
- break;
- case ENTITY_CIRCLE:
- destroyCircle(theEntity, aParamSet);
- break;
- case ENTITY_ARC:
- destroyArc(theEntity, aParamSet);
- break;
- default: break;
- }
+ GCS::SET_pD aParameters = PlaneGCSSolver_Tools::parameters(theEntity);
+ if (theEntity->isExternal())
+ myParamsOutOfStorage.insert(aParameters.begin(), aParameters.end());
+ else
+ myParams.insert(aParameters.begin(), aParameters.end());
}
static EntityWrapperPtr createLine(const AttributeEntityMap& theAttributes);
static EntityWrapperPtr createCircle(const AttributeEntityMap& theAttributes);
static EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
- PlaneGCSSolver_Storage* theStorage,
- std::list<GCSConstraintPtr>& theArcConstraints);
+ PlaneGCSSolver_Storage* theStorage);
PlaneGCSSolver_FeatureBuilder::PlaneGCSSolver_FeatureBuilder(
aResult = createCircle(myAttributes);
// Arc
else if (aFeatureKind == SketchPlugin_Arc::ID())
- aResult = createArc(myAttributes, myStorage, myFeatureConstraints);
+ aResult = createArc(myAttributes, myStorage);
// Point (it has low probability to be an attribute of constraint, so it is checked at the end)
else if (aFeatureKind == SketchPlugin_Point::ID() ||
aFeatureKind == SketchPlugin_IntersectionPoint::ID()) {
}
EntityWrapperPtr createArc(const AttributeEntityMap& theAttributes,
- PlaneGCSSolver_Storage* theStorage,
- std::list<GCSConstraintPtr>& theArcConstraints)
+ PlaneGCSSolver_Storage* theStorage)
{
std::shared_ptr<GCS::Arc> aNewArc(new GCS::Arc);
new GeomAPI_Dir2d((*aNewArc->end.x) - aCenter->x(), (*aNewArc->end.y) - aCenter->y()));
*aNewArc->endAngle = OX->angle(aDir);
- if (theStorage) {
- // Additional constaints to fix arc's extra DoF (if the arc is not external):
- // 1. distances from center till start and end points are equal to radius
- theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
- aNewArc->center, aNewArc->start, aNewArc->rad)));
- theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
- aNewArc->center, aNewArc->end, aNewArc->rad)));
- // 2. angles of start and end points should be equal to the arc angles
- theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
- aNewArc->center, aNewArc->start, aNewArc->startAngle)));
- theArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
- aNewArc->center, aNewArc->end, aNewArc->endAngle)));
- }
-
return EntityWrapperPtr(new PlaneGCSSolver_EdgeWrapper(aNewArc));
}
/// \param theFeature [in] feature to create
virtual EntityWrapperPtr createFeature(FeaturePtr theFeature);
- /// \brief Return list of constraints necessary to fix feature's extra DoF
- virtual const std::list<GCSConstraintPtr>& constraints() const
- { return myFeatureConstraints; }
-
private:
/// list of converted attributes (will be cleared when the feature is created)
AttributeEntityMap myAttributes;
-
- /// constraints for the feature
- /// (primarily used for constrain arcs, which have 9 parameters but 5 DoF)
- std::list<GCSConstraintPtr> myFeatureConstraints;
};
#endif
return aResult;
}
+void PlaneGCSSolver_Solver::addParameters(const GCS::SET_pD& theParams)
+{
+ GCS::SET_pD aParams(theParams);
+ // leave new parameters only
+ GCS::VEC_pD::iterator anIt = myParameters.begin();
+ for (; anIt != myParameters.end(); ++anIt)
+ if (aParams.find(*anIt) != aParams.end())
+ aParams.erase(*anIt);
+
+ myParameters.insert(myParameters.end(), aParams.begin(), aParams.end());
+ if (myConstraints.empty() && myDOF >=0)
+ myDOF += (int)aParams.size(); // calculate DoF by hand if and only if there is no constraints yet
+ else
+ myDiagnoseBeforeSolve = true;
+}
+
void PlaneGCSSolver_Solver::removeParameters(const GCS::SET_pD& theParams)
{
for (int i = (int)myParameters.size() - 1; i >= 0; --i)
myParameters.erase(myParameters.begin() + i);
--myDOF;
}
+ if (!myConstraints.empty())
+ myDiagnoseBeforeSolve = true;
}
void PlaneGCSSolver_Solver::initialize()
/// \brief Initialize memory for new solver's parameter
double* createParameter();
+ /// \brief Add parameters created elsewhere
+ void addParameters(const GCS::SET_pD& theParams);
/// \brief Release memory occupied by parameters
void removeParameters(const GCS::SET_pD& theParams);
#include <PlaneGCSSolver_ConstraintWrapper.h>
#include <PlaneGCSSolver_EdgeWrapper.h>
#include <PlaneGCSSolver_PointWrapper.h>
+#include <PlaneGCSSolver_Tools.h>
#include <PlaneGCSSolver_AttributeBuilder.h>
#include <PlaneGCSSolver_FeatureBuilder.h>
// (do not want to add several copies of it while adding attributes)
aRelated = createFeature(theFeature, &aBuilder);
myFeatureMap[theFeature] = aRelated;
-
- const std::list<GCSConstraintPtr>& aConstraints = aBuilder.constraints();
- if (!aConstraints.empty()) { // the feature is arc
- /// TODO: avoid this workaround
- ConstraintWrapperPtr aWrapper(
- new PlaneGCSSolver_ConstraintWrapper(aConstraints, CONSTRAINT_UNKNOWN));
- aWrapper->setId(++myConstraintLastID);
- constraintsToSolver(aWrapper, mySketchSolver);
-
- myArcConstraintMap[myFeatureMap[theFeature]] = aWrapper;
- }
+ createArcConstraints(aRelated);
isUpdated = true;
}
return isUpdated;
}
+void PlaneGCSSolver_Storage::makeExternal(const EntityWrapperPtr& theEntity)
+{
+ if (theEntity->isExternal())
+ return;
+
+ removeArcConstraints(theEntity);
+
+ GCS::SET_pD aParameters = PlaneGCSSolver_Tools::parameters(theEntity);
+ mySketchSolver->removeParameters(aParameters);
+ theEntity->setExternal(true);
+ myNeedToResolve = true;
+}
+
+void PlaneGCSSolver_Storage::makeNonExternal(const EntityWrapperPtr& theEntity)
+{
+ if (!theEntity->isExternal())
+ return;
+
+ GCS::SET_pD aParameters = PlaneGCSSolver_Tools::parameters(theEntity);
+ mySketchSolver->addParameters(aParameters);
+ theEntity->setExternal(false);
+
+ createArcConstraints(theEntity);
+
+ myNeedToResolve = true;
+}
+
+
+void PlaneGCSSolver_Storage::createArcConstraints(const EntityWrapperPtr& theArc)
+{
+ if (theArc->type() != ENTITY_ARC || theArc->isExternal())
+ return;
+
+ EdgeWrapperPtr anEdge = std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theArc);
+ std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEdge->entity());
+
+ // Additional constaints to fix arc's extra DoF (if the arc is not external):
+ std::list<GCSConstraintPtr> anArcConstraints;
+ // 1. distances from center till start and end points are equal to radius
+ anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+ anArc->center, anArc->start, anArc->rad)));
+ anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
+ anArc->center, anArc->end, anArc->rad)));
+ // 2. angles of start and end points should be equal to the arc angles
+ anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+ anArc->center, anArc->start, anArc->startAngle)));
+ anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
+ anArc->center, anArc->end, anArc->endAngle)));
+
+ ConstraintWrapperPtr aWrapper(
+ new PlaneGCSSolver_ConstraintWrapper(anArcConstraints, CONSTRAINT_UNKNOWN));
+ aWrapper->setId(++myConstraintLastID);
+ constraintsToSolver(aWrapper, mySketchSolver);
+
+ myArcConstraintMap[theArc] = aWrapper;
+}
+
+void PlaneGCSSolver_Storage::removeArcConstraints(const EntityWrapperPtr& theArc)
+{
+ std::map<EntityWrapperPtr, ConstraintWrapperPtr>::iterator
+ aFound = myArcConstraintMap.find(theArc);
+ if (aFound != myArcConstraintMap.end()) {
+ mySketchSolver->removeConstraint(aFound->second->id());
+ myArcConstraintMap.erase(aFound);
+ }
+}
bool PlaneGCSSolver_Storage::removeConstraint(ConstraintPtr theConstraint)
aDestroyer.remove(aFIter->second);
// remove invalid arc
- std::map<EntityWrapperPtr, ConstraintWrapperPtr>::iterator
- aFound = myArcConstraintMap.find(aFIter->second);
- if (aFound != myArcConstraintMap.end()) {
- mySketchSolver->removeConstraint(aFound->second->id());
- myArcConstraintMap.erase(aFound);
- }
+ removeArcConstraints(aFIter->second);
}
std::list<FeaturePtr>::const_iterator anInvFIt = anInvalidFeatures.begin();
for (; anInvFIt != anInvalidFeatures.end(); ++anInvFIt)
/// \return \c true if the attribute has been created or updated
virtual bool update(AttributePtr theAttribute, bool theForce = false);
+ /// \brief Make entity external
+ virtual void makeExternal(const EntityWrapperPtr& theEntity);
+ /// \brief Make entity non-external
+ virtual void makeNonExternal(const EntityWrapperPtr& theEntity);
/// \brief Removes constraint from the storage
/// \return \c true if the constraint and all its parameters are removed successfully
EntityWrapperPtr createAttribute(const AttributePtr& theAttribute,
PlaneGCSSolver_EntityBuilder* theBuilder);
+ void createArcConstraints(const EntityWrapperPtr& theArc);
+ void removeArcConstraints(const EntityWrapperPtr& theArc);
+
private:
ConstraintID myConstraintLastID; ///< identifier of last added constraint
createConstraintMiddlePoint(std::shared_ptr<PlaneGCSSolver_PointWrapper> thePoint,
std::shared_ptr<PlaneGCSSolver_EdgeWrapper> theEntity);
+static GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar);
+static GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint);
+static GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine);
+static GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle);
+static GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc);
+
}
+GCS::SET_pD PlaneGCSSolver_Tools::parameters(const EntityWrapperPtr& theEntity)
+{
+ switch (theEntity->type()) {
+ case ENTITY_SCALAR:
+ case ENTITY_ANGLE:
+ return scalarParameters(GCS_SCALAR_WRAPPER(theEntity));
+ case ENTITY_POINT:
+ return pointParameters(GCS_POINT_WRAPPER(theEntity));
+ case ENTITY_LINE:
+ return lineParameters(GCS_EDGE_WRAPPER(theEntity));
+ case ENTITY_CIRCLE:
+ return circleParameters(GCS_EDGE_WRAPPER(theEntity));
+ case ENTITY_ARC:
+ return arcParameters(GCS_EDGE_WRAPPER(theEntity));
+ default: break;
+ }
+ return GCS::SET_pD();
+}
+
+
+
aResult->setValueParameter(theIntermed);
return aResult;
}
+
+GCS::SET_pD scalarParameters(const ScalarWrapperPtr& theScalar)
+{
+ GCS::SET_pD aParams;
+ aParams.insert(theScalar->scalar());
+ return aParams;
+}
+
+GCS::SET_pD pointParameters(const PointWrapperPtr& thePoint)
+{
+ GCS::SET_pD aParams;
+ aParams.insert(thePoint->point()->x);
+ aParams.insert(thePoint->point()->y);
+ return aParams;
+}
+
+GCS::SET_pD lineParameters(const EdgeWrapperPtr& theLine)
+{
+ GCS::SET_pD aParams;
+ std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(theLine->entity());
+ aParams.insert(aLine->p1.x);
+ aParams.insert(aLine->p1.y);
+ aParams.insert(aLine->p2.x);
+ aParams.insert(aLine->p2.y);
+ return aParams;
+}
+
+GCS::SET_pD circleParameters(const EdgeWrapperPtr& theCircle)
+{
+ GCS::SET_pD aParams;
+ std::shared_ptr<GCS::Circle> aCirc = std::dynamic_pointer_cast<GCS::Circle>(theCircle->entity());
+ aParams.insert(aCirc->center.x);
+ aParams.insert(aCirc->center.y);
+ aParams.insert(aCirc->rad);
+ return aParams;
+}
+
+GCS::SET_pD arcParameters(const EdgeWrapperPtr& theArc)
+{
+ GCS::SET_pD aParams;
+ std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(theArc->entity());
+ aParams.insert(anArc->center.x);
+ aParams.insert(anArc->center.y);
+ aParams.insert(anArc->start.x);
+ aParams.insert(anArc->start.y);
+ aParams.insert(anArc->end.x);
+ aParams.insert(anArc->end.y);
+ aParams.insert(anArc->startAngle);
+ aParams.insert(anArc->endAngle);
+ aParams.insert(anArc->rad);
+ return aParams;
+}
/// \brief Convert entity to line
/// \return empty pointer if the entity is not a line
std::shared_ptr<GeomAPI_Lin2d> line(FeaturePtr theFeature);
+
+ /// brief Return list of parameters for the given entity
+ GCS::SET_pD parameters(const EntityWrapperPtr& theEntity);
};
#endif
#include <SketchPlugin_Point.h>
#include <SketchPlugin_IntersectionPoint.h>
+static void createCopiedEntity(const FeaturePtr& theFeature, const StoragePtr& theStorage)
+{
+ EntityWrapperPtr anEntity = theStorage->entity(theFeature);
+ if (anEntity) {
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
+ if (!anEntity->isExternal() && aSketchFeature->isCopy())
+ theStorage->makeExternal(anEntity);
+ }
+}
+
void SketchSolver_ConstraintMulti::getEntities(std::list<EntityWrapperPtr>& theEntities)
{
myAdjusted = false;
for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) {
// just add copied features into the list of objects
aFeature = ModelAPI_Feature::feature(*anObjIt);
- if (aFeature)
+ if (aFeature) {
+ createCopiedEntity(aFeature, myStorage);
myFeatures.insert(aFeature);
+ }
}
}
}
{
myStorage->unsubscribeUpdates(this);
+ // "Multi" constraint has been removed, thus all copy features become non-copied,
+ // add them once again to be a common feature
+ std::set<FeaturePtr>::iterator anIt = myFeatures.begin();
+ for (; anIt != myFeatures.end(); ++anIt) {
+ EntityWrapperPtr anEntity = myStorage->entity(*anIt);
+ if (anEntity) {
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
+ if (anEntity->isExternal() && !aSketchFeature->isExternal())
+ myStorage->makeNonExternal(anEntity);
+ } else
+ myStorage->update(*anIt, true);
+ }
+
myFeatures.clear();
return SketchSolver_Constraint::remove();
}
/// \brief Returns entity related to corresponding attribute
const EntityWrapperPtr& entity(const AttributePtr& theAttribute) const;
+ /// \brief Make entity external
+ virtual void makeExternal(const EntityWrapperPtr& theEntity) = 0;
+ /// \brief Make entity non-external
+ virtual void makeNonExternal(const EntityWrapperPtr& theEntity) = 0;
+
/// \brief Removes constraint from the storage
/// \return \c true if the constraint and all its parameters are removed successfully
virtual bool removeConstraint(ConstraintPtr theConstraint) = 0;