X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSketchPlugin%2FSketchPlugin_Tools.cpp;h=98a6c1524892e146daf313f59eb3fdaff6a57799;hb=5c13fa0e68725babdd09541b028c186896e27b4f;hp=a9aa9d90c9227f17193f72ea945b42141ec2fd42;hpb=42985955d89fa845790a7e38609f5b6838285147;p=modules%2Fshaper.git diff --git a/src/SketchPlugin/SketchPlugin_Tools.cpp b/src/SketchPlugin/SketchPlugin_Tools.cpp index a9aa9d90c..98a6c1524 100644 --- a/src/SketchPlugin/SketchPlugin_Tools.cpp +++ b/src/SketchPlugin/SketchPlugin_Tools.cpp @@ -6,12 +6,17 @@ #include "SketchPlugin_Tools.h" +#include "SketchPlugin_ConstraintCoincidence.h" +#include "SketchPlugin_ConstraintTangent.h" +#include "SketchPlugin_Point.h" +#include "SketchPlugin_SketchEntity.h" + +#include + +#include + #include #include -#include -#include -#include -#include namespace SketchPlugin_Tools { @@ -33,17 +38,17 @@ void clearExpressions(AttributePoint2DPtr theAttribute) void clearExpressions(AttributePtr theAttribute) { // Double - AttributeDoublePtr anAttributeDouble = + AttributeDoublePtr anAttributeDouble = std::dynamic_pointer_cast(theAttribute); if (anAttributeDouble.get()) clearExpressions(anAttributeDouble); // Point - AttributePointPtr anAttributePoint = + AttributePointPtr anAttributePoint = std::dynamic_pointer_cast(theAttribute); if (anAttributePoint.get()) clearExpressions(anAttributePoint); // Point2D - AttributePoint2DPtr anAttributePoint2D = + AttributePoint2DPtr anAttributePoint2D = std::dynamic_pointer_cast(theAttribute); if (anAttributePoint2D.get()) clearExpressions(anAttributePoint2D); @@ -54,7 +59,7 @@ void clearExpressions(FeaturePtr theFeature) if (!theFeature.get()) return; - std::list anAttributes = theFeature->data()->attributes(std::string()); + std::list anAttributes = theFeature->data()->attributes(std::string()); std::list::iterator anAttributeIt = anAttributes.begin(); for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) { clearExpressions(*anAttributeIt); @@ -63,13 +68,26 @@ void clearExpressions(FeaturePtr theFeature) std::shared_ptr getCoincidencePoint(const FeaturePtr theStartCoin) { - std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), - SketchPlugin_Constraint::ENTITY_A()); + std::shared_ptr aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), + SketchPlugin_Constraint::ENTITY_A()); if (aPnt.get() == NULL) aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B()); return aPnt; } +std::set findCoincidentConstraints(const FeaturePtr& theFeature) +{ + std::set aCoincident; + const std::set& aRefsList = theFeature->data()->refsToMe(); + std::set::const_iterator aIt; + for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { + FeaturePtr aConstrFeature = std::dynamic_pointer_cast((*aIt)->owner()); + if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) + aCoincident.insert(aConstrFeature); + } + return aCoincident; +} + void findCoincidences(const FeaturePtr theStartCoin, const std::string& theAttr, std::set& theList) @@ -85,73 +103,195 @@ void findCoincidences(const FeaturePtr theStartCoin, return; } theList.insert(aObj); - const std::set& aRefsList = aObj->data()->refsToMe(); - std::set::const_iterator aIt; - for(aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) { - std::shared_ptr aAttr = (*aIt); - FeaturePtr aConstrFeature = std::dynamic_pointer_cast(aAttr->owner()); - if(aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { - std::shared_ptr aPnt = getCoincidencePoint(aConstrFeature); - if(aPnt.get() && aOrig->isEqual(aPnt)) { - findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList); - findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList); - } + std::set aCoincidences = findCoincidentConstraints(aObj); + std::set::const_iterator aCIt = aCoincidences.begin(); + for (; aCIt != aCoincidences.end(); ++aCIt) { + FeaturePtr aConstrFeature = *aCIt; + std::shared_ptr aPnt = getCoincidencePoint(aConstrFeature); + if(aPnt.get() && aOrig->isEqual(aPnt)) { + findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList); + findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList); } } } } -void updateMultiAttribute(const AttributePtr& theFirstAngleAttribute, - const AttributePtr& theSecondAngleAttribute, - const int& theValue, - const bool toMultiply) +std::set findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint) { - if (theValue == 0 || !theFirstAngleAttribute->isInitialized()) - return; + std::set aCoincidentFeatures; + + FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner()); + aCoincidentFeatures.insert(anOwner); + + std::set aCoincidences = findCoincidentConstraints(anOwner); + std::set::const_iterator aCIt = aCoincidences.begin(); + for (; aCIt != aCoincidences.end(); ++aCIt) { + bool isPointUsedInCoincidence = false; + AttributeRefAttrPtr anOtherCoincidentAttr; + for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) { + AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i)); + if (!aRefAttr) + continue; + if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint) + isPointUsedInCoincidence = true; + else + anOtherCoincidentAttr = aRefAttr; + } - AttributeDoublePtr aDoubleFirstAttr = std::dynamic_pointer_cast( - theFirstAngleAttribute); - double aValue = aDoubleFirstAttr->value(); + if (isPointUsedInCoincidence) { + ObjectPtr anObj; + if (anOtherCoincidentAttr->isObject()) + anObj = anOtherCoincidentAttr->object(); + else + anObj = anOtherCoincidentAttr->attr()->owner(); + aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj)); + } + } - AttributeDoublePtr aDoubleSecondAttr = std::dynamic_pointer_cast( - theSecondAngleAttribute); - if (toMultiply) - aDoubleSecondAttr->setValue(aValue*theValue); - else - aDoubleSecondAttr->setValue(aValue/theValue); + return aCoincidentFeatures; } -void updateMultiAttribute(const AttributePtr& theFirstAttribute, - const AttributePtr& theSecondAttribute, - const AttributePtr& theModifiedAttribute, - const int& theValue, - const bool toMultiply) +// Container for point-point coincidences. +// Useful to find points coincident to a given point. +class CoincidentPoints { - if (theValue == 0 || !theFirstAttribute->isInitialized() - || !theSecondAttribute->isInitialized()) - return; +public: + void addCoincidence(const AttributePoint2DPtr& thePoint1, + const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr()) + { + std::list< std::set >::iterator aFound1 = find(thePoint1); + std::list< std::set >::iterator aFound2 = find(thePoint2); + if (aFound1 == myCoincidentPoints.end()) { + std::set aNewSet; + aNewSet.insert(thePoint1); + if (thePoint2) + aNewSet.insert(thePoint2); + myCoincidentPoints.push_back(aNewSet); + } else if (aFound2 == myCoincidentPoints.end()) { + if (thePoint2) + aFound1->insert(thePoint2); + } else { + aFound1->insert(aFound2->begin(), aFound2->end()); + myCoincidentPoints.erase(aFound2); + } + } - std::shared_ptr aFirstPoint = - std::dynamic_pointer_cast(theFirstAttribute); - std::shared_ptr aSecondPoint = - std::dynamic_pointer_cast(theSecondAttribute); - std::shared_ptr aModifiedPoint = - std::dynamic_pointer_cast(theModifiedAttribute); + std::set coincidentPoints(const AttributePoint2DPtr& thePoint) + { + std::list< std::set >::iterator aFound = find(thePoint); + if (aFound == myCoincidentPoints.end()) + return std::set(); + return *aFound; + } - if (!aFirstPoint.get() || !aSecondPoint.get() || !aModifiedPoint.get()) - return; +private: + std::list< std::set >::iterator find(const AttributePoint2DPtr& thePoint) + { + std::list< std::set >::iterator aSeek = myCoincidentPoints.begin(); + for (; aSeek != myCoincidentPoints.end(); ++aSeek) + if (aSeek->find(thePoint) != aSeek->end()) + return aSeek; + return myCoincidentPoints.end(); + } + +private: + std::list< std::set > myCoincidentPoints; +}; + +std::set findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint) +{ + CoincidentPoints aCoincidentPoints; + AttributePoint2DPtr aPoints[2]; + + FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner()); + std::set aCoincidences = findCoincidentConstraints(anOwner); + std::set::const_iterator aCIt = aCoincidences.begin(); + for (; aCIt != aCoincidences.end(); ++aCIt) { + aPoints[0] = AttributePoint2DPtr(); + aPoints[1] = AttributePoint2DPtr(); + for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) { + AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i)); + if (!aRefAttr) + continue; + if (!aRefAttr->isObject()) + aPoints[aPtInd++] = std::dynamic_pointer_cast(aRefAttr->attr()); + } - if (aFirstPoint->pnt()->isEqual(aSecondPoint->pnt())) - aModifiedPoint->setValue(aFirstPoint->pnt()); - else { - double aDx = aSecondPoint->x() - aFirstPoint->x(); - double aDy = aSecondPoint->y() - aFirstPoint->y(); + if (aPoints[0]) + aCoincidentPoints.addCoincidence(aPoints[0], aPoints[1]); + } - double aX = toMultiply ? aDx * theValue : aDx / theValue; - double anY = toMultiply ? aDy * theValue : aDy / theValue; + return aCoincidentPoints.coincidentPoints(thePoint); +} - aModifiedPoint->setValue(aFirstPoint->x() + aX, aFirstPoint->y() + anY); +void resetAttribute(SketchPlugin_Feature* theFeature, + const std::string& theId) +{ + AttributePtr anAttr = theFeature->attribute(theId); + if(anAttr.get()) { + anAttr->reset(); } } +void createConstraint(SketchPlugin_Feature* theFeature, + const std::string& theId, + const AttributePtr theAttr, + const ObjectPtr theObject, + const bool theIsCanBeTangent) +{ + AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId); + if(aRefAttr.get() && aRefAttr->isInitialized()) { + FeaturePtr aConstraint; + if(!theIsCanBeTangent) { + aConstraint = theFeature->sketch() + ->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } else { + if(aRefAttr->isObject()) { + ObjectPtr anObject = aRefAttr->object(); + FeaturePtr aFeature = ModelAPI_Feature::feature(anObject); + if(aFeature->getKind() == SketchPlugin_Point::ID()) { + aConstraint = theFeature->sketch() + ->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } else { + aConstraint = theFeature->sketch() + ->addFeature(SketchPlugin_ConstraintTangent::ID()); + } + } else { + aConstraint = theFeature->sketch() + ->addFeature(SketchPlugin_ConstraintCoincidence::ID()); + } + } + AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A()); + aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object()) + : aRefAttrA->setAttr(aRefAttr->attr()); + AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B()); + if(theObject.get()) { + aRefAttrB->setObject(theObject); + } else if(theAttr.get()) { + aRefAttrB->setAttr(theAttr); + } + } +} + +void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefAttr, + const AttributePtr& theDefaultAttr, + std::shared_ptr& theTangentCurve, + std::shared_ptr& thePassingPoint) +{ + AttributePtr anAttr = theDefaultAttr; + if (theRefAttr->isObject()) { + FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object()); + if (aTgFeature) { + if (aTgFeature->getKind() != SketchPlugin_Point::ID()) { + theTangentCurve = aTgFeature->lastResult()->shape(); + return; + } + anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID()); + } + } else + anAttr = theRefAttr->attr(); + + thePassingPoint = std::dynamic_pointer_cast(anAttr)->pnt(); +} + } // namespace SketchPlugin_Tools