X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintCoincidence.cpp;h=ae4a89bcc63d3d457fab1f59da8ce078b4b2a7ba;hb=4df4bd61da1ea5d357671c819a8ced6ec9ba77ac;hp=b10d7e95d44f25e14850f441cd45410275752e05;hpb=29d446f4dd2969d80087745fe44adb5638d13de7;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp b/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp index b10d7e95d..ae4a89bcc 100644 --- a/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp @@ -1,9 +1,91 @@ +// Copyright (C) 2014-2017 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 + +static void getCoincidentFeatureExtremities(const ConstraintPtr& theConstraint, + const StoragePtr& theStorage, + EntityWrapperPtr theExtremities[2]) +{ + for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) { + AttributeRefAttrPtr aRefAttr = theConstraint->refattr(SketchPlugin_Constraint::ATTRIBUTE(i)); + if (!aRefAttr || !aRefAttr->isObject()) + continue; + + FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object()); + if (!aFeature) + continue; + + if (aFeature->getKind() == SketchPlugin_Line::ID()) { + theExtremities[0] = theStorage->entity(aFeature->attribute(SketchPlugin_Line::START_ID())); + theExtremities[1] = theStorage->entity(aFeature->attribute(SketchPlugin_Line::END_ID())); + } else if (aFeature->getKind() == SketchPlugin_Arc::ID()) { + theExtremities[0] = theStorage->entity(aFeature->attribute(SketchPlugin_Arc::START_ID())); + theExtremities[1] = theStorage->entity(aFeature->attribute(SketchPlugin_Arc::END_ID())); + } + } +} + + +void SketchSolver_ConstraintCoincidence::process() +{ + cleanErrorMsg(); + if (!myBaseConstraint || !myStorage) { + // Not enough parameters are assigned + return; + } + + EntityWrapperPtr aValue; + std::vector anAttributes; + getAttributes(aValue, anAttributes); + if (!myErrorMsg.empty()) + return; + if (anAttributes.empty()) { + myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); + return; + } + + mySolverConstraint = PlaneGCSSolver_Tools::createConstraint( + myBaseConstraint, getType(), + aValue, anAttributes[0], anAttributes[1], anAttributes[2], anAttributes[3]); + + myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateCoincidence::GROUP()); + myStorage->notify(myBaseConstraint); +} + +bool SketchSolver_ConstraintCoincidence::remove() +{ + myInSolver = false; + myFeatureExtremities[0] = EntityWrapperPtr(); + myFeatureExtremities[1] = EntityWrapperPtr(); + return SketchSolver_Constraint::remove(); +} void SketchSolver_ConstraintCoincidence::getAttributes( - double& theValue, + EntityWrapperPtr& theValue, std::vector& theAttributes) { SketchSolver_Constraint::getAttributes(theValue, theAttributes); @@ -12,13 +94,8 @@ void SketchSolver_ConstraintCoincidence::getAttributes( return; } - if (theAttributes[1]) { + if (theAttributes[1]) myType = CONSTRAINT_PT_PT_COINCIDENT; - // Set the slave (second) point the same as master (first) point. - // This will allow to skip adding point-point coincidence to the set of constraints - // and give us speed-up in solving the set of equations - myStorage->addCoincidentPoints(theAttributes[0], theAttributes[1]); - } else if (theAttributes[2]) { // check the type of entity (line or circle) SketchSolver_EntityType anEntType = theAttributes[2]->type(); @@ -28,31 +105,38 @@ void SketchSolver_ConstraintCoincidence::getAttributes( myType = CONSTRAINT_PT_ON_CIRCLE; else myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); + + // obtain extremity points of the coincident feature for further checking of multi-coincidence + getCoincidentFeatureExtremities(myBaseConstraint, myStorage, myFeatureExtremities); } else myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); } - -static bool isBase(const std::list& theConstraints, AttributePtr theAttribute) +void SketchSolver_ConstraintCoincidence::notify(const FeaturePtr& theFeature, + PlaneGCSSolver_Update* theUpdater) { - AttributePtr anAttribute = theAttribute; - FeaturePtr aFeature; - AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast(theAttribute); - if (aRefAttr) { - if (aRefAttr->isObject()) - aFeature = ModelAPI_Feature::feature(aRefAttr->object()); - else - anAttribute = aRefAttr->attr(); + PlaneGCSSolver_UpdateCoincidence* anUpdater = + static_cast(theUpdater); + bool isAccepted = anUpdater->addCoincidence(myAttributes.front(), myAttributes.back()); + + // additionally check the point is coincident to extremity of coincident feature + if (myFeatureExtremities[0] && myFeatureExtremities[1]) { + EntityWrapperPtr aPoint = + myAttributes.front()->type() == ENTITY_POINT ? myAttributes.front() : myAttributes.back(); + + for (int i = 0; i < 2; ++i) + isAccepted = isAccepted && !anUpdater->isPointOnEntity(aPoint, myFeatureExtremities[i]); } - std::list::const_iterator aCIt = theConstraints.begin(); - for (; aCIt != theConstraints.end(); ++aCIt) { - std::list aSubs = (*aCIt)->entities(); - std::list::const_iterator aSIt = aSubs.begin(); - for (; aSIt != aSubs.end(); ++aSIt) - if ((aFeature && (*aSIt)->isBase(aFeature)) || - (!aFeature && (*aSIt)->isBase(anAttribute))) - return true; + if (isAccepted) { + if (!myInSolver) { + myInSolver = true; + myStorage->addConstraint(myBaseConstraint, mySolverConstraint); + } + } else { + if (myInSolver) { + myInSolver = false; + myStorage->removeConstraint(myBaseConstraint); + } } - return false; }