X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintManager.cpp;h=ff571878b964b567331ea2949d5efdb6fe9c38fd;hb=2ca823f76cac784f9e4a2fc37deeb7147b834814;hp=777519914ed712d9bb0bcc396fac73a43f459458;hpb=fe55d1385d83a74a7bfd0d1a5bd18d408009e6ab;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintManager.cpp b/src/SketchSolver/SketchSolver_ConstraintManager.cpp index 777519914..ff571878b 100644 --- a/src/SketchSolver/SketchSolver_ConstraintManager.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintManager.cpp @@ -5,25 +5,26 @@ #include "SketchSolver_ConstraintManager.h" #include -#include -#include -#include #include #include #include -#include +#include + #include -#include + +#include +#include #include +#include #include + +// Initialization of constraint manager self pointer SketchSolver_ConstraintManager* SketchSolver_ConstraintManager::_self = 0; -/// Global constaint manager object +/// Global constraint manager object SketchSolver_ConstraintManager* myManager = SketchSolver_ConstraintManager::Instance(); -/// This value is used to give unique index to the groups -static Slvs_hGroup myGroupIndexer = 0; // ======================================================== // ========= SketchSolver_ConstraintManager =============== @@ -43,6 +44,7 @@ SketchSolver_ConstraintManager::SketchSolver_ConstraintManager() Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED)); Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_UPDATED)); Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED)); + Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_MOVED)); } SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager() @@ -50,373 +52,328 @@ SketchSolver_ConstraintManager::~SketchSolver_ConstraintManager() myGroups.clear(); } +// ============================================================================ +// Function: processEvent +// Class: SketchSolver_PluginManager +// Purpose: listen the event loop and process the message +// ============================================================================ void SketchSolver_ConstraintManager::processEvent(const Events_Message* theMessage) { - if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED)) + if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_CREATED) || + theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED) || + theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_MOVED)) { - const Model_FeatureUpdatedMessage* aCreateMsg = dynamic_cast(theMessage); + const ModelAPI_FeatureUpdatedMessage* anUpdateMsg = + dynamic_cast(theMessage); + std::set< FeaturePtr > aFeatures = anUpdateMsg->features(); - // Only sketches and constraints can be added by Create event - boost::shared_ptr aSketch = - boost::dynamic_pointer_cast(aCreateMsg->feature()); - if (aSketch) + bool isModifiedEvt = + theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_MOVED); + if (!isModifiedEvt) { - addWorkplane(aSketch); - return ; - } - boost::shared_ptr aConstraint = - boost::dynamic_pointer_cast(aCreateMsg->feature()); - if (aConstraint) - { - addConstraint(aConstraint); - return ; + std::set< FeaturePtr >::iterator aFeatIter; + for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) + { + // Only sketches and constraints can be added by Create event + const std::string& aFeatureKind = (*aFeatIter)->getKind(); + if (aFeatureKind.compare(SKETCH_KIND) == 0) + { + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(*aFeatIter); + if (aSketch) + changeWorkplane(aSketch); + continue; + } + boost::shared_ptr aConstraint = + boost::dynamic_pointer_cast(*aFeatIter); + if (aConstraint) + changeConstraint(aConstraint); + else + { + // Sketch plugin features can be only updated + boost::shared_ptr aFeature = + boost::dynamic_pointer_cast(*aFeatIter); + if (aFeature) + updateEntity(aFeature); + } + } } + + // Solve the set of constraints + resolveConstraints(); } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED)) { - const Model_FeatureDeletedMessage* aDeleteMsg = dynamic_cast(theMessage); - /// \todo Implement deleting objects on event - } - else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED)) - { - const Model_FeatureUpdatedMessage* aUpdateMsg = dynamic_cast(theMessage); - - boost::shared_ptr aSketch = - boost::dynamic_pointer_cast(aUpdateMsg->feature()); - if (aSketch) - { -// updateWorkplane(aSketch); - return ; - } - - boost::shared_ptr aConstraint = - boost::dynamic_pointer_cast(aUpdateMsg->feature()); - if (aConstraint) + const ModelAPI_FeatureDeletedMessage* aDeleteMsg = + dynamic_cast(theMessage); + const std::set& aFeatureGroups = aDeleteMsg->groups(); + + // Find SKETCH_KIND in groups. The constraint groups should be updated when an object removed from Sketch + std::set::const_iterator aFGrIter; + for (aFGrIter = aFeatureGroups.begin(); aFGrIter != aFeatureGroups.end(); aFGrIter++) + if (aFGrIter->compare(SKETCH_KIND) == 0) + break; + + if (aFGrIter != aFeatureGroups.end()) { -// updateConstraint(aConstraint); - return ; + std::vector::iterator aGroupIter = myGroups.begin(); + std::vector aSeparatedGroups; + while (aGroupIter != myGroups.end()) + { + if (!(*aGroupIter)->isWorkplaneValid()) + { // the group should be removed + delete *aGroupIter; + int aShift = aGroupIter - myGroups.begin(); + myGroups.erase(aGroupIter); + aGroupIter = myGroups.begin() + aShift; + continue; + } + if ((*aGroupIter)->updateGroup()) + { // some constraints were removed, try to split the group + (*aGroupIter)->splitGroup(aSeparatedGroups); + } + aGroupIter++; + } + if (aSeparatedGroups.size() > 0) + myGroups.insert(myGroups.end(), aSeparatedGroups.begin(), aSeparatedGroups.end()); } - - boost::shared_ptr aFeature = - boost::dynamic_pointer_cast(aUpdateMsg->feature()); -// if (aFeature) -// updateEntity(aFeature); } } - -bool SketchSolver_ConstraintManager::addWorkplane(boost::shared_ptr theSketch) +// ============================================================================ +// Function: changeWorkplane +// Class: SketchSolver_PluginManager +// Purpose: update workplane by given parameters of the sketch +// ============================================================================ +bool SketchSolver_ConstraintManager::changeWorkplane(boost::shared_ptr theSketch) { - // Check the specified workplane is already used - std::vector::const_iterator aGroupIter; + bool aResult = true; // changed when a workplane wrongly updated + bool isUpdated = false; + // Try to update specified workplane in all groups + std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) - if (aGroupIter->isBaseWorkplane(theSketch)) - return true; - // Create new group for workplane - SketchSolver_ConstraintGroup aNewGroup(theSketch); - // Verify that the group is created successfully - if (!aNewGroup.isBaseWorkplane(theSketch)) - return false; - myGroups.push_back(aNewGroup); - return true; + if ((*aGroupIter)->isBaseWorkplane(theSketch)) + { + isUpdated = true; + if (!(*aGroupIter)->updateWorkplane()) + aResult = false; + } + // If the workplane is not updated, so this is a new workplane + if (!isUpdated) + { + SketchSolver_ConstraintGroup* aNewGroup = new SketchSolver_ConstraintGroup(theSketch); + // Verify that the group is created successfully + if (!aNewGroup->isBaseWorkplane(theSketch)) + { + delete aNewGroup; + return false; + } + myGroups.push_back(aNewGroup); + } + return aResult; } -bool SketchSolver_ConstraintManager::addConstraint( +// ============================================================================ +// Function: changeConstraint +// Class: SketchSolver_PluginManager +// Purpose: create/update the constraint and place it into appropriate group +// ============================================================================ +bool SketchSolver_ConstraintManager::changeConstraint( boost::shared_ptr theConstraint) { - // Search the groups which this constraint touchs - std::vector aGroups; + // Search the groups which this constraint touches + std::set aGroups; findGroups(theConstraint, aGroups); // Process the groups list if (aGroups.size() == 0) { // There are no groups applicable for this constraint => create new one - SketchSolver_ConstraintGroup aGroup(findWorkplaneForConstraint(theConstraint)); - aGroup.addConstraint(theConstraint); + boost::shared_ptr aWP = findWorkplaneForConstraint(theConstraint); + if (!aWP) return false; + SketchSolver_ConstraintGroup* aGroup = new SketchSolver_ConstraintGroup(aWP); + if (!aGroup->changeConstraint(theConstraint)) + { + delete aGroup; + return false; + } myGroups.push_back(aGroup); + return true; } else if (aGroups.size() == 1) { // Only one group => add constraint into it Slvs_hGroup aGroupId = *(aGroups.begin()); - std::vector::iterator aGroupIter; + std::vector::iterator aGroupIter; for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) - if (aGroupIter->getId() == aGroupId) - return aGroupIter->addConstraint(theConstraint); + if ((*aGroupIter)->getId() == aGroupId) + return (*aGroupIter)->changeConstraint(theConstraint); } else if (aGroups.size() > 1) { // Several groups applicable for this constraint => need to merge them - /// \todo Implement merging of groups + std::set::const_iterator aGroupsIter = aGroups.begin(); + + // Search first group + std::vector::iterator aFirstGroupIter; + for (aFirstGroupIter = myGroups.begin(); aFirstGroupIter != myGroups.end(); aFirstGroupIter++) + if ((*aFirstGroupIter)->getId() == *aGroupsIter) + break; + if (aFirstGroupIter == myGroups.end()) + return false; + + // Append other groups to the first one + std::vector::iterator anOtherGroupIter = aFirstGroupIter + 1; + for (aGroupsIter++; aGroupsIter != aGroups.end(); aGroupsIter++) + { + for ( ; anOtherGroupIter != myGroups.end(); anOtherGroupIter++) + if ((*anOtherGroupIter)->getId() == *aGroupsIter) + break; + if (anOtherGroupIter == myGroups.end()) + { // Group disappears + anOtherGroupIter = aFirstGroupIter + 1; + continue; + } + + (*aFirstGroupIter)->mergeGroups(**anOtherGroupIter); + int aShiftFirst = aFirstGroupIter - myGroups.begin(); + int aShiftOther = anOtherGroupIter - myGroups.begin(); + delete *anOtherGroupIter; + myGroups.erase(anOtherGroupIter); + aFirstGroupIter = myGroups.begin() + aShiftFirst; + anOtherGroupIter = myGroups.begin() + aShiftOther; + } + + return (*aFirstGroupIter)->changeConstraint(theConstraint); } // Something goes wrong return false; } - -void SketchSolver_ConstraintManager::findGroups( - boost::shared_ptr theConstraint, - std::vector& theGroupIDs) const +// ============================================================================ +// Function: updateEntity +// Class: SketchSolver_PluginManager +// Purpose: update any element on the sketch, which is used by constraints +// ============================================================================ +void SketchSolver_ConstraintManager::updateEntity(boost::shared_ptr theFeature) { - std::vector::const_iterator aGroupIter; - for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) - if (aGroupIter->isInteract(theConstraint)) - theGroupIDs.push_back(aGroupIter->getId()); -} - -boost::shared_ptr SketchSolver_ConstraintManager::findWorkplaneForConstraint( - boost::shared_ptr theConstraint) const -{ - std::vector::const_iterator aGroupIter; - for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) + // Create list of attributes depending on type of the feature + std::vector anAttrList; + const std::string& aFeatureKind = theFeature->getKind(); + // Point + if (aFeatureKind.compare(SKETCH_POINT_KIND) == 0) + anAttrList.push_back(POINT_ATTR_COORD); + // Line + else if (aFeatureKind.compare(SKETCH_LINE_KIND) == 0) { - boost::shared_ptr aWP = aGroupIter->getWorkplane(); - boost::shared_ptr aWPFeatures = - boost::dynamic_pointer_cast(aWP->data()->attribute(SKETCH_ATTR_FEATURES)); - std::list< boost::shared_ptr > aFeaturesList = aWPFeatures->list(); - std::list< boost::shared_ptr >::const_iterator anIter; - for (anIter = aFeaturesList.begin(); anIter != aFeaturesList.end(); anIter++) - if (*anIter == theConstraint) - return aWP; // workplane is found + anAttrList.push_back(LINE_ATTR_START); + anAttrList.push_back(LINE_ATTR_END); } - - return boost::shared_ptr(); -} - - - -// ======================================================== -// ========= SketchSolver_ConstraintGroup =============== -// ======================================================== - -SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup:: - SketchSolver_ConstraintGroup(boost::shared_ptr theWorkplane) - : myID(++myGroupIndexer), - myParamMaxID(0), - myEntityMaxID(0), - myConstrMaxID(0), - myConstraintMap() -{ - myParams.clear(); - myEntities.clear(); - myConstraints.clear(); - - // Nullify all elements of the set of equations - myConstrSet.param = 0; - myConstrSet.entity = 0; - myConstrSet.constraint = 0; - myConstrSet.failed = 0; - - // Initialize workplane - myWorkplane.h = 0; - addWorkplane(theWorkplane); -} - -SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::~SketchSolver_ConstraintGroup() -{ - myParams.clear(); - myEntities.clear(); - myConstraints.clear(); - myConstraintMap.clear(); - - if (myConstrSet.param) - delete [] myConstrSet.param; - if (myConstrSet.entity) - delete [] myConstrSet.entity; - if (myConstrSet.constraint) - delete [] myConstrSet.constraint; - if (myConstrSet.failed) - delete [] myConstrSet.failed; -} - -bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isBaseWorkplane( - boost::shared_ptr theWorkplane) const -{ - return theWorkplane == mySketch; -} - -bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::isInteract( - boost::shared_ptr theConstraint) const -{ - /// \todo Should be implemented - return false; -} - -bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addConstraint( - boost::shared_ptr theConstraint) -{ - // There is no workplane yet, something wrong - if (myWorkplane.h == 0) - return false; - - // Get constraint type and verify the constraint parameters are correct - int aConstrType = getConstraintType(theConstraint); - if (aConstrType == SLVS_C_UNKNOWN) - return false; - - // Create constraint parameters - double aDistance = 0.0; // scalar value of the constraint - boost::shared_ptr aDistAttr = - boost::dynamic_pointer_cast(theConstraint->data()->attribute(CONSTRAINT_ATTR_VALUE)); - if (aDistAttr) - aDistance = aDistAttr->value(); - - Slvs_hEntity aConstrEnt[CONSTRAINT_ATTR_SIZE]; // parameters of the constraint - for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) + // Circle + else if (aFeatureKind.compare(SKETCH_CIRCLE_KIND) == 0) { - boost::shared_ptr aConstrAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr]) - ); - aConstrEnt[indAttr] = addEntity(aConstrAttr->attr()); + anAttrList.push_back(CIRCLE_ATTR_CENTER); + anAttrList.push_back(CIRCLE_ATTR_RADIUS); } - - // Create SolveSpace constraint structure - Slvs_Constraint aConstraint = - Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType, myWorkplane.h, - aDistance, aConstrEnt[0], aConstrEnt[1], aConstrEnt[2], aConstrEnt[3]); - myConstraints.push_back(aConstraint); - myConstraintMap[theConstraint] = *(myConstraints.rbegin()); - - return true; -} - -Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addEntity( - boost::shared_ptr theEntity) -{ - // Look over supported types of entities - - // Point in 3D - boost::shared_ptr aPoint = - boost::dynamic_pointer_cast(theEntity); - if (aPoint) + // Arc + else if (aFeatureKind.compare(SKETCH_ARC_KIND) == 0) { - Slvs_hParam aX = addParameter(aPoint->x()); - Slvs_hParam aY = addParameter(aPoint->y()); - Slvs_hParam aZ = addParameter(aPoint->z()); - Slvs_Entity aPtEntity = Slvs_MakePoint3d(++myEntityMaxID, myID, aX, aY, aZ); - myEntities.push_back(aPtEntity); - return aPtEntity.h; + anAttrList.push_back(ARC_ATTR_CENTER); + anAttrList.push_back(ARC_ATTR_START); + anAttrList.push_back(ARC_ATTR_END); } + /// \todo Other types of features should be implemented - // Point in 2D - boost::shared_ptr aPoint2D = - boost::dynamic_pointer_cast(theEntity); - if (aPoint2D) + // Check changing of feature's attributes (go through the groups and search usage of the attributes) + std::vector::const_iterator anAttrIter; + for (anAttrIter = anAttrList.begin(); anAttrIter != anAttrList.end(); anAttrIter++) { - // The 2D points are created on workplane. So, if there is no workplane yet, then error - if (myWorkplane.h == 0) - return 0; - Slvs_hParam aU = addParameter(aPoint2D->x()); - Slvs_hParam aV = addParameter(aPoint2D->y()); - Slvs_Entity aPt2DEntity = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, aU, aV); - myEntities.push_back(aPt2DEntity); - return aPt2DEntity.h; + std::vector::iterator aGroupIter; + for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) + { + if ((*aGroupIter)->isEmpty()) + continue; + boost::shared_ptr anAttribute = + boost::dynamic_pointer_cast(theFeature->data()->attribute(*anAttrIter)); + (*aGroupIter)->updateEntityIfPossible(anAttribute); + } } - /// \todo Other types of entities - - // Unsupported or wrong entity type - return 0; + std::vector::iterator aGroupIter; + for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) + if (!(*aGroupIter)->isEmpty()) + (*aGroupIter)->updateRelatedConstraints(theFeature); } -Slvs_hEntity SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addNormal( - boost::shared_ptr theDirX, - boost::shared_ptr theDirY) + +// ============================================================================ +// Function: findGroups +// Class: SketchSolver_PluginManager +// Purpose: search groups of entities interacting with given constraint +// ============================================================================ +void SketchSolver_ConstraintManager::findGroups( + boost::shared_ptr theConstraint, + std::set& theGroupIDs) const { - boost::shared_ptr aDirX = boost::dynamic_pointer_cast(theDirX); - boost::shared_ptr aDirY = boost::dynamic_pointer_cast(theDirY); - if (!aDirX || !aDirY) - return 0; - - // quaternion parameters of normal vector - double qw, qx, qy, qz; - Slvs_MakeQuaternion(aDirX->x(), aDirX->y(), aDirX->z(), - aDirY->x(), aDirY->y(), aDirY->z(), - &qw, &qx, &qy, &qz); - - // Create a normal - Slvs_Entity aNormal = Slvs_MakeNormal3d(++myEntityMaxID, myID, - addParameter(qw), addParameter(qx), addParameter(qy), addParameter(qz)); - myEntities.push_back(aNormal); - return aNormal.h; -} + boost::shared_ptr aWP = findWorkplaneForConstraint(theConstraint); + SketchSolver_ConstraintGroup* anEmptyGroup = 0; // appropriate empty group for specified constraint + std::vector::const_iterator aGroupIter; + for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) + if (aWP == (*aGroupIter)->getWorkplane() && (*aGroupIter)->isInteract(theConstraint)) + { + if (!(*aGroupIter)->isEmpty()) + theGroupIDs.insert((*aGroupIter)->getId()); + else if (!anEmptyGroup) + anEmptyGroup = *aGroupIter; + } -bool SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addWorkplane( - boost::shared_ptr theSketch) -{ - if (myWorkplane.h) - return false; // the workplane already exists - - // Get parameters of workplane - boost::shared_ptr aDirX = theSketch->data()->attribute(SKETCH_ATTR_DIRX); - boost::shared_ptr aDirY = theSketch->data()->attribute(SKETCH_ATTR_DIRY); - boost::shared_ptr anOrigin = theSketch->data()->attribute(SKETCH_ATTR_ORIGIN); - // Transform them into SolveSpace format - Slvs_hEntity aNormalWP = addNormal(aDirX, aDirY); - if (!aNormalWP) return false; - Slvs_hEntity anOriginWP = addEntity(anOrigin); - if (!anOriginWP) return false; - // Create workplane - myWorkplane = Slvs_MakeWorkplane(++myEntityMaxID, myID, anOriginWP, aNormalWP); - mySketch = theSketch; - // Workplane should be added to the list of entities - myEntities.push_back(myWorkplane); - return true; + // When only empty group is found, use it + if (anEmptyGroup && theGroupIDs.empty()) + theGroupIDs.insert(anEmptyGroup->getId()); } -Slvs_hParam SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::addParameter(double theParam) +// ============================================================================ +// Function: findWorkplaneForConstraint +// Class: SketchSolver_PluginManager +// Purpose: search workplane containing given constraint +// ============================================================================ +boost::shared_ptr SketchSolver_ConstraintManager::findWorkplaneForConstraint( + boost::shared_ptr theConstraint) const { - Slvs_Param aParam = Slvs_MakeParam(++myParamMaxID, myID, theParam); - myParams.push_back(aParam); - return aParam.h; -} + // Already verified workplanes + std::set< boost::shared_ptr > aVerified; -int SketchSolver_ConstraintManager::SketchSolver_ConstraintGroup::getConstraintType( - const boost::shared_ptr& theConstraint) const -{ - // Constraint for coincidence of two points - boost::shared_ptr aPtEquiv = - boost::dynamic_pointer_cast(theConstraint); - if (aPtEquiv) + std::vector::const_iterator aGroupIter; + for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) { - // Verify the constraint has only two attributes and they are points - int aPt2d = 0; // bit-mapped field, each bit indicates whether the attribute is 2D point - int aPt3d = 0; // bit-mapped field, the same information for 3D points - for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) - { - boost::shared_ptr anAttr = - boost::dynamic_pointer_cast( - theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr]) - ); - // Verify the attribute is a 2D point - boost::shared_ptr aPoint2D = - boost::dynamic_pointer_cast(anAttr->attr()); - if (aPoint2D) - { - aPt2d |= (1 << indAttr); - continue; - } - // Verify the attribute is a 3D point - boost::shared_ptr aPoint3D = - boost::dynamic_pointer_cast(anAttr->attr()); - if (aPoint3D) - { - aPt3d |= (1 << indAttr); - continue; - } - // Attribute neither 2D nor 3D point is not supported by this type of constraint - return SLVS_C_UNKNOWN; - } - // The constrained points should be in first and second positions, - // so the expected value of aPt2d or aPt3d is 3 - if ((aPt2d == 3 && aPt3d == 0) || (aPt2d == 0 && aPt3d == 3)) - return SLVS_C_POINTS_COINCIDENT; - // Constraint parameters are wrong - return SLVS_C_UNKNOWN; + boost::shared_ptr aWP = (*aGroupIter)->getWorkplane(); + if (aVerified.find(aWP) != aVerified.end()) + continue; + + boost::shared_ptr aWPFeatures = + boost::dynamic_pointer_cast(aWP->data()->attribute(SKETCH_ATTR_FEATURES)); + std::list< FeaturePtr > aFeaturesList = aWPFeatures->list(); + std::list< FeaturePtr >::const_iterator anIter; + for (anIter = aFeaturesList.begin(); anIter != aFeaturesList.end(); anIter++) + if (*anIter == theConstraint) + return aWP; // workplane is found + aVerified.insert(aWP); } - /// \todo Implement other kind of constrtaints + return boost::shared_ptr(); +} + +// ============================================================================ +// Function: resolveConstraints +// Class: SketchSolver_PluginManager +// Purpose: change entities according to available constraints +// ============================================================================ +void SketchSolver_ConstraintManager::resolveConstraints() +{ + std::vector::iterator aGroupIter; + for (aGroupIter = myGroups.begin(); aGroupIter != myGroups.end(); aGroupIter++) + (*aGroupIter)->resolveConstraints(); - return SLVS_C_UNKNOWN; + // Features may be updated => send events + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED)); } +