X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_Group.cpp;h=11f334f51922cf00be3712b150d2560a9f06f34a;hb=d3883990177d27a12b8a2278cdbb82250ff19b79;hp=7fdc32a4c5e74b5c2c1ee514339fd2d28f60e298;hpb=fd4dd622a85a0dd19ff5616391f94e980abc26a1;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 7fdc32a4c..11f334f51 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -179,7 +180,8 @@ bool SketchSolver_Group::changeConstraint( if (!theConstraint) return false; - if (myConstraints.find(theConstraint) == myConstraints.end()) { + bool isNewConstraint = myConstraints.find(theConstraint) == myConstraints.end(); + if (isNewConstraint) { // Add constraint to the current group SolverConstraintPtr aConstraint = SketchSolver_Builder::getInstance()->createConstraint(theConstraint); @@ -215,7 +217,7 @@ bool SketchSolver_Group::changeConstraint( myConstraints[theConstraint]->update(); // Fix base features for fillet - if (theConstraint->getKind() == SketchPlugin_ConstraintFillet::ID()) { + if (isNewConstraint && theConstraint->getKind() == SketchPlugin_ConstraintFillet::ID()) { std::list anAttrList = theConstraint->data()->attributes(ModelAPI_AttributeRefAttr::typeId()); std::list::iterator anAttrIter = anAttrList.begin(); @@ -234,11 +236,22 @@ bool SketchSolver_Group::changeConstraint( setTemporary(aConstraint); } } - // Fix base features for mirror + // Fix mirror line if (theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID()) { - AttributeRefListPtr aRefList = std::dynamic_pointer_cast( - theConstraint->attribute(SketchPlugin_ConstraintMirror::ENTITY_B())); - fixFeaturesList(aRefList); + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast( + theConstraint->attribute(SketchPlugin_ConstraintMirror::ENTITY_A())); + if (aRefAttr && aRefAttr->isObject()) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + if (aFeature) { + SolverConstraintPtr aConstraint = + SketchSolver_Builder::getInstance()->createRigidConstraint(aFeature); + if (aConstraint) { + aConstraint->setGroup(this); + aConstraint->setStorage(myStorage); + setTemporary(aConstraint); + } + } + } } if (!myFeatureStorage) @@ -258,6 +271,11 @@ bool SketchSolver_Group::updateFeature(std::shared_ptr the std::set::iterator aCIter = aConstraints.begin(); for (; aCIter != aConstraints.end(); aCIter++) { ConstraintConstraintMap::iterator aSolConIter = myConstraints.find(*aCIter); + if (aSolConIter == myConstraints.end() || !aSolConIter->first->data() || + !aSolConIter->first->data()->isValid()) + continue; + myFeatureStorage->changeFeature(theFeature, aSolConIter->first); + aSolConIter->second->addFeature(theFeature); aSolConIter->second->update(); } return true; @@ -265,15 +283,17 @@ bool SketchSolver_Group::updateFeature(std::shared_ptr the void SketchSolver_Group::moveFeature(std::shared_ptr theFeature) { - updateFeature(theFeature); - // Temporary rigid constraint + // Firstly, create temporary rigid constraint SolverConstraintPtr aConstraint = - SketchSolver_Builder::getInstance()->createRigidConstraint(theFeature); + SketchSolver_Builder::getInstance()->createMovementConstraint(theFeature); if (!aConstraint) return; aConstraint->setGroup(this); aConstraint->setStorage(myStorage); - setTemporary(aConstraint); + if (aConstraint->error().empty()) + setTemporary(aConstraint); + // Secondly, update the feature + updateFeature(theFeature); } // ============================================================================ @@ -285,12 +305,27 @@ void SketchSolver_Group::fixFeaturesList(AttributeRefListPtr theList) { std::list aList = theList->list(); std::list::iterator anIt = aList.begin(); + std::list aFeatures; + // Sort features, at begining there are features used by Equal constraint for (; anIt != aList.end(); anIt++) { if (!(*anIt)) continue; FeaturePtr aFeature = ModelAPI_Feature::feature(*anIt); + std::set aConstraints = myFeatureStorage->getConstraints(aFeature); + std::set::iterator aCIter = aConstraints.begin(); + for (; aCIter != aConstraints.end(); aCIter++) + if ((*aCIter)->getKind() == SketchPlugin_ConstraintEqual::ID()) + break; + if (aCIter != aConstraints.end()) + aFeatures.push_front(aFeature); + else + aFeatures.push_back(aFeature); + } + + std::list::iterator aFeatIter = aFeatures.begin(); + for (; aFeatIter != aFeatures.end(); aFeatIter++) { SolverConstraintPtr aConstraint = - SketchSolver_Builder::getInstance()->createRigidConstraint(aFeature); + SketchSolver_Builder::getInstance()->createRigidConstraint(*aFeatIter); if (!aConstraint) continue; aConstraint->setGroup(this); @@ -384,7 +419,26 @@ bool SketchSolver_Group::resolveConstraints() myConstrSolver.setGroupID(myID); myStorage->initializeSolver(myConstrSolver); - int aResult = myConstrSolver.solve(); + int aResult = SLVS_RESULT_OKAY; + try { + if (myStorage->hasDuplicatedConstraint()) + aResult = SLVS_RESULT_INCONSISTENT; + else { + // To avoid overconstraint situation, we will remove temporary constraints one-by-one + // and try to find the case without overconstraint + int aNbTemp = myStorage->numberTemporary(); + while (true) { + aResult = myConstrSolver.solve(); + if (aResult == SLVS_RESULT_OKAY || aNbTemp <= 0) + break; + aNbTemp = myStorage->deleteTemporaryConstraint(); + myStorage->initializeSolver(myConstrSolver); + } + } + } catch (...) { + Events_Error::send(SketchSolver_Error::SOLVESPACE_CRASH(), this); + return false; + } if (aResult == SLVS_RESULT_OKAY) { // solution succeeded, store results into correspondent attributes myFeatureStorage->blockEvents(true); ConstraintConstraintMap::iterator aConstrIter = myConstraints.begin(); @@ -523,7 +577,8 @@ bool SketchSolver_Group::isConsistent() void SketchSolver_Group::removeTemporaryConstraints() { myTempConstraints.clear(); - myStorage->removeTemporaryConstraints(); + while (myStorage->numberTemporary()) + myStorage->deleteTemporaryConstraint(); // Clean lists of removed entities in the storage std::set aRemPar; std::set aRemEnt;