+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);
+ // the feature is a copy in "Multi" constraint and does not used in other constraints
+ if (!theForce && isCopy && myFeatureMap.find(theFeature) == myFeatureMap.end())
+ return false;
+
+ std::list<EntityWrapperPtr> aSubs;
+ // Reserve the feature in the map of features (do not want to add several copies of it)
+ myFeatureMap[theFeature] = aRelated;
+ // Firstly, create/update its attributes
+ std::list<AttributePtr> anAttrs = pointAttributes(theFeature);
+ std::list<AttributePtr>::const_iterator anIt = anAttrs.begin();
+ for (; anIt != anAttrs.end(); ++anIt) {
+ if (!(*anIt)->isInitialized())
+ return false;
+ 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, 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
+ if (theFeature->getKind() == SketchPlugin_Arc::ID() ||
+ theFeature->getKind() == SketchPlugin_Circle::ID()) {
+ EntityWrapperPtr aNormal = getNormal();
+ if (aNormal) aSubs.push_back(aNormal);
+ }
+ // Secondly, convert feature
+ BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
+ GroupID aGroup = theGroup != GID_UNKNOWN ? theGroup : myGroupID;
+ // Check external feature
+ if (aSketchFeature && (aSketchFeature->isExternal() || isCopy))
+ aGroup = GID_OUTOFGROUP;
+ aRelated = aBuilder->createFeature(theFeature, aSubs, aGroup);
+ if (!aRelated)
+ return false;
+ addEntity(theFeature, aRelated);
+ } else if (theGroup != GID_UNKNOWN)
+ changeGroup(aRelated, theGroup);
+ return update(aRelated) || isUpdated;