From: Jérôme Date: Tue, 6 Oct 2020 07:33:14 +0000 (+0200) Subject: Implementation of interpolation analytical (Work in progress) X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9ec51225ec9f5081904270c4b25183420f48d2f2;p=modules%2Fshaper.git Implementation of interpolation analytical (Work in progress) --- diff --git a/src/BuildPlugin/BuildPlugin_Interpolation.cpp b/src/BuildPlugin/BuildPlugin_Interpolation.cpp index b8422517b..c2d1d3f97 100644 --- a/src/BuildPlugin/BuildPlugin_Interpolation.cpp +++ b/src/BuildPlugin/BuildPlugin_Interpolation.cpp @@ -21,12 +21,21 @@ #include #include +#include +#include +#include +#include + #include #include #include +#include +#include #include +#include + #include #include #include @@ -34,9 +43,12 @@ #include #include #include +#include #include +#include + //================================================================================================= BuildPlugin_Interpolation::BuildPlugin_Interpolation() { @@ -51,6 +63,30 @@ void BuildPlugin_Interpolation::initAttributes() data()->addAttribute(USE_TANGENTS_ID(), ModelAPI_AttributeString::typeId()); data()->addAttribute(TANGENT_START_ID(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(TANGENT_END_ID(), ModelAPI_AttributeSelection::typeId()); + + data()->addAttribute(CREATION_METHODE_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(CREATION_METHODE_BY_SELECTION_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(CREATION_METHODE_ANALYTICAL_ID(), ModelAPI_AttributeString::typeId()); + + data()->addAttribute(EXPRESSION_ERROR_ID(), ModelAPI_AttributeString::typeId()); + data()->string(EXPRESSION_ERROR_ID())->setIsArgument(false); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ERROR_ID()); + + data()->addAttribute(XT_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(YT_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(ZT_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(MINT_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(MAXT_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(NUMSTEP_ID(), ModelAPI_AttributeInteger::typeId()); + + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHODE_ANALYTICAL_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHODE_BY_SELECTION_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), YT_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ZT_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), MINT_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), MAXT_ID()); + ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), NUMSTEP_ID()); + } //================================================================================================= @@ -78,62 +114,177 @@ static GeomDirPtr selectionToDir(const AttributeSelectionPtr& theSelection) //================================================================================================= void BuildPlugin_Interpolation::execute() { - // Get closed flag value - bool isClosed = boolean(CLOSED_ID())->value(); + if( string(CREATION_METHODE_ID())->value() == CREATION_METHODE_BY_SELECTION_ID() ) + { + // Get closed flag value + bool isClosed = boolean(CLOSED_ID())->value(); - // Get reorder flag value - bool isToReorder = boolean(REORDER_ID())->value(); + // Get reorder flag value + bool isToReorder = boolean(REORDER_ID())->value(); - // Get use tangents flag value - bool isToUseTangents = isClosed? false : (!string(USE_TANGENTS_ID())->value().empty()); + // Get use tangents flag value + bool isToUseTangents = isClosed? false : (!string(USE_TANGENTS_ID())->value().empty()); - // Get tangent for start and end points - GeomDirPtr aDirStart, aDirEnd; - if (isToUseTangents) { - aDirStart = selectionToDir(selection(TANGENT_START_ID())); - aDirEnd = selectionToDir(selection(TANGENT_END_ID())); - } + // Get tangent for start and end points + GeomDirPtr aDirStart, aDirEnd; + if (isToUseTangents) { + aDirStart = selectionToDir(selection(TANGENT_START_ID())); + aDirEnd = selectionToDir(selection(TANGENT_END_ID())); + } - // Get base objects list. - AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); - - // Collect points. - std::list aPoints; - std::set aContexts; - for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { - AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); - - GeomShapePtr aContextShape = aSelection->context()->shape(); - aContexts.insert(aContextShape); - - GeomShapePtr aShape = aSelection->value(); - if (!aShape.get()) { - aShape = aContextShape; - } - - GeomPointPtr aPoint = GeomAlgoAPI_PointBuilder::point(aShape); - aPoints.push_back(aPoint); - } - - // Create curve from points - GeomEdgePtr anEdge = - GeomAlgoAPI_CurveBuilder::edge(aPoints, isClosed, isToReorder, aDirStart, aDirEnd); - if (!anEdge.get()) { - setError("Error: Result curve is empty."); - return; - } + // Get base objects list. + AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID()); + + // Collect points. + std::list aPoints; + std::set aContexts; + for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) { + AttributeSelectionPtr aSelection = aSelectionList->value(anIndex); + + GeomShapePtr aContextShape = aSelection->context()->shape(); + aContexts.insert(aContextShape); + + GeomShapePtr aShape = aSelection->value(); + if (!aShape.get()) { + aShape = aContextShape; + } - // Store result. - ResultBodyPtr aResultBody = document()->createBody(data()); - std::set::const_iterator aContextIt = aContexts.begin(); - for (; aContextIt != aContexts.end(); aContextIt++) { - aResultBody->storeModified(*aContextIt, anEdge, aContextIt == aContexts.begin()); + GeomPointPtr aPoint = GeomAlgoAPI_PointBuilder::point(aShape); + aPoints.push_back(aPoint); + } + + // Create curve from points + GeomEdgePtr anEdge = + GeomAlgoAPI_CurveBuilder::edge(aPoints, isClosed, isToReorder, aDirStart, aDirEnd); + if (!anEdge.get()) { + setError("Error: Result curve is empty."); + return; + } + + // Store result. + ResultBodyPtr aResultBody = document()->createBody(data()); + std::set::const_iterator aContextIt = aContexts.begin(); + for (; aContextIt != aContexts.end(); aContextIt++) { + aResultBody->storeModified(*aContextIt, anEdge, aContextIt == aContexts.begin()); + } + int aVertexIndex = 1; + for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) { + std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex); + aResultBody->generated(anExp.current(), aVertexName); + } + + setResult(aResultBody); + }else + { + string(EXPRESSION_ERROR_ID())->setValue("rien"); + string(EXPRESSION_ID())->setValue(string( XT_ID())->value()); + string(VARIABLE_ID())->setValue("t"); + updateName(); + double res; + if (!updateExpression(res)) + setError("Expression error.", false); + std::cout << "res = " << res << std::endl; } - int aVertexIndex = 1; - for (GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::VERTEX); anExp.more(); anExp.next()) { - std::string aVertexName = "Vertex_" + std::to_string((long long)aVertexIndex); - aResultBody->generated(anExp.current(), aVertexName); + +} + +double BuildPlugin_Interpolation::evaluate(const std::wstring& /*theExpression*/, + std::string& theError) +{ + FeaturePtr aMyPtr = std::dynamic_pointer_cast(data()->owner()); + std::shared_ptr aProcessMessage = + ModelAPI_ParameterEvalMessage::send(aMyPtr, this); + + double aResult = 0; + if (aProcessMessage->isProcessed()) { + const std::list& aParamsList = aProcessMessage->params(); + aResult = aProcessMessage->result(); + theError = aProcessMessage->error(); + /* compare the list of parameters to store if changed + AttributeRefListPtr aParams = reflist(ARGUMENTS_ID()); + bool aDifferent = aParams->size() != (int)aParamsList.size(); + if (!aDifferent) { + std::list::const_iterator aNewIter = aParamsList.begin(); + std::list anOldList = aParams->list(); + std::list::const_iterator anOldIter = anOldList.begin(); + for(; !aDifferent && aNewIter != aParamsList.end(); aNewIter++, anOldIter++) { + if (*aNewIter != *anOldIter) + aDifferent = true; + } + } + if (aDifferent) { + aParams->clear(); + std::list::const_iterator aNewIter = aParamsList.begin(); + for(; aNewIter != aParamsList.end(); aNewIter++) { + aParams->append(*aNewIter); + } + }*/ + } else { // error: python interpreter is not active + theError = "Python interpreter is not available"; } + return aResult; +} + + +bool BuildPlugin_Interpolation::updateExpression(double& aValue) +{ + std::wstring anExpression = string(EXPRESSION_ID())->isUValue() ? + Locale::Convert::toWString(string(EXPRESSION_ID())->valueU()) : + Locale::Convert::toWString(string(EXPRESSION_ID())->value()); - setResult(aResultBody); + std::string outErrorMessage; + aValue = evaluate(anExpression, outErrorMessage); + + data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage); + if (!outErrorMessage.empty()) + return false; + + /*ResultParameterPtr aParam = document()->createParameter(data()); + AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE()); + aValueAttribute->setValue(aValue); + setResult(aParam);*/ + + return true; } + +void BuildPlugin_Interpolation::updateName() +{ + std::wstring aName = string(VARIABLE_ID())->isUValue() ? + Locale::Convert::toWString(string(VARIABLE_ID())->valueU()) : + Locale::Convert::toWString(string(VARIABLE_ID())->value()); + data()->setName(aName); + + ResultParameterPtr aParam = document()->createParameter(data()); + std::wstring anOldName = aParam->data()->name(); + aParam->data()->setName(aName); + setResult(aParam); + + + // #2474 : if parameter name now hides/shows the higher level parameter name, + // update the depended expressions + DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); + if (aParam->document() != aRootDoc) { + std::list aNames; // collect names in the root document that must be checked + aNames.push_back(aName); + if (anOldName != aName) { + aNames.push_back(anOldName); + } + std::list::iterator aNIter = aNames.begin(); + for (; aNIter != aNames.end(); aNIter++) { + double aValue; + ResultParameterPtr aRootParam; + FeaturePtr aThis = + std::dynamic_pointer_cast(string(VARIABLE_ID())->owner()); + if (ModelAPI_Tools::findVariable(aThis, *aNIter, aValue, aRootParam, aRootDoc)) { + std::set > anAttributes = + aRootParam->data()->refsToMe(); + std::set >::const_iterator anAttributeIt = + anAttributes.cbegin(); + for (; anAttributeIt != anAttributes.cend(); ++anAttributeIt) { + const AttributePtr& anAttribute = *anAttributeIt; + ModelAPI_AttributeEvalMessage::send(anAttribute, NULL); + } + } + } + } +} \ No newline at end of file diff --git a/src/BuildPlugin/BuildPlugin_Interpolation.h b/src/BuildPlugin/BuildPlugin_Interpolation.h index 912cc126f..fac6d6946 100644 --- a/src/BuildPlugin/BuildPlugin_Interpolation.h +++ b/src/BuildPlugin/BuildPlugin_Interpolation.h @@ -39,6 +39,25 @@ public: static const std::string MY_ID("Interpolation"); return MY_ID; } + /// Attribute name of creation method. + inline static const std::string& CREATION_METHODE_ID() + { + static const std::string MY_CREATION_METHODE_ID("interpolation_method"); + return MY_CREATION_METHODE_ID; + } + /// Attribute name of creation method by selection + inline static const std::string& CREATION_METHODE_BY_SELECTION_ID() + { + static const std::string MY_CREATION_METHODE_BY_SELECTION_ID("by_selection"); + return MY_CREATION_METHODE_BY_SELECTION_ID; + } + + /// Attribute name of creation method analytical + inline static const std::string& CREATION_METHODE_ANALYTICAL_ID() + { + static const std::string MY_CREATION_METHODE_ANALYTICAL_ID("analytical"); + return MY_CREATION_METHODE_ANALYTICAL_ID; + } /// Attribute name of base objects. inline static const std::string& BASE_OBJECTS_ID() @@ -81,6 +100,68 @@ public: static const std::string MY_TANGENT_END_ID("tangent_end"); return MY_TANGENT_END_ID; } + /// Attribute name of x(t) equation. + inline static const std::string& XT_ID() + { + static const std::string MY_XT_ID("xt"); + return MY_XT_ID; + } + + /// Attribute name of y(t) equation. + inline static const std::string& YT_ID() + { + static const std::string MY_YT_ID("yt"); + return MY_YT_ID; + } + + /// Attribute name of z(t) equation. + inline static const std::string& ZT_ID() + { + static const std::string MY_ZT_ID("zt"); + return MY_ZT_ID; + } + + /// Attribute name of min t. + inline static const std::string& MINT_ID() + { + static const std::string MY_MINT_ID("mint"); + return MY_MINT_ID; + } + + /// Attribute name of max t. + inline static const std::string& MAXT_ID() + { + static const std::string MY_MAXT_ID("maxt"); + return MY_MAXT_ID; + } + + /// attribute of parameter name + inline static const std::string& VARIABLE_ID() + { + static const std::string MY_VARIABLE_ID("variable"); + return MY_VARIABLE_ID; + } + + /// attribute of parameter expression + inline static const std::string& EXPRESSION_ID() + { + static const std::string MY_EXPRESSION_ID("expression"); + return MY_EXPRESSION_ID; + } + + /// attribute of parameter expression error + inline static const std::string& EXPRESSION_ERROR_ID() + { + static const std::string MY_EXPRESSION_ERROR_ID("ExpressionError"); + return MY_EXPRESSION_ERROR_ID; + } + + /// Attribute name of max t. + inline static const std::string& NUMSTEP_ID() + { + static const std::string MY_NUMSTEP_ID("numstep"); + return MY_NUMSTEP_ID; + } /// Default value of the closed attribute inline static bool CLOSED_DEFAULT() { return false; } @@ -97,6 +178,14 @@ public: /// Creates a new part document if needed. BUILDPLUGIN_EXPORT virtual void execute(); + + protected: + /// Evaluates theExpression and returns its value. + double evaluate(const std::wstring& theExpression, std::string& theError); + + bool updateExpression(double& aValue); + void updateName(); + }; #endif diff --git a/src/BuildPlugin/BuildPlugin_Plugin.cpp b/src/BuildPlugin/BuildPlugin_Plugin.cpp index e18d092cf..54ac6c7d0 100644 --- a/src/BuildPlugin/BuildPlugin_Plugin.cpp +++ b/src/BuildPlugin/BuildPlugin_Plugin.cpp @@ -59,6 +59,9 @@ BuildPlugin_Plugin::BuildPlugin_Plugin() new BuildPlugin_ValidatorFillingSelection()); aFactory->registerValidator("BuildPlugin_ValidatorBaseForVertex", new BuildPlugin_ValidatorBaseForVertex()); + aFactory->registerValidator("BuildPlugin_ValidatorExpressionInterpolation", + new BuildPlugin_ValidatorExpressionInterpolation()); + // Register this plugin. ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/BuildPlugin/BuildPlugin_Validators.cpp b/src/BuildPlugin/BuildPlugin_Validators.cpp index ac454e620..be26b1196 100644 --- a/src/BuildPlugin/BuildPlugin_Validators.cpp +++ b/src/BuildPlugin/BuildPlugin_Validators.cpp @@ -20,6 +20,7 @@ #include "BuildPlugin_Validators.h" #include +#include #include #include @@ -39,6 +40,8 @@ #include #include +#include + #include #include @@ -569,3 +572,28 @@ bool BuildPlugin_ValidatorBaseForVertex::isValid(const AttributePtr& theAttribut return true; } + + +bool BuildPlugin_ValidatorExpressionInterpolation::isValid(const AttributePtr& theAttribute, + const std::list& /*theArguments*/, + Events_InfoMessage& theError) const +{ + FeaturePtr aFeature = std::dynamic_pointer_cast(theAttribute->owner()); + + AttributeStringPtr aStrAttr = + std::dynamic_pointer_cast(theAttribute); + if (!aStrAttr->isInitialized()) { + theError = "Attribute \"%1\" is not initialized."; + theError.arg(aStrAttr->id()); + return false; + } + bool isEmptyExpr = aStrAttr->value().empty(); + if (isEmptyExpr) { + theError = "Expression is empty."; + return false; + } + + theError = aFeature->string(BuildPlugin_Interpolation::EXPRESSION_ERROR_ID())->value(); + return theError.empty(); +} + diff --git a/src/BuildPlugin/BuildPlugin_Validators.h b/src/BuildPlugin/BuildPlugin_Validators.h index 9d4670ef0..ffb8b0fbb 100644 --- a/src/BuildPlugin/BuildPlugin_Validators.h +++ b/src/BuildPlugin/BuildPlugin_Validators.h @@ -133,4 +133,26 @@ public: Events_InfoMessage& theError) const; }; +/** + * \class BuildPlugin_ValidatorExpression + * \ingroup Validators + * \brief Validator for the expression of parameter. + */ +class BuildPlugin_ValidatorExpressionInterpolation +: public ModelAPI_AttributeValidator +{ + public: + + /** + * \brief Returns true if attribute has a valid parameter expression. + * \param theAttribute the checked attribute + * \param theArguments arguments of the attribute + * \param theError the error string message if validation fails + */ + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + + #endif diff --git a/src/BuildPlugin/CMakeLists.txt b/src/BuildPlugin/CMakeLists.txt index ca262f1fb..e13730bea 100644 --- a/src/BuildPlugin/CMakeLists.txt +++ b/src/BuildPlugin/CMakeLists.txt @@ -23,6 +23,7 @@ INCLUDE(UnitTest) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events ${PROJECT_SOURCE_DIR}/src/Config ${PROJECT_SOURCE_DIR}/src/ModelAPI + ${PROJECT_SOURCE_DIR}/src/Locale ${PROJECT_SOURCE_DIR}/src/GeomAPI ${PROJECT_SOURCE_DIR}/src/GeomAlgoAPI ${PROJECT_SOURCE_DIR}/src/GeomDataAPI diff --git a/src/BuildPlugin/interpolation_widget.xml b/src/BuildPlugin/interpolation_widget.xml index 5a0acee2f..10efe19e7 100644 --- a/src/BuildPlugin/interpolation_widget.xml +++ b/src/BuildPlugin/interpolation_widget.xml @@ -1,32 +1,70 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +