X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSolveSpaceSolver%2FSolveSpaceSolver_Storage.cpp;h=999f43eefc46a7e7451a83382f998de382839106;hb=cf8f82e87c5bec5bef69549ce628bfdb093b92a1;hp=7843cd88c29d9afaa7baa28633ba7ab2efe04a7b;hpb=37c59d59b17e4a7e304588fb647488457a0c7283;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp b/src/SketchSolver/SolveSpaceSolver/SolveSpaceSolver_Storage.cpp index 7843cd88c..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); @@ -185,8 +201,6 @@ bool SolveSpaceSolver_Storage::update(ParameterWrapperPtr& theParameter) Slvs_Param aParamToUpd = aParameter->parameter(); if (aParamToUpd.group == SLVS_G_UNKNOWN) aParamToUpd.group = aParameter->isParametric() ? (Slvs_hGroup)GID_OUTOFGROUP : (Slvs_hGroup)myGroupID; -//// else if (aParameter->isParametric() && aParamToUpd.group != (Slvs_hGroup)GID_OUTOFGROUP) -//// aParameter->setGroup(GID_OUTOFGROUP); Slvs_hParam anID = updateParameter(aParamToUpd); if (aParam.h == SLVS_E_UNKNOWN) // new parameter aParameter->changeParameter() = getParameter(anID); @@ -294,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); @@ -313,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(); @@ -536,8 +553,10 @@ Slvs_hParam SolveSpaceSolver_Storage::updateParameter(const Slvs_Param& theParam // parameter already used, rewrite it int aPos = Search(theParam.h, myParameters); if (aPos >= 0 && aPos < (int)myParameters.size()) { - if (IsNotEqual(myParameters[aPos], theParam)) + if (IsNotEqual(myParameters[aPos], theParam)) { myUpdatedParameters.insert(theParam.h); + setNeedToResolve(true); + } myParameters[aPos] = theParam; return theParam.h; } @@ -564,11 +583,7 @@ bool SolveSpaceSolver_Storage::removeParameter(const Slvs_hParam& theParamID) myParameters.erase(myParameters.begin() + aPos); myParamMaxID = myParameters.empty() ? SLVS_E_UNKNOWN : myParameters.back().h; myNeedToResolve = true; -//// myRemovedParameters.insert(theParamID); - return true; } -//// else if (myRemovedParameters.find(theParamID) != myRemovedParameters.end()) -//// return true; return true; } @@ -664,12 +679,7 @@ bool SolveSpaceSolver_Storage::removeEntity(const Slvs_hEntity& theEntityID) if (anEntity.point[i] != SLVS_E_UNKNOWN) aResult = removeEntity(anEntity.point[i]) && aResult; myNeedToResolve = true; -//// myRemovedEntities.insert(theEntityID); -//// if (anEntity.type == SLVS_E_POINT_IN_2D || anEntity.type == SLVS_E_POINT_IN_3D) -//// removeCoincidentPoint(theEntityID); } -//// else if (myRemovedEntities.find(theEntityID) != myRemovedEntities.end()) -//// return true; return aResult; } @@ -750,9 +760,6 @@ void SolveSpaceSolver_Storage::removeUnusedEntities() for (int i = 0; i < 4; i++) if (anEntity.point[i] != SLVS_E_UNKNOWN) removeEntity(anEntity.point[i]); -//// myRemovedEntities.insert(*anEntIt); -//// if (anEntity.type == SLVS_E_POINT_IN_2D || anEntity.type == SLVS_E_POINT_IN_3D) -//// removeCoincidentPoint(*anEntIt); } } @@ -847,12 +854,6 @@ bool SolveSpaceSolver_Storage::isPointFixed( // Search the set of coincident points std::set aCoincident; aCoincident.insert(thePointID); -//// std::vector< std::set >::const_iterator aCPIter = myCoincidentPoints.begin(); -//// for (; aCPIter != myCoincidentPoints.end(); aCPIter++) -//// if (aCPIter->find(thePointID) != aCPIter->end()) { -//// aCoincident = *aCPIter; -//// break; -//// } // Check whether one of coincident points is out-of-group std::set::const_iterator aCoincIt = aCoincident.begin(); @@ -907,12 +908,6 @@ bool SolveSpaceSolver_Storage::isEntityFixed(const Slvs_hEntity& theEntityID, bo std::set aCoincident; aCoincident.insert(aPoint); -//// std::vector< std::set >::const_iterator aCPIter = myCoincidentPoints.begin(); -//// for (; aCPIter != myCoincidentPoints.end(); aCPIter++) -//// if (aCPIter->find(aPoint) != aCPIter->end()) { -//// aCoincident = *aCPIter; -//// break; -//// } // Search the Rigid constraint std::vector::const_iterator aConstrIter = myConstraints.begin(); @@ -1040,8 +1035,6 @@ Slvs_hConstraint SolveSpaceSolver_Storage::addConstraint(const Slvs_Constraint& aConstraint.h = ++myConstrMaxID; myConstraints.push_back(aConstraint); myNeedToResolve = true; -//// if (aConstraint.type == SLVS_C_POINTS_COINCIDENT) -//// addCoincidentPoints(aConstraint.ptA, aConstraint.ptB); return aConstraint.h; } @@ -1053,8 +1046,6 @@ Slvs_hConstraint SolveSpaceSolver_Storage::updateConstraint(const Slvs_Constrain if (aPos >= 0 && aPos < (int)myConstraints.size()) { myNeedToResolve = myNeedToResolve || IsNotEqual(myConstraints[aPos], theConstraint); myConstraints[aPos] = theConstraint; -//// if (theConstraint.type == SLVS_C_POINTS_COINCIDENT) -//// addCoincidentPoints(theConstraint.ptA, theConstraint.ptB); return theConstraint.h; } } @@ -1074,9 +1065,6 @@ bool SolveSpaceSolver_Storage::removeConstraint(const Slvs_hConstraint& theConst myConstraints.erase(myConstraints.begin() + aPos); myConstrMaxID = myConstraints.empty() ? SLVS_E_UNKNOWN : myConstraints.back().h; myNeedToResolve = true; -//// myRemovedConstraints.insert(theConstraintID); -//// if (aConstraint.type == SLVS_C_POINTS_COINCIDENT) -//// removeCoincidence(aConstraint); // Remove all entities Slvs_hEntity anEntities[6] = {aConstraint.ptA, aConstraint.ptB, @@ -1104,8 +1092,6 @@ bool SolveSpaceSolver_Storage::removeConstraint(const Slvs_hConstraint& theConst } } } -//// else if (myRemovedConstraints.find(theConstraintID) != myRemovedConstraints.end()) -//// return true; return aResult; } @@ -1141,80 +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::getRemoved( -//// std::set& theParameters, -//// std::set& theEntities, -//// std::set& theConstraints) -////{ -//// theParameters = myRemovedParameters; -//// theEntities = myRemovedEntities; -//// theConstraints = myRemovedConstraints; -//// -//// myRemovedParameters.clear(); -//// myRemovedEntities.clear(); -//// myRemovedConstraints.clear(); -////} void SolveSpaceSolver_Storage::initializeSolver(SolverPtr theSolver) { @@ -1252,96 +1164,10 @@ void SolveSpaceSolver_Storage::initializeSolver(SolverPtr theSolver) aSolver->setConstraints(aConstraints.data(), (int)aConstraints.size()); } -////void SolveSpaceSolver_Storage::addCoincidentPoints( -//// const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) -////{ -//// std::vector< std::set >::iterator aCIter = myCoincidentPoints.begin(); -//// std::vector< std::set >::iterator aFoundIter = myCoincidentPoints.end(); // already found coincidence -//// bool isFound = false; -//// for (; aCIter != myCoincidentPoints.end(); aCIter++) { -//// bool isFirstFound = aCIter->find(thePoint1) != aCIter->end(); -//// bool isSecondFound = aCIter->find(thePoint2) != aCIter->end(); -//// isFound = isFound || isFirstFound || isSecondFound; -//// if (isFirstFound && isSecondFound) -//// break; // already coincident -//// else if (isFirstFound || isSecondFound) { -//// if (aFoundIter != myCoincidentPoints.end()) { -//// // merge two sets -//// aFoundIter->insert(aCIter->begin(), aCIter->end()); -//// myCoincidentPoints.erase(aCIter); -//// break; -//// } else -//// aFoundIter = aCIter; -//// aCIter->insert(thePoint1); -//// aCIter->insert(thePoint2); -//// } -//// } -//// // coincident points not found -//// if (!isFound) { -//// std::set aNewSet; -//// aNewSet.insert(thePoint1); -//// aNewSet.insert(thePoint2); -//// myCoincidentPoints.push_back(aNewSet); -//// } -////} -//// -////void SolveSpaceSolver_Storage::removeCoincidentPoint(const Slvs_hEntity& thePoint) -////{ -//// std::vector< std::set >::iterator aCIter = myCoincidentPoints.begin(); -//// for (; aCIter != myCoincidentPoints.end(); aCIter++) -//// if (aCIter->find(thePoint) != aCIter->end()) { -//// aCIter->erase(thePoint); -//// if (aCIter->size() <= 1) -//// myCoincidentPoints.erase(aCIter); -//// break; -//// } -////} -//// -////void SolveSpaceSolver_Storage::removeCoincidence(const Slvs_Constraint& theCoincidence) -////{ -//// // Find set of coincident points -//// std::vector< std::set >::iterator aCIt = myCoincidentPoints.begin(); -//// for (; aCIt != myCoincidentPoints.end(); ++aCIt) -//// if (aCIt->find(theCoincidence.ptA) != aCIt->end() || -//// aCIt->find(theCoincidence.ptB) != aCIt->end()) -//// break; -//// if (aCIt == myCoincidentPoints.end()) -//// return; -//// -//// // Leave only the points which are still coincident -//// std::set aRemainCoincidence; -//// std::vector::const_iterator aConstrIt = myConstraints.begin(); -//// for (; aConstrIt != myConstraints.end(); ++aConstrIt) { -//// if (aConstrIt->type != SLVS_C_POINTS_COINCIDENT) -//// continue; -//// if (aCIt->find(aConstrIt->ptA) != aCIt->end() || -//// aCIt->find(aConstrIt->ptB) != aCIt->end()) { -//// aRemainCoincidence.insert(aConstrIt->ptA); -//// aRemainCoincidence.insert(aConstrIt->ptB); -//// } -//// } -//// if (aRemainCoincidence.size() <= 1) -//// myCoincidentPoints.erase(aCIt); -//// else -//// aCIt->swap(aRemainCoincidence); -////} -//// -////bool SolveSpaceSolver_Storage::isCoincident( -//// const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const -////{ -//// std::vector< std::set >::const_iterator aCIter = myCoincidentPoints.begin(); -//// for (; aCIter != myCoincidentPoints.end(); aCIter++) -//// if (aCIter->find(thePoint1) != aCIter->end() && aCIter->find(thePoint2) != aCIter->end()) -//// return true; -//// return false; -////} bool SolveSpaceSolver_Storage::isEqual( const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const { -//// if (isCoincident(thePoint1, thePoint2)) -//// return true; - // Precise checking of coincidence: verify that points have equal coordinates int aEnt1Pos = Search(thePoint1, myEntities); int aEnt2Pos = Search(thePoint2, myEntities); @@ -1396,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, @@ -1635,184 +1461,106 @@ bool SolveSpaceSolver_Storage::isUsedInEqual( return false; } -////bool SolveSpaceSolver_Storage::isNeedToResolve() -////{ -//// if (myConstraints.empty()) -//// return false; -//// -//// if (!myNeedToResolve) { -//// // Verify the updated parameters are used in constraints -//// std::set aPoints; -//// std::vector::const_iterator anEntIt = myEntities.begin(); -//// for (; anEntIt != myEntities.end(); ++anEntIt) { -//// for (int i = 0; i < 4 && anEntIt->param[i] != SLVS_E_UNKNOWN; ++i) -//// if (myUpdatedParameters.find(anEntIt->param[i]) != myUpdatedParameters.end()) { -//// aPoints.insert(anEntIt->h); -//// break; -//// } -//// } -//// std::set anEntities = aPoints; -//// for (anEntIt = myEntities.begin(); anEntIt != myEntities.end(); ++anEntIt) { -//// for (int i = 0; i < 4 && anEntIt->point[i] != SLVS_E_UNKNOWN; ++i) -//// if (aPoints.find(anEntIt->point[i]) != aPoints.end()) { -//// anEntities.insert(anEntIt->h); -//// break; -//// } -//// } -//// -//// std::vector::const_iterator aCIt = myConstraints.begin(); -//// for (; aCIt != myConstraints.end() && !myNeedToResolve; ++aCIt) { -//// Slvs_hEntity anAttrs[6] = -//// {aCIt->ptA, aCIt->ptB, aCIt->entityA, aCIt->entityB, aCIt->entityC, aCIt->entityD}; -//// for (int i = 0; i < 6; i++) -//// if (anAttrs[i] != SLVS_E_UNKNOWN && anEntities.find(anAttrs[i]) != anEntities.end()) { -//// myNeedToResolve = true; -//// break; -//// } -//// } -//// } -//// -//// myUpdatedParameters.clear(); -//// return myNeedToResolve; -////} - -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; -} -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; -} + if (aPtPtIt == myCoincidentPoints.end()) + return true; // already removed -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 = @@ -1830,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) @@ -1875,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]; @@ -1906,6 +1646,14 @@ void SolveSpaceSolver_Storage::refresh(bool theFixedOnly) const if (!isUpd[0]) aCoords[0] = aPoint2D->x(); if (!isUpd[1]) aCoords[1] = aPoint2D->y(); aPoint2D->setValue(aCoords[0], aCoords[1]); + // Find points coincident with this one (probably not in GID_OUTOFGROUP) + std::map::const_iterator aLocIt = + theFixedOnly ? myAttributeMap.begin() : anIt; + for (++aLocIt; aLocIt != myAttributeMap.end(); ++aLocIt) + if (anIt->second->id() == aLocIt->second->id()) { + aPoint2D = std::dynamic_pointer_cast(aLocIt->first); + aPoint2D->setValue(aCoords[0], aCoords[1]); + } } continue; } @@ -1929,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)