]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
functional version
authorJérôme <jerome.lucas@cesgenslab.fr>
Thu, 8 Oct 2020 20:28:06 +0000 (22:28 +0200)
committerJérôme <jerome.lucas@cesgenslab.fr>
Thu, 3 Dec 2020 13:49:55 +0000 (14:49 +0100)
15 files changed:
src/BuildPlugin/BuildPlugin_EvalListener.cpp [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_EvalListener.h [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_Interpolation.cpp
src/BuildPlugin/BuildPlugin_Interpolation.h
src/BuildPlugin/BuildPlugin_Plugin.cpp
src/BuildPlugin/BuildPlugin_Plugin.h
src/BuildPlugin/BuildPlugin_PyInterp.cpp [new file with mode: 0644]
src/BuildPlugin/BuildPlugin_PyInterp.h [new file with mode: 0644]
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/icons/feature_interpolation_analytical.png.png [new file with mode: 0644]
src/BuildPlugin/icons/feature_interpolation_by_selection.png [new file with mode: 0644]
src/BuildPlugin/interpolation_widget.xml
src/BuildPlugin/plugin-Build.xml
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h

diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.cpp b/src/BuildPlugin/BuildPlugin_EvalListener.cpp
new file mode 100644 (file)
index 0000000..73b4292
--- /dev/null
@@ -0,0 +1,294 @@
+// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <pyconfig.h>
+
+#include <BuildPlugin_EvalListener.h>
+#include <BuildPlugin_Interpolation.h>
+#include <BuildPlugin_PyInterp.h>
+
+#include <Events_InfoMessage.h>
+
+#include <Locale_Convert.h>
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeTables.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeValidator.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Point2D.h>
+
+#include <string>
+#include <set>
+#include <sstream>
+
+//------------------------------------------------------------------------------
+// Tools
+
+std::wstring toString(double theValue)
+{
+  std::wostringstream sstream;
+  // write value in scientific format with 16 digits,
+  // thus, not check the dot position
+  sstream.precision(16);
+  sstream << std::scientific << theValue;
+  return sstream.str();
+}
+
+std::set<std::wstring> toSet(const std::list<std::wstring>& theContainer)
+{
+  return std::set<std::wstring>(theContainer.begin(), theContainer.end());
+}
+
+//------------------------------------------------------------------------------
+
+BuildPlugin_EvalListener::BuildPlugin_EvalListener()
+{
+  Events_Loop* aLoop = Events_Loop::loop();
+
+  aLoop->registerListener(this, ModelAPI_AttributeEvalMessage::eventId(), NULL, true);
+  aLoop->registerListener(this, ModelAPI_BuildEvalMessage::eventId(), NULL, true);
+  aLoop->registerListener(this, ModelAPI_ComputePositionsMessage::eventId(), NULL, true);
+
+  myInterp = std::shared_ptr<BuildPlugin_PyInterp>(new BuildPlugin_PyInterp());
+  myInterp->initialize();
+}
+
+BuildPlugin_EvalListener::~BuildPlugin_EvalListener()
+{
+}
+
+double BuildPlugin_EvalListener::evaluate(FeaturePtr theParameter,
+  const std::wstring& theExpression, std::string& theError,
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+  const bool theIsParameter)
+{
+  std::list<std::wstring> anExprParams = myInterp->compile(theExpression);
+  // find expression's params in the model
+  std::list<std::wstring> aContext;
+  std::list<std::wstring>::iterator it = anExprParams.begin();
+  for ( ; it != anExprParams.end(); it++) {
+    double aValue;
+    ResultParameterPtr aParamRes;
+    // If variable does not exist python interpreter will generate an error. It is OK.
+    // But due to the issue 1479 it should not check the history position of parameters relatively
+    // to feature that contains expression
+    if (!ModelAPI_Tools::findVariable(theIsParameter ? theParameter : FeaturePtr(),
+      *it, aValue, aParamRes, theParameter->document()))
+      continue;
+
+    if (theIsParameter)
+      theParamsList.push_back(aParamRes);
+    aContext.push_back(*it + L"=" + toString(aValue));
+  }
+  myInterp->extendLocalContext(aContext);
+  double result = myInterp->evaluate(theExpression, theError);
+  myInterp->clearLocalContext();
+  return result;
+}
+
+
+void BuildPlugin_EvalListener::processEvent(
+    const std::shared_ptr<Events_Message>& theMessage)
+{
+  if (!theMessage.get())
+    return;
+
+  if (theMessage->eventID() == ModelAPI_AttributeEvalMessage::eventId()) {
+    processEvaluationEvent(theMessage);
+  } else if (theMessage->eventID() == ModelAPI_BuildEvalMessage::eventId()) {
+    std::shared_ptr<ModelAPI_BuildEvalMessage> aMsg =
+      std::dynamic_pointer_cast<ModelAPI_BuildEvalMessage>(theMessage);
+    FeaturePtr aParam = aMsg->parameter();
+
+    AttributeStringPtr anVariableAttr = aParam->string(BuildPlugin_Interpolation::VARIABLE_ID());
+    std::wstring anVar = anVariableAttr->isUValue() ?
+        Locale::Convert::toWString(anVariableAttr->valueU()) :
+        Locale::Convert::toWString(anVariableAttr->value());
+    AttributeTablesPtr anValueAttr = aParam->tables(BuildPlugin_Interpolation::VALUE_ID());
+    std::string anError;
+    std::list<std::shared_ptr<ModelAPI_ResultParameter> > aParamsList;
+        
+    AttributeStringPtr anExprAttr; 
+    ModelAPI_AttributeTables::Value aVal;
+    for(int step =0; step < anValueAttr->rows(); step++ ){
+        anExprAttr = aParam->string(BuildPlugin_Interpolation::XT_ID());
+        std::wstring anExp = anExprAttr->isUValue() ?
+        Locale::Convert::toWString(anExprAttr->valueU()) :
+        Locale::Convert::toWString(anExprAttr->value());
+        aVal.myDouble = evaluate(anVar,anValueAttr->value(step,0).myDouble,aParam, anExp, anError, aParamsList, true);
+        anValueAttr->setValue(aVal,step,1);     
+        
+        anExprAttr = aParam->string(BuildPlugin_Interpolation::YT_ID());
+        anExp = anExprAttr->isUValue() ?
+        Locale::Convert::toWString(anExprAttr->valueU()) :
+        Locale::Convert::toWString(anExprAttr->value());
+        aVal.myDouble = evaluate(anVar,anValueAttr->value(step,0).myDouble,aParam, anExp, anError, aParamsList, true);
+        anValueAttr->setValue(aVal,step,2);
+
+        anExprAttr = aParam->string(BuildPlugin_Interpolation::ZT_ID());
+        anExp = anExprAttr->isUValue() ?
+        Locale::Convert::toWString(anExprAttr->valueU()) :
+        Locale::Convert::toWString(anExprAttr->value());
+        aVal.myDouble = evaluate(anVar,anValueAttr->value(step,0).myDouble,aParam, anExp, anError, aParamsList, true);
+        anValueAttr->setValue(aVal,step,3);
+    }
+
+    aMsg->setResults(aParamsList, 1, anError);
+  } else if (theMessage->eventID() == ModelAPI_ComputePositionsMessage::eventId()) {
+    std::shared_ptr<ModelAPI_ComputePositionsMessage> aMsg =
+      std::dynamic_pointer_cast<ModelAPI_ComputePositionsMessage>(theMessage);
+    aMsg->setPositions(myInterp->positions(aMsg->expression(), aMsg->parameter()));
+  }
+}
+
+double BuildPlugin_EvalListener::evaluate(
+  std::wstring& theVariable, 
+  double theValueVariable,
+  FeaturePtr theParameter,
+  const std::wstring& theExpression, 
+  std::string& theError,
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+  const bool theIsParameter)
+{
+  std::list<std::wstring> anExprParams = myInterp->compile(theExpression);
+  // find expression's params in the model
+  std::list<std::wstring> aContext;
+  std::list<std::wstring>::iterator it = anExprParams.begin();
+  for ( ; it != anExprParams.end(); it++) {
+    double aValue;
+    ResultParameterPtr aParamRes;
+    // If variable does not exist python interpreter will generate an error. It is OK.
+    // But due to the issue 1479 it should not check the history position of parameters relatively
+    // to feature that contains expression
+    if (!ModelAPI_Tools::findVariable(theIsParameter ? theParameter : FeaturePtr(),
+      *it, aValue, aParamRes, theParameter->document()))
+      continue;
+
+    if (theIsParameter)
+      theParamsList.push_back(aParamRes);
+    aContext.push_back(*it + L"=" + toString(aValue));
+  }
+  aContext.push_back(theVariable + L"=" + toString(theValueVariable));
+  myInterp->extendLocalContext(aContext);
+  double result = myInterp->evaluate(theExpression, theError);
+  myInterp->clearLocalContext();
+  return result;
+}
+
+void BuildPlugin_EvalListener::processEvaluationEvent(
+    const std::shared_ptr<Events_Message>& theMessage)
+{
+  std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
+      std::dynamic_pointer_cast<ModelAPI_AttributeEvalMessage>(theMessage);
+
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> > aParamsList;
+  FeaturePtr aParamFeature =
+    std::dynamic_pointer_cast<ModelAPI_Feature>(aMessage->attribute()->owner());
+  if (aMessage->attribute()->attributeType() == ModelAPI_AttributeInteger::typeId()) {
+    AttributeIntegerPtr anAttribute =
+        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aMessage->attribute());
+    std::string anError;
+    int aValue = (int)evaluate(aParamFeature, anAttribute->text(), anError, aParamsList);
+    bool isValid = anError.empty();
+    if (isValid)
+      anAttribute->setCalculatedValue(aValue);
+    anAttribute->setUsedParameters(isValid ?
+      toSet(myInterp->compile(anAttribute->text())) : std::set<std::wstring>());
+    anAttribute->setExpressionInvalid(!isValid);
+    anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError);
+  } else
+  if (aMessage->attribute()->attributeType() == ModelAPI_AttributeDouble::typeId()) {
+    AttributeDoublePtr anAttribute =
+        std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aMessage->attribute());
+    std::string anError;
+    double aValue = evaluate(aParamFeature, anAttribute->text(), anError, aParamsList);
+    bool isValid = anError.empty();
+    if (isValid)
+      anAttribute->setCalculatedValue(aValue);
+    anAttribute->setUsedParameters(isValid ?
+      toSet(myInterp->compile(anAttribute->text())) : std::set<std::wstring>());
+    anAttribute->setExpressionInvalid(!isValid);
+    anAttribute->setExpressionError(anAttribute->text().empty() ? "" : anError);
+  } else
+  if (aMessage->attribute()->attributeType() == GeomDataAPI_Point::typeId()) {
+    AttributePointPtr anAttribute =
+        std::dynamic_pointer_cast<GeomDataAPI_Point>(aMessage->attribute());
+    std::wstring aText[] = {
+      anAttribute->textX(),
+      anAttribute->textY(),
+      anAttribute->textZ()
+    };
+    double aCalculatedValue[] = {
+      anAttribute->x(),
+      anAttribute->y(),
+      anAttribute->z()
+    };
+    for (int i = 0; i < 3; ++i) {
+      std::string anError;
+      double aValue = evaluate(aParamFeature, aText[i], anError, aParamsList);
+      bool isValid = anError.empty();
+      if (isValid) aCalculatedValue[i] = aValue;
+      anAttribute->setUsedParameters(i,
+        isValid ? toSet(myInterp->compile(aText[i])) : std::set<std::wstring>());
+      anAttribute->setExpressionInvalid(i, !isValid);
+      anAttribute->setExpressionError(i, aText[i].empty() ? "" : anError);
+    }
+    anAttribute->setCalculatedValue(aCalculatedValue[0],
+                                    aCalculatedValue[1],
+                                    aCalculatedValue[2]);
+  } else
+  if (aMessage->attribute()->attributeType() == GeomDataAPI_Point2D::typeId()) {
+    AttributePoint2DPtr anAttribute =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMessage->attribute());
+    std::wstring aText[] = {
+      anAttribute->textX(),
+      anAttribute->textY()
+    };
+    double aCalculatedValue[] = {
+      anAttribute->x(),
+      anAttribute->y()
+    };
+    for (int i = 0; i < 2; ++i) {
+      std::string anError;
+      double aValue = evaluate(aParamFeature, aText[i], anError, aParamsList);
+      bool isValid = anError.empty();
+      if (isValid) aCalculatedValue[i] = aValue;
+      anAttribute->setUsedParameters(i,
+        isValid ? toSet(myInterp->compile(aText[i])) : std::set<std::wstring>());
+      anAttribute->setExpressionInvalid(i, !isValid);
+      anAttribute->setExpressionError(i, aText[i].empty() ? "" : anError);
+    }
+    anAttribute->setCalculatedValue(aCalculatedValue[0],
+                                    aCalculatedValue[1]);
+  }
+}
+
+void BuildPlugin_EvalListener::initDataModel()
+{
+  myInterp->runString("import salome_iapp;salome_iapp.register_module_in_study(\"Shaper\")");
+}
diff --git a/src/BuildPlugin/BuildPlugin_EvalListener.h b/src/BuildPlugin/BuildPlugin_EvalListener.h
new file mode 100644 (file)
index 0000000..3698e6f
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef SRC_BUILDPLUGIN_EVALLISTENER_H_
+#define SRC_BUILDPLUGIN_EVALLISTENER_H_
+
+#include <BuildPlugin.h>
+#include <Events_Loop.h>
+
+class ModelAPI_Attribute;
+class ModelAPI_Document;
+class ModelAPI_Feature;
+class ModelAPI_ResultParameter;
+// JL_CGLB n'existe pas class InitializationPlugin_Parameter;
+class BuildPlugin_PyInterp;
+
+/**
+ * \class BuildPlugin_EvalListener
+ * \ingroup Plugins
+ * \brief Class which process the events from the event loop.
+ */
+class BuildPlugin_EvalListener : public Events_Listener
+{
+ public:
+  BUILDPLUGIN_EXPORT BuildPlugin_EvalListener();
+  BUILDPLUGIN_EXPORT virtual ~BuildPlugin_EvalListener();
+
+  /// Reimplemented from Events_Listener::processEvent().
+  BUILDPLUGIN_EXPORT
+    virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
+
+  // performs the python call to initialize high level data model on internal data model creation
+  void initDataModel();
+
+ protected:
+  /// Evaluates theExpression and returns its value.
+  double evaluate(std::wstring& theVariable, 
+                  double theValueVariable,std::shared_ptr<ModelAPI_Feature> theParameter,
+                  const std::wstring& theExpression, std::string& theError,
+                  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+                  const bool theIsParameter = false);
+
+  double evaluate(std::shared_ptr<ModelAPI_Feature> theParameter,
+                  const std::wstring& theExpression, std::string& theError,
+                  std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+                  const bool theIsParameter = false);
+
+  /// Processes Evaluation event.
+  void processEvaluationEvent(const std::shared_ptr<Events_Message>& theMessage);
+
+ private:
+  std::shared_ptr<BuildPlugin_PyInterp> myInterp;
+};
+
+#endif /* SRC_BUILDPLUGIN_EVALLISTENER_H_ */
index cffa63c576c09c24750bc6f5ceb0f3e78cf4c635..ab0dec57ae7cc59b66728765eab0d76dfca94106 100644 (file)
@@ -24,6 +24,7 @@
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeTables.h>
 
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 #include <GeomAPI_ShapeExplorer.h>
 #include <ModelAPI_Tools.h>
 
+#include <ModelAPI_Expression.h>
+
 #include <algorithm>
 
 #include <iostream>
+#include <sstream>
 
-std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
-    size_t start_pos = 0;
-    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
-        str.replace(start_pos, from.length(), to);
-        start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
-    }
-    return str;
-}
 
 //=================================================================================================
 BuildPlugin_Interpolation::BuildPlugin_Interpolation()
 {
+   
 }
 
 //=================================================================================================
@@ -82,6 +79,7 @@ void BuildPlugin_Interpolation::initAttributes()
   data()->addAttribute(EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
   data()->addAttribute(EXPRESSION_ERROR_ID(), ModelAPI_AttributeString::typeId());
   data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(VALUE_ID(), ModelAPI_AttributeTables::typeId());
   data()->string(EXPRESSION_ERROR_ID())->setIsArgument(false);
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ERROR_ID());
 
@@ -96,6 +94,7 @@ void BuildPlugin_Interpolation::initAttributes()
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CREATION_METHODE_BY_SELECTION_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXPRESSION_ID());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VARIABLE_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), VALUE_ID());
 
   data()->addAttribute(ARGUMENTS_ID(), ModelAPI_AttributeRefList::typeId());
   data()->reflist(ARGUMENTS_ID())->setIsArgument(false);
@@ -104,8 +103,44 @@ void BuildPlugin_Interpolation::initAttributes()
 }
 
 void BuildPlugin_Interpolation::attributeChanged(const std::string& theID)
-{
+{ 
+  if( (theID == XT_ID() 
+    || theID == YT_ID() 
+    || theID == ZT_ID() 
+    || theID == MINT_ID()
+    || theID == MAXT_ID()
+    || theID == NUMSTEP_ID())
+    && string(XT_ID())->value() !=""
+    && string(YT_ID())->value() !=""
+    && string(ZT_ID())->value() !=""
+    ){
+    updateCoods();
+  }
+    
+}
+
+void BuildPlugin_Interpolation::updateCoods()
+{ 
+    std::wstring exp;
+    double aMint = real(MINT_ID())->value(); 
+    double aMaxt = real(MAXT_ID())->value();
+    int aNbrStep = integer(NUMSTEP_ID())->value(); 
+    double scale = (aMaxt - aMint )/aNbrStep; 
+    string(VARIABLE_ID())->setValue("t");
 
+    tables(VALUE_ID())->setSize(aNbrStep,4);
+    for( int step = 0; step < aNbrStep; step++ ){
+      ModelAPI_AttributeTables::Value aVal;
+      aVal.myDouble = step * scale + aMint;
+      tables(VALUE_ID())->setValue(aVal,step,0);   
+    }
+
+    outErrorMessage="";
+    
+    evaluate(outErrorMessage);
+    if (!outErrorMessage.empty()){
+     std::cout << L"outErrorMessage= " << outErrorMessage << std::endl;
+    }
 }
 
 //=================================================================================================
@@ -196,148 +231,91 @@ void BuildPlugin_Interpolation::execute()
 
   }else
   {
-    double aMint = real(MINT_ID())->value(); 
-    double aMaxt = real(MAXT_ID())->value();
-    int aNbrStep = integer(NUMSTEP_ID())->value(); 
-    double scale = (aMaxt - aMint )/aNbrStep; 
-    std::cout << "aMint = " << aMint << std::endl;
-    std::cout << "aMaxt = " << aMaxt << std::endl;
-    std::cout << "aNbrStep = " << aNbrStep << std::endl;
-    std::cout << "scale = " << scale << std::endl;
-
+    if(   string( XT_ID())->value() == ""
+        ||string( YT_ID())->value() == ""
+        ||string( ZT_ID())->value() == "")
+      return; 
+    
+    if (!outErrorMessage.empty()){
+      setError("Error: Python interpreter " + outErrorMessage);
+      return;
+    }
+    AttributeTablesPtr table = tables( VALUE_ID() ); 
     std::list<std::vector<double> > aCoodPoints;
-    for( int step = 0; step < aNbrStep; step++ ){
-      std::vector<double> coodPoint;
-      double result; 
-      double value = step * scale + aMint; 
+    for( int step = 0; step < table->rows() ; step++ ){
+      std::vector<double> coodPoint; 
+      ModelAPI_AttributeTables::Value value;
       //x
-      std::string exp = string( XT_ID())->value();
-      exp = ReplaceAll(exp,"t", std::to_string(value) ); 
-      string(EXPRESSION_ID())->setValue(exp);
-      if (!updateExpression(result))
-        setError("Expression error.", false);
-      coodPoint.push_back(result); 
+      value = table->value(step, 1); 
+      coodPoint.push_back( value.myDouble ); 
       //y
-      exp = string( YT_ID())->value();
-      exp = ReplaceAll(exp,"t", std::to_string(value) ); 
-      string(EXPRESSION_ID())->setValue(exp);
-      if (!updateExpression(result))
-        setError("Expression error.", false);
-      coodPoint.push_back(result); 
-      //Z
-      exp = string( ZT_ID())->value();
-      exp = ReplaceAll(exp,"t", std::to_string(value) ); 
-      string(EXPRESSION_ID())->setValue(exp);
-      if (!updateExpression(result))
-        setError("Expression error.", false);
-      coodPoint.push_back(result);
+      value = table->value(step, 2); 
+      coodPoint.push_back( value.myDouble ); 
+      //
+      value = table->value(step, 3); 
+      coodPoint.push_back( value.myDouble ); 
 
       aCoodPoints.push_back(coodPoint);
     }
-
+    
     std::list<GeomPointPtr> aPoints;
+    std::list<GeomVertexPtr> aVertices;
     std::list<std::vector<double> >::const_iterator aItCoodPoints = aCoodPoints.begin();
  
     for( ; aItCoodPoints != aCoodPoints.end(); ++aItCoodPoints ){
       std::cout << "cood = " << "(" << (*aItCoodPoints)[0] << ", "<< 
                                        (*aItCoodPoints)[1] << ", "<< 
                                        (*aItCoodPoints)[2] << " ) "<<  std::endl;
-      std::shared_ptr<GeomAPI_Vertex> vertex = 
+      GeomVertexPtr vertex = 
           GeomAlgoAPI_PointBuilder::vertex( (*aItCoodPoints)[0],
                                             (*aItCoodPoints)[1],
                                             (*aItCoodPoints)[2]);
       aPoints.push_back (vertex->point()); 
+      aVertices.push_back (vertex);
     } 
+    /* 
     GeomDirPtr aDirStart(new GeomAPI_Dir( aCoodPoints.front()[0],
                                         aCoodPoints.front()[1], 
                                         aCoodPoints.front()[2]));
     GeomDirPtr aDirEnd(new GeomAPI_Dir( aCoodPoints.back()[0],
                                         aCoodPoints.back()[1], 
-                                        aCoodPoints.back()[2]));
+                                        aCoodPoints.back()[2]));*/
     // Create curve from points
     GeomEdgePtr anEdge =
-      GeomAlgoAPI_CurveBuilder::edge(aPoints, false, true, aDirStart, aDirEnd);
+      GeomAlgoAPI_CurveBuilder::edge(aPoints, false, true,GeomDirPtr(),GeomDirPtr()); //aDirStart, aDirEnd);
     if (!anEdge.get()) {
       setError("Error: Result curve is empty.");
       return;
     }
-
-    // Store result.
     ResultBodyPtr aResultBody = document()->createBody(data());
-    /*std::set<GeomShapePtr>::const_iterator aContextIt = aContexts.begin();
-    for (; aContextIt != aContexts.end(); aContextIt++) {
-      aResultBody->storeModified(*aContextIt, anEdge, aContextIt == aContexts.begin());
-    }
-    std::list<GeomPointPtr>::const_iterator aPointsIt = aPoints.begin();
-    GeomAPI_ShapeExplorer anExp(anEdge, GeomAPI_Shape::EDGE);
-    for (; anExp.more() && aPointsIt != aPoints.cend(); anExp.next(), ++aPointsIt) {
-      GeomShapePtr aPoint = std::dynamic_pointer_cast<GeomAPI_Shape>( *aPointsIt );
-      GeomShapePtr anEdge = anExp.current();
-      aResultBody->generated(aPoint, anEdge);
-    }*/
+    // Load the result
+    aResultBody->store(anEdge);
     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);
+      aVertexIndex++;
     }
-
+   
     setResult(aResultBody);
         
   }
 
 }
 
-double BuildPlugin_Interpolation::evaluate(const std::wstring& /*theExpression*/,
-                                            std::string& theError)
+void  BuildPlugin_Interpolation::evaluate(std::string& theError)
 {
   FeaturePtr aMyPtr = std::dynamic_pointer_cast<ModelAPI_Feature>(data()->owner());
-  std::shared_ptr<ModelAPI_ParameterEvalMessage> aProcessMessage =
-    ModelAPI_ParameterEvalMessage::send(aMyPtr, this);
+  std::shared_ptr<ModelAPI_BuildEvalMessage> aProcessMessage =
+    ModelAPI_BuildEvalMessage::send(aMyPtr, this);
 
-  double aResult = 0;
   if (aProcessMessage->isProcessed()) {
-    const std::list<ResultParameterPtr>& 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<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
-      std::list<ObjectPtr> anOldList = aParams->list();
-      std::list<ObjectPtr>::const_iterator anOldIter = anOldList.begin();
-      for(; !aDifferent && aNewIter != aParamsList.end(); aNewIter++, anOldIter++) {
-        if (*aNewIter != *anOldIter)
-          aDifferent = true;
-      }
-    }
-    if (aDifferent) {
-      aParams->clear();
-      std::list<ResultParameterPtr>::const_iterator aNewIter = aParamsList.begin();
-      for(; aNewIter != aParamsList.end(); aNewIter++) {
-        aParams->append(*aNewIter);
-      }
-    }*/
+    std::cout << "theError= " << theError << std::endl;
   } else { // error: python interpreter is not active
     theError = "Python interpreter is not available";
   }
-  return aResult;
 }
 
 
-bool BuildPlugin_Interpolation::updateExpression(double& result)
-{
-  std::wstring anExpression = string(EXPRESSION_ID())->isUValue() ?
-      Locale::Convert::toWString(string(EXPRESSION_ID())->valueU()) :
-      Locale::Convert::toWString(string(EXPRESSION_ID())->value());
-
-  std::string outErrorMessage;
-  result= evaluate(anExpression, outErrorMessage);
-
-  data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage);
-  if (!outErrorMessage.empty())
-    return false;
-  
-  std::cout << "result = " << result << std::endl;
-  return true;
-}
index 899819510c710fc55a466f5c5cc068d96becd62d..64181cb3b391f0a17d0fd796b12a3ff0885d02e9 100644 (file)
@@ -141,6 +141,13 @@ public:
     static const std::string MY_VARIABLE_ID("variable");
     return MY_VARIABLE_ID;
   }
+
+  /// attribute of parameter name
+  inline static const std::string& VALUE_ID()
+  {
+    static const std::string MY_VALUE_ID("value");
+    return MY_VALUE_ID;
+  }
   
   /// attribute of parameter expression
   inline static const std::string& EXPRESSION_ID()
@@ -190,9 +197,12 @@ public:
 
   protected:
   /// Evaluates theExpression and returns its value.
-  double evaluate(const std::wstring& theExpression, std::string& theError);
+  void evaluate(std::string& theError);
+
+  void updateCoods();
 
-  bool updateExpression(double& result);
+  std::list<double> aCoodPoints[3];
+  std::string outErrorMessage;
 
 };
 
index 54ac6c7d0e5acde742d0fabcc346c63af0edfaa7..45893e4c5656daeb7ffee8426269ee654837ddad 100644 (file)
@@ -36,6 +36,9 @@
 #include <BuildPlugin_Filling.h>
 #include <BuildPlugin_Validators.h>
 
+#include <BuildPlugin_EvalListener.h>
+
+
 // the only created instance of this plugin
 static BuildPlugin_Plugin* MY_INSTANCE = new BuildPlugin_Plugin();
 
@@ -62,9 +65,11 @@ BuildPlugin_Plugin::BuildPlugin_Plugin()
   aFactory->registerValidator("BuildPlugin_ValidatorExpressionInterpolation",
                               new BuildPlugin_ValidatorExpressionInterpolation());
   
-
   // Register this plugin.
   ModelAPI_Session::get()->registerPlugin(this);
+
+  myEvalListener =
+    std::shared_ptr<BuildPlugin_EvalListener>(new BuildPlugin_EvalListener());
 }
 
 //=================================================================================================
index bafd517021df53699106c7defbc6ea593c420f87..4f3f7f62a30709845d1bf02e7b10b233f6f5bc7e 100644 (file)
@@ -25,6 +25,8 @@
 #include <ModelAPI_Plugin.h>
 #include <ModelAPI_Feature.h>
 
+class BuildPlugin_EvalListener;
+
 /// \class BuildPlugin_Plugin
 /// \ingroup Plugins
 /// \brief The main class for management the build features as plugin.
@@ -36,6 +38,9 @@ public:
 
   /// Creates the feature object of this plugin by the feature string ID
   virtual FeaturePtr createFeature(std::string theFeatureID);
+
+ private:
+   std::shared_ptr<BuildPlugin_EvalListener> myEvalListener;
 };
 
 #endif
diff --git a/src/BuildPlugin/BuildPlugin_PyInterp.cpp b/src/BuildPlugin/BuildPlugin_PyInterp.cpp
new file mode 100644 (file)
index 0000000..ae85fd5
--- /dev/null
@@ -0,0 +1,268 @@
+// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <BuildPlugin_PyInterp.h>
+
+#include <Locale_Convert.h>
+
+#include <string>
+#include <stdexcept>
+#include <clocale>
+
+BuildPlugin_PyInterp::BuildPlugin_PyInterp()
+: PyInterp_Interp()
+{
+}
+
+BuildPlugin_PyInterp::~BuildPlugin_PyInterp()
+{
+}
+
+const char* aSearchCode =
+  "import ast\n"
+  "class FindName(ast.NodeVisitor):\n"
+  "    def __init__(self, name):\n"
+  "        self.name = name\n"
+  "    def visit_Name(self, node):\n"
+  "        if node.id == self.name:\n"
+  "            positions.append((node.lineno, node.col_offset))\n"
+  "FindName(name).visit(ast.parse(expression))";
+
+// make the expression be correct for the python interpreter even for the
+// beta=alfa*2 expressions
+static std::wstring adjustExpression(const std::wstring& theExpression) {
+  std::wstring anExpression = theExpression;
+  if (!anExpression.empty() && anExpression.back() == L'=') {
+    anExpression = anExpression.substr(0, anExpression.length() - 1);
+  }
+  return anExpression;
+}
+
+std::list<std::pair<int, int> >
+BuildPlugin_PyInterp::positions(const std::wstring& theExpression,
+                                         const std::wstring& theName)
+{
+  PyLockWrapper lck; // Acquire GIL until the end of the method
+
+  std::list<std::pair<int, int> > aResult;
+
+  // prepare a context
+  PyObject* aContext = PyDict_New();
+  PyDict_SetItemString(aContext, "__builtins__", PyEval_GetBuiltins());
+
+  std::wstring anExpression = adjustExpression(theExpression);
+  // extend aContext with variables
+  PyDict_SetItemString(aContext, "expression",
+      PyUnicode_FromWideChar(anExpression.c_str(), anExpression.size()));
+  PyDict_SetItemString(aContext, "name", PyUnicode_FromWideChar(theName.c_str(), theName.size()));
+  PyDict_SetItemString(aContext, "positions", Py_BuildValue("[]"));
+
+  // run the search code
+  PyObject* aExecResult = PyRun_String(aSearchCode, Py_file_input, aContext, aContext);
+  Py_XDECREF(aExecResult);
+
+  // receive results from context
+  PyObject* aPositions = PyDict_GetItemString(aContext, "positions");
+  for (int anIndex = 0; anIndex < PyList_Size(aPositions); ++anIndex) {
+    PyObject* aPosition = PyList_GetItem(aPositions, anIndex);
+    PyObject* aLineNo = PyTuple_GetItem(aPosition, 0);
+    PyObject* aColOffset = PyTuple_GetItem(aPosition, 1);
+
+    aResult.push_back(
+        std::pair<int, int>((int)PyLong_AsLong(aLineNo),
+                            (int)PyLong_AsLong(aColOffset)));
+  }
+
+  // TODO(spo): after this refCount of the variable is not 0. Is there memory leak?
+  Py_DECREF(aContext);
+
+  return aResult;
+}
+
+
+std::list<std::wstring> BuildPlugin_PyInterp::compile(const std::wstring& theExpression)
+{
+  PyLockWrapper lck; // Acquire GIL until the end of the method
+  std::list<std::wstring> aResult;
+  PyObject *aCodeopModule = PyImport_AddModule("codeop");
+  if(!aCodeopModule) { // Fatal error. No way to go on.
+    PyErr_Print();
+    return aResult;
+  }
+  // support "variable_name=" expression as "variable_name"
+  std::wstring anExpression = adjustExpression(theExpression);
+
+  PyObject *aCodePyObj =
+    PyObject_CallMethod(aCodeopModule, (char*)"compile_command", (char*)"(s)",
+                        Locale::Convert::toString(anExpression).c_str());
+
+  if(!aCodePyObj || aCodePyObj == Py_None || !PyCode_Check(aCodePyObj)) {
+    Py_XDECREF(aCodePyObj);
+    return aResult;
+  }
+
+  PyCodeObject* aCodeObj = (PyCodeObject*) aCodePyObj;
+  std::string aCodeName(PyBytes_AsString(aCodeObj->co_code));
+  // co_names should be tuple, but can be changed in modern versions of python (>2.7.3)
+  if(!PyTuple_Check(aCodeObj->co_names)) {
+    return aResult;
+  }
+
+  size_t params_size = PyTuple_Size(aCodeObj->co_names);
+  if (params_size > 0) {
+    for (size_t i = 0; i < params_size; i++) {
+      PyObject* aParamObj = PyTuple_GetItem(aCodeObj->co_names, i);
+      PyObject* aParamObjStr = PyObject_Str(aParamObj);
+      Py_ssize_t aSize;
+      std::wstring aParamName(PyUnicode_AsWideCharString(aParamObjStr, &aSize));
+      aResult.push_back(aParamName);
+      Py_XDECREF(aParamObjStr);
+    }
+  }
+  Py_XDECREF(aCodeObj);
+  return aResult;
+}
+
+void BuildPlugin_PyInterp::extendLocalContext(const std::list<std::wstring>& theParameters)
+{
+  PyLockWrapper lck; // Acquire GIL until the end of the method
+  if (theParameters.empty())
+    return;
+  std::list<std::wstring>::const_iterator it = theParameters.begin();
+  for ( ; it != theParameters.cend(); it++) {
+    std::string aParamValue = Locale::Convert::toString(*it);
+    simpleRun(aParamValue.c_str(), false);
+  }
+}
+
+void BuildPlugin_PyInterp::clearLocalContext()
+{
+  PyLockWrapper lck;
+  PyDict_Clear(_local_context);
+}
+
+double BuildPlugin_PyInterp::evaluate(const std::wstring& theExpression,
+                                               std::string& theError)
+{
+  // support "variable_name=" expression as "variable_name"
+  std::wstring anExpression = adjustExpression(theExpression);
+
+  PyLockWrapper lck; // Acquire GIL until the end of the method
+  PyCompilerFlags aFlags = {CO_FUTURE_DIVISION};
+  aFlags.cf_flags = CO_FUTURE_DIVISION;
+  PyCodeObject* anExprCode = (PyCodeObject *) Py_CompileStringFlags(
+                                Locale::Convert::toString(anExpression).c_str(),
+                                "<string>", Py_eval_input, &aFlags);
+  if(!anExprCode) {
+    theError = errorMessage();
+    Py_XDECREF(anExprCode);
+    return 0.;
+  }
+
+  PyObject* anEvalResult = PyEval_EvalCode((PyObject *)anExprCode, _global_context, _local_context);
+  if(!anEvalResult) {
+    theError = errorMessage();
+    Py_XDECREF(anExprCode);
+    Py_XDECREF(anEvalResult);
+    return 0.;
+  }
+
+  PyObject* anEvalStrObj = PyObject_Str(anEvalResult);
+  std::string anEvalStr(PyUnicode_AsUTF8(anEvalStrObj));
+  Py_XDECREF(anExprCode);
+  Py_XDECREF(anEvalResult);
+  Py_XDECREF(anEvalStrObj);
+  double result = 0.;
+  try {
+    // set locale due to the #2485
+    std::string aCurLocale = std::setlocale(LC_NUMERIC, 0);
+    std::setlocale(LC_NUMERIC, "C");
+    result = std::stod(anEvalStr);
+    std::setlocale(LC_NUMERIC, aCurLocale.c_str());
+  }
+  catch (const std::invalid_argument&) {
+    theError = "Unable to eval " + anEvalStr;
+  }
+
+  return result;
+}
+
+std::string BuildPlugin_PyInterp::errorMessage()
+{
+  std::string aPyError;
+  if (PyErr_Occurred()) {
+    PyObject *pstr, *ptype, *pvalue, *ptraceback;
+    PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+    PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
+    pstr = PyObject_Str(pvalue);
+    aPyError = std::string(PyUnicode_AsUTF8(pstr));
+    Py_XDECREF(pstr);
+    Py_XDECREF(ptype);
+    Py_XDECREF(pvalue);
+    Py_XDECREF(ptraceback);
+  }
+  return aPyError;
+}
+
+bool BuildPlugin_PyInterp::initContext()
+{
+  PyObject *m = PyImport_AddModule("__main__");  // interpreter main module (module context)
+  if(!m){
+    PyErr_Print();
+    return false;
+  }
+  _global_context = PyModule_GetDict(m);          // get interpreter global variable context
+  Py_INCREF(_global_context);
+  _local_context = PyDict_New();
+  Py_INCREF(_local_context);
+
+  // to avoid "help()" hang in the python console
+  const static char* aHelpTxt = "def help(): print(\"Available modules:\\n"
+    "  salome.shaper.model : higher level access to features and data model\\n"
+    "  BuildAPI            : Build plugin features allowing to build shapes\\n"
+    "  ConfigAPI           : configuration management: preferences and XML properties\\n"
+    "  ConstructionAPI     : Construction plugin for auxiliary features creation\\n"
+    "  EventsAPI           : application events receiving and emitting manager\\n"
+    "  ExchangeAPI         : Exchange plugin with import/export features\\n"
+    "  FeaturesAPI         : Features plugin with general 3D features\\n"
+    "  GeomAlgoAPI         : geometrical algorithms\\n"
+    "  GeomAPI             : geometrical data structures\\n"
+    "  GeomDataAPI         : specific geometrical data structures stored in the data model\\n"
+    "  ModelAPI            : general low-level interface to access data model\\n"
+    "  ModelHighAPI        : general high-level interface to access data model\\n"
+    "  ParametersAPI       : Parameters plugin for parameters feature management\\n"
+    "  PartSetAPI          : PartSet plugin for management Parts features\\n"
+    "  SketchAPI           : Sketch plugin with all sketch features\")";
+
+  PyRun_SimpleString(aHelpTxt);
+
+  return PyRun_SimpleString("from math import *") == 0;
+}
+
+void BuildPlugin_PyInterp::closeContext()
+{
+  Py_XDECREF(_local_context);
+  PyInterp_Interp::closeContext();
+}
+
+bool BuildPlugin_PyInterp::runString(std::string theString)
+{
+  PyLockWrapper lck; // Acquire GIL until the end of the method
+  return PyRun_SimpleString(theString.c_str());
+}
diff --git a/src/BuildPlugin/BuildPlugin_PyInterp.h b/src/BuildPlugin/BuildPlugin_PyInterp.h
new file mode 100644 (file)
index 0000000..b5b8e14
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef BUILDPLUGIN_PYINTERP_H_
+#define BUILDPLUGIN_PYINTERP_H_
+
+#include <PyInterp_Interp.h>
+#include <BuildPlugin.h>
+
+#include <list>
+#include <string>
+#include <utility>
+
+/**
+ * \class BuildPlugin_PyInterp
+ * \ingroup Plugins
+ * \brief Helper class for using Python interpreter.
+ */
+class BUILDPLUGIN_EXPORT BuildPlugin_PyInterp : public PyInterp_Interp
+{
+ public:
+  BuildPlugin_PyInterp();
+  virtual ~BuildPlugin_PyInterp();
+
+  /// Returns a list of positions for theName in theExpression.
+  std::list<std::pair<int, int> > positions(const std::wstring& theExpression,
+                                            const std::wstring& theName);
+  /// Compiles theExpression and returns a list of parameters used in theExpression.
+  std::list<std::wstring> compile(const std::wstring& theExpression);
+  /// Extends local context with the list of parameters.
+  void extendLocalContext(const std::list<std::wstring>& theParameters);
+  /// Clears local context.
+  void clearLocalContext();
+  /// Evaluates theExpression and returns its value.
+  double evaluate(const std::wstring& theExpression, std::string& theError);
+
+  /// Runs the string command in the python interpreter. Returns true if no error is in result.
+  bool runString(std::string theString);
+
+ protected:
+  /// Returns error message.
+  std::string errorMessage();
+  /// Overrides PyInterp_Interp.
+  virtual bool initContext();
+  /// Reimplemented from PyInterp_Interp::closeContext().
+  virtual void closeContext();
+};
+
+#endif /* BUILDPLUGIN_PYINTERP_H_ */
index e13730bea5594dec5310d0da0d812d1aa34baff8..929c321c6857f94a92711b10b6e13e200889a3f8 100644 (file)
@@ -29,6 +29,8 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
                     ${PROJECT_SOURCE_DIR}/src/GeomValidators
                     ${PROJECT_SOURCE_DIR}/src/SketchPlugin
+                    ${SUIT_INCLUDE}
+                    ${PYTHON_INCLUDE_DIR}
 )
 
 SET(PROJECT_HEADERS
@@ -48,6 +50,8 @@ SET(PROJECT_HEADERS
     BuildPlugin_SubShapes.h
     BuildPlugin_Filling.h
     BuildPlugin_Validators.h
+    BuildPlugin_EvalListener.h
+    BuildPlugin_PyInterp.h
 )
 
 SET(PROJECT_SOURCES
@@ -66,6 +70,8 @@ SET(PROJECT_SOURCES
     BuildPlugin_SubShapes.cpp
     BuildPlugin_Filling.cpp
     BuildPlugin_Validators.cpp
+    BuildPlugin_EvalListener.cpp
+    BuildPlugin_PyInterp.cpp
 )
 
 SET(XML_RESOURCES
@@ -99,6 +105,8 @@ SET(PROJECT_LIBRARIES
     GeomAPI
     GeomAlgoAPI
     GeomValidators
+    ${PyInterp}
+    ${PYTHON_LIBRARIES}
 )
 
 ADD_DEFINITIONS(-DBUILDPLUGIN_EXPORTS)
diff --git a/src/BuildPlugin/icons/feature_interpolation_analytical.png.png b/src/BuildPlugin/icons/feature_interpolation_analytical.png.png
new file mode 100644 (file)
index 0000000..e5c5374
Binary files /dev/null and b/src/BuildPlugin/icons/feature_interpolation_analytical.png.png differ
diff --git a/src/BuildPlugin/icons/feature_interpolation_by_selection.png b/src/BuildPlugin/icons/feature_interpolation_by_selection.png
new file mode 100644 (file)
index 0000000..f2964c7
Binary files /dev/null and b/src/BuildPlugin/icons/feature_interpolation_by_selection.png differ
index 10efe19e76510b9f2aaf0abbc83e54b8fe0aca6b..cd35b15223d6bfa08c10e8971c006cd9a68438f2 100644 (file)
@@ -1,7 +1,8 @@
 <source>
   <toolbox id="interpolation_method">
     <box id="by_selection" 
-         icon="icons/BuildPlugin/edge_by_points_32x32.png">
+         title="Curve by selection"
+         icon="icons/Build/feature_interpolation_by_selection.png">
       <multi_selector id="base_objects"
                       label="Points and vertices:"
                       tooltip="Select points or vertices objects."
           </shape_selector>
         </optionalbox>
       </optionalbox>
-      <validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/>
+      <!--JL_CGLB validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/-->
     </box>
     <box id="analytical"
-         title="Curve parameters"
+         title="Curve analytical"
          tooltip="???"
-         icon="icons/BuildPlugin/feature_edge.png">
+         icon="icons/Build/feature_interpolation_analytical.png">
       <stringvalue id="xt" label="X(t) equation" >
           <validator id="BuildPlugin_ValidatorExpressionInterpolation"/>
         </stringvalue>
                    label="Min t"
                    min="0"
                    default="0">
-        <validator id="GeomValidators_Positive"/>
+        <!--validator id="GeomValidators_Positive"/-->
       </doublevalue>
        <doublevalue id="maxt"
                    label="Max t"
                    min="0"
                    default="100">
-        <validator id="GeomValidators_Positive"/>
+        <!--validator id="GeomValidators_Positive"/-->
       </doublevalue>
        <integervalue id="numstep"
                    label="Number of steps"
index 32c20569a15bc5a7f46d3b93bb271a9ada783252..be1d599973a2ab050bfab323ea02a5b0d4fe3460 100644 (file)
@@ -10,7 +10,7 @@
         <source path="edge_widget.xml"/>
       </feature>
       <feature id="Interpolation" title="Interpolation" tooltip ="Create an interpolation curve from points" icon="icons/Build/feature_interpolation.png"
-               auto_preview="false"  helpfile="interpolationFeature.html">
+               helpfile="interpolationFeature.html">
         <source path="interpolation_widget.xml"/>
       </feature>
       <feature id="Wire" title="Wire" tooltip ="Create a wire from sketch edges, edges and wires objects" icon="icons/Build/feature_wire.png"
index cebf9ca791fcf5133e83da9a5f31436ab5c704e3..7632dca2d43ba5536b40fa294d576c868c7159e0 100644 (file)
@@ -188,6 +188,55 @@ const std::string& ModelAPI_ParameterEvalMessage::error() const
   return myError;
 }
 
+ModelAPI_BuildEvalMessage::ModelAPI_BuildEvalMessage(
+  const Events_ID theID, const void* theSender)
+  : Events_Message(theID, theSender), myIsProcessed(false)
+{}
+
+ModelAPI_BuildEvalMessage::~ModelAPI_BuildEvalMessage()
+{}
+
+FeaturePtr ModelAPI_BuildEvalMessage::parameter() const
+{
+  return myParam;
+}
+
+void ModelAPI_BuildEvalMessage::setParameter(FeaturePtr theParam)
+{
+  myParam = theParam;
+}
+
+void ModelAPI_BuildEvalMessage::setResults(
+    const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+    const double theResult, const std::string& theError)
+{
+  myParamsList = theParamsList;
+  myResult = theResult;
+  myError = theError;
+  myIsProcessed = true;
+}
+
+bool ModelAPI_BuildEvalMessage::isProcessed()
+{
+  return myIsProcessed;
+}
+
+const std::list<std::shared_ptr<ModelAPI_ResultParameter> >&
+  ModelAPI_BuildEvalMessage::params() const
+{
+  return myParamsList;
+}
+
+const double& ModelAPI_BuildEvalMessage::result() const
+{
+  return myResult;
+}
+
+const std::string& ModelAPI_BuildEvalMessage::error() const
+{
+  return myError;
+}
+
 ModelAPI_ComputePositionsMessage::ModelAPI_ComputePositionsMessage(
   const Events_ID theID, const void* theSender)
   : Events_Message(theID, theSender)
index fccf6e24002965de8378e7c4553460eb6808d3b3..11a6aecc9724380c1513ba07571bd8c99ca340e3 100644 (file)
@@ -352,6 +352,59 @@ class ModelAPI_ParameterEvalMessage : public Events_Message
   MODELAPI_EXPORT const std::string& error() const;
 };
 
+class ModelAPI_BuildEvalMessage : public Events_Message
+{
+  FeaturePtr myParam; ///< parameters that should be evaluated
+  bool myIsProcessed; ///< true if results were set
+  /// result of processing, list of parameters in expression found
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> > myParamsList;
+  double myResult; ///< result of processing, the computed value of the expression
+  std::string myError; ///< error of processing, empty if there is no error
+
+ public:
+  /// Static. Returns EventID of the message.
+  MODELAPI_EXPORT static Events_ID& eventId()
+  {
+    static const char * MY_BUILD_EVALUATION_EVENT_ID("ParameterEvaluationRequest");
+    static Events_ID anId = Events_Loop::eventByName(MY_BUILD_EVALUATION_EVENT_ID);
+    return anId;
+  }
+
+  /// Useful method that creates and sends the event.
+  /// Returns the message, processed, with the resulting fields filled.
+  MODELAPI_EXPORT static std::shared_ptr<ModelAPI_BuildEvalMessage>
+    send(FeaturePtr theParameter, const void* theSender)
+  {
+    std::shared_ptr<ModelAPI_BuildEvalMessage> aMessage =
+      std::shared_ptr<ModelAPI_BuildEvalMessage>(
+      new ModelAPI_BuildEvalMessage(eventId(), theSender));
+    aMessage->setParameter(theParameter);
+    Events_Loop::loop()->send(aMessage);
+    return aMessage;
+  }
+
+  /// Creates an empty message
+  MODELAPI_EXPORT ModelAPI_BuildEvalMessage(const Events_ID theID, const void* theSender = 0);
+  /// The virtual destructor
+  MODELAPI_EXPORT virtual ~ModelAPI_BuildEvalMessage();
+
+  /// Returns a parameter stored in the message
+  MODELAPI_EXPORT FeaturePtr parameter() const;
+  /// Sets a parameter to the message
+  MODELAPI_EXPORT void setParameter(FeaturePtr theParam);
+  /// Sets the results of processing
+  MODELAPI_EXPORT void setResults(
+    const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+    const double theResult, const std::string& theError);
+  /// Returns true if the expression is processed
+  MODELAPI_EXPORT bool isProcessed();
+  /// Returns the results of processing: list of parameters found in the expression
+  MODELAPI_EXPORT const std::list<std::shared_ptr<ModelAPI_ResultParameter> >& params() const;
+  /// Returns the expression result
+  MODELAPI_EXPORT const double& result() const;
+  /// Returns the interpreter error (empty if no error)
+  MODELAPI_EXPORT const std::string& error() const;
+};
 
 /// Message to ask compute the positions of parameters in the expression
 class ModelAPI_ComputePositionsMessage : public Events_Message