Salome HOME
Issue #1158: To use parameters in integer attributes -- Data Model
authorspo <sergey.pokhodenko@opencascade.com>
Wed, 23 Dec 2015 14:27:48 +0000 (17:27 +0300)
committerspo <sergey.pokhodenko@opencascade.com>
Thu, 24 Dec 2015 13:27:48 +0000 (16:27 +0300)
17 files changed:
src/GeomData/GeomData_Point.h
src/GeomData/GeomData_Point2D.h
src/Model/Model_AttributeDouble.cpp
src/Model/Model_AttributeDouble.h
src/Model/Model_AttributeInteger.cpp
src/Model/Model_AttributeInteger.h
src/Model/Model_AttributeValidator.cpp
src/Model/Model_Data.cpp
src/Model/Model_Expression.cpp
src/Model/Model_Expression.h
src/Model/Model_Update.cpp
src/ModelAPI/ModelAPI_AttributeDouble.h
src/ModelAPI/ModelAPI_AttributeInteger.h
src/ModelAPI/ModelAPI_Expression.cpp
src/ModelAPI/ModelAPI_Expression.h
src/ParametersPlugin/ParametersPlugin_EvalListener.cpp
src/PythonAPI/model/tools.py

index 71c663e90e26a84b59171a346ae08531c261e359..56d9c042ba8ecb8f6bc3d9af2aa317b4e22c4d8e 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <TDF_Label.hxx>
 
-class ModelAPI_Expression;
+class ModelAPI_ExpressionDouble;
 
 /**\class GeomData_Point
  * \ingroup DataModel
@@ -21,7 +21,7 @@ class ModelAPI_Expression;
 class GeomData_Point : public GeomDataAPI_Point
 {
   enum { NUM_COMPONENTS = 3 };
-  std::shared_ptr<ModelAPI_Expression> myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y and Z 
+  std::shared_ptr<ModelAPI_ExpressionDouble> myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y and Z 
  public:
   /// Defines the double value
   GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY, const double theZ);
index 0384409ee91ced4458980ebcfb19f343c1572e5c..8b4affa03ebc1bec6f155723e283d0589fee1fbb 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <TDF_Label.hxx>
 
-class ModelAPI_Expression;
+class ModelAPI_ExpressionDouble;
 
 /**\class GeomData_Point2D
  * \ingroup DataModel
@@ -22,7 +22,7 @@ class ModelAPI_Expression;
 class GeomData_Point2D : public GeomDataAPI_Point2D
 {
   enum { NUM_COMPONENTS = 2 };
-  std::shared_ptr<ModelAPI_Expression> myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y
+  std::shared_ptr<ModelAPI_ExpressionDouble> myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y
  public:
   /// Defines the double value
   GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY);
index 91cebf7363bb3e18b96c3841b973795deab2bbf1..0a8566d119954485f051674eca21380c27045d1c 100644 (file)
@@ -9,7 +9,7 @@
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Expression.h>
-#include <ModelAPI_Feature.h>
+#include <ModelAPI_Object.h>
 
 Model_AttributeDouble::Model_AttributeDouble(TDF_Label& theLabel)
 {
@@ -38,7 +38,7 @@ void Model_AttributeDouble::setText(const std::string& theValue)
 {
   if (text() != theValue) {
     myExpression->setText(theValue);
-    // Send it to evaluator to convert into the double and store in the attribute
+    // Send it to evaluator to convert text to double and store in the attribute
     ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this);
     owner()->data()->sendAttributeUpdated(this);
   }
index 390cc66bc7bfcbe0824bb75ad9212d9c9850a48a..da9ca4b55d62cf0c67285873ccc7869598e20d5b 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <TDF_Label.hxx>
 
-class ModelAPI_Expression;
+class ModelAPI_ExpressionDouble;
 
 /**\class Model_AttributeDouble
  * \ingroup DataModel
@@ -21,7 +21,7 @@ class ModelAPI_Expression;
 
 class Model_AttributeDouble : public ModelAPI_AttributeDouble
 {
-  std::shared_ptr<ModelAPI_Expression> myExpression;
+  std::shared_ptr<ModelAPI_ExpressionDouble> myExpression;
 
  public:
   /// Defines the double value
index b93bfa855cec04391064137e5dea7d054ee32f13..bd355d4d8f27e9add6734490c96ff4e410bbe042 100644 (file)
@@ -6,32 +6,76 @@
 
 #include <Model_AttributeInteger.h>
 
-#include <ModelAPI_Attribute.h>
 #include <ModelAPI_Data.h>
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Expression.h>
 #include <ModelAPI_Object.h>
 
-#include <Standard_TypeDef.hxx>
-#include <TDataStd_Integer.hxx>
+Model_AttributeInteger::Model_AttributeInteger(TDF_Label& theLabel)
+{
+  myIsInitialized = true;
+}
 
-void Model_AttributeInteger::setValue(const int theValue)
+void Model_AttributeInteger::setCalculatedValue(const int theValue)
 {
-  if (!myIsInitialized || myInteger->Get() != theValue) {
-    myInteger->Set(theValue);
+  if (!myIsInitialized || value() != theValue) {
+    myExpression->setValue(theValue);
     owner()->data()->sendAttributeUpdated(this);
   }
 }
 
+void Model_AttributeInteger::setValue(const int theValue)
+{
+  setCalculatedValue(text().empty() ? theValue : value());
+}
+
 int Model_AttributeInteger::value()
 {
-  return myInteger->Get();
+  return myExpression->value();
 }
 
-Model_AttributeInteger::Model_AttributeInteger(TDF_Label& theLabel)
+void Model_AttributeInteger::setText(const std::string& theValue)
 {
-  // check the attribute could be already presented in this doc (after load document)
-  myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), myInteger) == Standard_True;
-  if (!myIsInitialized) {
-    // create attribute: not initialized by value yet, just zero
-    myInteger = TDataStd_Integer::Set(theLabel, 0);
+  if (text() != theValue) {
+    myExpression->setText(theValue);
+    // Send it to evaluator to convert text to integer and store in the attribute
+    ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
+
+std::string Model_AttributeInteger::text()
+{
+  return myExpression->text();
+}
+
+void Model_AttributeInteger::setExpressionInvalid(const bool theFlag)
+{
+  myExpression->setInvalid(theFlag);
+}
+
+bool Model_AttributeInteger::expressionInvalid()
+{
+  return myExpression->isInvalid();
+}
+
+void Model_AttributeInteger::setExpressionError(const std::string& theError)
+{
+  if (expressionError() != theError)
+    myExpression->setError(theError);
+}
+
+std::string Model_AttributeInteger::expressionError()
+{
+  return myExpression->error();
+}
+
+void Model_AttributeInteger::setUsedParameters(const std::set<std::string>& theUsedParameters)
+{
+  myExpression->setUsedParameters(theUsedParameters);
+}
+
+std::set<std::string> Model_AttributeInteger::usedParameters() const
+{
+  return myExpression->usedParameters();
+}
index 88b50a504af77c2d3ec7c202296fed2f9860af7d..bd6a12da3a36108febbb67c27c83b6e278517fe0 100644 (file)
 #include <ModelAPI_AttributeInteger.h>
 
 #include <TDF_Label.hxx>
-#include <TDataStd_Integer.hxx>
+
+class ModelAPI_ExpressionInteger;
 
 /**\class Model_AttributeInteger
  * \ingroup DataModel
- * \brief Attribute that contains integer (int).
+ * \brief Attribute that contains integer.
  */
 
 class Model_AttributeInteger : public ModelAPI_AttributeInteger
 {
-  Handle_TDataStd_Integer myInteger;
  public:
-  /// Defines the int value
+  /// Defines the integer value
   MODEL_EXPORT virtual void setValue(const int theValue);
 
-  /// Returns the int value
+  /// Returns the integer value
   MODEL_EXPORT virtual int value();
 
+  /// Defines the calculated value
+  MODEL_EXPORT virtual void setCalculatedValue(const int theValue);
+
+  /// Defines the text value
+  MODEL_EXPORT virtual void setText(const std::string& theText);
+
+  /// Returns the text value
+  MODEL_EXPORT virtual std::string text();
+
+  /// Allows to set expression (text) as invalid (by the parameters listener)
+  MODEL_EXPORT virtual void setExpressionInvalid(const bool theFlag);
+
+  /// Returns true if text is invalid
+  MODEL_EXPORT virtual bool expressionInvalid();
+
+  /// Allows to set expression (text) error (by the parameters listener)
+  MODEL_EXPORT virtual void setExpressionError(const std::string& theError);
+
+  /// Returns an expression error
+  MODEL_EXPORT virtual std::string expressionError();
+
+  /// Defines the used parameters
+  MODEL_EXPORT virtual void setUsedParameters(const std::set<std::string>& theUsedParameters);
+
+  /// Returns the used parameters
+  MODEL_EXPORT virtual std::set<std::string> usedParameters() const;
+
  protected:
   /// Initializes attributes
   Model_AttributeInteger(TDF_Label& theLabel);
 
   friend class Model_Data;
+
+ private:
+  std::shared_ptr<ModelAPI_ExpressionInteger> myExpression;
 };
 
 #endif
index 9a6c954653200f1ddd1b670d3df2d8928773294c..93e32183232445a6c22320e974106e371cdd34f6 100644 (file)
@@ -5,7 +5,10 @@
 // Author:      Sergey POKHODENKO
 
 #include "Model_AttributeValidator.h"
+
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
+
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 
@@ -13,6 +16,14 @@ bool Model_AttributeValidator::isValid(const AttributePtr& theAttribute,
                                        const std::list<std::string>& theArguments, 
                                        std::string& theError) const
 {
+  if (theAttribute->attributeType() == ModelAPI_AttributeInteger::typeId()) {
+    AttributeIntegerPtr anAttribue =
+        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttribute);
+    if (!anAttribue->expressionError().empty()) {
+      theError = anAttribue->expressionError();
+      return false;
+    }
+  } else
   if (theAttribute->attributeType() == ModelAPI_AttributeDouble::typeId()) {
     AttributeDoublePtr anAttribue = 
         std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
index 1072d921bc4ee4a125ced38c5f6775c708ab0181..42f04f66aa88fba4408115caedc3c4aa15ee3925 100644 (file)
@@ -120,12 +120,17 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin
   if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
     anAttr = new Model_AttributeDocRef(anAttrLab);
   } else if (theAttrType == Model_AttributeInteger::typeId()) {
-    anAttr = new Model_AttributeInteger(anAttrLab);
+    Model_AttributeInteger* anAttribute = new Model_AttributeInteger(anAttrLab);
+    // Expression should use the same label to support backward compatibility
+    TDF_Label anExpressionLab = anAttrLab;
+    anAttribute->myExpression.reset(new Model_ExpressionInteger(anExpressionLab));
+    anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized();
+    anAttr = anAttribute;
   } else if (theAttrType == ModelAPI_AttributeDouble::typeId()) {
     Model_AttributeDouble* anAttribute = new Model_AttributeDouble(anAttrLab);
     TDF_Label anExpressionLab = anAttrLab.FindChild(1);
-    anAttribute->myExpression.reset(new Model_Expression(anExpressionLab));
-    anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized(); 
+    anAttribute->myExpression.reset(new Model_ExpressionDouble(anExpressionLab));
+    anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized();
     anAttr = anAttribute;
   } else if (theAttrType == Model_AttributeBoolean::typeId()) {
     anAttr = new Model_AttributeBoolean(anAttrLab);
@@ -149,7 +154,7 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin
     GeomData_Point* anAttribute = new GeomData_Point(anAttrLab);
     for (int aComponent = 0; aComponent < GeomData_Point::NUM_COMPONENTS; ++aComponent) {
       TDF_Label anExpressionLab = anAttrLab.FindChild(aComponent + 1);
-      anAttribute->myExpression[aComponent].reset(new Model_Expression(anExpressionLab));
+      anAttribute->myExpression[aComponent].reset(new Model_ExpressionDouble(anExpressionLab));
       anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression[aComponent]->isInitialized(); 
     }
     anAttr = anAttribute;
@@ -159,7 +164,7 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin
     GeomData_Point2D* anAttribute = new GeomData_Point2D(anAttrLab);
     for (int aComponent = 0; aComponent < GeomData_Point2D::NUM_COMPONENTS; ++aComponent) {
       TDF_Label anExpressionLab = anAttrLab.FindChild(aComponent + 1);
-      anAttribute->myExpression[aComponent].reset(new Model_Expression(anExpressionLab));
+      anAttribute->myExpression[aComponent].reset(new Model_ExpressionDouble(anExpressionLab));
       anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression[aComponent]->isInitialized(); 
     }
     anAttr = anAttribute;
@@ -509,6 +514,12 @@ void Model_Data::referencesToObjects(
       for(int a = aRef->size() - 1; a >= 0; a--) {
         aReferenced.push_back(aRef->value(a)->context());
       }
+    } else if (aType == ModelAPI_AttributeInteger::typeId()) { // integer attribute
+      AttributeIntegerPtr anAttribute =
+          std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(anAttr->second);
+      std::set<std::string> anUsedParameters = anAttribute->usedParameters();
+      std::list<ResultParameterPtr> aParameters = findVariables(anUsedParameters, aMyFeature->document());
+      aReferenced.insert(aReferenced.end(), aParameters.begin(), aParameters.end());
     } else if (aType == ModelAPI_AttributeDouble::typeId()) { // double attribute
       AttributeDoublePtr anAttribute =
           std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr->second);
index 27e94d4067eedbd0ab8f78b2d9bc63e36b6d9133..ef7408e36f335d3f30a6d9782977442b71f090c7 100644 (file)
 #include <TDataStd_RealArray.hxx>
 #include <TDataStd_ExtStringArray.hxx>
 
+
+static Standard_GUID kInvalidGUID("caee5ce4-34b1-4b29-abcb-685287d18096");
+
+
 Model_Expression::Model_Expression(TDF_Label& theLabel)
 {
   myIsInitialized = true;
   if (!theLabel.FindAttribute(TDataStd_Name::GetID(), myText)) {
     myText = TDataStd_Name::Set(theLabel, TCollection_ExtendedString());
-    myIsInitialized = false;
+//    myIsInitialized = false;
   }
   if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myError)) {
     myError = TDataStd_Comment::Set(theLabel, TCollection_ExtendedString());
-    myIsInitialized = false;
+//    myIsInitialized = false;
   }
   if (!theLabel.FindAttribute(TDataStd_ExtStringList::GetID(), myUsedParameters)) {
     myUsedParameters = TDataStd_ExtStringList::Set(theLabel);
-    myIsInitialized = false;
+//    myIsInitialized = false;
   }
+  // All this attributes should not set myIsInitialized = false.
+  // This attributes are optional and may absent in old files. So this is OK.
+  // The reason to set myIsInitialized = false is only absence of
+  // the value attribute.
+}
+
+void Model_Expression::setText(const std::string& theValue)
+{
+  if (text() != theValue)
+    myText->Set(TCollection_ExtendedString(theValue.c_str()));
+
+  setError(text().empty() ? "" : "Not a double value.");
+}
+
+std::string Model_Expression::text() const 
+{
+  return TCollection_AsciiString(myText->Get()).ToCString();
+}
+
+void Model_Expression::setError(const std::string& theError)
+{
+  if (error() != theError)
+    myError->Set(TCollection_ExtendedString(theError.c_str()));
+}
+
+std::string Model_Expression::error()
+{
+  return TCollection_AsciiString(myError->Get()).ToCString();
+}
+
+void Model_Expression::setUsedParameters(const std::set<std::string>& theUsedParameters)
+{
+  myUsedParameters->Clear();
+  std::set<std::string>::const_iterator anIt = theUsedParameters.begin();
+  for (; anIt != theUsedParameters.end(); ++anIt)
+    myUsedParameters->Append(TCollection_ExtendedString(anIt->c_str()));
+}
+
+std::set<std::string> Model_Expression::usedParameters() const
+{
+  std::set<std::string> aResult;
+  TDataStd_ListIteratorOfListOfExtendedString aIt;
+  for (aIt.Initialize(myUsedParameters->List()); aIt.More(); aIt.Next())
+    aResult.insert(TCollection_AsciiString(aIt.Value()).ToCString());
+  return aResult;
+}
+
+Model_ExpressionDouble::Model_ExpressionDouble(TDF_Label& theLabel)
+    : Model_Expression(theLabel)
+{
   if (!theLabel.FindAttribute(TDataStd_Real::GetID(), myReal)) {
     myReal = TDataStd_Real::Set(theLabel, 0.);
     myIsInitialized = false;
@@ -52,37 +106,21 @@ Model_Expression::Model_Expression(TDF_Label& theLabel)
         }
       }
     }
-
   }
 }
 
-void Model_Expression::setValue(const double theValue)
+void Model_ExpressionDouble::setValue(const double theValue)
 {
   if (value() != theValue)
     myReal->Set(theValue);
 }
 
-double Model_Expression::value()
+double Model_ExpressionDouble::value()
 {
   return myReal->Get();
 }
 
-void Model_Expression::setText(const std::string& theValue)
-{
-  if (text() != theValue)
-    myText->Set(TCollection_ExtendedString(theValue.c_str()));
-
-  setError(text().empty() ? "" : "Not a double value.");
-}
-
-std::string Model_Expression::text() const 
-{
-  return TCollection_AsciiString(myText->Get()).ToCString();
-}
-
-static Standard_GUID kInvalidGUID("caee5ce4-34b1-4b29-abcb-685287d18096");
-
-void Model_Expression::setInvalid(const bool theFlag)
+void Model_ExpressionDouble::setInvalid(const bool theFlag)
 {
   if (theFlag) {
     TDataStd_UAttribute::Set(myReal->Label(), kInvalidGUID);
@@ -91,35 +129,42 @@ void Model_Expression::setInvalid(const bool theFlag)
   }
 }
 
-bool Model_Expression::isInvalid()
+bool Model_ExpressionDouble::isInvalid()
 {
   return myReal->Label().IsAttribute(kInvalidGUID) == Standard_True;
 }
 
-void Model_Expression::setError(const std::string& theError)
+
+Model_ExpressionInteger::Model_ExpressionInteger(TDF_Label& theLabel)
+    : Model_Expression(theLabel)
 {
-  if (error() != theError)
-    myError->Set(TCollection_ExtendedString(theError.c_str()));
+  if (!theLabel.FindAttribute(TDataStd_Integer::GetID(), myInteger)) {
+    myInteger = TDataStd_Integer::Set(theLabel, 0);
+    myIsInitialized = false;
+  }
 }
 
-std::string Model_Expression::error()
+void Model_ExpressionInteger::setValue(const int theValue)
 {
-  return TCollection_AsciiString(myError->Get()).ToCString();
+  if (value() != theValue)
+    myInteger->Set(theValue);
 }
 
-void Model_Expression::setUsedParameters(const std::set<std::string>& theUsedParameters)
+int Model_ExpressionInteger::value()
 {
-  myUsedParameters->Clear();
-  std::set<std::string>::const_iterator anIt = theUsedParameters.begin();
-  for (; anIt != theUsedParameters.end(); ++anIt)
-    myUsedParameters->Append(TCollection_ExtendedString(anIt->c_str()));
+  return myInteger->Get();
 }
 
-std::set<std::string> Model_Expression::usedParameters() const
+void Model_ExpressionInteger::setInvalid(const bool theFlag)
 {
-  std::set<std::string> aResult;
-  TDataStd_ListIteratorOfListOfExtendedString aIt;
-  for (aIt.Initialize(myUsedParameters->List()); aIt.More(); aIt.Next())
-    aResult.insert(TCollection_AsciiString(aIt.Value()).ToCString());
-  return aResult;
+  if (theFlag) {
+    TDataStd_UAttribute::Set(myInteger->Label(), kInvalidGUID);
+  } else {
+    myInteger->Label().ForgetAttribute(kInvalidGUID);
+  }
+}
+
+bool Model_ExpressionInteger::isInvalid()
+{
+  return myInteger->Label().IsAttribute(kInvalidGUID) == Standard_True;
 }
index 2963afd3667ecd5b325aa6efb9cfe3b6e23304a3..4e48d15cc6cdcb378082a5b04e952d430c058325 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <TDataStd_Comment.hxx>
 #include <TDataStd_ExtStringList.hxx>
+#include <TDataStd_Integer.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_Real.hxx>
 
  * \ingroup DataModel
  * \brief Implementation of ModelAPI_Expression.
  */
-class Model_Expression : public ModelAPI_Expression
+class Model_Expression : public virtual ModelAPI_Expression
 {
-  Handle_TDataStd_Real myReal; ///< double is Real attribute
-  Handle_TDataStd_Name myText; ///< Text representation of the attribute (may differ for parameters)
-  Handle_TDataStd_Comment myError; ///< Error of expression of the text attribute
-  Handle_TDataStd_ExtStringList myUsedParameters; ///< Parameters used in expression
  public:
-  /// Defines the double value
-  MODEL_EXPORT virtual void setValue(const double theValue);
-
-  /// Returns the double value
-  MODEL_EXPORT virtual double value();
-
   /// Sets the text of this Expression
   MODEL_EXPORT virtual void setText(const std::string& theText);
 
   /// Returns the text of this Expression
   MODEL_EXPORT virtual std::string text() const;
 
-  /// Allows to set expression (text) as invalid (by the parameters listener)
-  MODEL_EXPORT virtual void setInvalid(const bool theFlag);
-
-  /// Returns true if text is invalid
-  MODEL_EXPORT virtual bool isInvalid();
-
   /// Allows to set expression (text) error (by the parameters listener)
   MODEL_EXPORT virtual void setError(const std::string& theError);
 
@@ -62,7 +47,75 @@ class Model_Expression : public ModelAPI_Expression
   /// Initializes attributes
   Model_Expression(TDF_Label& theLabel);
 
+  Handle_TDataStd_Name myText; ///< Text representation of the attribute (may differ for parameters)
+  Handle_TDataStd_Comment myError; ///< Error of expression of the text attribute
+  Handle_TDataStd_ExtStringList myUsedParameters; ///< Parameters used in expression
+
   friend class Model_Data;
 };
 
-#endif
+
+/**\class Model_ExpressionDouble
+ * \ingroup DataModel
+ * \brief Implementation of ModelAPI_ExpressionDouble.
+ */
+class Model_ExpressionDouble :
+    public Model_Expression, // implementation inheritance
+    public ModelAPI_ExpressionDouble
+{
+ public:
+  /// Defines the double value
+  MODEL_EXPORT virtual void setValue(const double theValue);
+
+  /// Returns the double value
+  MODEL_EXPORT virtual double value();
+
+  /// Allows to set expression (text) as invalid (by the parameters listener)
+  MODEL_EXPORT virtual void setInvalid(const bool theFlag);
+
+  /// Returns true if text is invalid
+  MODEL_EXPORT virtual bool isInvalid();
+
+ protected:
+  /// Initializes attributes
+  Model_ExpressionDouble(TDF_Label& theLabel);
+
+  friend class Model_Data;
+
+ private:
+  Handle_TDataStd_Real myReal; ///< double is Real attribute
+};
+
+
+/**\class Model_ExpressionInteger
+ * \ingroup DataModel
+ * \brief Implementation of ModelAPI_ExpressionInteger.
+ */
+class Model_ExpressionInteger :
+    public Model_Expression, // implementation inheritance
+    public ModelAPI_ExpressionInteger
+{
+ public:
+  /// Defines the integer value
+  MODEL_EXPORT virtual void setValue(const int theValue);
+
+  /// Returns the integer value
+  MODEL_EXPORT virtual int value();
+
+  /// Allows to set expression (text) as invalid (by the parameters listener)
+  MODEL_EXPORT virtual void setInvalid(const bool theFlag);
+
+  /// Returns true if text is invalid
+  MODEL_EXPORT virtual bool isInvalid();
+
+ protected:
+  /// Initializes attributes
+  Model_ExpressionInteger(TDF_Label& theLabel);
+
+  friend class Model_Data;
+
+ private:
+  Handle_TDataStd_Integer myInteger;
+};
+
+#endif // Model_Expression_H_
index 9d655c03c64a57db054c18350b13bd99554b50fc..5749ee70bc98748941cf413a598a6da047b6bb26 100644 (file)
@@ -488,19 +488,39 @@ void Model_Update::updateArguments(FeaturePtr theFeature) {
   if (aState == ModelAPI_StateInvalidArgument) // a chance to be corrected
     aState = ModelAPI_StateMustBeUpdated;
   // check the parameters state
-  // Double
-  std::list<AttributePtr> aDoubles =
-    theFeature->data()->attributes(ModelAPI_AttributeDouble::typeId());
-  std::list<AttributePtr>::iterator aDoubleIter = aDoubles.begin();
-  for(; aDoubleIter != aDoubles.end(); aDoubleIter++) {
-    AttributeDoublePtr aDouble =
-      std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(*aDoubleIter);
-    if (aDouble.get() && !aDouble->text().empty()) {
-      if (myIsParamUpdated) {
-        ModelAPI_AttributeEvalMessage::send(aDouble, this);
+  // Integer
+  {
+    std::list<AttributePtr> anAttrinbutes =
+      theFeature->data()->attributes(ModelAPI_AttributeInteger::typeId());
+    std::list<AttributePtr>::iterator anIter = anAttrinbutes.begin();
+    for(; anIter != anAttrinbutes.end(); anIter++) {
+      AttributeIntegerPtr anAttribute =
+        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(*anIter);
+      if (anAttribute.get() && !anAttribute->text().empty()) {
+        if (myIsParamUpdated) {
+          ModelAPI_AttributeEvalMessage::send(anAttribute, this);
+        }
+        if (anAttribute->expressionInvalid()) {
+          aState = ModelAPI_StateInvalidArgument;
+        }
       }
-      if (aDouble->expressionInvalid()) {
-        aState = ModelAPI_StateInvalidArgument;
+    }
+  }
+  // Double
+  {
+    std::list<AttributePtr> aDoubles =
+      theFeature->data()->attributes(ModelAPI_AttributeDouble::typeId());
+    std::list<AttributePtr>::iterator aDoubleIter = aDoubles.begin();
+    for(; aDoubleIter != aDoubles.end(); aDoubleIter++) {
+      AttributeDoublePtr aDouble =
+        std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(*aDoubleIter);
+      if (aDouble.get() && !aDouble->text().empty()) {
+        if (myIsParamUpdated) {
+          ModelAPI_AttributeEvalMessage::send(aDouble, this);
+        }
+        if (aDouble->expressionInvalid()) {
+          aState = ModelAPI_StateInvalidArgument;
+        }
       }
     }
   }
index 9332e61b2f7cbaff46525b8d165433436fe820be..79370eedd8965fa16529f11da45aa6e4986e4d50 100644 (file)
@@ -7,11 +7,10 @@
 #ifndef ModelAPI_AttributeDouble_H_
 #define ModelAPI_AttributeDouble_H_
 
-#include "ModelAPI_Attribute.h"
+#include <ModelAPI_Attribute.h>
 
 #include <set>
-
-class ModelAPI_Expression;
+#include <string>
 
 /**\class ModelAPI_AttributeDouble
  * \ingroup DataModel
index d16924a98feb67e4822e11f6eb8859d3f13b8241..52062faef0f01279f1814d342f65794e9da929eb 100644 (file)
@@ -7,12 +7,11 @@
 #ifndef MODELAPI_ATTRIBUTEINTEGER_H_
 #define MODELAPI_ATTRIBUTEINTEGER_H_
 
-#include <ModelAPI.h>
 #include <ModelAPI_Attribute.h>
 
+#include <set>
 #include <string>
 
-
 /**\class ModelAPI_AttributeInteger
  * \ingroup DataModel
  * \brief API for the attribute that contains integer (int).
@@ -27,6 +26,33 @@ class ModelAPI_AttributeInteger : public ModelAPI_Attribute
   /// Returns the integer value
   MODELAPI_EXPORT virtual int value() = 0;
 
+  /// Defines the calculated value
+  MODELAPI_EXPORT virtual void setCalculatedValue(const int theValue) = 0;
+
+  /// Defines the text value
+  MODELAPI_EXPORT virtual void setText(const std::string& theText) = 0;
+
+  /// Returns the text value
+  MODELAPI_EXPORT virtual std::string text() = 0;
+
+  /// Allows to set expression (text) as invalid (by the parameters listener)
+  MODELAPI_EXPORT virtual void setExpressionInvalid(const bool theFlag) = 0;
+
+  /// Returns true if text is invalid
+  MODELAPI_EXPORT virtual bool expressionInvalid() = 0;
+
+  /// Allows to set expression (text) error (by the parameters listener)
+  MODELAPI_EXPORT virtual void setExpressionError(const std::string& theError) = 0;
+
+  /// Returns an expression error
+  MODELAPI_EXPORT virtual std::string expressionError() = 0;
+
+  /// Defines the used parameters
+  MODELAPI_EXPORT virtual void setUsedParameters(const std::set<std::string>& theUsedParameters) = 0;
+
+  /// Returns the used parameters
+  MODELAPI_EXPORT virtual std::set<std::string> usedParameters() const = 0;
+
   /// Returns the type of this class of attributes
   MODELAPI_EXPORT static std::string typeId()
   {
index 39284ef28a9ca195648e63150a2362a3a223e813..bc966b1312d63f68c66249d96e7ee3cfbaa4eaa5 100644 (file)
@@ -25,3 +25,13 @@ void ModelAPI_Expression::setInitialized()
 {
   myIsInitialized = true;
 }
+
+ModelAPI_ExpressionDouble::ModelAPI_ExpressionDouble()
+{
+
+}
+
+ModelAPI_ExpressionInteger::ModelAPI_ExpressionInteger()
+{
+
+}
index 2c140b63b11865a2ee5000e738549ce057657be4..c583e58c7afecbb52991f6e62ac33a2b48e2079f 100644 (file)
@@ -8,6 +8,7 @@
 #define ModelAPI_Expression_H_
 
 #include "ModelAPI.h"
+
 #include <memory>
 #include <set>
 #include <string>
@@ -18,9 +19,6 @@
  */
 class ModelAPI_Expression
 {
- protected:
-  bool myIsInitialized; ///< is some value assigned to this attribute
-
  public:
   /// To virtually destroy the fields of successors
   MODELAPI_EXPORT virtual ~ModelAPI_Expression();
@@ -31,12 +29,6 @@ class ModelAPI_Expression
   /// Makes attribute initialized
   MODELAPI_EXPORT virtual void setInitialized();
 
-  /// Defines the double value
-  MODELAPI_EXPORT virtual void setValue(const double theValue) = 0;
-
-  /// Returns the double value
-  MODELAPI_EXPORT virtual double value() = 0;
-
   /// Sets the text of this Expression
   MODELAPI_EXPORT virtual void setText(const std::string& theText) = 0;
 
@@ -65,10 +57,57 @@ class ModelAPI_Expression
   /// Objects are created for features automatically
   MODELAPI_EXPORT ModelAPI_Expression();
 
+  bool myIsInitialized; ///< is some value assigned to this attribute
+
   friend class Model_Data;
 };
 
-//! Pointer on Expression object
+
+/**\class ModelAPI_ExpressionDouble
+ * \ingroup DataModel
+ * \brief Expression for calculated double values.
+ */
+class ModelAPI_ExpressionDouble : public virtual ModelAPI_Expression
+{
+ public:
+  /// Defines the double value
+  MODELAPI_EXPORT virtual void setValue(const double theValue) = 0;
+
+  /// Returns the double value
+  MODELAPI_EXPORT virtual double value() = 0;
+
+ protected:
+  /// Objects are created for features automatically
+  MODELAPI_EXPORT ModelAPI_ExpressionDouble();
+
+  friend class Model_Data;
+};
+
+
+/**\class ModelAPI_ExpressionInteger
+ * \ingroup DataModel
+ * \brief Expression for calculated integer values.
+ */
+class ModelAPI_ExpressionInteger : public virtual ModelAPI_Expression
+{
+ public:
+  /// Defines the integer value
+  MODELAPI_EXPORT virtual void setValue(const int theValue) = 0;
+
+  /// Returns the integer value
+  MODELAPI_EXPORT virtual int value() = 0;
+
+ protected:
+  /// Objects are created for features automatically
+  MODELAPI_EXPORT ModelAPI_ExpressionInteger();
+
+  friend class Model_Data;
+};
+
+
+//! Smart pointers for objects
 typedef std::shared_ptr<ModelAPI_Expression> ExpressionPtr;
+typedef std::shared_ptr<ModelAPI_ExpressionDouble> ExpressionDoublePtr;
+typedef std::shared_ptr<ModelAPI_ExpressionInteger> ExpressionIntegerPtr;
 
 #endif
index 3d5212bfb25db258485de23eddf5231d1ebecd68..126b0b0f0346ba509e2bfa9ff761066530d59eed 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <Events_Error.h>
 
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeValidator.h>
@@ -21,7 +23,6 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Tools.h>
 
-#include <ModelAPI_AttributeDouble.h>
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 
@@ -116,6 +117,18 @@ void ParametersPlugin_EvalListener::processEvaluationEvent(
   std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
       std::dynamic_pointer_cast<ModelAPI_AttributeEvalMessage>(theMessage);
 
+  if (aMessage->attribute()->attributeType() == ModelAPI_AttributeInteger::typeId()) {
+    AttributeIntegerPtr anAttribute =
+        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aMessage->attribute());
+    std::string anError;
+    int aValue = (int)evaluate(anAttribute->text(), anError, anAttribute->owner()->document());
+    bool isValid = anError.empty();
+    if (isValid)
+      anAttribute->setCalculatedValue(aValue);
+    anAttribute->setUsedParameters(isValid ? toSet(myInterp->compile(anAttribute->text())) : std::set<std::string>());
+    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());
@@ -241,6 +254,14 @@ void ParametersPlugin_EvalListener::renameInAttribute(
     const std::string& theOldName,
     const std::string& theNewName)
 {
+  if (theAttribute->attributeType() == ModelAPI_AttributeInteger::typeId()) {
+    AttributeIntegerPtr anAttribute =
+        std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(theAttribute);
+    std::string anExpressionString = anAttribute->text();
+    anExpressionString = renameInPythonExpression(anExpressionString,
+                                                  theOldName, theNewName);
+    anAttribute->setText(anExpressionString);
+  } else
   if (theAttribute->attributeType() == ModelAPI_AttributeDouble::typeId()) {
     AttributeDoublePtr anAttribute =
         std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
index 36726317a9d52a52134f5db8b0f939ceb98a1bd4..5081261863a166b52a4fd0c36d9cc4cf5288543a 100644 (file)
@@ -62,7 +62,6 @@ def fill_attribute(attribute, value):
     """
     if (isinstance(attribute, ModelAPI.ModelAPI_AttributeBoolean) or
         isinstance(attribute, ModelAPI.ModelAPI_AttributeDocRef) or
-        isinstance(attribute, ModelAPI.ModelAPI_AttributeInteger) or
         isinstance(attribute, ModelAPI.ModelAPI_AttributeReference)
         ):
         attribute.setValue(value)
@@ -70,7 +69,9 @@ def fill_attribute(attribute, value):
     elif isinstance(attribute, ModelAPI.ModelAPI_AttributeString):
         attribute.setValue(str(value))
 
-    elif isinstance(attribute, ModelAPI.ModelAPI_AttributeDouble):
+    elif (isinstance(attribute, ModelAPI.ModelAPI_AttributeDouble) or
+          isinstance(attribute, ModelAPI.ModelAPI_AttributeInteger)
+          ):
         if isinstance(value, basestring):
             attribute.setText(value)
         else: