From a99d088ab2827a48a72148c17fd366c39efde8f3 Mon Sep 17 00:00:00 2001 From: vsv Date: Tue, 5 Aug 2014 12:03:06 +0400 Subject: [PATCH] Improve Distance constraint --- src/ModuleBase/ModuleBase_Operation.cpp | 11 +- src/ModuleBase/ModuleBase_WidgetFeature.cpp | 16 ++- .../ModuleBase_WidgetFeatureOrAttribute.cpp | 6 +- .../PartSet_OperationFeatureCreate.cpp | 2 + .../SketchPlugin_ConstraintDistance.cpp | 109 +++++++++++++++--- src/SketchPlugin/SketchPlugin_Plugin.cpp | 1 - src/SketchPlugin/SketchPlugin_Validators.cpp | 5 +- src/SketchPlugin/plugin-Sketch.xml | 3 +- 8 files changed, 122 insertions(+), 31 deletions(-) diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index ba44d4581..44eddb349 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -102,12 +102,15 @@ bool ModuleBase_Operation::canBeCommitted() const PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - const ModelAPI_Validator* aValidator = aFactory->validator(aId); - if (aValidator) { + std::list aValidators; + aFactory->validators(aId, aValidators); + std::list::const_iterator aIt; + for (aIt = aValidators.cbegin(); aIt != aValidators.cend(); ++aIt) { const ModuleBase_FeatureValidator* aFValidator = - dynamic_cast(aValidator); + dynamic_cast(*aIt); if (aFValidator) { - return aFValidator->isValid(aFeature); + if (!aFValidator->isValid(aFeature)) + return false; } } return true; diff --git a/src/ModuleBase/ModuleBase_WidgetFeature.cpp b/src/ModuleBase/ModuleBase_WidgetFeature.cpp index 0246514d1..e699a72de 100644 --- a/src/ModuleBase/ModuleBase_WidgetFeature.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFeature.cpp @@ -80,16 +80,20 @@ bool ModuleBase_WidgetFeature::setObject(const ObjectPtr& theObject) std::list > anArguments; aFactory->validators(parentID(), attributeID(), aValidators, anArguments); std::list::iterator aValidator = aValidators.begin(); + bool isValid = true; for(; aValidator != aValidators.end(); aValidator++) { - if (*aValidator) { - const ModuleBase_ResultValidator* aResValidator = - dynamic_cast(*aValidator); - if (aResValidator) { - if (!aResValidator->isValid(theObject)) - return false; + const ModuleBase_ResultValidator* aResValidator = + dynamic_cast(*aValidator); + if (aResValidator) { + isValid = false; + if (aResValidator->isValid(theObject)) { + isValid = true; + break; } } } + if (!isValid) + return false; myObject = theObject; myEditor->setText(theObject ? theObject->data()->name().c_str() : ""); diff --git a/src/ModuleBase/ModuleBase_WidgetFeatureOrAttribute.cpp b/src/ModuleBase/ModuleBase_WidgetFeatureOrAttribute.cpp index 10f8ba4f3..daa23d531 100644 --- a/src/ModuleBase/ModuleBase_WidgetFeatureOrAttribute.cpp +++ b/src/ModuleBase/ModuleBase_WidgetFeatureOrAttribute.cpp @@ -53,7 +53,7 @@ bool ModuleBase_WidgetFeatureOrAttribute::setValue(ModuleBase_WidgetValue* theVa if (aObject) { isDone = setObject(aObject); } - if (!isDone && aValuePoint) { + if (aValuePoint) { FeaturePtr aFeature = ModuleBase_Tools::feature(aObject); if (aFeature) { // find the given point in the feature attributes @@ -89,7 +89,7 @@ bool ModuleBase_WidgetFeatureOrAttribute::storeValue(ObjectPtr theFeature) const ModuleBase_WidgetFeatureOrAttribute* that = (ModuleBase_WidgetFeatureOrAttribute*) this; if (object()) aRef->setObject(object()); - else if (myAttribute) + if (myAttribute) aRef->setAttr(myAttribute); aFeature->execute(); @@ -112,7 +112,7 @@ bool ModuleBase_WidgetFeatureOrAttribute::restoreValue(ObjectPtr theFeature) std::string aText = ""; if (aFeature) aText = aFeature->data()->name().c_str(); - else if (myAttribute) + if (myAttribute) aText = myAttribute->attributeType().c_str(); editor()->setText(aText.c_str()); diff --git a/src/PartSet/PartSet_OperationFeatureCreate.cpp b/src/PartSet/PartSet_OperationFeatureCreate.cpp index 816153a00..f8b2dddf1 100644 --- a/src/PartSet/PartSet_OperationFeatureCreate.cpp +++ b/src/PartSet/PartSet_OperationFeatureCreate.cpp @@ -271,6 +271,8 @@ FeaturePtr PartSet_OperationFeatureCreate::createFeature(const bool theFlushMess bool PartSet_OperationFeatureCreate::setWidgetValue(ObjectPtr theFeature, double theX, double theY) { + if (!myActiveWidget) + return false; ModuleBase_WidgetValueFeature* aValue = new ModuleBase_WidgetValueFeature(); aValue->setObject(theFeature); aValue->setPoint(boost::shared_ptr(new GeomAPI_Pnt2d(theX, theY))); diff --git a/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp b/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp index 0c499fff0..531f09bd6 100644 --- a/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp +++ b/src/SketchPlugin/SketchPlugin_ConstraintDistance.cpp @@ -5,6 +5,7 @@ #include "SketchPlugin_ConstraintDistance.h" #include #include +#include #include #include @@ -18,11 +19,17 @@ static boost::shared_ptr getFeaturePoint( DataPtr theData, const std::string& theAttribute); +static boost::shared_ptr getFeatureLine(DataPtr theData, const std::string& theAttribute); + +static boost::shared_ptr getProjectionPoint(const boost::shared_ptr& theLine, + const boost::shared_ptr& thePoint); + SketchPlugin_ConstraintDistance::SketchPlugin_ConstraintDistance() { } +//************************************************************************************* void SketchPlugin_ConstraintDistance::initAttributes() { data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::type()); @@ -31,22 +38,39 @@ void SketchPlugin_ConstraintDistance::initAttributes() data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type()); } +//************************************************************************************* void SketchPlugin_ConstraintDistance::execute() { boost::shared_ptr aData = data(); - - boost::shared_ptr aPoint_A = getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A()); - boost::shared_ptr aPoint_B = getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B()); - if (aPoint_A && aPoint_B) { - AttributeDoublePtr anAttr_Value = - boost::dynamic_pointer_cast(aData->attribute(SketchPlugin_Constraint::VALUE())); - - if (!anAttr_Value->isInitialized()) { - anAttr_Value->setValue(aPoint_A->pnt()->distance(aPoint_B->pnt())); + AttributeDoublePtr anAttr_Value = + boost::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::VALUE())); + + if (!anAttr_Value->isInitialized()) { + boost::shared_ptr aPoint_A = + getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A()); + boost::shared_ptr aPoint_B = + getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B()); + + if (aPoint_A && aPoint_B) { // both points + anAttr_Value->setValue(aPoint_A->pnt()->distance(aPoint_B->pnt())); + } else { + if (!aPoint_A && aPoint_B) { //Line and point + boost::shared_ptr aLine = + getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A()); + if (aLine) + anAttr_Value->setValue(aLine->distanceToPoint(aPoint_B->pnt())); + } else if (aPoint_A && !aPoint_B) { // Point and line + boost::shared_ptr aLine = + getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B()); + if(aLine) + anAttr_Value->setValue(aLine->distanceToPoint(aPoint_A->pnt())); + } } } } +//************************************************************************************* boost::shared_ptr SketchPlugin_ConstraintDistance::getAISObject( boost::shared_ptr thePrevious) { @@ -58,14 +82,36 @@ boost::shared_ptr SketchPlugin_ConstraintDistance::getAISObje DataPtr aData = data(); boost::shared_ptr aPoint_A = getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A()); boost::shared_ptr aPoint_B = getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B()); - if (!aPoint_A || !aPoint_B) + + boost::shared_ptr aPnt_A; + boost::shared_ptr aPnt_B; + + if (aPoint_A && aPoint_B) { + aPnt_A = aPoint_A->pnt(); + aPnt_B = aPoint_B->pnt(); + } else if (!aPoint_A && aPoint_B) { + boost::shared_ptr aLine = + getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A()); + if (aLine) { + aPnt_B = aPoint_B->pnt(); + aPnt_A = getProjectionPoint(aLine, aPnt_B); + } + } else if (aPoint_A && !aPoint_B) { + boost::shared_ptr aLine = + getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B()); + if (aLine) { + aPnt_A = aPoint_A->pnt(); + aPnt_B = getProjectionPoint(aLine, aPnt_A); + } + } + if (!aPnt_A || !aPnt_B) return thePrevious; boost::shared_ptr aFlyOutAttr = boost::dynamic_pointer_cast(aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT())); - boost::shared_ptr aPoint1 = sketch()->to3D(aPoint_A->x(), aPoint_A->y()); - boost::shared_ptr aPoint2 = sketch()->to3D(aPoint_B->x(), aPoint_B->y()); + boost::shared_ptr aPoint1 = sketch()->to3D(aPnt_A->x(), aPnt_A->y()); + boost::shared_ptr aPoint2 = sketch()->to3D(aPnt_B->x(), aPnt_B->y()); boost::shared_ptr aFlyoutPnt = aFlyOutAttr->isInitialized() ? sketch()->to3D(aFlyOutAttr->x(), aFlyOutAttr->y()) : boost::shared_ptr(); @@ -82,6 +128,7 @@ boost::shared_ptr SketchPlugin_ConstraintDistance::getAISObje return anAIS; } +//************************************************************************************* void SketchPlugin_ConstraintDistance::move(double theDeltaX, double theDeltaY) { boost::shared_ptr aData = data(); @@ -93,6 +140,7 @@ void SketchPlugin_ConstraintDistance::move(double theDeltaX, double theDeltaY) aPoint1->setValue(aPoint1->x() + theDeltaX, aPoint1->y() + theDeltaY); } +//************************************************************************************* boost::shared_ptr getFeaturePoint(DataPtr theData, const std::string& theAttribute) { @@ -113,9 +161,42 @@ boost::shared_ptr getFeaturePoint(DataPtr theData, else if (aFeature && aFeature->getKind() == SketchPlugin_Circle::ID()) aPointAttr = boost::dynamic_pointer_cast (aFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID())); - else { - if (anAttr->attr()) + else if (anAttr->attr()) { aPointAttr = boost::dynamic_pointer_cast(anAttr->attr()); } return aPointAttr; } + +//************************************************************************************* +boost::shared_ptr getFeatureLine(DataPtr theData, const std::string& theAttribute) +{ + boost::shared_ptr aLine; + if (!theData) + return aLine; + + boost::shared_ptr anAttr = + boost::dynamic_pointer_cast(theData->attribute(theAttribute)); + if (anAttr) { + FeaturePtr aFeature = SketchPlugin_Sketch::getFeature(anAttr->object()); + if (aFeature && aFeature->getKind() == SketchPlugin_Line::ID()) { + aLine = boost::dynamic_pointer_cast(aFeature); + } + } + return aLine; +} + +//************************************************************************************* +boost::shared_ptr getProjectionPoint(const boost::shared_ptr& theLine, + const boost::shared_ptr& thePoint) +{ + boost::shared_ptr aData = theLine->data(); + boost::shared_ptr aPoint1 = + boost::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::START_ID())); + boost::shared_ptr aPoint2 = + boost::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Line::END_ID())); + + GeomAPI_Lin2d aLin2d(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y()); + return aLin2d.project(thePoint); +} \ No newline at end of file diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 687e2cd94..8c9de8767 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -24,7 +24,6 @@ SketchPlugin_Plugin::SketchPlugin_Plugin() { PluginManagerPtr aMgr = ModelAPI_PluginManager::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - aFactory->registerValidator("SketchPlugin_DistanceFeatureValidator", new SketchPlugin_DistanceFeatureValidator); // register this plugin ModelAPI_PluginManager::get()->registerPlugin(this); diff --git a/src/SketchPlugin/SketchPlugin_Validators.cpp b/src/SketchPlugin/SketchPlugin_Validators.cpp index 7f44ef5b1..161a1442c 100644 --- a/src/SketchPlugin/SketchPlugin_Validators.cpp +++ b/src/SketchPlugin/SketchPlugin_Validators.cpp @@ -38,7 +38,8 @@ bool SketchPlugin_DistanceFeatureValidator::isValid(const FeaturePtr theFeature) if (!aRefA || !aRefB) return false; - FeaturePtr aFetureA = SketchPlugin_Sketch::getFeature(aRefA->object()); + return true; +/* FeaturePtr aFetureA = SketchPlugin_Sketch::getFeature(aRefA->object()); FeaturePtr aFetureB = SketchPlugin_Sketch::getFeature(aRefB->object()); if (!aFetureA || !aFetureB) return false; @@ -52,5 +53,5 @@ bool SketchPlugin_DistanceFeatureValidator::isValid(const FeaturePtr theFeature) return isValidType(aTypeA); } else return isValidType(aTypeA) && isValidType(aTypeB); - return false; + return false;*/ } diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 96ccaefce..ed01bb4ca 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -30,14 +30,15 @@