X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintMultiTranslation.cpp;h=4f1741e7662916798ecae0c844f21434d02118ed;hb=4f565b2204d3fba046aa8c851abada2a5a17bf6c;hp=eb6b61e43c3f1c2478e2f8285bba120bcd837431;hpb=50390ebfa041960511dea2dbfec54aadf082ddb3;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp b/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp index eb6b61e43..4f1741e76 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp @@ -1,27 +1,18 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + #include -#include #include +#include -#include #include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include +#include +#include void SketchSolver_ConstraintMultiTranslation::getAttributes( - Slvs_hEntity& theStartPoint, Slvs_hEntity& theEndPoint, - std::vector< std::vector >& thePoints, - std::vector< std::vector >& theEntities) + EntityWrapperPtr& theStartPoint, EntityWrapperPtr& theEndPoint, + bool& theFullValue, std::list& theEntities) { DataPtr aData = myBaseConstraint->data(); AttributePtr aStartPointAttr = aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID()); @@ -32,344 +23,166 @@ void SketchSolver_ConstraintMultiTranslation::getAttributes( return; } - int aType = SLVS_E_UNKNOWN; // type of created entity - Slvs_hEntity anEntityID = myGroup->getAttributeId(aStartPointAttr); - if (anEntityID == SLVS_E_UNKNOWN) - anEntityID = changeEntity(aStartPointAttr, aType); - theStartPoint = anEntityID; - anEntityID = myGroup->getAttributeId(aEndPointAttr); - if (anEntityID == SLVS_E_UNKNOWN) - anEntityID = changeEntity(aEndPointAttr, aType); - theEndPoint = anEntityID; - - // 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_MultiTranslation::NUMBER_OF_COPIES_ID())->value(); - AttributeRefListPtr aRefList = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); - if (!aRefList) { - myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); - return; - } + myType = CONSTRAINT_MULTI_TRANSLATION; - // 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; // list of translated entities - 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; - } - } + myStorage->update(aStartPointAttr); + theStartPoint = myStorage->entity(aStartPointAttr); + myStorage->update(aEndPointAttr); + theEndPoint = myStorage->entity(aEndPointAttr); - 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); - } + AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiTranslation::VALUE_TYPE()); + theFullValue = aMethodTypeAttr->value() != "SingleValue"; + + getEntities(theEntities); } void SketchSolver_ConstraintMultiTranslation::process() { cleanErrorMsg(); - if (!myBaseConstraint || !myStorage || myGroup == 0) { + if (!myBaseConstraint || !myStorage || myGroupID == GID_UNKNOWN) { /// TODO: Put error message here return; } - if (!mySlvsConstraints.empty()) // some data is changed, update constraint - update(myBaseConstraint); - Slvs_hEntity aStartPoint, aEndPoint; - std::vector > anEntitiesAndCopies; - getAttributes(aStartPoint, aEndPoint, myPointsAndCopies, anEntitiesAndCopies); + EntityWrapperPtr aStartPoint, aEndPoint; + bool aFullValue; + std::list aBaseEntities; + getAttributes(aStartPoint, aEndPoint, aFullValue, aBaseEntities); if (!myErrorMsg.empty()) return; - // Create translation line - if (myTranslationLine == SLVS_E_UNKNOWN) { - Slvs_Entity aTranslationLine = Slvs_MakeLineSegment(SLVS_E_UNKNOWN, myGroup->getId(), - myGroup->getWorkplaneId(), aStartPoint, aEndPoint); - aTranslationLine.h = myStorage->addEntity(aTranslationLine); - myTranslationLine = aTranslationLine.h; - } else { - Slvs_Entity aTranslationLine = myStorage->getEntity(myTranslationLine); - if (aTranslationLine.point[0] != aStartPoint || aTranslationLine.point[1] != aEndPoint) { - aTranslationLine.point[0] = aStartPoint; - aTranslationLine.point[1] = aEndPoint; - myStorage->updateEntity(aTranslationLine); - } - } + AttributeStringPtr aMethodTypeAttr = + myBaseConstraint->data()->string(SketchPlugin_MultiTranslation::VALUE_TYPE()); - // Keep all objects unchanged (only initial object may be changed by user) - myCircsAndCopies.clear(); - std::vector >::const_iterator anEntIt = anEntitiesAndCopies.begin(); - std::vector::const_iterator aCpIt; - for (; anEntIt != anEntitiesAndCopies.end(); ++anEntIt) { - std::vector aCircs; - aCpIt = anEntIt->begin(); - // Obtain initial points - Slvs_Entity anInitial = myStorage->getEntity(*aCpIt); - if (anInitial.type == SLVS_E_POINT_IN_2D || anInitial.type == SLVS_E_POINT_IN_3D) - myInitialPoints.insert(anInitial.h); - else { - for (int i = 0; i < 4 && anInitial.point[i] != SLVS_E_UNKNOWN; i++) - myInitialPoints.insert(anInitial.point[i]); - } - - // Fix the copies - for (++aCpIt; aCpIt != anEntIt->end(); ++aCpIt) { - const Slvs_Entity& anEntity = myStorage->getEntity(*aCpIt); - std::vector aNewConstr; - if (anEntity.type == SLVS_E_CIRCLE) { - aCircs.push_back(anEntity.distance); - // for circles we fix only center - aNewConstr = myStorage->fixEntity(anEntity.point[0]); - } else - aNewConstr = myStorage->fixEntity(*aCpIt); - if (anEntity.type == SLVS_E_ARC_OF_CIRCLE) - aCircs.push_back(anEntity.h); - mySlvsConstraints.insert(mySlvsConstraints.end(), aNewConstr.begin(), aNewConstr.end()); - } + BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); + std::list aTransConstraints; - if (!aCircs.empty()) { - if (anInitial.type == SLVS_E_CIRCLE) - aCircs.insert(aCircs.begin(), anInitial.distance); - else - aCircs.insert(aCircs.begin(), anInitial.h); - myCircsAndCopies.push_back(aCircs); - } + std::list::iterator anEntIt = aBaseEntities.begin(); + for (; anEntIt != aBaseEntities.end(); ++anEntIt) { + std::list aNewConstraints = + aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType, + 0.0, aFullValue, aStartPoint, aEndPoint, std::list(1, *anEntIt)); + aTransConstraints.insert(aTransConstraints.end(), + aNewConstraints.begin(), aNewConstraints.end()); } + myStorage->addConstraint(myBaseConstraint, aTransConstraints); + + myAdjusted = false; adjustConstraint(); } -void SketchSolver_ConstraintMultiTranslation::update(ConstraintPtr theConstraint) +const std::string& SketchSolver_ConstraintMultiTranslation::nameNbObjects() { - cleanErrorMsg(); - if (!theConstraint || theConstraint == myBaseConstraint) { - AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast( - myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); - AttributeIntegerPtr aNbCopies = myBaseConstraint->integer(SketchPlugin_MultiTranslation::NUMBER_OF_COPIES_ID()); - if (anInitialRefList->size() != myNumberOfObjects || - (size_t)aNbCopies->value() != myNumberOfCopies) { - remove(myBaseConstraint); - process(); - return; - } - } - SketchSolver_Constraint::update(); + return SketchPlugin_MultiTranslation::NUMBER_OF_OBJECTS_ID(); } -bool SketchSolver_ConstraintMultiTranslation::remove(ConstraintPtr theConstraint) +void SketchSolver_ConstraintMultiTranslation::updateLocal() { - cleanErrorMsg(); - if (theConstraint && theConstraint != myBaseConstraint) - return false; - bool isFullyRemoved = true; - std::vector::iterator aCIter = mySlvsConstraints.begin(); - for (; aCIter != mySlvsConstraints.end(); aCIter++) - isFullyRemoved = myStorage->removeConstraint(*aCIter) && isFullyRemoved; - mySlvsConstraints.clear(); - - std::map::iterator aFeatIt = myFeatureMap.begin(); - for (; aFeatIt != myFeatureMap.end(); aFeatIt++) - myStorage->removeEntity(aFeatIt->second); - - std::map aFeatureMapCopy = myFeatureMap; - - if (isFullyRemoved) { - myFeatureMap.clear(); - myAttributeMap.clear(); - myValueMap.clear(); - } else - cleanRemovedEntities(); - - // Restore initial features - std::map::iterator aFIter = aFeatureMapCopy.begin(); - for (; aFIter != aFeatureMapCopy.end(); ++aFIter) - { - if (myFeatureMap.find(aFIter->first) != myFeatureMap.end()) - continue; // the feature was not removed - Slvs_hEntity anEntity = myGroup->getFeatureId(aFIter->first); - if (anEntity != SLVS_E_UNKNOWN) - myFeatureMap[aFIter->first] = anEntity; - } - - return true; -} + DataPtr aData = myBaseConstraint->data(); + AttributePoint2DPtr aStartPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData, + SketchPlugin_MultiTranslation::START_POINT_ID()); + AttributePoint2DPtr anEndPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData, + SketchPlugin_MultiTranslation::END_POINT_ID()); + AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiTranslation::VALUE_TYPE()); + bool aFullValue = aMethodTypeAttr->value() != "SingleValue"; + + bool aStartPointChanged = aStartPointAttribute != myStartPointAttribute; + bool anEndPointChanged = anEndPointAttribute != myEndPointAttribute; + bool isMethodChanged = aFullValue != myIsFullValue; + + if (aStartPointChanged) + myStartPointAttribute = aStartPointAttribute; + if (aStartPointChanged) + myEndPointAttribute = anEndPointAttribute; + if (isMethodChanged) + myIsFullValue = aFullValue; + + if (aStartPointChanged || anEndPointChanged || isMethodChanged) { + DataPtr aData = myBaseConstraint->data(); + std::list aConstraints = myStorage->constraint(myBaseConstraint); + std::list::const_iterator anIt = aConstraints.begin(), + aLast = aConstraints.end(); + std::list anEntities; + for (; anIt != aLast; anIt++) { + ConstraintWrapperPtr aConstraint = *anIt; + aConstraint->setIsFullValue(myIsFullValue); + anEntities.clear(); + + const std::list& aConstraintEntities = aConstraint->entities(); + std::list::const_iterator aSIt = aConstraintEntities.begin(), + aSLast = aConstraintEntities.end(); + EntityWrapperPtr aStartEntity = *aSIt++; + if (aStartPointChanged) { + AttributePtr aStartPointAttr = + aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID()); + myStorage->update(aStartPointAttr); + aStartEntity = myStorage->entity(aStartPointAttr); + } + anEntities.push_back(aStartEntity); + + EntityWrapperPtr anEndEntity = *aSIt++; + if (anEndPointChanged) { + AttributePtr anEndPointAttr = + aData->attribute(SketchPlugin_MultiTranslation::END_POINT_ID()); + myStorage->update(anEndPointAttr); + anEndEntity = myStorage->entity(anEndPointAttr); + } + anEntities.push_back(anEndEntity); -void SketchSolver_ConstraintMultiTranslation::addFeature(FeaturePtr theFeature) -{ - SketchSolver_Constraint::addFeature(theFeature); + for (; aSIt != aSLast; ++aSIt) + anEntities.push_back(*aSIt); - std::map::iterator aFeatIt = myFeatureMap.find(theFeature); - if (aFeatIt == myFeatureMap.end()) - return; + aConstraint->setEntities(anEntities); + } + myStorage->addConstraint(myBaseConstraint, aConstraints); - // store list of points of the feature - const Slvs_Entity& theEntity = myStorage->getEntity(aFeatIt->second); - for (int i = 0; i < 4; i++) - if (theEntity.point[i] != SLVS_E_UNKNOWN) - myPointsJustUpdated.insert(theEntity.point[i]); + myAdjusted = false; + } } void SketchSolver_ConstraintMultiTranslation::adjustConstraint() { - Slvs_Entity aTranslationLine = myStorage->getEntity(myTranslationLine); - Slvs_hConstraint aFixed; // temporary variable - // Set the translation line unchanged during constraint recalculation - for (int i = 0; i < 2; i++) { - if (myStorage->isPointFixed(aTranslationLine.point[i], aFixed, true)) - continue; - Slvs_Constraint aConstraint = Slvs_MakeConstraint( - SLVS_E_UNKNOWN, myGroup->getId(), SLVS_C_WHERE_DRAGGED, myGroup->getWorkplaneId(), 0.0, - aTranslationLine.point[i], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN); - aConstraint.h = myStorage->addConstraint(aConstraint); - myStorage->addTemporaryConstraint(aConstraint.h); - } - - // Check if the distance between point is 0, no need to resolve constraints (just wait another values) - double aXY[4]; - for (int i = 0; i < 2; i++) { - Slvs_Entity aPnt = myStorage->getEntity(aTranslationLine.point[i]); - aXY[2*i] = myStorage->getParameter(aPnt.param[0]).val; - aXY[2*i+1] = myStorage->getParameter(aPnt.param[1]).val; - } - double aDelta[2] = {aXY[2] - aXY[0], aXY[3] - aXY[1]}; - if (fabs(aDelta[0]) + fabs(aDelta[1]) < tolerance) { - myStorage->setNeedToResolve(false); + if (myAdjusted) return; - } - std::list aCoincident = myStorage->getConstraintsByType(SLVS_C_POINTS_COINCIDENT); - std::list::const_iterator aCoIt; - - double aCoord[2]; - - // Update positions of all points to satisfy distances - std::vector< std::vector >::const_iterator aPointsIter = myPointsAndCopies.begin(); - std::vector::const_iterator aCopyIter; - for (; aPointsIter != myPointsAndCopies.end(); ++aPointsIter) { - aCopyIter = aPointsIter->begin(); - const Slvs_Entity& anInitial = myStorage->getEntity(*aCopyIter); - for (int i = 0; i < 2; i++) - aCoord[i] = myStorage->getParameter(anInitial.param[i]).val; - - // if the point is coincident with another one which is temporary fixed (moved by user), - // we will update its position correspondingly - Slvs_hConstraint aFixed; - for (aCoIt = aCoincident.begin(); aCoIt != aCoincident.end(); ++aCoIt) { - if ((aCoIt->ptA == anInitial.h && myInitialPoints.find(aCoIt->ptB) != myInitialPoints.end()) || - (aCoIt->ptB == anInitial.h && myInitialPoints.find(aCoIt->ptA) != myInitialPoints.end())) { - Slvs_hEntity anOtherId = aCoIt->ptA == anInitial.h ? aCoIt->ptB : aCoIt->ptA; - if (!myStorage->isTemporary(aFixed) && - myPointsJustUpdated.find(anOtherId) == myPointsJustUpdated.end()) - continue; // nothing to change - - const Slvs_Entity& anOtherPnt = myStorage->getEntity(anOtherId); - for (int i = 0; i < 2; i++) { - Slvs_Param anInitParam = myStorage->getParameter(anInitial.param[i]); - const Slvs_Param& anOtherParam = myStorage->getParameter(anOtherPnt.param[i]); - anInitParam.val = anOtherParam.val; - myStorage->updateParameter(anInitParam); - aCoord[i] = anOtherParam.val; - } - } - } + // Obtain delta between start and end points of translation + EntityWrapperPtr aStart = myStorage->entity( + myBaseConstraint->attribute(SketchPlugin_MultiTranslation::START_POINT_ID())); + std::list aStartParams = aStart->parameters(); + EntityWrapperPtr aEnd = myStorage->entity( + myBaseConstraint->attribute(SketchPlugin_MultiTranslation::END_POINT_ID())); + std::list aEndParams = aEnd->parameters(); - // update copied points - aCopyIter = aPointsIter->begin(); - for (++aCopyIter; aCopyIter != aPointsIter->end(); ++aCopyIter) { - // update position - aCoord[0] += aDelta[0]; - aCoord[1] += aDelta[1]; - - const Slvs_Entity& aTarget = myStorage->getEntity(*aCopyIter); - for (int i = 0; i < 2; i++) { - Slvs_Param aParam = myStorage->getParameter(aTarget.param[i]); - aParam.val = aCoord[i]; - myStorage->updateParameter(aParam); - } - } - } + myDelta[0] = aEndParams.front()->value() - aStartParams.front()->value(); + myDelta[1] = aEndParams.back()->value() - aStartParams.back()->value(); - std::list aDiamConstr; - for (aPointsIter = myCircsAndCopies.begin(); aPointsIter != myCircsAndCopies.end(); ++aPointsIter) { - aCopyIter = aPointsIter->begin(); - const Slvs_Entity& anInitial = myStorage->getEntity(*aCopyIter); - if (anInitial.type == SLVS_E_DISTANCE) { - const Slvs_Param& anInitRad = myStorage->getParameter(anInitial.param[0]); - for (++aCopyIter; aCopyIter != aPointsIter->end(); ++aCopyIter) { - const Slvs_Entity& aCopy = myStorage->getEntity(*aCopyIter); - Slvs_Param aCopyRad = myStorage->getParameter(aCopy.param[0]); - aCopyRad.val = anInitRad.val; - myStorage->updateParameter(aCopyRad); - } - } else if (anInitial.type == SLVS_E_ARC_OF_CIRCLE) { - const Slvs_Entity& aCenterEnt = myStorage->getEntity(anInitial.point[0]); - const Slvs_Entity& aStartEnt = myStorage->getEntity(anInitial.point[1]); - - if (aDiamConstr.empty()) - aDiamConstr = myStorage->getConstraintsByType(SLVS_C_DIAMETER); - // Calculate diameter of initial arc - double aDiam = 0.0; - for (int i = 0; i < 2; i++) { - double d = myStorage->getParameter(aStartEnt.param[i]).val - - myStorage->getParameter(aCenterEnt.param[i]).val; - aDiam += d * d; - } - aDiam = sqrt(aDiam) * 2.0; - // Update the Diameter constraints of copied arcs - for (++aCopyIter; aCopyIter != aPointsIter->end(); ++aCopyIter) { - std::list::iterator aDCIt = aDiamConstr.begin(); - for (; aDCIt != aDiamConstr.end(); ++aDCIt) - if (aDCIt->entityA == *aCopyIter) { - aDCIt->valA = aDiam; - myStorage->updateConstraint(*aDCIt); - aDiamConstr.erase(aDCIt); - break; - } - } - } + if (myIsFullValue && myNumberOfCopies > 0) { + myDelta[0] /= myNumberOfCopies; + myDelta[1] /= myNumberOfCopies; } - myPointsJustUpdated.clear(); + SketchSolver_ConstraintMulti::adjustConstraint(); } + +void SketchSolver_ConstraintMultiTranslation::getRelative( + double theAbsX, double theAbsY, double& theRelX, double& theRelY) +{ + theRelX = theAbsX; + theRelY = theAbsY; +} + +void SketchSolver_ConstraintMultiTranslation::getAbsolute( + double theRelX, double theRelY, double& theAbsX, double& theAbsY) +{ + theAbsX = theRelX; + theAbsY = theRelY; +} + +void SketchSolver_ConstraintMultiTranslation::transformRelative(double& theX, double& theY) +{ + // translate coordinates + theX += myDelta[0]; + theY += myDelta[1]; +} +