Updated procedure of removing Fixed constraint.
aFeature = ModelAPI_Feature::feature(myFixedAttribute->object());
if (aFeature)
myStorage->update(aFeature, myGroupID);
+ else if (myFixedAttribute)
+ myStorage->update(myFixedAttribute, myGroupID);
// Remove constraint or base feature
if (myBaseConstraint) {
ConstraintConstraintMap::iterator aCIter = myConstraints.begin();
for (; aCIter != myConstraints.end(); aCIter++)
if (aCIter->first == theConstraint) {
- if (!aCIter->second->remove()) // the constraint is not fully removed
- isFullyRemoved = false;
+ aCIter->second->remove(); // the constraint is not fully removed
break;
}
- if (aCIter == myConstraints.end())
- return;
-
- if (isFullyRemoved)
+ if (aCIter != myConstraints.end())
myConstraints.erase(aCIter);
- else if (aCIter != myConstraints.end() &&
- aCIter->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
- // Update multicoincidence
- std::list<ConstraintPtr> aMultiCoinc;
- SolverConstraintPtr aCoincidence = aCIter->second;
- while (aCIter != myConstraints.end()) {
- if (aCIter->second != aCoincidence) {
- ++aCIter;
- continue;
- }
- if (aCIter->first != theConstraint)
- aMultiCoinc.push_back(aCIter->first);
- aCIter->second->remove();
- ConstraintConstraintMap::iterator aRemoveIt = aCIter++;
- myConstraints.erase(aRemoveIt);
- }
-
- std::list<ConstraintPtr>::iterator anIt = aMultiCoinc.begin();
- for (; anIt != aMultiCoinc.end(); ++anIt)
- changeConstraint(*anIt);
- }
}
// ============================================================================
void SketchSolver_Storage::addConstraint(ConstraintPtr theConstraint,
ConstraintWrapperPtr theSolverConstraint)
{
- std::list<ConstraintWrapperPtr> aConstrList(1, theSolverConstraint);
- addConstraint(theConstraint, aConstrList);
+ if (theSolverConstraint) {
+ std::list<ConstraintWrapperPtr> aConstrList(1, theSolverConstraint);
+ addConstraint(theConstraint, aConstrList);
+ } else
+ addConstraint(theConstraint, std::list<ConstraintWrapperPtr>());
}
void SketchSolver_Storage::addConstraint(
if (aFound == myConstraintMap.end() || !isEqual(aFound->second, theSolverConstraints))
setNeedToResolve(true);
- // Do not add point-point coincidence, because it is already made by setting
- // the same parameters for both points
- if (!theSolverConstraints.empty() &&
- theSolverConstraints.front()->type() != CONSTRAINT_PT_PT_COINCIDENT) {
+ if (theSolverConstraints.empty()) {
+ // constraint links to the empty list, add its attributes linked to the empty entities
+ std::list<AttributePtr> aRefAttrs =
+ theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ std::list<AttributePtr>::const_iterator anAttrIt = aRefAttrs.begin();
+ for (; anAttrIt != aRefAttrs.end(); ++anAttrIt) {
+ AttributeRefAttrPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIt);
+ if (aRef->isObject()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
+ if (aFeature) addEntity(aFeature, EntityWrapperPtr());
+ } else
+ addEntity(aRef->attr(), EntityWrapperPtr());
+ }
+ std::list<AttributePtr> aRefLists =
+ theConstraint->data()->attributes(ModelAPI_AttributeRefList::typeId());
+ for (anAttrIt = aRefLists.begin(); anAttrIt != aRefLists.end(); ++anAttrIt) {
+ AttributeRefListPtr aRef = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIt);
+ std::list<ObjectPtr> anObj = aRef->list();
+ std::list<ObjectPtr>::iterator anIt = anObj.begin();
+ for (; anIt != anObj.end(); ++anIt) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt);
+ if (aFeature) addEntity(aFeature, EntityWrapperPtr());
+ }
+ }
+ }
+ else if (theSolverConstraints.front()->type() != CONSTRAINT_PT_PT_COINCIDENT) {
+ // Do not add point-point coincidence, because it is already made by setting
+ // the same parameters for both points
std::list<ConstraintWrapperPtr>::iterator aCIt = theSolverConstraints.begin();
for (; aCIt != theSolverConstraints.end(); ++aCIt)
update(*aCIt);
EntityWrapperPtr theSolverEntity)
{
std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFound = myFeatureMap.find(theFeature);
- if (aFound == myFeatureMap.end() || !aFound->second || !aFound->second->isEqual(theSolverEntity))
+ if (aFound == myFeatureMap.end() || !aFound->second ||
+ (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
setNeedToResolve(true); // the entity is new or modified
myFeatureMap[theFeature] = theSolverEntity;
EntityWrapperPtr theSolverEntity)
{
std::map<AttributePtr, EntityWrapperPtr>::const_iterator aFound = myAttributeMap.find(theAttribute);
- if (aFound == myAttributeMap.end() || !aFound->second || !aFound->second->isEqual(theSolverEntity))
+ if (aFound == myAttributeMap.end() || !aFound->second ||
+ (theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
setNeedToResolve(true); // the entity is new or modified
myAttributeMap[theAttribute] = theSolverEntity;
++anIt;
}
}
- if (!isFullyRemoved) {
- // revert removed constraint
- addConstraint(theConstraint, aConstrList);
- }
return isFullyRemoved;
}
if (aFound == myFeatureMap.end())
return false; // feature not found, nothing to delete
+ EntityWrapperPtr anEntity = aFound->second;
+ myFeatureMap.erase(aFound);
+
// Check the feature is not used by constraints
if (isUsed(theFeature))
return false; // the feature is used, don't remove it
// Remove feature
- EntityWrapperPtr anEntity = aFound->second;
- myFeatureMap.erase(aFound);
if (remove(anEntity))
return true;
// feature is not removed, revert operation
if (aFound == myAttributeMap.end())
return false; // attribute not found, nothing to delete
+ EntityWrapperPtr anEntity = aFound->second;
+ myAttributeMap.erase(aFound);
+
// Check the attribute is not used by constraints
if (isUsed(theAttribute))
return false; // the attribute is used, don't remove it
return false;
// Remove attribute
- EntityWrapperPtr anEntity = aFound->second;
- myAttributeMap.erase(aFound);
if (remove(anEntity))
return true;
// attribute is not removed, revert operation
if ((*anEntIt)->group() != myGroupID)
return true;
}
+
+ std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator aCIt = myConstraintMap.begin();
+ std::list<ConstraintWrapperPtr>::const_iterator aCWIt;
+ for (; aCIt != myConstraintMap.end(); ++aCIt) {
+ if (aCIt->second.empty())
+ continue;
+ aCWIt = aCIt->second.begin();
+ if ((*aCWIt)->type() != CONSTRAINT_FIXED)
+ continue;
+ for (; aCWIt != aCIt->second.end(); ++aCIt)
+ if ((theEntity->baseAttribute() && (*aCWIt)->isUsed(theEntity->baseAttribute())) ||
+ (theEntity->baseFeature() && (*aCWIt)->isUsed(theEntity->baseFeature())))
+ return true;
+ }
+
return false;
}
/// \brief Check the entity is fixed.
/// If the point is under verification, all coincident points are checked too.
- bool isFixed(EntityWrapperPtr theEntity) const;
+ SKETCHSOLVER_EXPORT bool isFixed(EntityWrapperPtr theEntity) const;
/// \brief Shows the sketch should be resolved
virtual bool isNeedToResolve()
#include <GeomDataAPI_Point.h>
#include <GeomDataAPI_Point2D.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeRefAttr.h>
#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
/** \brief Search the entity/parameter with specified ID in the list of elements
* \param[in] theEntityID unique ID of the element
if (aSlvsEnt.group == SLVS_G_UNKNOWN)
aSlvsEnt.group = (Slvs_hGroup)myGroupID;
Slvs_hEntity anEntID = updateEntity(aSlvsEnt);
- if (aSlvsEnt.h == SLVS_E_UNKNOWN) {
+ if (aSlvsEnt.h == SLVS_E_UNKNOWN || isUpdated) {
anEntity->changeEntity() = getEntity(anEntID);
isUpdated = true;
}
+bool SolveSpaceSolver_Storage::removeCoincidence(ConstraintWrapperPtr theConstraint)
+{
+ std::list<EntityWrapperPtr> aPoints = theConstraint->entities();
+ std::list<EntityWrapperPtr>::const_iterator aPIt;
+
+ CoincidentPointsMap::iterator aPtPtIt = myCoincidentPoints.begin();
+ for (; aPtPtIt != myCoincidentPoints.end(); ++aPtPtIt) {
+ for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt)
+ if (aPtPtIt->first == *aPIt ||
+ aPtPtIt->second.find(*aPIt) != aPtPtIt->second.end())
+ break;
+ if (aPIt != aPoints.end())
+ break;
+ }
+
+ if (aPtPtIt == myCoincidentPoints.end())
+ return true; // already removed
+
+ // Create new copies of coincident points
+ BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance();
+ std::list<EntityWrapperPtr> aNewPoints;
+ for (aPIt = aPoints.begin(); aPIt != aPoints.end(); ++aPIt)
+ aNewPoints.push_back(aBuilder->createAttribute(
+ (*aPIt)->baseAttribute(), myGroupID, myWorkplaneID));
+
+ // Find all points fallen out of group of coincident points
+ std::map<EntityWrapperPtr, EntityWrapperPtr> aNotCoinc;
+ aNotCoinc[aPtPtIt->first] = EntityWrapperPtr();
+ std::set<EntityWrapperPtr>::const_iterator aTempIt = aPtPtIt->second.begin();
+ for (; aTempIt != aPtPtIt->second.end(); ++aTempIt)
+ aNotCoinc[*aTempIt] = EntityWrapperPtr();
+ std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::iterator
+ aConstrIt = myConstraintMap.begin();
+ for (; aConstrIt != myConstraintMap.end(); ++aConstrIt)
+ if (aConstrIt->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+ AttributeRefAttrPtr aRefAttrA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ if (!aRefAttrA || !aRefAttrB || aRefAttrA->isObject() || aRefAttrB->isObject())
+ continue;
+ std::map<AttributePtr, EntityWrapperPtr>::iterator
+ aFound = myAttributeMap.find(aRefAttrA->attr());
+ if (aFound != myAttributeMap.end())
+ aNotCoinc.erase(aFound->second);
+ aFound = myAttributeMap.find(aRefAttrB->attr());
+ if (aFound != myAttributeMap.end())
+ aNotCoinc.erase(aFound->second);
+ }
+ if (aNotCoinc.empty())
+ return false;
+ std::list<EntityWrapperPtr>::const_iterator aNewPIt;
+ for (aPIt = aPoints.begin(), aNewPIt = aNewPoints.begin();
+ aPIt != aPoints.end(); ++aPIt, ++aNewPIt) {
+ if (aNotCoinc.find(*aPIt) != aNotCoinc.end())
+ aNotCoinc[*aPIt] = *aNewPIt;
+ }
+
+ // Find all features and constraints uses coincident points
+ std::map<EntityWrapperPtr, EntityWrapperPtr>::iterator aNotCIt;
+ std::set<EntityWrapperPtr> anUpdFeatures;
+ std::map<FeaturePtr, EntityWrapperPtr>::iterator aFIt = myFeatureMap.begin();
+ for (; aFIt != myFeatureMap.end(); ++aFIt) {
+ for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) {
+ if (!aFIt->second->isUsed(aNotCIt->first->baseAttribute()))
+ continue;
+ std::list<EntityWrapperPtr> aSubs = aFIt->second->subEntities();
+ std::list<EntityWrapperPtr>::iterator aSIt = aSubs.begin();
+ for (; aSIt != aSubs.end(); ++aSIt)
+ if (*aSIt == aNotCIt->first)
+ *aSIt = aNotCIt->second;
+ aFIt->second->setSubEntities(aSubs);
+ anUpdFeatures.insert(aFIt->second);
+ }
+ }
+ // update features
+ std::set<EntityWrapperPtr>::iterator anUpdIt = anUpdFeatures.begin();
+ for (; anUpdIt != anUpdFeatures.end(); ++anUpdIt)
+ update(EntityWrapperPtr(*anUpdIt));
+
+ // remove not coincident points
+ for (aNotCIt = aNotCoinc.begin(); aNotCIt != aNotCoinc.end(); ++aNotCIt) {
+ if (aPtPtIt->first == aNotCIt->first) {
+ std::set<EntityWrapperPtr> aSlaves = aPtPtIt->second;
+ EntityWrapperPtr aNewMaster = *aSlaves.begin();
+ aSlaves.erase(aSlaves.begin());
+ myCoincidentPoints[aNewMaster] = aSlaves;
+ myCoincidentPoints.erase(aPtPtIt);
+ aPtPtIt = myCoincidentPoints.find(aNewMaster);
+ } else
+ aPtPtIt->second.erase(aNotCIt->first);
+ }
+ return true;
+}
+
bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
{
std::shared_ptr<SolveSpaceSolver_ConstraintWrapper> aConstraint =
return true;
bool isFullyRemoved = removeConstraint((Slvs_hConstraint)aConstraint->id());
+
+ // remove point-point coincidence
+ if (aConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT)
+ isFullyRemoved = removeCoincidence(theConstraint);
+
return SketchSolver_Storage::remove(theConstraint) && isFullyRemoved;
}
std::list<ParameterWrapperPtr> aParams;
std::list<ParameterWrapperPtr>::const_iterator aParIt;
for (; anIt != myAttributeMap.end(); ++anIt) {
+ if (!anIt->second)
+ continue;
// the external feature always should keep the up to date values, so,
// refresh from the solver is never needed
if (anIt->first.get()) {
{
std::map<AttributePtr, EntityWrapperPtr>::iterator anAttrIt = myAttributeMap.begin();
for (; anAttrIt != myAttributeMap.end(); ++anAttrIt) {
+ if (!anAttrIt->second)
+ continue;
const std::list<ParameterWrapperPtr>& aParameters = anAttrIt->second->parameters();
std::list<ParameterWrapperPtr>::const_iterator aParIt = aParameters.begin();
for (; aParIt != aParameters.end(); ++aParIt)
/// \return \c true if the parameter has been removed
virtual bool remove(ParameterWrapperPtr theParameter);
+ /// \brief Remove point-point coincidence
+ bool removeCoincidence(ConstraintWrapperPtr theConstraint);
+
/// \brief Update the group for the given entity, its sub-entities and parameters
virtual void changeGroup(EntityWrapperPtr theEntity, const GroupID& theGroup);
/// \brief Update the group for the given parameter