Salome HOME
CEA : Lot1 - Interpolation
authorcg246364 <clarisse.genrault@cea.fr>
Fri, 19 Feb 2021 17:29:05 +0000 (18:29 +0100)
committercg246364 <clarisse.genrault@cea.fr>
Wed, 3 Mar 2021 13:09:29 +0000 (14:09 +0100)
30 files changed:
src/BuildAPI/BuildAPI_Interpolation.cpp
src/BuildAPI/BuildAPI_Interpolation.h
src/BuildPlugin/BuildPlugin_Interpolation.cpp
src/BuildPlugin/BuildPlugin_Interpolation.h
src/BuildPlugin/BuildPlugin_Plugin.cpp
src/BuildPlugin/BuildPlugin_Validators.cpp
src/BuildPlugin/BuildPlugin_Validators.h
src/BuildPlugin/BuildPlugin_msg_fr.ts
src/BuildPlugin/CMakeLists.txt
src/BuildPlugin/Test/TestInterpolation.py
src/BuildPlugin/doc/TUI_interpolationAnalytical.rst [new file with mode: 0644]
src/BuildPlugin/doc/TUI_interpolationBySelection.rst [new file with mode: 0644]
src/BuildPlugin/doc/TUI_interpolationFeature.rst [deleted file]
src/BuildPlugin/doc/examples/interpolationAnalytical.py [new file with mode: 0644]
src/BuildPlugin/doc/images/CreateInterpolationAnalytical.png [new file with mode: 0644]
src/BuildPlugin/doc/images/Interpolation.png
src/BuildPlugin/doc/images/InterpolationAnalytical.png [new file with mode: 0644]
src/BuildPlugin/doc/images/feature_interpolation_analytical.png [new file with mode: 0644]
src/BuildPlugin/doc/images/feature_interpolation_by_selection.png [new file with mode: 0644]
src/BuildPlugin/doc/interpolationFeature.rst
src/BuildPlugin/icons/feature_interpolation_analytical.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/GeomValidators/CMakeLists.txt
src/GeomValidators/GeomValidators_MinObjectsSelected.cpp
src/InitializationPlugin/CMakeLists.txt
src/InitializationPlugin/InitializationPlugin_EvalListener.cpp
src/InitializationPlugin/InitializationPlugin_EvalListener.h
src/ModelAPI/ModelAPI_Events.cpp
src/ModelAPI/ModelAPI_Events.h

index 113ed4227d8905bdac1c01ebde3754944ec86477..8f1efda8c98d106d3b74122e3de9783d9f0331ac 100644 (file)
@@ -38,7 +38,8 @@ BuildAPI_Interpolation::BuildAPI_Interpolation(const FeaturePtr& theFeature,
                     const bool theIsToReorder)
 : ModelHighAPI_Interface(theFeature)
 {
-  if(initialize()) {
+  if (initialize()) {
+    fillAttribute(BuildPlugin_Interpolation::CREATION_METHOD_BY_SELECTION_ID(),mycreationmethod);
     setUseTangents(true);
     setTangents(theStartTangent, theEndTangent);
     setClosed(theIsClosed);
@@ -55,6 +56,7 @@ BuildAPI_Interpolation::BuildAPI_Interpolation(const FeaturePtr& theFeature,
   : ModelHighAPI_Interface(theFeature)
 {
   if (initialize()) {
+    fillAttribute(BuildPlugin_Interpolation::CREATION_METHOD_BY_SELECTION_ID(),mycreationmethod);
     setClosed(theIsClosed);
     setReorder(theIsToReorder);
     setUseTangents(false);
@@ -62,6 +64,29 @@ BuildAPI_Interpolation::BuildAPI_Interpolation(const FeaturePtr& theFeature,
   }
 }
 
+//==================================================================================================
+BuildAPI_Interpolation::BuildAPI_Interpolation(const FeaturePtr& theFeature,
+                                               const std::string & theXTexpression,
+                                               const std::string & theYTexpression,
+                                               const std::string & theZTexpression,
+                                               const ModelHighAPI_Double& theMinT,
+                                               const ModelHighAPI_Double& theMaxT,
+                                               const ModelHighAPI_Integer& theNbStep)
+: ModelHighAPI_Interface(theFeature)
+{
+  if (initialize()) {
+    fillAttribute(BuildPlugin_Interpolation::CREATION_METHOD_ANALYTICAL_ID(),mycreationmethod);
+    fillAttribute(theXTexpression, myxt);
+    fillAttribute(theYTexpression, myyt);
+    fillAttribute(theZTexpression, myzt);
+    fillAttribute(theMinT, mymint);
+    fillAttribute(theMaxT, mymaxt);
+    fillAttribute(theNbStep, mynumstep);
+
+    execute();
+  }
+}
+
 //==================================================================================================
 BuildAPI_Interpolation::~BuildAPI_Interpolation()
 {
@@ -112,24 +137,45 @@ void BuildAPI_Interpolation::dump(ModelHighAPI_Dumper& theDumper) const
   FeaturePtr aBase = feature();
   std::string aPartName = theDumper.name(aBase->document());
 
-  AttributeSelectionListPtr anAttrBaseObjects =
-    aBase->selectionList(BuildPlugin_Interpolation::BASE_OBJECTS_ID());
-
-  theDumper << aBase << " = model.addInterpolation(" << aPartName << ", "
-            << anAttrBaseObjects << ", ";
-
-  AttributeStringPtr useTangentsAttr = useTangents();
-  std::string useTangents = useTangentsAttr->value();
-  if (!useTangents.empty()) {
-    AttributeSelectionPtr anAttrStartTangent =
-      aBase->selection(BuildPlugin_Interpolation::TANGENT_START_ID());
-    AttributeSelectionPtr anAttrEndTangent =
-      aBase->selection(BuildPlugin_Interpolation::TANGENT_END_ID());
-
-    theDumper << anAttrStartTangent << ", " << anAttrEndTangent << ", ";
+  if (aBase->string(BuildPlugin_Interpolation::CREATION_METHOD_ID())->value() ==
+            BuildPlugin_Interpolation::CREATION_METHOD_BY_SELECTION_ID())
+  {
+    AttributeSelectionListPtr anAttrBaseObjects =
+      aBase->selectionList(BuildPlugin_Interpolation::BASE_OBJECTS_ID());
+
+    theDumper << aBase << " = model.addInterpolation(" << aPartName << ", "
+              << anAttrBaseObjects << ", ";
+
+    AttributeStringPtr useTangentsAttr = useTangents();
+    std::string useTangents = useTangentsAttr->value();
+    if (!useTangents.empty()) {
+      AttributeSelectionPtr anAttrStartTangent =
+        aBase->selection(BuildPlugin_Interpolation::TANGENT_START_ID());
+      AttributeSelectionPtr anAttrEndTangent =
+        aBase->selection(BuildPlugin_Interpolation::TANGENT_END_ID());
+
+      theDumper << anAttrStartTangent << ", " << anAttrEndTangent << ", ";
+    }
+
+    theDumper << closed() << ", " << reorder() << ")" << std::endl;
+  } else {
+    theDumper << aBase << " = model.addInterpolation(" << aPartName ;
+    AttributeStringPtr XtAttr = xt();
+    std::string xt = XtAttr->value();
+    AttributeStringPtr YtAttr = yt();
+    std::string yt = YtAttr->value();
+    AttributeStringPtr ZtAttr = zt();
+    std::string zt = ZtAttr->value();
+    AttributeDoublePtr minTAttr = mint();
+    double mint = minTAttr->value();
+    AttributeDoublePtr maxTAttr = maxt();
+    double maxt = maxTAttr->value();
+    AttributeIntegerPtr nbStepAttr = numstep();
+    int nbStep = nbStepAttr->value();
+
+    theDumper<< ", \""  << xt << "\",\"" << yt << "\",\""<< zt<< "\", " ;
+    theDumper << mint << ", " << maxt << ", "<< nbStep<< ")"<<std::endl;
   }
-
-  theDumper << closed() << ", " << reorder() << ")" << std::endl;
 }
 
 //==================================================================================================
@@ -162,9 +208,27 @@ InterpolationPtr addInterpolation(const std::shared_ptr<ModelAPI_Document>& theP
                                                      theIsToReorder));
 }
 
+InterpolationPtr addInterpolation(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                  const std::string & theXTexpression,
+                                  const std::string & theYTexpression,
+                                  const std::string & theZTexpression,
+                                  const ModelHighAPI_Double& theMinT,
+                                  const ModelHighAPI_Double& theMaxT,
+                                  const ModelHighAPI_Integer& theNbStep)
+{
+  std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(BuildAPI_Interpolation::ID());
+  return InterpolationPtr(new BuildAPI_Interpolation(aFeature,
+                                                     theXTexpression,
+                                                     theYTexpression,
+                                                     theZTexpression,
+                                                     theMinT,
+                                                     theMaxT,
+                                                     theNbStep));
+}
+
 //==================================================================================================
 void BuildAPI_Interpolation::execIfBaseNotEmpty()
 {
   if (baseObjects()->size() > 0)
     execute();
-}
\ No newline at end of file
+}
index e1ee1031d58dbc6aa949e9ee442884c7f131bb8e..86c511f0c415fc0f7f1c60e06a82bdf5d94fdfb2 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <BuildPlugin_Interpolation.h>
 
+#include <ModelHighAPI_Double.h>
+#include <ModelHighAPI_Integer.h>
 #include <ModelHighAPI_Interface.h>
 #include <ModelHighAPI_Macro.h>
 #include <ModelHighAPI_Selection.h>
@@ -54,11 +56,21 @@ public:
                                     const std::list<ModelHighAPI_Selection>& theBaseObjects,
                                     const bool theIsClosed, const bool theIsToReorder);
 
+  /// Constructor with expression analytical of X,Y andZ
+  BUILDAPI_EXPORT
+    explicit BuildAPI_Interpolation(const FeaturePtr& theFeature,
+                                    const std::string & theXTexpression,
+                                    const std::string & theYTexpression,
+                                    const std::string & theZTexpression,
+                                    const ModelHighAPI_Double& theMinT,
+                                    const ModelHighAPI_Double& theMaxT,
+                                    const ModelHighAPI_Integer& theNbStep);
+
   /// Destructor.
   BUILDAPI_EXPORT
   virtual ~BuildAPI_Interpolation();
 
-  INTERFACE_6(BuildPlugin_Interpolation::ID(),
+  INTERFACE_13(BuildPlugin_Interpolation::ID(),
               baseObjects, BuildPlugin_Interpolation::BASE_OBJECTS_ID(),
               ModelAPI_AttributeSelectionList, /** Base objects */,
               closed, BuildPlugin_Interpolation::CLOSED_ID(),
@@ -70,7 +82,21 @@ public:
               startTangent, BuildPlugin_Interpolation::TANGENT_START_ID(),
               ModelAPI_AttributeSelection, /** Start point tangent */,
               endTangent, BuildPlugin_Interpolation::TANGENT_END_ID(),
-              ModelAPI_AttributeSelection, /** End point tangent */)
+              ModelAPI_AttributeSelection, /** End point tangent */,
+              xt, BuildPlugin_Interpolation::XT_ID(),
+              ModelAPI_AttributeString, /** xt expression*/,
+              yt, BuildPlugin_Interpolation::YT_ID(),
+              ModelAPI_AttributeString, /** yt expression*/,
+              zt, BuildPlugin_Interpolation::ZT_ID(),
+              ModelAPI_AttributeString, /** zt expression*/,
+              mint, BuildPlugin_Interpolation::MINT_ID(),
+              ModelAPI_AttributeDouble, /** Min*/,
+              maxt, BuildPlugin_Interpolation::MAXT_ID(),
+              ModelAPI_AttributeDouble, /** Max*/,
+              numstep, BuildPlugin_Interpolation::NUMSTEP_ID(),
+              ModelAPI_AttributeInteger, /** Number of steps*/,
+              creationmethod, BuildPlugin_Interpolation::CREATION_METHOD_ID(),
+              ModelAPI_AttributeString, /** Creation method*/)
 
   /// Modify base attribute of the feature.
   BUILDAPI_EXPORT
@@ -118,4 +144,15 @@ InterpolationPtr addInterpolation(const std::shared_ptr<ModelAPI_Document>& theP
                                   const bool theIsClosed = false,
                                   const bool theIsToReorder = false);
 
+/// \ingroup CPPHighAPI
+/// \brief Create Interpolation feature using tangents.
+BUILDAPI_EXPORT
+InterpolationPtr addInterpolation(const std::shared_ptr<ModelAPI_Document>& thePart,
+                                  const std::string & theXTexpression,
+                                  const std::string & theYTexpression,
+                                  const std::string & theZTexpression,
+                                  const ModelHighAPI_Double& theMinT,
+                                  const ModelHighAPI_Double& theMaxT,
+                                  const ModelHighAPI_Integer& theNbStep);
+
 #endif // BuildAPI_Interpolation_H_
index b8422517b0cedbddfdcad816322e34d5ffc015fc..bb8266db066631738295c64162fadca340a3d0d6 100644 (file)
 #include "BuildPlugin_Interpolation.h"
 
 #include <ModelAPI_AttributeBoolean.h>
-#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeTables.h>
+#include <ModelAPI_Events.h>
 #include <ModelAPI_ResultBody.h>
-#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
 
 #include <Events_InfoMessage.h>
 
+#include <Locale_Convert.h>
+
 #include <GeomAlgoAPI_ShapeTools.h>
 #include <GeomAlgoAPI_CurveBuilder.h>
 #include <GeomAlgoAPI_PointBuilder.h>
@@ -36,6 +45,7 @@
 #include <GeomAPI_ShapeExplorer.h>
 
 #include <algorithm>
+#include <sstream>
 
 //=================================================================================================
 BuildPlugin_Interpolation::BuildPlugin_Interpolation()
@@ -51,6 +61,92 @@ 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_METHOD_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(CREATION_METHOD_BY_SELECTION_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(CREATION_METHOD_ANALYTICAL_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());
+
+  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_METHOD_ANALYTICAL_ID());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(),
+                                                 CREATION_METHOD_BY_SELECTION_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);
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ARGUMENTS_ID());
+
+  if (string(XT_ID())->value() == ""
+     && string(YT_ID())->value() == ""
+     && string(ZT_ID())->value() == "") {
+      string(XT_ID())->setValue("t");
+      string(YT_ID())->setValue("t");
+      string(ZT_ID())->setValue("t");
+      real(MINT_ID())->setValue(0);
+      real(MAXT_ID())->setValue(100);
+      integer(NUMSTEP_ID())->setValue(10);
+      updateCoordinates();
+  }
+}
+
+//=================================================================================================
+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() !=""
+    && string(CREATION_METHOD_ID())->value() == CREATION_METHOD_ANALYTICAL_ID()) {
+    updateCoordinates();
+  }
+}
+
+//=================================================================================================
+void BuildPlugin_Interpolation::updateCoordinates()
+{
+    std::wstring exp;
+    double aMint = real(MINT_ID())->value();
+    double aMaxt = real(MAXT_ID())->value();
+    int aNbrStep = integer(NUMSTEP_ID())->value();
+
+    if (aMaxt < aMint) {
+      setError("The minimum value of the parameter must be less than maximum value !!!");
+    }
+
+    double aScale = (aMaxt - aMint)/aNbrStep;
+    string(VARIABLE_ID())->setValue("t");
+
+    tables(VALUE_ID())->setSize(aNbrStep+1,4);
+    for (int step = 0; step <= aNbrStep; step++) {
+      ModelAPI_AttributeTables::Value aVal;
+      aVal.myDouble = step * aScale + aMint;
+      tables(VALUE_ID())->setValue(aVal,step,0);
+    }
+
+    outErrorMessage="";
+    evaluate(outErrorMessage);
+    data()->string(EXPRESSION_ERROR_ID())->setValue(outErrorMessage);
+    if (!outErrorMessage.empty()) {
+      setError("Error: Python interpreter ");
+      return;
+    }
 }
 
 //=================================================================================================
@@ -78,62 +174,159 @@ static GeomDirPtr selectionToDir(const AttributeSelectionPtr& theSelection)
 //=================================================================================================
 void BuildPlugin_Interpolation::execute()
 {
-  // Get closed flag value
-  bool isClosed = boolean(CLOSED_ID())->value();
+  if (string(CREATION_METHOD_ID())->value() == CREATION_METHOD_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<GeomPointPtr> aPoints;
-  std::set<GeomShapePtr> 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());
 
-  // 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());
-  }
-  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);
-  }
+    // Collect points.
+    std::list<GeomPointPtr> aPoints;
+    std::set<GeomShapePtr> 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;
+    }
+
+    // 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());
+    }
+    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 {
+    if (string(XT_ID())->value() == ""
+        ||string(YT_ID())->value() == ""
+        ||string(ZT_ID())->value() == ""
+        ||tables(VALUE_ID())->rows()== 0)
+      return;
+
+    bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+    updateCoordinates();
+    data()->blockSendAttributeUpdated(aWasBlocked, false);
+
+    AttributeTablesPtr aTable = tables(VALUE_ID());
+    std::list<std::vector<double>> aCoordPoints;
+    for (int step = 0; step < aTable->rows(); step++) {
+      std::vector<double> aCoordPoint;
+      ModelAPI_AttributeTables::Value aValue;
+      //x
+      aValue = aTable->value(step, 1);
+      aCoordPoint.push_back(aValue.myDouble);
+      //y
+      aValue = aTable->value(step, 2);
+      aCoordPoint.push_back(aValue.myDouble);
+      //
+      aValue = aTable->value(step, 3);
+      aCoordPoint.push_back(aValue.myDouble);
+
+      aCoordPoints.push_back(aCoordPoint);
+    }
+
+    std::list<GeomPointPtr> aPoints;
+    std::list<std::vector<double>>::const_iterator anItCoordPoints = aCoordPoints.begin();
 
-  setResult(aResultBody);
+    for (; anItCoordPoints!=aCoordPoints.end(); ++anItCoordPoints) {
+
+      GeomVertexPtr aVertex = GeomAlgoAPI_PointBuilder::vertex((*anItCoordPoints)[0],
+                                                               (*anItCoordPoints)[1],
+                                                               (*anItCoordPoints)[2]);
+      aPoints.push_back(aVertex->point());
+    }
+
+    // test if some points are identical
+    std::list<GeomPointPtr>::const_iterator anItPoint1 = aPoints.begin();
+    std::list<GeomPointPtr>::const_iterator anItPoint2;
+    for(; anItPoint1 != aPoints.end(); ++ anItPoint1) {
+      anItPoint2 = anItPoint1;
+      ++anItPoint2;
+      for(; anItPoint2 != aPoints.end(); ++ anItPoint2)
+          if ((*anItPoint2)->isEqual(*anItPoint1)) {
+            setError("Error: Several points are identical");
+            return;
+          }
+    }
+
+    // Create curve from points
+    GeomEdgePtr anEdge =
+      GeomAlgoAPI_CurveBuilder::edge(aPoints, false, false,GeomDirPtr(),GeomDirPtr());
+    if (!anEdge.get()) {
+      setError("Error: Result curve is empty.");
+      return;
+    }
+
+    ResultBodyPtr aResultBody = document()->createBody(data());
+    // 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);
+  }
 }
+
+//=================================================================================================
+void BuildPlugin_Interpolation::evaluate(std::string& theError)
+{
+  FeaturePtr aMyPtr = std::dynamic_pointer_cast<ModelAPI_Feature>(data()->owner());
+  std::shared_ptr<ModelAPI_BuildEvalMessage> aProcessMessage =
+    ModelAPI_BuildEvalMessage::send(aMyPtr, this);
+
+  if (aProcessMessage->isProcessed()) {
+    theError = aProcessMessage->error();
+
+    const std::list<ResultParameterPtr>& aParamsList = aProcessMessage->params();
+    //store the list of parameters to store if changed
+    AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
+    aParams->clear();
+    std::list<ResultParameterPtr>::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";
+  }
+}
\ No newline at end of file
index 912cc126ff14ef4c90ee1a96e2fd38aa0a54db5d..624d584f1ea99e32fda4345a01d6cbef36d3de69 100644 (file)
@@ -40,6 +40,27 @@ public:
     return MY_ID;
   }
 
+  /// Attribute name of creation method.
+  inline static const std::string& CREATION_METHOD_ID()
+  {
+    static const std::string MY_CREATION_METHOD_ID("interpolation_method");
+    return MY_CREATION_METHOD_ID;
+  }
+
+  /// Attribute name of creation method by selection
+  inline static const std::string& CREATION_METHOD_BY_SELECTION_ID()
+  {
+    static const std::string MY_CREATION_METHOD_BY_SELECTION_ID("by_selection");
+    return MY_CREATION_METHOD_BY_SELECTION_ID;
+  }
+
+  /// Attribute name of creation method analytical
+  inline static const std::string& CREATION_METHOD_ANALYTICAL_ID()
+  {
+    static const std::string MY_CREATION_METHOD_ANALYTICAL_ID("analytical");
+    return MY_CREATION_METHOD_ANALYTICAL_ID;
+  }
+
   /// Attribute name of base objects.
   inline static const std::string& BASE_OBJECTS_ID()
   {
@@ -82,9 +103,79 @@ public:
     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 of variable
+  inline static const std::string& VARIABLE_ID()
+  {
+    static const std::string MY_VARIABLE_ID("variable");
+    return MY_VARIABLE_ID;
+  }
+
+  /// Attribute of parameter name of value
+  inline static const std::string& VALUE_ID()
+  {
+    static const std::string MY_VALUE_ID("value");
+    return MY_VALUE_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 number of steps
+  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; }
 
+  /// List of references to the arguments of this expression
+  inline static const std::string& ARGUMENTS_ID()
+  {
+    static const std::string MY_ARGUMENTS_ID("arguments");
+    return MY_ARGUMENTS_ID;
+  }
+
   /// \return the kind of a feature.
   BUILDPLUGIN_EXPORT virtual const std::string& getKind()
   {
@@ -97,6 +188,21 @@ public:
 
   /// Creates a new part document if needed.
   BUILDPLUGIN_EXPORT virtual void execute();
+
+  /// Called on change of any argument-attribute of this object.
+  /// \param[in] theID identifier of changed attribute.
+  BUILDPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
+  protected:
+  /// Evaluates the expression x(t), y(t),z(t) in value table.
+  void evaluate(std::string& theError);
+
+  /// Update coordinates x,y,z
+  void updateCoordinates();
+
+  /// Output error for python interpreter
+  std::string outErrorMessage;
+
 };
 
 #endif
index e18d092cfea452708bc289417e237747a1fdb062..77a710b69b30a0321bbc291e7b261acf17292124 100644 (file)
@@ -59,6 +59,8 @@ 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);
index ac454e620fd03348cf9162e682171fb8320e2fda..f0657537db0b466d621e47f6c656d7e6349fb575 100644 (file)
@@ -20,6 +20,7 @@
 #include "BuildPlugin_Validators.h"
 
 #include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_ResultConstruction.h>
 
 #include <GeomAPI_PlanarEdges.h>
@@ -39,6 +40,8 @@
 #include <GeomValidators_FeatureKind.h>
 #include <GeomValidators_ShapeType.h>
 
+#include <BuildPlugin_Interpolation.h>
+
 #include <SketchPlugin_Sketch.h>
 
 #include <Events_InfoMessage.h>
@@ -569,3 +572,28 @@ bool BuildPlugin_ValidatorBaseForVertex::isValid(const AttributePtr& theAttribut
 
   return true;
 }
+
+//=================================================================================================
+bool BuildPlugin_ValidatorExpressionInterpolation::isValid(const AttributePtr& theAttribute,
+                                                   const std::list<std::string>& /*theArguments*/,
+                                                   Events_InfoMessage& theError) const
+{
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+
+  AttributeStringPtr aStrAttr =
+      std::dynamic_pointer_cast<ModelAPI_AttributeString>(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();
+}
+
index 9d4670ef041019657e8be6178d521ad7bff71813..e1fd0c244cb6d2118251ccf500fc49c261096a0f 100644 (file)
@@ -133,4 +133,19 @@ public:
                         Events_InfoMessage& theError) const;
 };
 
+ /// \class BuildPlugin_ValidatorExpression
+ /// \ingroup Validators
+ /// \brief Validator for the expression of parameter.
+class BuildPlugin_ValidatorExpressionInterpolation: public ModelAPI_AttributeValidator
+{
+public:
+   //! 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<std::string>& theArguments,
+                        Events_InfoMessage& theError) const;
+};
+
 #endif
index e6c433fbb2984c34a05b587ba0f9c0eb48a50284..163ef0773b0c7eed0e52934e1725284416246e96 100644 (file)
       <translation>Tangentes</translation>
     </message>
   </context>
-
+  <context>
+    <name>Interpolation</name>
+    <message>
+      <source>Curves parameters</source>
+      <translation>Paramètres de la courbe</translation>
+    </message>
+  </context>
+  <context>
+    <name>Interpolation:xt</name>
+    <message>
+      <source>X(t) equation</source>
+      <translation>Équation X(t)</translation>
+    </message>
+  </context>
+  <context>
+    <name>Interpolation:yt</name>
+    <message>
+      <source>Y(t) equation</source>
+      <translation>Équation Y(t)</translation>
+    </message>
+  </context>
+  <context>
+    <name>Interpolation:zt</name>
+    <message>
+      <source>Z(t) equation</source>
+      <translation>Équation Z(t)</translation>
+    </message>
+  </context>
+  <context>
+    <name>Interpolation:numstep</name>
+    <message>
+      <source>Number of steps</source>
+      <translation>Nombre de pas</translation>
+    </message>
+  </context>
   <context>
     <name>Polyline:base_objects</name>
     <message>
index c018a5d7d43b6f5885f69d4f28be931071add100..be036a0a64d3eeecd13828f895b7b70f09ad72d7 100644 (file)
@@ -23,11 +23,15 @@ 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
                     ${PROJECT_SOURCE_DIR}/src/GeomValidators
                     ${PROJECT_SOURCE_DIR}/src/SketchPlugin
+                    ${PROJECT_SOURCE_DIR}/src/InitializationPlugin
+                    ${SUIT_INCLUDE}
+                    ${PYTHON_INCLUDE_DIR}
 )
 
 SET(PROJECT_HEADERS
@@ -98,6 +102,8 @@ SET(PROJECT_LIBRARIES
     GeomAPI
     GeomAlgoAPI
     GeomValidators
+    ${PyInterp}
+    ${PYTHON_LIBRARIES}
 )
 
 ADD_DEFINITIONS(-DBUILDPLUGIN_EXPORTS)
index 2fae36742489457c9b6ceb41c36b7604dd851da3..d2460699fcf4d8a42e4e1611999c79caec5d680f 100644 (file)
@@ -172,6 +172,16 @@ model.testHaveNamingSubshapes(Interpolation_9, model, Part_3_doc)
 model.end()
 
 # =============================================================================
-# Test 12. Check Python dump
+# Test 12. Create curve using an analytical expression
+# =============================================================================
+Part_5 = model.addPart(partSet)
+Part_5_doc = Part_5.document()
+
+Interpolation_11 = model.addInterpolation(Part_5_doc, "sin(t)","cos(t)","t", 0, 100, 10)
+model.do()
+model.testNbResults(Interpolation_11, 1)
+model.end()
+# =============================================================================
+# Test 13. Check Python dump
 # =============================================================================
 assert(model.checkPythonDump(model.ModelHighAPI.CHECK_NAMING))
diff --git a/src/BuildPlugin/doc/TUI_interpolationAnalytical.rst b/src/BuildPlugin/doc/TUI_interpolationAnalytical.rst
new file mode 100644 (file)
index 0000000..137be14
--- /dev/null
@@ -0,0 +1,12 @@
+   
+  .. _tui_create_interpolation_analytical:
+
+Create Interpolation analytical
+===============================
+
+.. literalinclude:: examples/interpolationAnalytical.py
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/interpolationAnalytical.py>` 
+   
diff --git a/src/BuildPlugin/doc/TUI_interpolationBySelection.rst b/src/BuildPlugin/doc/TUI_interpolationBySelection.rst
new file mode 100644 (file)
index 0000000..6e5a6a5
--- /dev/null
@@ -0,0 +1,12 @@
+
+  .. _tui_create_interpolation_by_selection:
+
+Create Interpolation by selection
+=================================
+
+.. literalinclude:: examples/interpolation.py
+    :linenos:
+    :language: python
+
+:download:`Download this script <examples/interpolation.py>` 
+   
diff --git a/src/BuildPlugin/doc/TUI_interpolationFeature.rst b/src/BuildPlugin/doc/TUI_interpolationFeature.rst
deleted file mode 100644 (file)
index cfcaf78..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-  .. _tui_create_interpolation:
-
-Create Interpolation
-====================
-
-.. literalinclude:: examples/interpolation.py
-    :linenos:
-    :language: python
-
-:download:`Download this script <examples/interpolation.py>` 
-   
diff --git a/src/BuildPlugin/doc/examples/interpolationAnalytical.py b/src/BuildPlugin/doc/examples/interpolationAnalytical.py
new file mode 100644 (file)
index 0000000..f39fe81
--- /dev/null
@@ -0,0 +1,9 @@
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Interpolation_1 = model.addInterpolation(Part_1_doc, "5*sin(t)","5*cos(t)","t*0.2", 0, 25, 100)
+model.do()
+model.end()
diff --git a/src/BuildPlugin/doc/images/CreateInterpolationAnalytical.png b/src/BuildPlugin/doc/images/CreateInterpolationAnalytical.png
new file mode 100644 (file)
index 0000000..2daa945
Binary files /dev/null and b/src/BuildPlugin/doc/images/CreateInterpolationAnalytical.png differ
index 14967cf1f6b404c3ad91a8b446f90c7a6253bc62..e03f336c0e03436820032a351b6751a187e8195d 100644 (file)
Binary files a/src/BuildPlugin/doc/images/Interpolation.png and b/src/BuildPlugin/doc/images/Interpolation.png differ
diff --git a/src/BuildPlugin/doc/images/InterpolationAnalytical.png b/src/BuildPlugin/doc/images/InterpolationAnalytical.png
new file mode 100644 (file)
index 0000000..472c4db
Binary files /dev/null and b/src/BuildPlugin/doc/images/InterpolationAnalytical.png differ
diff --git a/src/BuildPlugin/doc/images/feature_interpolation_analytical.png b/src/BuildPlugin/doc/images/feature_interpolation_analytical.png
new file mode 100644 (file)
index 0000000..a47790f
Binary files /dev/null and b/src/BuildPlugin/doc/images/feature_interpolation_analytical.png differ
diff --git a/src/BuildPlugin/doc/images/feature_interpolation_by_selection.png b/src/BuildPlugin/doc/images/feature_interpolation_by_selection.png
new file mode 100644 (file)
index 0000000..e5c5374
Binary files /dev/null and b/src/BuildPlugin/doc/images/feature_interpolation_by_selection.png differ
index 2da696243c2e9bb93d8913a1961882ce8f1dd9f1..d782bca1b7f94fb9b02f6710fc3f52129c479c7c 100644 (file)
@@ -3,19 +3,35 @@
 Interpolation
 =============
 
-Interpolation feature creates a curve (edge) using vertices already existing in other objects.
+Interpolation feature creates an interpolated curve (edge) based on existing points/vertices or based on analytical mathematical expression.
 
 To create an interpolation in the active part:
 
 #. select in the Main Menu *Build - > Interpolation* item  or
 #. click |feature_interpolation.icon| **Interpolation** button in the toolbar
 
-The following property panel will be opened:
+There are two creation modes of an interpolation:
+
+.. figure:: images/feature_interpolation_by_selection.png   
+   :align: left
+   :height: 24px
+
+Interpolation by selection
+
+.. figure:: images/feature_interpolation_analytical.png   
+   :align: left
+   :height: 24px
+
+Interpolation analytical
+
+Interpolation by selection
+""""""""""""""""""""""""""
+The  property panel is shown below.
 
 .. figure:: images/Interpolation.png
   :align: center
 
-  Create an interpolation
+  Create an interpolation by selection
 
 Select one or several vertices or points in the viewer.
 
@@ -59,4 +75,56 @@ The result of the operation will be a curve created from the selected shapes:
 
   Result of the operation.
 
-**See Also** a sample TUI Script of :ref:`tui_create_interpolation` operation.
+**See Also** a sample TUI Script of :ref:`tui_create_interpolation_by_selection` operation.
+
+Interpolation analytical
+""""""""""""""""""""""""
+
+The  property panel is shown below.
+
+.. figure:: images/InterpolationAnalytical.png
+  :align: center
+
+  Create an interpolation analytical
+
+Select one or several vertices or points in the viewer.
+
+- **Curves parameters** panel allows to define the mathematical expression for creating the interpolated curve.
+   - **X(t) equation** define the expression of X with t variable.
+   - **Y(t) equation** define the expression of Y with t variable.
+   - **Z(t) equation** define the expression of Z with t variable.
+
+- **Min t** define the minimun of t.
+
+- **Max t** define the maximum of t.
+
+- **Number of steps** define the number of steps.
+
+**Apply** button creates an interpolation.
+
+**Cancel** button cancels the operation. 
+
+**TUI Commands**:
+
+.. py:function:: model.addInterpolation(Part_doc, xt, yt, zt, mint, maxt, nbSteps)
+
+    :param part: The current part object.
+    :param string: Expression of x.
+    :param string: Expression of y.
+    :param string: Expression of z.
+    :param number: Minimum value of t.
+    :param number: Maximum value of t.
+    :param number: Number of steps. 
+    :return: Result object.
+
+Result
+""""""
+
+The result of the operation will be a curve created from analytical expressions for x,y and z as functions of variable t:
+
+.. figure:: images/CreateInterpolationAnalytical.png
+  :align: center
+
+  Result of the operation.
+
+**See Also** a sample TUI Script of :ref:`tui_create_interpolation_analytical` operation.
diff --git a/src/BuildPlugin/icons/feature_interpolation_analytical.png b/src/BuildPlugin/icons/feature_interpolation_analytical.png
new file mode 100644 (file)
index 0000000..a47790f
Binary files /dev/null and b/src/BuildPlugin/icons/feature_interpolation_analytical.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..e5c5374
Binary files /dev/null and b/src/BuildPlugin/icons/feature_interpolation_by_selection.png differ
index 5a0acee2fed3d086753912d7314983c60f264d3d..fed9ed99d3c0e2328d47abcdf321c967cd9277ca 100644 (file)
@@ -1,32 +1,67 @@
 <source>
-  <multi_selector id="base_objects"
-                  label="Points and vertices:"
-                  tooltip="Select points or vertices objects."
-                  shape_types="vertices"
-                  concealment="true">
-    <validator id="GeomValidators_DifferentShapes"/>
-  </multi_selector>
-  <boolvalue id="reorder" label="Reorder" tooltip="Changes the order of points to construct the shortest curve." default="false"/>
-  <optionalbox id="closed" title="Closed" tooltip="Makes the curve closed or not." default="false"
-               has_frame="false" enable_on_check="false">
-    <optionalbox id="use_tangents" title="Tangents" default="false">
-      <shape_selector id="tangent_start"
-                      icon="icons/Features/axis.png"
-                      label="Start"
-                      tooltip="Select vector tangent to the start of curve"
-                      shape_types="edge"
-                      default="&lt;start&gt;">
-        <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
-      </shape_selector>
-      <shape_selector id="tangent_end"
-                      icon="icons/Features/axis.png"
-                      label="End"
-                      tooltip="Select vector tangent to the end of curve"
-                      shape_types="edge"
-                      default="&lt;end&gt;">
-        <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
-      </shape_selector>
-    </optionalbox>
-  </optionalbox>
-  <validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/>
+  <toolbox id="interpolation_method">
+    <box id="by_selection" 
+         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_types="vertices"
+                      concealment="true">
+        <validator id="GeomValidators_DifferentShapes"/>
+      </multi_selector>
+      <boolvalue id="reorder" label="Reorder" tooltip="Changes the order of points to construct the shortest curve." default="false"/>
+      <optionalbox id="closed" title="Closed" tooltip="Makes the curve closed or not." default="false"
+                  has_frame="false" enable_on_check="false">
+        <optionalbox id="use_tangents" title="Tangents" default="false">
+          <shape_selector id="tangent_start"
+                          icon="icons/Features/axis.png"
+                          label="Start"
+                          tooltip="Select vector tangent to the start of curve"
+                          shape_types="edge"
+                          default="&lt;start&gt;">
+            <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
+          </shape_selector>
+          <shape_selector id="tangent_end"
+                          icon="icons/Features/axis.png"
+                          label="End"
+                          tooltip="Select vector tangent to the end of curve"
+                          shape_types="edge"
+                          default="&lt;end&gt;">
+            <validator id="GeomValidators_ShapeType" parameters="empty,line"/>
+          </shape_selector>
+        </optionalbox>
+      </optionalbox>
+      <validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/>
+    </box>
+    <box id="analytical"
+         title="Curve analytical"
+         icon="icons/Build/feature_interpolation_analytical.png">
+      <groupbox id="curves_parameters" title="Curves parameters">
+        <stringvalue id="xt" label="X(t) equation">
+            <validator id="BuildPlugin_ValidatorExpressionInterpolation"/>
+          </stringvalue>
+        <stringvalue id="yt" label="Y(t) equation">
+          <validator id="BuildPlugin_ValidatorExpressionInterpolation"/>
+        </stringvalue>
+        <stringvalue id="zt" label="Z(t) equation">
+          <validator id="BuildPlugin_ValidatorExpressionInterpolation"/>
+        </stringvalue>
+        <doublevalue id="mint"
+                     label="Min t"
+                     default="0">
+        </doublevalue>
+        <doublevalue id="maxt"
+                     label="Max t"
+                     default="100">
+        </doublevalue>
+        <integervalue id="numstep"
+                      label="Number of steps"
+                      min="0"
+                      default="10">
+          <validator id="GeomValidators_Positive"/>
+        </integervalue>
+      </groupbox>
+    </box>
+  </toolbox>
 </source>
index 40890c4cae469d14ae558be10ac9f5607f7aae22..c2ff50c8d6f8c6ab106ab9e6e28c0209b8de79ce 100644 (file)
@@ -78,6 +78,7 @@ INCLUDE_DIRECTORIES(
   ${PROJECT_SOURCE_DIR}/src/Events
   ${PROJECT_SOURCE_DIR}/src/GeomAPI
   ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
+  ${PROJECT_SOURCE_DIR}/src/BuildPlugin
 )
 
 INSTALL(TARGETS GeomValidators DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES})
index 174d1b71c962936cfc075a8f80534e0fba314720..93968cf4808ec7669e6cb7e9b12a948b35efea29 100644 (file)
 
 #include <Events_InfoMessage.h>
 
+#include <BuildPlugin_Interpolation.h>
+
 #include <ModelAPI_AttributeInteger.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeSelectionList.h>
 
 //=================================================================================================
@@ -29,17 +32,25 @@ bool GeomValidators_MinObjectsSelected::isValid(const std::shared_ptr<ModelAPI_F
                                                 const std::list<std::string>& theArguments,
                                                 Events_InfoMessage& theError) const
 {
-  if(theArguments.size() != 2) {
+  if (theArguments.size() != 2) {
 // LCOV_EXCL_START
     theError =
       "Error: Wrong number of arguments (expected 2): selection list id and min number of objects";
     return false;
 // LCOV_EXCL_STOP
   }
+  //"Interpolation"
+  if (theFeature->name().substr(0, 6) == L"Interp")
+  {
+    AttributeStringPtr anAttr =theFeature->string(BuildPlugin_Interpolation::CREATION_METHOD_ID());
+    if (anAttr->isInitialized())
+      if (anAttr->value() == BuildPlugin_Interpolation::CREATION_METHOD_ANALYTICAL_ID())
+        return true;
+  }
 
   std::string aSelectionListId = theArguments.front();
   AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(aSelectionListId);
-  if(!anAttrSelList.get()) {
+  if (!anAttrSelList.get()) {
 // LCOV_EXCL_START
     theError = "Error: Could not get attribute \"%1\".";
     theError.arg(aSelectionListId);
@@ -50,7 +61,7 @@ bool GeomValidators_MinObjectsSelected::isValid(const std::shared_ptr<ModelAPI_F
 
   int aMinObjectsNb = atoi(theArguments.back().c_str());
 
-  if(anObjectsNb < aMinObjectsNb) {
+  if (anObjectsNb < aMinObjectsNb) {
     theError = "Error: Attribute \"%1\" should contain at least %2 items.";
     theError.arg(aSelectionListId).arg(aMinObjectsNb);
     return false;
index a9518f877e54d45ea856962b16f9a7b496cc9cfc..93162e0aaac470779bf9c3c101ad1f56ad16ac71 100644 (file)
@@ -26,6 +26,7 @@ INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
                     ${PROJECT_SOURCE_DIR}/src/GeomDataAPI
                     ${PROJECT_SOURCE_DIR}/src/Locale
                     ${PROJECT_SOURCE_DIR}/src/ParametersPlugin
+                    ${PROJECT_SOURCE_DIR}/src/BuildPlugin
                     ${SUIT_INCLUDE}
                     ${PYTHON_INCLUDE_DIR}
 )
index e2dceb117b7870bc89080d29f5f1bec3bafe24b8..4e2d8f6c6eec96bd98797b86e6872ec389a641c2 100644 (file)
 #include <pyconfig.h>
 
 #include <InitializationPlugin_EvalListener.h>
-#include <ParametersPlugin_Parameter.h>
 #include <InitializationPlugin_PyInterp.h>
 
+#include <BuildPlugin_Interpolation.h>
+
+#include <ParametersPlugin_Parameter.h>
+
 #include <Events_InfoMessage.h>
 
 #include <Locale_Convert.h>
@@ -31,6 +34,7 @@
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeTables.h>
 #include <ModelAPI_AttributeValidator.h>
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Events.h>
 #include <string>
 #include <set>
 #include <sstream>
+#include <iostream>
+#include <algorithm>
 
-//------------------------------------------------------------------------------
+//=================================================================================================
 // Tools
 
 std::wstring toString(double theValue)
@@ -63,24 +69,26 @@ std::set<std::wstring> toSet(const std::list<std::wstring>& theContainer)
   return std::set<std::wstring>(theContainer.begin(), theContainer.end());
 }
 
-//------------------------------------------------------------------------------
-
+//=================================================================================================
 InitializationPlugin_EvalListener::InitializationPlugin_EvalListener()
 {
   Events_Loop* aLoop = Events_Loop::loop();
 
   aLoop->registerListener(this, ModelAPI_AttributeEvalMessage::eventId(), NULL, true);
   aLoop->registerListener(this, ModelAPI_ParameterEvalMessage::eventId(), NULL, true);
+  aLoop->registerListener(this, ModelAPI_BuildEvalMessage::eventId(), NULL, true);
   aLoop->registerListener(this, ModelAPI_ComputePositionsMessage::eventId(), NULL, true);
 
   myInterp = std::shared_ptr<InitializationPlugin_PyInterp>(new InitializationPlugin_PyInterp());
   myInterp->initialize();
 }
 
+//=================================================================================================
 InitializationPlugin_EvalListener::~InitializationPlugin_EvalListener()
 {
 }
 
+//=================================================================================================
 void InitializationPlugin_EvalListener::processEvent(
     const std::shared_ptr<Events_Message>& theMessage)
 {
@@ -105,9 +113,116 @@ void InitializationPlugin_EvalListener::processEvent(
     std::shared_ptr<ModelAPI_ComputePositionsMessage> aMsg =
       std::dynamic_pointer_cast<ModelAPI_ComputePositionsMessage>(theMessage);
     aMsg->setPositions(myInterp->positions(aMsg->expression(), aMsg->parameter()));
+  } 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;
+    bool anIsFirstTime = true;
+    anExprAttr = aParam->string(BuildPlugin_Interpolation::XT_ID());
+    std::wstring anExpX = anExprAttr->isUValue() ?
+    Locale::Convert::toWString(anExprAttr->valueU()) :
+    Locale::Convert::toWString(anExprAttr->value());
+    anExpX.erase(std::remove(anExpX.begin(), anExpX.end(), ' '), anExpX.end());
+    anExprAttr = aParam->string(BuildPlugin_Interpolation::YT_ID());
+    std::wstring anExpY = anExprAttr->isUValue() ?
+    Locale::Convert::toWString(anExprAttr->valueU()) :
+    Locale::Convert::toWString(anExprAttr->value());
+    anExpY.erase(std::remove(anExpY.begin(), anExpY.end(), ' '), anExpY.end());
+    anExprAttr = aParam->string(BuildPlugin_Interpolation::ZT_ID());
+    std::wstring anExpZ = anExprAttr->isUValue() ?
+    Locale::Convert::toWString(anExprAttr->valueU()) :
+    Locale::Convert::toWString(anExprAttr->value());
+    anExpZ.erase(std::remove(anExpZ.begin(),anExpZ.end(), ' '), anExpZ.end());
+
+    for (int step =0; step < anValueAttr->rows(); step++) {
+      aVal.myDouble = evaluate(anVar,
+                                anValueAttr->value(step,0).myDouble,
+                                aParam,
+                                anExpX,
+                                anError,
+                                aParamsList,
+                                anIsFirstTime);
+      if (!anError.empty()) break;
+      anValueAttr->setValue(aVal,step,1);
+      aVal.myDouble = evaluate(anVar,
+                              anValueAttr->value(step,0).myDouble,
+                              aParam,
+                              anExpY,
+                              anError,
+                              aParamsList,
+                              anIsFirstTime);
+      if (!anError.empty()) break;
+      anValueAttr->setValue(aVal,step,2);
+      aVal.myDouble = evaluate(anVar,
+                                anValueAttr->value(step,0).myDouble,
+                                aParam,
+                                anExpZ,
+                                anError,
+                                aParamsList,
+                                anIsFirstTime);
+      if (!anError.empty()) break;
+      anValueAttr->setValue(aVal,step,3);
+      if (anIsFirstTime)
+          anIsFirstTime = false;
+    }
+    aMsg->setResults(aParamsList, anError);
+  }
+}
+
+//=================================================================================================
+double InitializationPlugin_EvalListener::evaluate(std::wstring& theVariable,
+                              double theValueVariable,
+                              FeaturePtr theParameter,
+                              const std::wstring& theExpression,
+                              std::string& theError,
+                              std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
+                              bool theIsFirstTime)
+{
+  std::list<std::wstring> aContext;
+  aContext.push_back(theVariable + L"=" + toString(theValueVariable));
+  myInterp->extendLocalContext(aContext);
+  aContext.clear();
+
+  std::list<std::wstring> anExprParams = myInterp->compile(theExpression);
+  // find expression's params in the model
+  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.
+    if (!ModelAPI_Tools::findVariable(FeaturePtr(),
+                           *it, aValue, aParamRes, theParameter->document()))
+      continue;
+
+    if (theIsFirstTime)
+    {
+      std::list<ResultParameterPtr>::iterator anIter =
+                          std::find(theParamsList.begin(),theParamsList.end(), aParamRes);
+      if (anIter == theParamsList.end())
+        theParamsList.push_back(aParamRes);
+    }
+
+    aContext.push_back(*it + L"=" + toString(aValue));
   }
+  myInterp->extendLocalContext(aContext);
+  double result = myInterp->evaluate(theExpression, theError);
+  myInterp->clearLocalContext();
+  return result;
 }
 
+//=================================================================================================
 double InitializationPlugin_EvalListener::evaluate(FeaturePtr theParameter,
   const std::wstring& theExpression, std::string& theError,
   std::list<std::shared_ptr<ModelAPI_ResultParameter> >& theParamsList,
@@ -117,7 +232,7 @@ double InitializationPlugin_EvalListener::evaluate(FeaturePtr theParameter,
   // 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++) {
+  for (; it != anExprParams.end(); it++) {
     double aValue;
     ResultParameterPtr aParamRes;
     // If variable does not exist python interpreter will generate an error. It is OK.
@@ -137,6 +252,7 @@ double InitializationPlugin_EvalListener::evaluate(FeaturePtr theParameter,
   return result;
 }
 
+//=================================================================================================
 void InitializationPlugin_EvalListener::processEvaluationEvent(
     const std::shared_ptr<Events_Message>& theMessage)
 {
@@ -158,8 +274,7 @@ void InitializationPlugin_EvalListener::processEvaluationEvent(
       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()) {
+  } else if (aMessage->attribute()->attributeType() == ModelAPI_AttributeDouble::typeId()) {
     AttributeDoublePtr anAttribute =
         std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aMessage->attribute());
     std::string anError;
@@ -171,8 +286,7 @@ void InitializationPlugin_EvalListener::processEvaluationEvent(
       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()) {
+  } else if (aMessage->attribute()->attributeType() == GeomDataAPI_Point::typeId()) {
     AttributePointPtr anAttribute =
         std::dynamic_pointer_cast<GeomDataAPI_Point>(aMessage->attribute());
     std::wstring aText[] = {
@@ -198,8 +312,7 @@ void InitializationPlugin_EvalListener::processEvaluationEvent(
     anAttribute->setCalculatedValue(aCalculatedValue[0],
                                     aCalculatedValue[1],
                                     aCalculatedValue[2]);
-  } else
-  if (aMessage->attribute()->attributeType() == GeomDataAPI_Point2D::typeId()) {
+  } else if (aMessage->attribute()->attributeType() == GeomDataAPI_Point2D::typeId()) {
     AttributePoint2DPtr anAttribute =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aMessage->attribute());
     std::wstring aText[] = {
@@ -225,6 +338,7 @@ void InitializationPlugin_EvalListener::processEvaluationEvent(
   }
 }
 
+//=================================================================================================
 void InitializationPlugin_EvalListener::initDataModel()
 {
   myInterp->runString("import salome_iapp;salome_iapp.register_module_in_study(\"Shaper\")");
index 756b335ec0a739ee10c9bd1d63f7255338b87b3e..5036863a98be9bcc508d6d943aa535d4a947d66a 100644 (file)
@@ -50,11 +50,21 @@ class InitializationPlugin_EvalListener : public Events_Listener
 
  protected:
   /// Evaluates theExpression and returns its value.
-   double evaluate(std::shared_ptr<ModelAPI_Feature> theParameter,
+  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);
 
+  /// Evaluates theExpression with variable local 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,
+                  bool theIsFirstTime);
+
+
   /// Processes Evaluation event.
   void processEvaluationEvent(const std::shared_ptr<Events_Message>& theMessage);
 
index cebf9ca791fcf5133e83da9a5f31436ab5c704e3..054d0bacf4dc43c2b86e90a360aaa638707d2988 100644 (file)
@@ -188,6 +188,49 @@ 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 std::string& theError)
+{
+  myParamsList = theParamsList;
+  myError = theError;
+  myIsProcessed = true;
+}
+
+const std::list<std::shared_ptr<ModelAPI_ResultParameter> >&
+  ModelAPI_BuildEvalMessage::params() const
+{
+  return myParamsList;
+}
+
+bool ModelAPI_BuildEvalMessage::isProcessed()
+{
+  return myIsProcessed;
+}
+
+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..e11ab4b068d11b4fab7f5d214c90ef7e16b929e3 100644 (file)
@@ -352,6 +352,57 @@ 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
+  std::string myError; ///< error of processing, empty if there is no error
+  /// result of processing, list of parameters in expression found
+  std::list<std::shared_ptr<ModelAPI_ResultParameter> > myParamsList;
+
+ public:
+  /// Static. Returns EventID of the message.
+  MODELAPI_EXPORT static Events_ID& eventId()
+  {
+    static const char * MY_BUILD_EVALUATION_EVENT_ID("BuildEvaluationRequest");
+    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 std::string& theError);
+  /// 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 true if the expression is processed
+  MODELAPI_EXPORT bool isProcessed();
+
+  /// 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