// additionally check redundant constraints
GCS::VEC_I aRedundantID;
myEquationSystem.getRedundant(aRedundantID);
+ // Workaround: remove all constraints "Equal"
+ if (!aRedundantID.empty()) {
+ std::set<GCS::Constraint*>::const_iterator aCIt = myConstraints.begin();
+ for (; aCIt != myConstraints.end(); ++aCIt) {
+ GCS::VEC_I::iterator aRIt = aRedundantID.begin();
+ for (; aRIt != aRedundantID.end(); ++aRIt)
+ if ((*aCIt)->getTag() == *aRIt) {
+ aRedundantID.erase(aRIt);
+ break;
+ }
+ }
+ }
// The system with tangent constraints may show redundant constraints if the entities are coupled smoothly.
// Sometimes tangent constraints are fall to both conflicting and redundant constraints.
// Need to check if there are redundant constraints without these tangencies.
static bool isCopyInMulti(std::shared_ptr<SketchPlugin_Feature> theFeature,
const std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >& theConstraints)
{
+ if (!theFeature)
+ return false;
bool aResult = theFeature->isCopy();
if (aResult) {
std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
return aResult;
}
-bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup)
+bool SketchSolver_Storage::update(FeaturePtr theFeature, const GroupID& theGroup, bool theForce)
{
bool isUpdated = false;
EntityWrapperPtr aRelated = entity(theFeature);
if (!aRelated) { // Feature is not exist, create it
+ std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
+ bool isCopy = isCopyInMulti(aSketchFeature, myConstraintMap);
+ if (!theForce && isCopy && myFeatureMap.find(theFeature) == myFeatureMap.end())
+ return false; // the feature is a copy in "Multi" constraint and does not used in other constraints
+
std::list<EntityWrapperPtr> aSubs;
// Reserve the feature in the map of features (do not want to add several copies of it)
myFeatureMap[theFeature] = aRelated;
std::list<AttributePtr> anAttrs = pointAttributes(theFeature);
std::list<AttributePtr>::const_iterator anIt = anAttrs.begin();
for (; anIt != anAttrs.end(); ++anIt) {
- isUpdated = update(*anIt, theGroup) || isUpdated;
+ isUpdated = update(*anIt, theGroup, theForce) || isUpdated;
aSubs.push_back(entity(*anIt));
}
// If the feature is a circle, add its radius as a sub
if (theFeature->getKind() == SketchPlugin_Circle::ID()) {
AttributePtr aRadius = theFeature->attribute(SketchPlugin_Circle::RADIUS_ID());
- isUpdated = update(aRadius, theGroup) || isUpdated;
+ isUpdated = update(aRadius, theGroup, theForce) || isUpdated;
aSubs.push_back(entity(aRadius));
}
// If the feature if circle or arc, we need to add normal of the sketch to the list of subs
BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
// Check external feature
- std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
- if (aSketchFeature && (aSketchFeature->isExternal() || isCopyInMulti(aSketchFeature, myConstraintMap)))
+ if (aSketchFeature && (aSketchFeature->isExternal() || isCopy))
aGroup = GID_OUTOFGROUP;
aRelated = aBuilder->createFeature(theFeature, aSubs, aGroup);
if (!aRelated)
return update(aRelated) || isUpdated;
}
-bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theGroup)
+bool SketchSolver_Storage::update(AttributePtr theAttribute, const GroupID& theGroup, bool theForce)
{
AttributePtr anAttribute = theAttribute;
AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
if (aRefAttr) {
if (aRefAttr->isObject()) {
FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
- return update(aFeature, theGroup);
+ return update(aFeature, theGroup, theForce);
} else
anAttribute = aRefAttr->attr();
}
if (aFeature->attribute(SketchPlugin_Arc::CENTER_ID())->isInitialized() &&
aFeature->attribute(SketchPlugin_Arc::START_ID())->isInitialized() &&
aFeature->attribute(SketchPlugin_Arc::END_ID())->isInitialized()) {
- return SketchSolver_Storage::update(aFeature);
+ return SketchSolver_Storage::update(aFeature, theGroup, theForce);
} else {
myFeatureMap[aFeature] = EntityWrapperPtr();
myExistArc = true;
/// \brief Convert feature to the form applicable for specific solver and map it
/// \param theFeature [in] feature to convert
/// \param theGroup [in] id of the group where the feature should be placed
+ /// \param theForce [in] forced feature creation
/// \return \c true if the feature has been created or updated
- SKETCHSOLVER_EXPORT bool update(FeaturePtr theFeature, const GroupID& theGroup = GID_UNKNOWN);
+ SKETCHSOLVER_EXPORT bool update(FeaturePtr theFeature, const GroupID& theGroup = GID_UNKNOWN, bool theForce = false);
/// \brief Convert attribute to the form applicable for specific solver and map it
- /// \param theFeature [in] feature to convert
+ /// \param theAttribute [in] attribute to convert
+ /// \param theGroup [in] id of the group where the feature should be placed
+ /// \param theForce [in] forced feature creation
/// \return \c true if the attribute has been created or updated
- SKETCHSOLVER_EXPORT bool update(AttributePtr theAttribute, const GroupID& theGroup = GID_UNKNOWN);
+ SKETCHSOLVER_EXPORT bool update(AttributePtr theAttribute, const GroupID& theGroup = GID_UNKNOWN, bool theForce = false);
/// \brief Returns constraint related to corresponding constraint
SKETCHSOLVER_EXPORT