X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSolveSpaceSolver%2FSolveSpaceSolver_Storage.cpp;h=999f43eefc46a7e7451a83382f998de382839106;hb=cf8f82e87c5bec5bef69549ce628bfdb093b92a1;hp=2a6fb95bf08fb7694c762431a8405c7c92f25b40;hpb=29d446f4dd2969d80087745fe44adb5638d13de7;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp index 2a6fb95bf..999f43eef 100644 --- a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp +++ b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include /** \brief Search the entity/parameter with specified ID in the list of elements * \param[in] theEntityID unique ID of the element @@ -47,7 +50,7 @@ SolveSpaceSolver_Storage::SolveSpaceSolver_Storage(const GroupID& theGroup) { } -bool SolveSpaceSolver_Storage::update(ConstraintWrapperPtr& theConstraint) +bool SolveSpaceSolver_Storage::update(ConstraintWrapperPtr theConstraint) { bool isUpdated = false; std::shared_ptr aConstraint = @@ -73,6 +76,9 @@ bool SolveSpaceSolver_Storage::update(ConstraintWrapperPtr& theConstraint) std::list::iterator anIt = anEntities.begin(); for (; anIt != anEntities.end(); ++anIt) { isUpdated = update(*anIt) || isUpdated; + // do not update constrained entities for Multi constraints + if (aSlvsConstr.type == SLVS_C_MULTI_ROTATION || aSlvsConstr.type != SLVS_C_MULTI_TRANSLATION) + continue; Slvs_hEntity anID = (Slvs_hEntity)(*anIt)->id(); if ((*anIt)->type() == ENTITY_POINT) { @@ -105,7 +111,7 @@ bool SolveSpaceSolver_Storage::update(ConstraintWrapperPtr& theConstraint) return isUpdated; } -bool SolveSpaceSolver_Storage::update(EntityWrapperPtr& theEntity) +bool SolveSpaceSolver_Storage::update(EntityWrapperPtr theEntity) { bool isUpdated = false; std::shared_ptr anEntity = @@ -158,6 +164,15 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr& theEntity) isUpdated = true; } } + if (theEntity->type() == ENTITY_POINT && aSubEntities.size() == 1) { + // theEntity is based on SketchPlugin_Point => need to substitute its attribute instead + bool isNew = (aSlvsEnt.h == SLVS_E_UNKNOWN); + aSlvsEnt = getEntity(aSlvsEnt.point[0]); + if (isNew) { + anEntity->changeEntity() = aSlvsEnt; + isUpdated = true; + } + } // update entity itself if (aSlvsEnt.wrkpl == SLVS_E_UNKNOWN && myWorkplaneID != SLVS_E_UNKNOWN) @@ -165,17 +180,18 @@ bool SolveSpaceSolver_Storage::update(EntityWrapperPtr& theEntity) 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; if (anEntity->type() == ENTITY_SKETCH) storeWorkplane(anEntity); } + return isUpdated; } -bool SolveSpaceSolver_Storage::update(ParameterWrapperPtr& theParameter) +bool SolveSpaceSolver_Storage::update(ParameterWrapperPtr theParameter) { std::shared_ptr aParameter = std::dynamic_pointer_cast(theParameter); @@ -292,8 +308,9 @@ void SolveSpaceSolver_Storage::addCoincidentPoints( replaceInFeatures(theSlave, theMaster); replaceInConstraints(theSlave, theMaster); - // Remove slave entity - removeEntity((Slvs_hEntity)theSlave->id()); + // Remove slave entity (if the IDs are equal no need to remove slave entity, just update it) + if (theMaster->id() != theSlave->id()) + removeEntity((Slvs_hEntity)theSlave->id()); std::shared_ptr aPointMaster = std::dynamic_pointer_cast(theMaster); @@ -311,6 +328,8 @@ void SolveSpaceSolver_Storage::replaceInFeatures( { std::map::const_iterator anIt = myFeatureMap.begin(); for (; anIt != myFeatureMap.end(); ++anIt) { + if (!anIt->second) + continue; bool isUpdated = false; std::list aSubs = anIt->second->subEntities(); std::list::iterator aSubIt = aSubs.begin(); @@ -1108,67 +1127,6 @@ void SolveSpaceSolver_Storage::addConstraintWhereDragged(const Slvs_hConstraint& myFixed = theConstraintID; } -void SolveSpaceSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID) -{ - myTemporaryConstraints.insert(theConstraintID); -} - -void SolveSpaceSolver_Storage::removeAllTemporary() -{ - myTemporaryConstraints.clear(); -} - -size_t SolveSpaceSolver_Storage::removeTemporary(size_t theNbConstraints) -{ - if (myTemporaryConstraints.empty()) - return 0; - // Search the point-on-line or a non-rigid constraint - std::set::iterator aCIt = myTemporaryConstraints.begin(); - for (; aCIt != myTemporaryConstraints.end(); aCIt++) { - int aPos = Search(*aCIt, myConstraints); - if (aPos >= (int)myConstraints.size() || myConstraints[aPos].type != SLVS_C_WHERE_DRAGGED) - break; - std::vector::iterator anIt = myConstraints.begin(); - for (; anIt != myConstraints.end(); anIt++) - if (anIt->type == SLVS_C_PT_ON_LINE && anIt->ptA == myConstraints[aPos].ptA) - break; - if (anIt != myConstraints.end()) - break; - } - if (aCIt == myTemporaryConstraints.end()) - aCIt = myTemporaryConstraints.begin(); - bool aNewFixed = false; - - size_t aNbRemain = theNbConstraints; - while (aNbRemain > 0 && aCIt != myTemporaryConstraints.end()) { - aNewFixed = aNewFixed || (*aCIt == myFixed); - --aNbRemain; - - std::set::iterator aRemoveIt = aCIt++; - removeConstraint(*aRemoveIt); - myTemporaryConstraints.erase(aRemoveIt); - if (aCIt == myTemporaryConstraints.end()) - aCIt = myTemporaryConstraints.begin(); - } - - if (aNewFixed) { - for (aCIt = myTemporaryConstraints.begin(); aCIt != myTemporaryConstraints.end(); aCIt++) { - int aPos = Search(*aCIt, myConstraints); - if (myConstraints[aPos].type == SLVS_C_WHERE_DRAGGED) { - myFixed = *aCIt; - break; - } - } - } - return myTemporaryConstraints.size(); -} - -bool SolveSpaceSolver_Storage::isTemporary(const Slvs_hConstraint& theConstraintID) const -{ - return myTemporaryConstraints.find(theConstraintID) != myTemporaryConstraints.end(); -} - - void SolveSpaceSolver_Storage::initializeSolver(SolverPtr theSolver) { @@ -1264,7 +1222,7 @@ void SolveSpaceSolver_Storage::fixPoint(const Slvs_Entity& thePoint, Slvs_Constraint aConstraint; Slvs_hConstraint aConstrID = SLVS_E_UNKNOWN; bool isFixed = isPointFixed(thePoint.h, aConstrID, true); - bool isForceUpdate = (isFixed && isTemporary(aConstrID)); + bool isForceUpdate = (isFixed /*&& isTemporary(aConstrID)*/); if (!isForceUpdate) { // create new constraint if (isFixed) return; aConstraint = Slvs_MakeConstraint(SLVS_E_UNKNOWN, thePoint.group, SLVS_C_WHERE_DRAGGED, thePoint.wrkpl, @@ -1503,143 +1461,106 @@ bool SolveSpaceSolver_Storage::isUsedInEqual( return false; } -void SolveSpaceSolver_Storage::setTemporary(ConstraintPtr theConstraint) -{ - // TODO -} -bool SolveSpaceSolver_Storage::removeConstraint(ConstraintPtr theConstraint) +bool SolveSpaceSolver_Storage::removeCoincidence(ConstraintWrapperPtr theConstraint) { - std::map >::iterator - aFound = myConstraintMap.find(theConstraint); - if (aFound == myConstraintMap.end()) - return true; // no constraint, already deleted - - // Remove constraint - std::list aConstrList = aFound->second; - myConstraintMap.erase(aFound); - // Remove SolveSpace constraints - bool isFullyRemoved = true; - std::list::iterator anIt = aConstrList.begin(); - while (anIt != aConstrList.end()) { - if (remove(*anIt)) { - std::list::iterator aRemoveIt = anIt++; - aConstrList.erase(aRemoveIt); - } else { - isFullyRemoved = false; - ++anIt; - } + std::list aPoints = theConstraint->entities(); + std::list::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 (!isFullyRemoved) - myConstraintMap[theConstraint] = aConstrList; - return isFullyRemoved; -} - -template -static bool isUsed(ConstraintWrapperPtr theConstraint, ENT_TYPE theEntity) -{ - std::list::const_iterator anEntIt = theConstraint->entities().begin(); - for (; anEntIt != theConstraint->entities().end(); ++anEntIt) - if (std::dynamic_pointer_cast(*anEntIt)->isBase(theEntity)) - return true; - return false; -} -static bool isUsed(EntityWrapperPtr theFeature, AttributePtr theSubEntity) -{ - std::list::const_iterator aSubIt = theFeature->subEntities().begin(); - for (; aSubIt != theFeature->subEntities().end(); ++aSubIt) - if (std::dynamic_pointer_cast(*aSubIt)->isBase(theSubEntity)) - return true; - return false; -} + if (aPtPtIt == myCoincidentPoints.end()) + return true; // already removed -bool SolveSpaceSolver_Storage::isUsed(FeaturePtr theFeature) const -{ - std::map >::const_iterator - aCIt = myConstraintMap.begin(); - std::list::const_iterator aCWIt; - for (; aCIt != myConstraintMap.end(); ++aCIt) - for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt) - if (::isUsed(*aCWIt, theFeature)) - return true; - // check attributes - std::list anAttrList = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list::const_iterator anIt = anAttrList.begin(); - for (; anIt != anAttrList.end(); ++anIt) - if (isUsed(*anIt)) - return true; - return false; -} - -bool SolveSpaceSolver_Storage::isUsed(AttributePtr theAttribute) const -{ - AttributePtr anAttribute = theAttribute; - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttribute); - if (aRefAttr) { - if (aRefAttr->isObject()) - return isUsed(ModelAPI_Feature::feature(aRefAttr->object())); - else - anAttribute = aRefAttr->attr(); + // Create new copies of coincident points + BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance(); + std::list 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 aNotCoinc; + aNotCoinc[aPtPtIt->first] = EntityWrapperPtr(); + std::set::const_iterator aTempIt = aPtPtIt->second.begin(); + for (; aTempIt != aPtPtIt->second.end(); ++aTempIt) + aNotCoinc[*aTempIt] = EntityWrapperPtr(); + std::map >::iterator + aConstrIt = myConstraintMap.begin(); + for (; aConstrIt != myConstraintMap.end(); ++aConstrIt) + if (aConstrIt->first->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { + AttributeRefAttrPtr aRefAttrA = std::dynamic_pointer_cast( + aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_A())); + AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast( + aConstrIt->first->attribute(SketchPlugin_Constraint::ENTITY_B())); + if (!aRefAttrA || !aRefAttrB || aRefAttrA->isObject() || aRefAttrB->isObject()) + continue; + std::map::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::const_iterator aNewPIt; + for (aPIt = aPoints.begin(), aNewPIt = aNewPoints.begin(); + aPIt != aPoints.end(); ++aPIt, ++aNewPIt) { + if (aNotCoinc.find(*aPIt) != aNotCoinc.end()) + aNotCoinc[*aPIt] = *aNewPIt; } - std::map >::const_iterator - aCIt = myConstraintMap.begin(); - std::list::const_iterator aCWIt; - for (; aCIt != myConstraintMap.end(); ++aCIt) - for (aCWIt = aCIt->second.begin(); aCWIt != aCIt->second.end(); ++aCWIt) - if (::isUsed(*aCWIt, anAttribute)) - return true; - return false; -} - - -bool SolveSpaceSolver_Storage::removeEntity(FeaturePtr theFeature) -{ - std::map::iterator aFound = myFeatureMap.find(theFeature); - if (aFound == myFeatureMap.end()) - return false; // feature not found, nothing to delete - - // 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 - myFeatureMap[theFeature] = anEntity; - return false; -} - -bool SolveSpaceSolver_Storage::removeEntity(AttributePtr theAttribute) -{ - std::map::iterator aFound = myAttributeMap.find(theAttribute); - if (aFound == myAttributeMap.end()) - return false; // attribute not found, nothing to delete - - // Check the attribute is not used by constraints - if (isUsed(theAttribute)) - return false; // the attribute is used, don't remove it - // Check the attribute is not used by other features - std::map::const_iterator aFIt = myFeatureMap.begin(); - for (; aFIt != myFeatureMap.end(); ++aFIt) - if (::isUsed(aFIt->second, theAttribute)) // 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 - myAttributeMap[theAttribute] = anEntity; - return false; + // Find all features and constraints uses coincident points + std::map::iterator aNotCIt; + std::set anUpdFeatures; + std::map::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 aSubs = aFIt->second->subEntities(); + std::list::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::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->second.size() <= 1) { + myCoincidentPoints.erase(aPtPtIt); + break; + } + if (aPtPtIt->first == aNotCIt->first) { + std::set 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 aConstraint = @@ -1657,41 +1578,22 @@ bool SolveSpaceSolver_Storage::remove(ConstraintWrapperPtr theConstraint) bool isFullyRemoved = removeConstraint((Slvs_hConstraint)aConstraint->id()); - std::list::const_iterator anIt = aConstraint->entities().begin(); - for (; anIt != aConstraint->entities().end(); ++anIt) { - std::shared_ptr anEntity = - std::dynamic_pointer_cast(*anIt); - FeaturePtr aBaseFeature = anEntity->baseFeature(); - if (aBaseFeature) - isFullyRemoved = removeEntity(aBaseFeature) && isFullyRemoved; - else - isFullyRemoved = removeEntity(anEntity->baseAttribute()) && isFullyRemoved; - } + // remove point-point coincidence + if (aConstraint->type() == CONSTRAINT_PT_PT_COINCIDENT) + isFullyRemoved = removeCoincidence(theConstraint); - return isFullyRemoved; + return SketchSolver_Storage::remove(theConstraint) && isFullyRemoved; } bool SolveSpaceSolver_Storage::remove(EntityWrapperPtr theEntity) { + if (!theEntity) + return false; + std::shared_ptr anEntity = std::dynamic_pointer_cast(theEntity); bool isFullyRemoved = removeEntity((Slvs_hEntity)anEntity->id()); - - std::list::const_iterator anEntIt = anEntity->subEntities().begin(); - for (; anEntIt != anEntity->subEntities().end(); ++anEntIt) { - std::shared_ptr aSubEntity = - std::dynamic_pointer_cast(*anEntIt); - FeaturePtr aBaseFeature = aSubEntity->baseFeature(); - if (aBaseFeature) - isFullyRemoved = removeEntity(aBaseFeature) && isFullyRemoved; - else - isFullyRemoved = removeEntity(aSubEntity->baseAttribute()) && isFullyRemoved; - } - - std::list::const_iterator aParIt = anEntity->parameters().begin(); - for (; aParIt != anEntity->parameters().end(); ++aParIt) - isFullyRemoved = remove(*aParIt) && isFullyRemoved; - return isFullyRemoved; + return SketchSolver_Storage::remove(theEntity) && isFullyRemoved; } bool SolveSpaceSolver_Storage::remove(ParameterWrapperPtr theParameter) @@ -1702,12 +1604,23 @@ bool SolveSpaceSolver_Storage::remove(ParameterWrapperPtr theParameter) void SolveSpaceSolver_Storage::refresh(bool theFixedOnly) const { - blockEvents(true); + //blockEvents(true); std::map::const_iterator anIt = myAttributeMap.begin(); std::list aParams; std::list::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::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(anIt->first->owner()); + if (aSketchFeature.get() && aSketchFeature->isExternal()) + continue; + } + // update parameter wrappers and obtain values of attributes aParams = anIt->second->parameters(); double aCoords[3]; @@ -1764,13 +1677,15 @@ void SolveSpaceSolver_Storage::refresh(bool theFixedOnly) const } } - blockEvents(false); + //blockEvents(false); } void SolveSpaceSolver_Storage::verifyFixed() { std::map::iterator anAttrIt = myAttributeMap.begin(); for (; anAttrIt != myAttributeMap.end(); ++anAttrIt) { + if (!anAttrIt->second) + continue; const std::list& aParameters = anAttrIt->second->parameters(); std::list::const_iterator aParIt = aParameters.begin(); for (; aParIt != aParameters.end(); ++aParIt)