X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_Constraint.cpp;h=7d047ac8091f1a83ecf5bc37098628918dbcbae1;hb=97c06c5cd9fc736f9b5a1dacde369a9d7b5be703;hp=7dbde50c73130c4ffba06118fc35165b95b2fe7c;hpb=4e04f27e9f9639aaf902c9221e494677c70b94ae;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_Constraint.cpp b/src/SketchSolver/SketchSolver_Constraint.cpp index 7dbde50c7..7d047ac80 100644 --- a/src/SketchSolver/SketchSolver_Constraint.cpp +++ b/src/SketchSolver/SketchSolver_Constraint.cpp @@ -1,7 +1,27 @@ +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + #include -#include #include -#include + +#include +#include #include #include @@ -10,10 +30,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -33,22 +55,23 @@ SketchSolver_Constraint::SketchSolver_Constraint( ConstraintPtr theConstraint) : myBaseConstraint(theConstraint), - myGroupID(GID_UNKNOWN), myType(CONSTRAINT_UNKNOWN) { } -void SketchSolver_Constraint::process(StoragePtr theStorage, - const GroupID& theGroupID, - const EntityID& theSketchID) +void SketchSolver_Constraint::process(StoragePtr theStorage, bool theEvensBlocked) { myStorage = theStorage; - myGroupID = theGroupID; - mySketchID = theSketchID; + blockEvents(theEvensBlocked); // Process constraint according to its type process(); } +void SketchSolver_Constraint::blockEvents(bool isBlocked) +{ + myBaseConstraint->data()->blockSendAttributeUpdated(isBlocked); +} + SketchSolver_ConstraintType SketchSolver_Constraint::TYPE(ConstraintPtr theConstraint) { @@ -79,19 +102,23 @@ SketchSolver_ConstraintType SketchSolver_Constraint::TYPE(ConstraintPtr theConst return CONSTRAINT_RADIUS; else if (aType == SketchPlugin_ConstraintTangent::ID()) return CONSTRAINT_TANGENT; + else if (aType == SketchPlugin_ConstraintCollinear::ID()) + return CONSTRAINT_COLLINEAR; + else if (aType == SketchPlugin_ConstraintMiddle::ID()) + return CONSTRAINT_MIDDLE_POINT; return CONSTRAINT_UNKNOWN; } void SketchSolver_Constraint::process() { cleanErrorMsg(); - if (!myBaseConstraint || !myStorage || myGroupID == GID_UNKNOWN) { + if (!myBaseConstraint || !myStorage) { // Not enough parameters are assigned return; } SketchSolver_ConstraintType aConstrType = getType(); - double aValue; + EntityWrapperPtr aValue; std::vector anAttributes; getAttributes(aValue, anAttributes); if (!myErrorMsg.empty()) @@ -103,11 +130,14 @@ void SketchSolver_Constraint::process() if (aConstrType == CONSTRAINT_UNKNOWN) aConstrType = getType(); - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); - std::list aNewConstraints = aBuilder->createConstraint( - myBaseConstraint, myGroupID, mySketchID, aConstrType, + ConstraintWrapperPtr aNewConstraint = PlaneGCSSolver_Tools::createConstraint( + myBaseConstraint, aConstrType, aValue, anAttributes[0], anAttributes[1], anAttributes[2], anAttributes[3]); - myStorage->addConstraint(myBaseConstraint, aNewConstraints); + if (!aNewConstraint) { + myErrorMsg = SketchSolver_Error::WRONG_CONSTRAINT_TYPE(); + return; + } + myStorage->addConstraint(myBaseConstraint, aNewConstraint); adjustConstraint(); } @@ -116,18 +146,41 @@ void SketchSolver_Constraint::update() { cleanErrorMsg(); - std::list aWrapper = myStorage->constraint(myBaseConstraint); - AttributeDoublePtr aValueAttr = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::VALUE())); - if (aValueAttr) { - std::list::iterator aWIt = aWrapper.begin(); - for (; aWIt != aWrapper.end(); ++aWIt) - if (fabs((*aWIt)->value() - aValueAttr->value()) > tolerance) { - (*aWIt)->setValue(aValueAttr->value()); - myStorage->setNeedToResolve(true); + // Get list of attributes of the constraint and compare it with previously stored. + // If the lists are different, fully rebuild constraint + std::set anAttributes; + for (int anEntIndex = 0; anEntIndex < 4; ++anEntIndex) { + AttributePtr anAttr = + myBaseConstraint->attribute(SketchPlugin_Constraint::ATTRIBUTE(anEntIndex)); + if (!anAttr) + continue; + + if (myBaseConstraint->getKind() == SketchPlugin_ConstraintLength::ID()) { + AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(anAttr); + FeaturePtr aFeat = ModelAPI_Feature::feature(aRefAttr->object()); + if (aFeat) { + // Workaround for the Length constraint: add points of line, not line itself + anAttributes.insert(myStorage->entity(aFeat->attribute(SketchPlugin_Line::START_ID()))); + anAttributes.insert(myStorage->entity(aFeat->attribute(SketchPlugin_Line::END_ID()))); } + } else + anAttributes.insert(myStorage->entity(anAttr)); } - myStorage->addConstraint(myBaseConstraint, aWrapper); + + std::set::iterator aFound; + std::list::const_iterator anAttrIt = myAttributes.begin(); + for (; anAttrIt != myAttributes.end() && !anAttributes.empty(); ++anAttrIt) + anAttributes.erase(*anAttrIt); + + if (!anAttributes.empty()) { + remove(); + process(); + return; + } + + AttributePtr aValueAttr = myBaseConstraint->attribute(SketchPlugin_Constraint::VALUE()); + if (aValueAttr) + myStorage->update(aValueAttr); adjustConstraint(); } @@ -135,24 +188,29 @@ void SketchSolver_Constraint::update() bool SketchSolver_Constraint::remove() { cleanErrorMsg(); + myType = CONSTRAINT_UNKNOWN; + myStorage->unsubscribeUpdates(this); return myStorage->removeConstraint(myBaseConstraint); } void SketchSolver_Constraint::getAttributes( - double& theValue, + EntityWrapperPtr& theValue, std::vector& theAttributes) { static const int anInitNbOfAttr = 4; theAttributes.assign(anInitNbOfAttr, EntityWrapperPtr()); + myAttributes.clear(); DataPtr aData = myBaseConstraint->data(); - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); myType = TYPE(myBaseConstraint); - AttributeDoublePtr aValueAttr = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Constraint::VALUE())); - theValue = aValueAttr ? aValueAttr->value() : 0.0; + AttributePtr aValueAttr = aData->attribute(SketchPlugin_Constraint::VALUE()); + if (aValueAttr) { + PlaneGCSSolver_AttributeBuilder aValueBuilder; + theValue = aValueBuilder.createAttribute(aValueAttr); + myStorage->addEntity(aValueAttr, theValue); + } int aPtInd = 0; // index of first point in the list of attributes int aEntInd = 2; // index of first entity in the list of attributes @@ -166,8 +224,9 @@ void SketchSolver_Constraint::getAttributes( return; } - myStorage->update(*anIter/*, myGroupID*/); + myStorage->update(*anIter, true); EntityWrapperPtr anEntity = myStorage->entity(*anIter); + myAttributes.push_back(anEntity); SketchSolver_EntityType aType = anEntity->type(); if (aType == ENTITY_UNKNOWN) @@ -183,40 +242,3 @@ void SketchSolver_Constraint::getAttributes( } } } - -bool SketchSolver_Constraint::isUsed(FeaturePtr theFeature) const -{ - const std::list& aCList = myStorage->constraint(myBaseConstraint); - std::list::const_iterator aCIt = aCList.begin(); - for (; aCIt != aCList.end(); ++aCIt) - if ((*aCIt)->isUsed(theFeature)) - return true; - - std::list anAttrList = theFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); - std::list::const_iterator anAttrIt = anAttrList.begin(); - for (; anAttrIt != anAttrList.end(); ++ anAttrIt) - if (isUsed(*anAttrIt)) - return true; - - return false; -} - -bool SketchSolver_Constraint::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(); - } - - const std::list& aCList = myStorage->constraint(myBaseConstraint); - std::list::const_iterator aCIt = aCList.begin(); - for (; aCIt != aCList.end(); ++aCIt) - if ((*aCIt)->isUsed(theAttribute)) - return true; - return false; -}