X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintMultiRotation.cpp;h=cf2cac48aab28cee9cf02c1e0e9a49e9574ff8d0;hb=97c06c5cd9fc736f9b5a1dacde369a9d7b5be703;hp=91fd4bf40cfdf9d0d0909ad05af121d8096378e2;hpb=fd1617a51701c43474d78719acd35dc3fc05109e;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp b/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp index 91fd4bf40..cf2cac48a 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp @@ -1,30 +1,49 @@ +// 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 + #include -////#include -////#include -////#include -////#include -////#include -//// -////#include -////#include +#include -#include +#include void SketchSolver_ConstraintMultiRotation::getAttributes( - EntityWrapperPtr& theCenter, double& theAngle, - std::list< std::list >& theEntities) + EntityWrapperPtr& theCenter, ScalarWrapperPtr& theAngle, + bool& theFullValue, bool& theReversed, std::list& theEntities) { - DataPtr aData = myBaseConstraint->data(); - theAngle = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_MultiRotation::ANGLE_ID()))->value(); - - AttributePtr aCenterAttr = aData->attribute(SketchPlugin_MultiRotation::CENTER_ID()); + AttributePtr anAngleAttr = myBaseConstraint->attribute(SketchPlugin_MultiRotation::ANGLE_ID()); + PlaneGCSSolver_AttributeBuilder aValueBuilder; + theAngle = std::dynamic_pointer_cast( + aValueBuilder.createAttribute(anAngleAttr)); + myStorage->addEntity(anAngleAttr, theAngle); + + AttributeRefAttrPtr aCenterAttr = + myBaseConstraint->refattr(SketchPlugin_MultiRotation::CENTER_ID()); if (!aCenterAttr || !aCenterAttr->isInitialized()) { myErrorMsg = SketchSolver_Error::NOT_INITIALIZED(); return; @@ -32,207 +51,142 @@ void SketchSolver_ConstraintMultiRotation::getAttributes( myType = CONSTRAINT_MULTI_ROTATION; - myStorage->update(aCenterAttr, GID_OUTOFGROUP); - theCenter = myStorage->entity(aCenterAttr); - - getEntitiesAndCopies(theEntities); - -//// // Lists of objects and number of copies -//// AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast( -//// aData->attribute(SketchPlugin_Constraint::ENTITY_A())); -//// myNumberOfObjects = anInitialRefList->size(); -//// myNumberOfCopies = (size_t) aData->integer(SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID())->value() - 1; -//// if (myNumberOfCopies <= 0) -//// return; -//// AttributeRefListPtr aRefList = std::dynamic_pointer_cast( -//// myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); -//// if (!aRefList) { -//// myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); -//// return; -//// } -//// -//// // Obtain all points of initial features and store them into separate lists -//// // containing their translated copies. -//// // Also all circles and arc collected too, because they will be constrained by equal radii. -//// FeaturePtr aFeature; -//// ResultConstructionPtr aRC; -//// static const size_t MAX_POINTS = 3; -//// std::vector aPoints[MAX_POINTS]; // lists of points of features -//// std::vector anEntities; -//// std::list anObjectList = aRefList->list(); -//// std::list::iterator anObjectIter = anObjectList.begin(); -//// while (anObjectIter != anObjectList.end()) { -//// for (size_t i = 0; i < MAX_POINTS; ++i) -//// aPoints[i].clear(); -//// anEntities.clear(); -//// -//// for (size_t i = 0; i <= myNumberOfCopies && anObjectIter != anObjectList.end(); i++, anObjectIter++) { -//// aFeature = ModelAPI_Feature::feature(*anObjectIter); -//// if (!aFeature) -//// continue; -//// anEntityID = changeEntity(aFeature, aType); -//// anEntities.push_back(anEntityID); -//// Slvs_Entity anEntity = myStorage->getEntity(anEntityID); -//// switch (aType) { -//// case SLVS_E_POINT_IN_2D: -//// case SLVS_E_POINT_IN_3D: -//// aPoints[0].push_back(anEntityID); -//// break; -//// case SLVS_E_LINE_SEGMENT: -//// aPoints[0].push_back(anEntity.point[0]); // start point of line -//// aPoints[1].push_back(anEntity.point[1]); // end point of line -//// break; -//// case SLVS_E_CIRCLE: -//// aPoints[0].push_back(anEntity.point[0]); // center of circle -//// break; -//// case SLVS_E_ARC_OF_CIRCLE: -//// aPoints[0].push_back(anEntity.point[0]); // center of arc -//// aPoints[1].push_back(anEntity.point[1]); // start point of arc -//// aPoints[2].push_back(anEntity.point[2]); // end point of arc -//// break; -//// default: -//// myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); -//// return; -//// } -//// } -//// -//// for (size_t i = 0; i < MAX_POINTS; ++i) -//// if (!aPoints[i].empty()) -//// thePoints.push_back(aPoints[i]); -//// if (!anEntities.empty()) -//// theEntities.push_back(anEntities); -//// } + myStorage->update(AttributePtr(aCenterAttr)); + theCenter = myStorage->entity(AttributePtr(aCenterAttr)); + + AttributeStringPtr aMethodTypeAttr = + myBaseConstraint->string(SketchPlugin_MultiRotation::ANGLE_TYPE()); + theFullValue = aMethodTypeAttr->value() != "SingleAngle"; + + theReversed = myBaseConstraint->boolean(SketchPlugin_MultiRotation::REVERSED_ID())->value(); + + getEntities(theEntities); + + // add owner of central point of Multi-Rotation to the list of monitored features + FeaturePtr anOwner = ModelAPI_Feature::feature(aCenterAttr->attr()->owner()); + if (anOwner) + myOriginalFeatures.insert(anOwner); } void SketchSolver_ConstraintMultiRotation::process() { cleanErrorMsg(); - if (!myBaseConstraint || !myStorage || myGroupID == GID_UNKNOWN) { - /// TODO: Put error message here + if (!myBaseConstraint || !myStorage) { + // Not enough parameters are assigned return; } -//// if (!mySlvsConstraints.empty()) // some data is changed, update constraint -//// update(myBaseConstraint); EntityWrapperPtr aRotationCenter; - std::list > anEntitiesAndCopies; - getAttributes(aRotationCenter, myAngle, anEntitiesAndCopies); + std::list aBaseEntities; + getAttributes(aRotationCenter, myAngle, myIsFullValue, myIsRevered, aBaseEntities); if (!myErrorMsg.empty()) return; -//// // Set the rotation center unchanged during constraint recalculation -//// Slvs_Constraint aConstraint; -//// if (!myStorage->isPointFixed(myRotationCenter, aConstraint.h, true)) { -//// aConstraint = Slvs_MakeConstraint( -//// SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_WHERE_DRAGGED, myGroup->getWorkplaneId(), 0.0, -//// myRotationCenter, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); -//// aConstraint.h = myStorage->addConstraint(aConstraint); -//// mySlvsConstraints.push_back(aConstraint.h); -//// } - - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); - std::list aRotConstraints; - - std::list< std::list >::iterator anEntIt = anEntitiesAndCopies.begin(); - for (; anEntIt != anEntitiesAndCopies.end(); ++anEntIt) { - std::list aNewConstraints = - aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType, - myAngle, aRotationCenter, EntityWrapperPtr(), *anEntIt); - aRotConstraints.insert(aRotConstraints.end(), aNewConstraints.begin(), aNewConstraints.end()); - } - myStorage->addConstraint(myBaseConstraint, aRotConstraints); - myAdjusted = false; -//// processEntities(anEntitiesAndCopies); adjustConstraint(); + + myStorage->subscribeUpdates(this, PlaneGCSSolver_UpdateFeature::GROUP()); } void SketchSolver_ConstraintMultiRotation::updateLocal() { - double aValue = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_MultiRotation::ANGLE_ID()))->value(); - if (fabs(myAngle - aValue) > tolerance) + double aValue = myBaseConstraint->real(SketchPlugin_MultiRotation::ANGLE_ID())->value(); + bool isReversed = myBaseConstraint->boolean(SketchPlugin_MultiRotation::REVERSED_ID())->value(); + if (fabs(myAngle->value() - aValue) > tolerance || isReversed != myIsRevered) myAdjusted = false; // update angle value - myAngle = aValue; + myAngle->setValue(aValue); + myIsRevered = isReversed; // update center - AttributePtr aCenterAttr = myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID()); - if (myStorage->update(aCenterAttr, myGroupID)) { - myStorage->update(aCenterAttr, GID_UNKNOWN); + DataPtr aData = myBaseConstraint->data(); + AttributePoint2DPtr aCenterPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData, + SketchPlugin_MultiRotation::CENTER_ID()); + bool aCenterPointChanged = aCenterPointAttribute != myCenterPointAttribute; + if (aCenterPointChanged) + myCenterPointAttribute = aCenterPointAttribute; + + AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE()); + bool aFullValue = aMethodTypeAttr->value() != "SingleAngle"; + bool isMethodChanged = aFullValue != myIsFullValue; + if (isMethodChanged) + myIsFullValue = aFullValue; + + if (aCenterPointChanged || isMethodChanged) myAdjusted = false; - } } void SketchSolver_ConstraintMultiRotation::adjustConstraint() { - if (fabs(myAngle) < tolerance) { + if (myAdjusted) + return; + + double anAngleValue = myAngle->value(); + if (fabs(anAngleValue) < tolerance) { myStorage->setNeedToResolve(false); return; } -//// if (myAdjusted) -//// return; -//// -//// std::list aCoincident = myStorage->getConstraintsByType(SLVS_C_POINTS_COINCIDENT); -//// std::list::const_iterator aCoIt; -//// -//// // Check overconstrained on rotation center (if it is coincident with other fixed point) -//// Slvs_hConstraint aFixedCenter; -//// if (myStorage->isPointFixed(myRotationCenter, aFixedCenter, false)) { -//// Slvs_hConstraint aFixed; -//// for (aCoIt = aCoincident.begin(); aCoIt != aCoincident.end(); ++aCoIt) -//// if ((aCoIt->ptA == myRotationCenter && myStorage->isPointFixed(aCoIt->ptB, aFixed, true)) || -//// (aCoIt->ptB == myRotationCenter && myStorage->isPointFixed(aCoIt->ptA, aFixed, true))) { -//// // Un-fix the center -//// myStorage->removeConstraint(aFixedCenter); -//// std::vector::iterator aSCIt = mySlvsConstraints.begin(); -//// for (; aSCIt != mySlvsConstraints.end(); ++aSCIt) -//// if (*aSCIt == aFixedCenter) { -//// mySlvsConstraints.erase(aSCIt); -//// break; -//// } -//// } -//// } -//// -//// // Obtain coordinates of rotation center -//// Slvs_Entity aRotCenter = myStorage->getEntity(myRotationCenter); -//// myCenterCoord[0] = myStorage->getParameter(aRotCenter.param[0]).val; -//// myCenterCoord[1] = myStorage->getParameter(aRotCenter.param[1]).val; -//// -//// myRotationVal[0] = sin(myAngle * PI / 180.0); -//// myRotationVal[1] = cos(myAngle * PI / 180.0); -//// - - const std::list& aConstraints = myStorage->constraint(myBaseConstraint); - std::list::const_iterator aCIt = aConstraints.begin(); - for (; aCIt != aConstraints.end(); ++aCIt) - (*aCIt)->setValue(myAngle); + if (myIsRevered) + anAngleValue *= -1.0; + + // Obtain coordinates of rotation center + AttributeRefAttrPtr aCenterAttr = + myBaseConstraint->refattr(SketchPlugin_MultiRotation::CENTER_ID()); + std::shared_ptr aRotCenter = + std::dynamic_pointer_cast( + myStorage->entity(AttributePtr(aCenterAttr))); + if (aRotCenter) + { + GCSPointPtr aCenterPoint = aRotCenter->point(); + myCenterCoord[0] = *(aCenterPoint->x); + myCenterCoord[1] = *(aCenterPoint->y); + } + else + { + AttributePoint2DPtr aCenterPnt = + std::dynamic_pointer_cast(aCenterAttr->attr()); + myCenterCoord[0] = aCenterPnt->x(); + myCenterCoord[1] = aCenterPnt->y(); + } + + if (myIsFullValue && myNumberOfCopies > 0) + { + // if the full angle value is equal to 360, then distribute rotated items + // to avoid superposition of original feature and last copy + if (fabs(anAngleValue - 360.0) < 1.e-7) + anAngleValue /= (myNumberOfCopies + 1); + else + anAngleValue /= myNumberOfCopies; + } + + myRotationVal[0] = sin(anAngleValue * PI / 180.0); + myRotationVal[1] = cos(anAngleValue * PI / 180.0); SketchSolver_ConstraintMulti::adjustConstraint(); } -////void SketchSolver_ConstraintMultiRotation::getRelative( -//// double theAbsX, double theAbsY, double& theRelX, double& theRelY) -////{ -//// theRelX = theAbsX - myCenterCoord[0]; -//// theRelY = theAbsY - myCenterCoord[1]; -////} -//// -////void SketchSolver_ConstraintMultiRotation::getAbsolute( -//// double theRelX, double theRelY, double& theAbsX, double& theAbsY) -////{ -//// theAbsX = theRelX + myCenterCoord[0]; -//// theAbsY = theRelY + myCenterCoord[1]; -////} -//// -////void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, double& theY) -////{ -//// // rotate direction -//// // myRotationVal[0] = sinA, myRotationVal[1] = cosA -//// double aTemp = theX * myRotationVal[1] - theY * myRotationVal[0]; -//// theY = theX * myRotationVal[0] + theY * myRotationVal[1]; -//// theX = aTemp; -////} +void SketchSolver_ConstraintMultiRotation::getRelative( + double theAbsX, double theAbsY, double& theRelX, double& theRelY) +{ + theRelX = theAbsX - myCenterCoord[0]; + theRelY = theAbsY - myCenterCoord[1]; +} + +void SketchSolver_ConstraintMultiRotation::getAbsolute( + double theRelX, double theRelY, double& theAbsX, double& theAbsY) +{ + theAbsX = theRelX + myCenterCoord[0]; + theAbsY = theRelY + myCenterCoord[1]; +} + +void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, double& theY) +{ + // rotate direction + // myRotationVal[0] = sinA, myRotationVal[1] = cosA + double aTemp = theX * myRotationVal[1] - theY * myRotationVal[0]; + theY = theX * myRotationVal[0] + theY * myRotationVal[1]; + theX = aTemp; +} const std::string& SketchSolver_ConstraintMultiRotation::nameNbObjects() {