X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchSolver%2FSketchSolver_ConstraintMulti.cpp;h=bd0a82ad3206962483ae6a6bffa4b5d5fe5b5fa8;hb=176403004ff97696f3c0b5f8bdf48692177fb34a;hp=a445fe7ba96d83c1ba08fcd6585edee557116823;hpb=5e2fa65b68341b718d7469fde02978b80d6abcea;p=modules%2Fshaper.git diff --git a/src/SketchSolver/SketchSolver_ConstraintMulti.cpp b/src/SketchSolver/SketchSolver_ConstraintMulti.cpp index a445fe7ba..bd0a82ad3 100644 --- a/src/SketchSolver/SketchSolver_ConstraintMulti.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintMulti.cpp @@ -1,13 +1,20 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + #include #include #include +#include #include #include #include +#include +#include +#include +#include +#include -void SketchSolver_ConstraintMulti::getEntitiesAndCopies( - std::list< std::list >& theEntAndCopies) +void SketchSolver_ConstraintMulti::getEntities(std::list& theEntities) { myAdjusted = false; DataPtr aData = myBaseConstraint->data(); @@ -28,40 +35,71 @@ void SketchSolver_ConstraintMulti::getEntitiesAndCopies( } FeaturePtr aFeature; - std::list anEntities; // list of transformed entities std::list anObjectList = aRefList->list(); std::list::iterator anObjIt = anObjectList.begin(); - if (myNumberOfCopies + 1 != aRefList->size()) // execute for the feature is not called yet - myNumberOfCopies = aRefList->size() - 1; + // execute for the feature is not called yet + if ((myNumberOfCopies + 1) * myNumberOfObjects != aRefList->size()) + myNumberOfCopies = aRefList->size() / myNumberOfObjects - 1; while (anObjIt != anObjectList.end()) { - anEntities.clear(); - for (int i = 0; i <= myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) { - aFeature = ModelAPI_Feature::feature(*anObjIt); - if (!aFeature) - continue; + aFeature = ModelAPI_Feature::feature(*anObjIt++); + if (!aFeature) + continue; - myStorage->update(aFeature); - anEntities.push_back(myStorage->entity(aFeature)); + // the entity is not created, so it is a copy in "multi" constraint, force its creation + if (!myStorage->update(aFeature)) + myStorage->update(aFeature, myGroupID, true); + theEntities.push_back(myStorage->entity(aFeature)); + myFeatures.insert(aFeature); + for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) { + // just add copied features into the list of objects + aFeature = ModelAPI_Feature::feature(*anObjIt); + if (aFeature) + myFeatures.insert(aFeature); } - if (!anEntities.empty()) - theEntAndCopies.push_back(anEntities); } } +bool SketchSolver_ConstraintMulti::remove() +{ + myFeatures.clear(); + return SketchSolver_Constraint::remove(); +} + void SketchSolver_ConstraintMulti::update() { update(false); } - void SketchSolver_ConstraintMulti::update(bool isForce) { cleanErrorMsg(); AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast( myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A())); AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects()); - if (anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies) { + if (!anInitialRefList || !aNbObjects) + return; // the "Multi" constraint is in queue to remove + bool isUpdated = + anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies; + if (!isUpdated) { + // additional check that the features and their copies are changed + AttributeRefListPtr aRefList = std::dynamic_pointer_cast( + myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); + if (aRefList && aRefList->size() != 0) { + FeaturePtr aFeature; + std::list anObjectList = aRefList->list(); + std::list::iterator anObjIt = anObjectList.begin(); + for (; anObjIt != anObjectList.end(); ++anObjIt) { + aFeature = ModelAPI_Feature::feature(*anObjIt); + if (aFeature && myFeatures.find(aFeature) == myFeatures.end()) { + isUpdated = true; + break; + } + } + } else + isUpdated = true; + } + if (isUpdated) { remove(); process(); return; @@ -71,22 +109,127 @@ void SketchSolver_ConstraintMulti::update(bool isForce) updateLocal(); if (isForce) myAdjusted = false; - // update parent object - SketchSolver_Constraint::update(); + adjustConstraint(); } void SketchSolver_ConstraintMulti::adjustConstraint() { - if (myAdjusted) - return; // constraint already adjusted, don't do it once again + AttributeRefListPtr aRefList = std::dynamic_pointer_cast( + myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B())); + if (!aRefList || aRefList->size() == 0) { + myErrorMsg = SketchSolver_Error::INCORRECT_ATTRIBUTE(); + return; + } + + FeaturePtr anOriginal, aFeature; + std::list anObjectList = aRefList->list(); + std::list::iterator anObjIt = anObjectList.begin(); + while (anObjIt != anObjectList.end()) { + anOriginal = ModelAPI_Feature::feature(*anObjIt++); + if (!anOriginal) + continue; + + // Fill lists of coordinates of points composing a feature + std::list aX, aY; + std::list::iterator aXIt, aYIt; + double aXCoord, aYCoord; + EntityWrapperPtr anEntity = myStorage->entity(anOriginal); + std::list aSubs = anEntity->subEntities(); + std::list::const_iterator aSIt = aSubs.begin(); + for (; aSIt != aSubs.end(); ++aSIt) { + if ((*aSIt)->type() != ENTITY_POINT) + continue; + AttributePoint2DPtr aPoint = + std::dynamic_pointer_cast((*aSIt)->baseAttribute()); + if (aPoint) { + aXCoord = aPoint->x(); + aYCoord = aPoint->y(); + } else { + std::list aParameters = (*aSIt)->parameters(); + aXCoord = aParameters.front()->value(); + aYCoord = aParameters.back()->value(); + } + getRelative(aXCoord, aYCoord, aXCoord, aYCoord); + aX.push_back(aXCoord); + aY.push_back(aYCoord); + } + + // Calculate positions of copied features + for (int i = 0; i < myNumberOfCopies && anObjIt != anObjectList.end(); ++i, ++anObjIt) { + aFeature = ModelAPI_Feature::feature(*anObjIt); + if (!aFeature) + continue; + anEntity = myStorage->entity(aFeature); + + if (!anEntity || !myStorage->isEventsBlocked()) + aFeature->data()->blockSendAttributeUpdated(true); + + std::list aPoints; + if (aFeature->getKind() == SketchPlugin_Arc::ID()) { + aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::CENTER_ID())); + aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::START_ID())); + aPoints.push_back(aFeature->attribute(SketchPlugin_Arc::END_ID())); + } else if (aFeature->getKind() == SketchPlugin_Line::ID()) { + aPoints.push_back(aFeature->attribute(SketchPlugin_Line::START_ID())); + aPoints.push_back(aFeature->attribute(SketchPlugin_Line::END_ID())); + } else if (aFeature->getKind() == SketchPlugin_Circle::ID()) { + aPoints.push_back(aFeature->attribute(SketchPlugin_Circle::CENTER_ID())); + // update circle's radius + aFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue( + anOriginal->real(SketchPlugin_Circle::RADIUS_ID())->value()); + } else if (aFeature->getKind() == SketchPlugin_Point::ID() || + aFeature->getKind() == SketchPlugin_IntersectionPoint::ID()) + aPoints.push_back(aFeature->attribute(SketchPlugin_Point::COORD_ID())); + + std::list::iterator aPtIt = aPoints.begin(); + for (aXIt = aX.begin(), aYIt = aY.begin(); aPtIt != aPoints.end(); ++aXIt, ++aYIt, ++aPtIt) { + transformRelative(*aXIt, *aYIt); + getAbsolute(*aXIt, *aYIt, aXCoord, aYCoord); + + std::shared_ptr aPoint2D = + std::dynamic_pointer_cast(*aPtIt); + aPoint2D->setValue(aXCoord, aYCoord); + } - BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder(); + // update feature in the storage if it is used by another constraints + if (anEntity) + myStorage->update(aFeature); + else { // update attributes, if they exist in the storage + for (aPtIt = aPoints.begin(); aPtIt != aPoints.end(); ++aPtIt) { + EntityWrapperPtr aPntEnt = myStorage->entity(*aPtIt); + if (aPntEnt) + myStorage->update(*aPtIt); + } + } - const std::list& aConstraints = myStorage->constraint(myBaseConstraint); - std::list::const_iterator anIt = aConstraints.begin(); - for (; anIt != aConstraints.end(); ++anIt) - aBuilder->adjustConstraint(*anIt); - myStorage->addConstraint(myBaseConstraint, aConstraints); + if (!anEntity || !myStorage->isEventsBlocked()) + aFeature->data()->blockSendAttributeUpdated(false); + } + } myAdjusted = true; } + +bool SketchSolver_ConstraintMulti::isUsed(FeaturePtr theFeature) const +{ + return theFeature && (myFeatures.find(theFeature) != myFeatures.end() || + SketchSolver_Constraint::isUsed(theFeature)); +} + +bool SketchSolver_ConstraintMulti::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(); + } + if (!anAttribute) + return false; + + FeaturePtr anOwner = ModelAPI_Feature::feature(anAttribute->owner()); + return myFeatures.find(anOwner) != myFeatures.end(); +}