X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_Group.cpp;h=11f334f51922cf00be3712b150d2560a9f06f34a;hb=d3883990177d27a12b8a2278cdbb82250ff19b79;hp=b51828ba9d0eb78e560f1d934f11f9801a4642a3;hpb=80d9dcc9384a77fb31ecf668598129083dca6675;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index b51828ba9..11f334f51 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -25,11 +25,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include @@ -178,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); @@ -214,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(); @@ -230,14 +233,25 @@ bool SketchSolver_Group::changeConstraint( continue; aConstraint->setGroup(this); aConstraint->setStorage(myStorage); - myTempConstraints.insert(aConstraint); + 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) @@ -257,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; @@ -264,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); - myTempConstraints.insert(aConstraint); + if (aConstraint->error().empty()) + setTemporary(aConstraint); + // Secondly, update the feature + updateFeature(theFeature); } // ============================================================================ @@ -284,17 +305,32 @@ 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); aConstraint->setStorage(myStorage); - myTempConstraints.insert(aConstraint); + setTemporary(aConstraint); } } @@ -383,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(); @@ -413,9 +468,18 @@ void SketchSolver_Group::mergeGroups(const SketchSolver_Group& theGroup) if (!myFeatureStorage) myFeatureStorage = FeatureStoragePtr(new SketchSolver_FeatureStorage); + std::vector aComplexConstraints; ConstraintConstraintMap::const_iterator aConstrIter = theGroup.myConstraints.begin(); + // append simple constraints for (; aConstrIter != theGroup.myConstraints.end(); aConstrIter++) - changeConstraint(aConstrIter->first); + if (isComplexConstraint(aConstrIter->first)) + aComplexConstraints.push_back(aConstrIter->first); + else + changeConstraint(aConstrIter->first); + // append complex constraints + std::vector::iterator aComplexIter = aComplexConstraints.begin(); + for (; aComplexIter != aComplexConstraints.end(); aComplexIter++) + changeConstraint(*aComplexIter); } // ============================================================================ @@ -513,6 +577,8 @@ bool SketchSolver_Group::isConsistent() void SketchSolver_Group::removeTemporaryConstraints() { myTempConstraints.clear(); + while (myStorage->numberTemporary()) + myStorage->deleteTemporaryConstraint(); // Clean lists of removed entities in the storage std::set aRemPar; std::set aRemEnt; @@ -539,3 +605,27 @@ void SketchSolver_Group::removeConstraint(ConstraintPtr theConstraint) if (aCIter != myConstraints.end()) myConstraints.erase(aCIter); } + +// ============================================================================ +// Function: isComplexConstraint +// Class: SketchSolver_Group +// Purpose: verifies the constraint is complex, i.e. it needs another constraints to be created before +// ============================================================================ +bool SketchSolver_Group::isComplexConstraint(FeaturePtr theConstraint) +{ + return theConstraint->getKind() == SketchPlugin_ConstraintFillet::ID() || + theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID() || + theConstraint->getKind() == SketchPlugin_ConstraintTangent::ID(); +} + +// ============================================================================ +// Function: setTemporary +// Class: SketchSolver_Group +// Purpose: append given constraint to th group of temporary constraints +// ============================================================================ +void SketchSolver_Group::setTemporary(SolverConstraintPtr theConstraint) +{ + theConstraint->makeTemporary(); + myTempConstraints.insert(theConstraint); +} +