From f8c36784f4699f0e3d04f4e8e067c7bd317b4a1c Mon Sep 17 00:00:00 2001 From: spo Date: Wed, 5 Aug 2015 17:25:43 +0300 Subject: [PATCH] Introduce ModelAPI_Expression. Implement DoubleAttribute, Point and Point2D using ModelAPI_Expression. --- src/GeomData/GeomData_Point.cpp | 98 ++++++++++++------------ src/GeomData/GeomData_Point.h | 25 +++++-- src/GeomData/GeomData_Point2D.cpp | 87 ++++++++++++---------- src/GeomData/GeomData_Point2D.h | 24 ++++-- src/GeomDataAPI/GeomDataAPI_Point.h | 15 ++++ src/GeomDataAPI/GeomDataAPI_Point2D.h | 15 ++++ src/Model/CMakeLists.txt | 2 + src/Model/Model_AttributeDouble.cpp | 72 +++++++++--------- src/Model/Model_AttributeDouble.h | 22 ++++-- src/Model/Model_Data.cpp | 20 ++++- src/Model/Model_Expression.cpp | 99 +++++++++++++++++++++++++ src/Model/Model_Expression.h | 68 +++++++++++++++++ src/ModelAPI/CMakeLists.txt | 2 + src/ModelAPI/ModelAPI_Attribute.h | 4 +- src/ModelAPI/ModelAPI_AttributeDouble.h | 16 ++++ src/ModelAPI/ModelAPI_Expression.cpp | 27 +++++++ src/ModelAPI/ModelAPI_Expression.h | 74 ++++++++++++++++++ 17 files changed, 525 insertions(+), 145 deletions(-) create mode 100644 src/Model/Model_Expression.cpp create mode 100644 src/Model/Model_Expression.h create mode 100644 src/ModelAPI/ModelAPI_Expression.cpp create mode 100644 src/ModelAPI/ModelAPI_Expression.h diff --git a/src/GeomData/GeomData_Point.cpp b/src/GeomData/GeomData_Point.cpp index 894550ba8..d034dd656 100644 --- a/src/GeomData/GeomData_Point.cpp +++ b/src/GeomData/GeomData_Point.cpp @@ -5,20 +5,27 @@ // Author: Mikhail PONIKAROV #include "GeomData_Point.h" + #include -#include + #include #include +#include +#include + +#include -using namespace std; +GeomData_Point::GeomData_Point(TDF_Label& theLabel) +{ + myIsInitialized = true; +} void GeomData_Point::setCalculatedValue(const double theX, const double theY, const double theZ) { - if (!myIsInitialized || myCoords->Value(0) != theX || myCoords->Value(1) != theY - || myCoords->Value(2) != theZ) { - myCoords->SetValue(0, theX); - myCoords->SetValue(1, theY); - myCoords->SetValue(2, theZ); + if (!myIsInitialized || x() != theX || y() != theY || z() != theZ) { + myExpression[0]->setValue(theX); + myExpression[1]->setValue(theY); + myExpression[2]->setValue(theZ); owner()->data()->sendAttributeUpdated(this); } } @@ -37,23 +44,22 @@ void GeomData_Point::setValue(const std::shared_ptr& thePoint) double GeomData_Point::x() const { - return myCoords->Value(0); + return myExpression[0]->value(); } double GeomData_Point::y() const { - return myCoords->Value(1); + return myExpression[1]->value(); } double GeomData_Point::z() const { - return myCoords->Value(2); + return myExpression[2]->value(); } std::shared_ptr GeomData_Point::pnt() { - std::shared_ptr aResult( - new GeomAPI_Pnt(myCoords->Value(0), myCoords->Value(1), myCoords->Value(2))); + std::shared_ptr aResult(new GeomAPI_Pnt(x(), y(), z())); return aResult; } @@ -61,17 +67,10 @@ void GeomData_Point::setText(const std::string& theX, const std::string& theY, const std::string& theZ) { - TCollection_ExtendedString aX(theX.c_str()); - TCollection_ExtendedString aY(theY.c_str()); - TCollection_ExtendedString aZ(theZ.c_str()); - - if (!myIsInitialized || - myTextArray->Value(0) != aX || - myTextArray->Value(1) != aY || - myTextArray->Value(2) != aZ) { - myTextArray->SetValue(0, aX); - myTextArray->SetValue(1, aY); - myTextArray->SetValue(2, aZ); + if (!myIsInitialized || textX() != theX || textY() != theY || textZ() != theZ) { + myExpression[0]->setText(theX); + myExpression[1]->setText(theY); + myExpression[2]->setText(theZ); // Send it to evaluator to convert into the double and store in the attribute ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this); owner()->data()->sendAttributeUpdated(this); @@ -80,46 +79,51 @@ void GeomData_Point::setText(const std::string& theX, std::string GeomData_Point::textX() { - return TCollection_AsciiString(myTextArray->Value(0)).ToCString();; + return myExpression[0]->text(); } std::string GeomData_Point::textY() { - return TCollection_AsciiString(myTextArray->Value(1)).ToCString();; + return myExpression[1]->text(); } std::string GeomData_Point::textZ() { - return TCollection_AsciiString(myTextArray->Value(2)).ToCString();; + return myExpression[2]->text(); } void GeomData_Point::setExpressionInvalid(int theComponent, bool theFlag) { - if (!myIsInitialized || myExpressionInvalidArray->Value(theComponent) != theFlag) { - myExpressionInvalidArray->SetValue(theComponent, theFlag); - } + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + if (!myIsInitialized || expressionInvalid(theComponent) != theFlag) + myExpression[theComponent]->setInvalid(theFlag); } bool GeomData_Point::expressionInvalid(int theComponent) { - return myExpressionInvalidArray->Value(theComponent); + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + return myExpression[theComponent]->isInvalid(); } -GeomData_Point::GeomData_Point(TDF_Label& theLabel) +void GeomData_Point::setExpressionError(int theComponent, const std::string& theError) { - myIsInitialized = true; + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + if (expressionError(theComponent) != theError) + myExpression[theComponent]->setError(theError); +} - if (theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords) != Standard_True) { - // create attribute: not initialized by value yet, just zero - myCoords = TDataStd_RealArray::Set(theLabel, 0, 2); - myIsInitialized = false; - } - if (theLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), myTextArray) != Standard_True) { - // create attribute: not initialized by value yet, just zero - myTextArray = TDataStd_ExtStringArray::Set(theLabel, 0, 2); - myIsInitialized = false; - } - if (theLabel.FindAttribute(TDataStd_BooleanArray::GetID(), myExpressionInvalidArray) != Standard_True) { - // create attribute: not initialized by value yet, just zero - myExpressionInvalidArray = TDataStd_BooleanArray::Set(theLabel, 0, 2); - myIsInitialized = false; - } +std::string GeomData_Point::expressionError(int theComponent) +{ + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + return myExpression[theComponent]->error(); +} + +void GeomData_Point::setUsedParameters(int theComponent, const std::set& theUsedParameters) +{ + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + myExpression[theComponent]->setUsedParameters(theUsedParameters); +} + +std::set GeomData_Point::usedParameters(int theComponent) const +{ + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + return myExpression[theComponent]->usedParameters(); } diff --git a/src/GeomData/GeomData_Point.h b/src/GeomData/GeomData_Point.h index f01814359..71c663e90 100644 --- a/src/GeomData/GeomData_Point.h +++ b/src/GeomData/GeomData_Point.h @@ -9,21 +9,19 @@ #include "GeomData.h" #include "GeomDataAPI_Point.h" -#include -#include -#include + #include +class ModelAPI_Expression; + /**\class GeomData_Point * \ingroup DataModel * \brief Attribute that contains 3D point. */ - class GeomData_Point : public GeomDataAPI_Point { - Handle_TDataStd_RealArray myCoords; ///< X, Y and Z doubles as real array attribute [0; 2] - Handle_TDataStd_ExtStringArray myTextArray; ///< Text representation of the X, Y and Z attributes [0; 2] - Handle_TDataStd_BooleanArray myExpressionInvalidArray; ///< Flag of invalid expression of the X, Y and Z attributes [0; 2] + enum { NUM_COMPONENTS = 3 }; + std::shared_ptr 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); @@ -60,6 +58,19 @@ class GeomData_Point : public GeomDataAPI_Point /// Returns true if text is invalid GEOMDATA_EXPORT virtual bool expressionInvalid(int); + /// Allows to set expression (text) error (by the parameters listener) + GEOMDATA_EXPORT virtual void setExpressionError(int theComponent, const std::string& theError); + + /// Returns an expression error + GEOMDATA_EXPORT virtual std::string expressionError(int theComponent); + + /// Defines the used parameters + GEOMDATA_EXPORT virtual void setUsedParameters(int theComponent, + const std::set& theUsedParameters); + + /// Returns the used parameters + GEOMDATA_EXPORT virtual std::set usedParameters(int theComponent) const; + protected: /// Initializes attributes GEOMDATA_EXPORT GeomData_Point(TDF_Label& theLabel); diff --git a/src/GeomData/GeomData_Point2D.cpp b/src/GeomData/GeomData_Point2D.cpp index 8bb2eaa31..0eca72f8c 100644 --- a/src/GeomData/GeomData_Point2D.cpp +++ b/src/GeomData/GeomData_Point2D.cpp @@ -5,18 +5,26 @@ // Author: Mikhail PONIKAROV #include "GeomData_Point2D.h" + #include -#include + #include #include +#include +#include + +#include -using namespace std; +GeomData_Point2D::GeomData_Point2D(TDF_Label& theLabel) +{ + myIsInitialized = true; +} void GeomData_Point2D::setCalculatedValue(const double theX, const double theY) { - if (!myIsInitialized || myCoords->Value(0) != theX || myCoords->Value(1) != theY) { - myCoords->SetValue(0, theX); - myCoords->SetValue(1, theY); + if (!myIsInitialized || x() != theX || y() != theY) { + myExpression[0]->setValue(theX); + myExpression[1]->setValue(theY); owner()->data()->sendAttributeUpdated(this); } } @@ -34,32 +42,26 @@ void GeomData_Point2D::setValue(const std::shared_ptr& thePoint) double GeomData_Point2D::x() const { - return myCoords->Value(0); + return myExpression[0]->value(); } double GeomData_Point2D::y() const { - return myCoords->Value(1); + return myExpression[1]->value(); } std::shared_ptr GeomData_Point2D::pnt() { - std::shared_ptr aResult( - new GeomAPI_Pnt2d(myCoords->Value(0), myCoords->Value(1))); + std::shared_ptr aResult(new GeomAPI_Pnt2d(x(), y())); return aResult; } void GeomData_Point2D::setText(const std::string& theX, const std::string& theY) { - TCollection_ExtendedString aX(theX.c_str()); - TCollection_ExtendedString aY(theY.c_str()); - - if (!myIsInitialized || - myTextArray->Value(0) != aX || - myTextArray->Value(1) != aY) { - myTextArray->SetValue(0, aX); - myTextArray->SetValue(1, aY); + if (!myIsInitialized || textX() != theX || textY() != theY) { + myExpression[0]->setText(theX); + myExpression[1]->setText(theY); // Send it to evaluator to convert into the double and store in the attribute ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this); owner()->data()->sendAttributeUpdated(this); @@ -68,42 +70,47 @@ void GeomData_Point2D::setText(const std::string& theX, std::string GeomData_Point2D::textX() { - return TCollection_AsciiString(myTextArray->Value(0)).ToCString();; + return myExpression[0]->text(); } std::string GeomData_Point2D::textY() { - return TCollection_AsciiString(myTextArray->Value(1)).ToCString();; + return myExpression[1]->text(); } void GeomData_Point2D::setExpressionInvalid(int theComponent, bool theFlag) { - if (!myIsInitialized || myExpressionInvalidArray->Value(theComponent) != theFlag) { - myExpressionInvalidArray->SetValue(theComponent, theFlag); - } + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + if (!myIsInitialized || expressionInvalid(theComponent) != theFlag) + myExpression[theComponent]->setInvalid(theFlag); } bool GeomData_Point2D::expressionInvalid(int theComponent) { - return myExpressionInvalidArray->Value(theComponent); + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + return myExpression[theComponent]->isInvalid(); } -GeomData_Point2D::GeomData_Point2D(TDF_Label& theLabel) +void GeomData_Point2D::setExpressionError(int theComponent, const std::string& theError) { - myIsInitialized = true; + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + if (expressionError(theComponent) != theError) + myExpression[theComponent]->setError(theError); +} - if (theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords) != Standard_True) { - // create attribute: not initialized by value yet, just zero - myCoords = TDataStd_RealArray::Set(theLabel, 0, 1); - myIsInitialized = false; - } - if (theLabel.FindAttribute(TDataStd_ExtStringArray::GetID(), myTextArray) != Standard_True) { - // create attribute: not initialized by value yet, just zero - myTextArray = TDataStd_ExtStringArray::Set(theLabel, 0, 1); - myIsInitialized = false; - } - if (theLabel.FindAttribute(TDataStd_BooleanArray::GetID(), myExpressionInvalidArray) != Standard_True) { - // create attribute: not initialized by value yet, just zero - myExpressionInvalidArray = TDataStd_BooleanArray::Set(theLabel, 0, 1); - myIsInitialized = false; - } +std::string GeomData_Point2D::expressionError(int theComponent) +{ + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + return myExpression[theComponent]->error(); +} + +void GeomData_Point2D::setUsedParameters(int theComponent, const std::set& theUsedParameters) +{ + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + myExpression[theComponent]->setUsedParameters(theUsedParameters); +} + +std::set GeomData_Point2D::usedParameters(int theComponent) const +{ + assert(theComponent >= 0 && theComponent < NUM_COMPONENTS); + return myExpression[theComponent]->usedParameters(); } diff --git a/src/GeomData/GeomData_Point2D.h b/src/GeomData/GeomData_Point2D.h index 503674150..0384409ee 100644 --- a/src/GeomData/GeomData_Point2D.h +++ b/src/GeomData/GeomData_Point2D.h @@ -9,11 +9,11 @@ #include "GeomData.h" #include "GeomDataAPI_Point2D.h" -#include -#include -#include + #include +class ModelAPI_Expression; + /**\class GeomData_Point2D * \ingroup DataModel * \brief Attribute that contains 2D point. @@ -21,9 +21,8 @@ class GeomData_Point2D : public GeomDataAPI_Point2D { - Handle_TDataStd_RealArray myCoords; ///< X and Y doubles as real array attribute [0; 1] - Handle_TDataStd_ExtStringArray myTextArray; ///< Text representation of the X, Y and Z attributes [0; 2] - Handle_TDataStd_BooleanArray myExpressionInvalidArray; ///< Flag of invalid expression of the X, Y and Z attributes [0; 2] + enum { NUM_COMPONENTS = 2 }; + std::shared_ptr myExpression[NUM_COMPONENTS]; ///< Expressions for X, Y public: /// Defines the double value GEOMDATA_EXPORT virtual void setValue(const double theX, const double theY); @@ -54,6 +53,19 @@ class GeomData_Point2D : public GeomDataAPI_Point2D /// Returns true if text is invalid GEOMDATA_EXPORT virtual bool expressionInvalid(int); + /// Allows to set expression (text) error (by the parameters listener) + GEOMDATA_EXPORT virtual void setExpressionError(int theComponent, const std::string& theError); + + /// Returns an expression error + GEOMDATA_EXPORT virtual std::string expressionError(int theComponent); + + /// Defines the used parameters + GEOMDATA_EXPORT virtual void setUsedParameters(int theComponent, + const std::set& theUsedParameters); + + /// Returns the used parameters + GEOMDATA_EXPORT virtual std::set usedParameters(int theComponent) const; + protected: /// Initializes attributes GEOMDATA_EXPORT GeomData_Point2D(TDF_Label& theLabel); diff --git a/src/GeomDataAPI/GeomDataAPI_Point.h b/src/GeomDataAPI/GeomDataAPI_Point.h index e021a4a1a..0167f479b 100644 --- a/src/GeomDataAPI/GeomDataAPI_Point.h +++ b/src/GeomDataAPI/GeomDataAPI_Point.h @@ -10,6 +10,8 @@ #include "GeomDataAPI.h" #include +#include + class GeomAPI_Pnt; /**\class GeomDataAPI_Point @@ -58,6 +60,19 @@ class GeomDataAPI_Point : public ModelAPI_Attribute /// Returns true if text is invalid GEOMDATAAPI_EXPORT virtual bool expressionInvalid(int theComponent) = 0; + /// Allows to set expression (text) error (by the parameters listener) + GEOMDATAAPI_EXPORT virtual void setExpressionError(int theComponent, const std::string& theError) = 0; + + /// Returns an expression error + GEOMDATAAPI_EXPORT virtual std::string expressionError(int theComponent) = 0; + + /// Defines the used parameters + GEOMDATAAPI_EXPORT virtual void setUsedParameters(int theComponent, + const std::set& theUsedParameters) = 0; + + /// Returns the used parameters + GEOMDATAAPI_EXPORT virtual std::set usedParameters(int theComponent) const = 0; + /// Returns the type of this class of attributes static std::string typeId() { diff --git a/src/GeomDataAPI/GeomDataAPI_Point2D.h b/src/GeomDataAPI/GeomDataAPI_Point2D.h index 3da9d2f00..021d24b7c 100644 --- a/src/GeomDataAPI/GeomDataAPI_Point2D.h +++ b/src/GeomDataAPI/GeomDataAPI_Point2D.h @@ -10,6 +10,8 @@ #include #include +#include + class GeomAPI_Pnt2d; /**\class GeomDataAPI_Point2D @@ -53,6 +55,19 @@ class GeomDataAPI_Point2D : public ModelAPI_Attribute /// Returns true if text is invalid GEOMDATAAPI_EXPORT virtual bool expressionInvalid(int theComponent) = 0; + /// Allows to set expression (text) error (by the parameters listener) + GEOMDATAAPI_EXPORT virtual void setExpressionError(int theComponent, const std::string& theError) = 0; + + /// Returns an expression error + GEOMDATAAPI_EXPORT virtual std::string expressionError(int theComponent) = 0; + + /// Defines the used parameters + GEOMDATAAPI_EXPORT virtual void setUsedParameters(int theComponent, + const std::set& theUsedParameters) = 0; + + /// Returns the used parameters + GEOMDATAAPI_EXPORT virtual std::set usedParameters(int theComponent) const = 0; + /// Appends the delta values to point GEOMDATAAPI_EXPORT void move(const double theDeltaX, const double theDeltaY); diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 156764125..36eb50535 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -22,6 +22,7 @@ SET(PROJECT_HEADERS Model_AttributeSelectionList.h Model_BodyBuilder.h Model_Events.h + Model_Expression.h Model_Update.h Model_Validator.h Model_ResultBody.h @@ -52,6 +53,7 @@ SET(PROJECT_SOURCES Model_AttributeSelectionList.cpp Model_BodyBuilder.cpp Model_Events.cpp + Model_Expression.cpp Model_Update.cpp Model_Validator.cpp Model_ResultBody.cpp diff --git a/src/Model/Model_AttributeDouble.cpp b/src/Model/Model_AttributeDouble.cpp index 009de2b8e..91cebf736 100644 --- a/src/Model/Model_AttributeDouble.cpp +++ b/src/Model/Model_AttributeDouble.cpp @@ -5,20 +5,21 @@ // Author: Mikhail PONIKAROV #include "Model_AttributeDouble.h" -#include + #include #include +#include +#include -#include -#include -#include - -using namespace std; +Model_AttributeDouble::Model_AttributeDouble(TDF_Label& theLabel) +{ + myIsInitialized = true; +} void Model_AttributeDouble::setCalculatedValue(const double theValue) { - if (!myIsInitialized || myReal->Get() != theValue) { - myReal->Set(theValue); + if (!myIsInitialized || value() != theValue) { + myExpression->setValue(theValue); owner()->data()->sendAttributeUpdated(this); } } @@ -30,50 +31,51 @@ void Model_AttributeDouble::setValue(const double theValue) double Model_AttributeDouble::value() { - return myReal->Get(); -} - -Model_AttributeDouble::Model_AttributeDouble(TDF_Label& theLabel) -{ - // check the attribute could be already presented in this doc (after load document) - myIsInitialized = theLabel.FindAttribute(TDataStd_Real::GetID(), myReal) == Standard_True; - if (!myIsInitialized) { - // create attribute: not initialized by value yet, just zero - myReal = TDataStd_Real::Set(theLabel, 0.); - } - if (!theLabel.FindAttribute(TDataStd_Name::GetID(), myText)) { - myText = TDataStd_Name::Set(theLabel, TCollection_ExtendedString()); - } + return myExpression->value(); } void Model_AttributeDouble::setText(const std::string& theValue) { - TCollection_ExtendedString aValue(theValue.c_str()); - if (myText->Get() != aValue) { - myText->Set(aValue); + if (text() != theValue) { + myExpression->setText(theValue); // Send it to evaluator to convert into the double and store in the attribute ModelAPI_AttributeEvalMessage::send(owner()->data()->attribute(id()), this); owner()->data()->sendAttributeUpdated(this); } } -string Model_AttributeDouble::text() +std::string Model_AttributeDouble::text() { - return TCollection_AsciiString(myText->Get()).ToCString(); + return myExpression->text(); } -Standard_GUID kInvalidGUID("caee5ce4-34b1-4b29-abcb-685287d18096"); - void Model_AttributeDouble::setExpressionInvalid(const bool theFlag) { - if (theFlag) { - TDataStd_UAttribute::Set(myReal->Label(), kInvalidGUID); - } else { - myReal->Label().ForgetAttribute(kInvalidGUID); - } + myExpression->setInvalid(theFlag); } bool Model_AttributeDouble::expressionInvalid() { - return myReal->Label().IsAttribute(kInvalidGUID) == Standard_True; + return myExpression->isInvalid(); +} + +void Model_AttributeDouble::setExpressionError(const std::string& theError) +{ + if (expressionError() != theError) + myExpression->setError(theError); +} + +std::string Model_AttributeDouble::expressionError() +{ + return myExpression->error(); +} + +void Model_AttributeDouble::setUsedParameters(const std::set& theUsedParameters) +{ + myExpression->setUsedParameters(theUsedParameters); +} + +std::set Model_AttributeDouble::usedParameters() const +{ + return myExpression->usedParameters(); } diff --git a/src/Model/Model_AttributeDouble.h b/src/Model/Model_AttributeDouble.h index d93b60673..390cc66bc 100644 --- a/src/Model/Model_AttributeDouble.h +++ b/src/Model/Model_AttributeDouble.h @@ -9,10 +9,10 @@ #include "Model.h" #include "ModelAPI_AttributeDouble.h" -#include + #include -#include +class ModelAPI_Expression; /**\class Model_AttributeDouble * \ingroup DataModel @@ -21,8 +21,8 @@ class Model_AttributeDouble : public ModelAPI_AttributeDouble { - Handle_TDataStd_Real myReal; ///< double is Real attribute - Handle_TDataStd_Name myText; ///< Text representation of the attribute (may differ for parametres) + std::shared_ptr myExpression; + public: /// Defines the double value MODEL_EXPORT virtual void setValue(const double theValue); @@ -45,8 +45,20 @@ class Model_AttributeDouble : public ModelAPI_AttributeDouble /// 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& theUsedParameters); + + /// Returns the used parameters + MODEL_EXPORT virtual std::set usedParameters() const; + protected: - /// Initializes attibutes + /// Initializes attributes Model_AttributeDouble(TDF_Label& theLabel); friend class Model_Data; diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index dd2f83130..78d6fca5c 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -101,7 +102,10 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin } else if (theAttrType == Model_AttributeInteger::typeId()) { anAttr = new Model_AttributeInteger(anAttrLab); } else if (theAttrType == ModelAPI_AttributeDouble::typeId()) { - anAttr = new Model_AttributeDouble(anAttrLab); + Model_AttributeDouble* anAttribute = new Model_AttributeDouble(anAttrLab); + anAttribute->myExpression.reset(new Model_Expression(myLab.FindChild(myLab.NbChildren() + 1))); + anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression->isInitialized(); + anAttr = anAttribute; } else if (theAttrType == Model_AttributeBoolean::typeId()) { anAttr = new Model_AttributeBoolean(anAttrLab); } else if (theAttrType == Model_AttributeString::typeId()) { @@ -121,11 +125,21 @@ AttributePtr Model_Data::addAttribute(const std::string& theID, const std::strin } // create also GeomData attributes here because only here the OCAF structure is known else if (theAttrType == GeomData_Point::typeId()) { - anAttr = new GeomData_Point(anAttrLab); + GeomData_Point* anAttribute = new GeomData_Point(anAttrLab); + for (int aComponent = 0; aComponent < GeomData_Point::NUM_COMPONENTS; ++aComponent) { + anAttribute->myExpression[aComponent].reset(new Model_Expression(myLab.FindChild(myLab.NbChildren() + 1))); + anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression[aComponent]->isInitialized(); + } + anAttr = anAttribute; } else if (theAttrType == GeomData_Dir::typeId()) { anAttr = new GeomData_Dir(anAttrLab); } else if (theAttrType == GeomData_Point2D::typeId()) { - anAttr = new GeomData_Point2D(anAttrLab); + GeomData_Point2D* anAttribute = new GeomData_Point2D(anAttrLab); + for (int aComponent = 0; aComponent < GeomData_Point2D::NUM_COMPONENTS; ++aComponent) { + anAttribute->myExpression[aComponent].reset(new Model_Expression(myLab.FindChild(myLab.NbChildren() + 1))); + anAttribute->myIsInitialized = anAttribute->myIsInitialized && anAttribute->myExpression[aComponent]->isInitialized(); + } + anAttr = anAttribute; } if (anAttr) { aResult = std::shared_ptr(anAttr); diff --git a/src/Model/Model_Expression.cpp b/src/Model/Model_Expression.cpp new file mode 100644 index 000000000..1529d3bc0 --- /dev/null +++ b/src/Model/Model_Expression.cpp @@ -0,0 +1,99 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: Model_Expression.cpp +// Created: 5 Aug 2015 +// Author: Sergey POKHODENKO + +#include "Model_Expression.h" + +#include +#include +#include +#include + +Model_Expression::Model_Expression(TDF_Label& theLabel) +{ + myIsInitialized = true; + if (!theLabel.FindAttribute(TDataStd_Real::GetID(), myReal)) { + myReal = TDataStd_Real::Set(theLabel, 0.); + myIsInitialized = false; + } + if (!theLabel.FindAttribute(TDataStd_Name::GetID(), myText)) { + myText = TDataStd_Name::Set(theLabel, TCollection_ExtendedString()); + myIsInitialized = false; + } + if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myError)) { + myError = TDataStd_Comment::Set(theLabel, TCollection_ExtendedString()); + myIsInitialized = false; + } + if (!theLabel.FindAttribute(TDataStd_ExtStringList::GetID(), myUsedParameters)) { + myUsedParameters = TDataStd_ExtStringList::Set(theLabel); + myIsInitialized = false; + } +} + +void Model_Expression::setValue(const double theValue) +{ + if (value() != theValue) + myReal->Set(theValue); +} + +double Model_Expression::value() +{ + return myReal->Get(); +} + +void Model_Expression::setText(const std::string& theValue) +{ + if (text() != theValue) + myText->Set(TCollection_ExtendedString(theValue.c_str())); +} + +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) +{ + if (theFlag) { + TDataStd_UAttribute::Set(myReal->Label(), kInvalidGUID); + } else { + myReal->Label().ForgetAttribute(kInvalidGUID); + } +} + +bool Model_Expression::isInvalid() +{ + return myReal->Label().IsAttribute(kInvalidGUID) == Standard_True; +} + +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& theUsedParameters) +{ + myUsedParameters->Clear(); + std::set::const_iterator anIt = theUsedParameters.begin(); + for (; anIt != theUsedParameters.end(); ++anIt) + myUsedParameters->Append(TCollection_ExtendedString(anIt->c_str())); +} + +std::set Model_Expression::usedParameters() const +{ + std::set aResult; + TDataStd_ListIteratorOfListOfExtendedString aIt; + for (aIt.Initialize(myUsedParameters->List()); aIt.More(); aIt.Next()) + aResult.insert(TCollection_AsciiString(aIt.Value()).ToCString()); + return aResult; +} diff --git a/src/Model/Model_Expression.h b/src/Model/Model_Expression.h new file mode 100644 index 000000000..2963afd36 --- /dev/null +++ b/src/Model/Model_Expression.h @@ -0,0 +1,68 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: Model_Expression.h +// Created: 5 Aug 2015 +// Author: Sergey POKHODENKO + +#ifndef Model_Expression_H_ +#define Model_Expression_H_ + +#include "Model.h" +#include "ModelAPI_Expression.h" + +#include +#include +#include +#include + +#include + +/**\class Model_Expression + * \ingroup DataModel + * \brief Implementation of ModelAPI_Expression. + */ +class Model_Expression : public 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); + + /// Returns an expression error + MODEL_EXPORT virtual std::string error(); + + /// Defines the used parameters (by the parameters listener) + MODEL_EXPORT virtual void setUsedParameters(const std::set& theUsedParameters); + + /// Returns the used parameters + MODEL_EXPORT virtual std::set usedParameters() const; + + protected: + /// Initializes attributes + Model_Expression(TDF_Label& theLabel); + + friend class Model_Data; +}; + +#endif diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 51e7a18ff..e0c9dbb40 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -25,6 +25,7 @@ SET(PROJECT_HEADERS ModelAPI_Data.h ModelAPI_Document.h ModelAPI_Events.h + ModelAPI_Expression.h ModelAPI_Feature.h ModelAPI_FeatureValidator.h ModelAPI_Object.h @@ -61,6 +62,7 @@ SET(PROJECT_SOURCES ModelAPI_Data.cpp ModelAPI_Document.cpp ModelAPI_Events.cpp + ModelAPI_Expression.cpp ModelAPI_Feature.cpp ModelAPI_FeatureValidator.cpp ModelAPI_Object.cpp diff --git a/src/ModelAPI/ModelAPI_Attribute.h b/src/ModelAPI/ModelAPI_Attribute.h index 442e4e4a0..22231be4b 100644 --- a/src/ModelAPI/ModelAPI_Attribute.h +++ b/src/ModelAPI/ModelAPI_Attribute.h @@ -61,12 +61,12 @@ class ModelAPI_Attribute /// Returns true if attribute causes the result change MODELAPI_EXPORT bool isArgument(); - /// Immutable argument can not be changed programaticaly (e.g. by constraint) + /// Immutable argument can not be changed programmatically (e.g. by constraint) /// By default it is false. /// Returns the previous state of the attribute's immutability. MODELAPI_EXPORT bool setImmutable(const bool theFlag); - /// Returns true if can not be changed programaticaly + /// Returns true if can not be changed programmatically MODELAPI_EXPORT bool isImmutable(); /// ID of the attribute in Data diff --git a/src/ModelAPI/ModelAPI_AttributeDouble.h b/src/ModelAPI/ModelAPI_AttributeDouble.h index f2b01862b..9332e61b2 100644 --- a/src/ModelAPI/ModelAPI_AttributeDouble.h +++ b/src/ModelAPI/ModelAPI_AttributeDouble.h @@ -9,6 +9,10 @@ #include "ModelAPI_Attribute.h" +#include + +class ModelAPI_Expression; + /**\class ModelAPI_AttributeDouble * \ingroup DataModel * \brief Attribute that contains real value with double precision. @@ -38,6 +42,18 @@ class ModelAPI_AttributeDouble : public ModelAPI_Attribute /// 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& theUsedParameters) = 0; + + /// Returns the used parameters + MODELAPI_EXPORT virtual std::set usedParameters() const = 0; + /// Returns the type of this class of attributes MODELAPI_EXPORT static std::string typeId() { diff --git a/src/ModelAPI/ModelAPI_Expression.cpp b/src/ModelAPI/ModelAPI_Expression.cpp new file mode 100644 index 000000000..39284ef28 --- /dev/null +++ b/src/ModelAPI/ModelAPI_Expression.cpp @@ -0,0 +1,27 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: ModelAPI_Expression.cpp +// Created: 5 Aug 2015 +// Author: Sergey POKHODENKO + +#include "ModelAPI_Expression.h" + +ModelAPI_Expression::ModelAPI_Expression() +{ + +} + +ModelAPI_Expression::~ModelAPI_Expression() +{ + +} + +bool ModelAPI_Expression::isInitialized() +{ + return myIsInitialized; +} + +void ModelAPI_Expression::setInitialized() +{ + myIsInitialized = true; +} diff --git a/src/ModelAPI/ModelAPI_Expression.h b/src/ModelAPI/ModelAPI_Expression.h new file mode 100644 index 000000000..2c140b63b --- /dev/null +++ b/src/ModelAPI/ModelAPI_Expression.h @@ -0,0 +1,74 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: ModelAPI_Expression.h +// Created: 5 Aug 2015 +// Author: Sergey POKHODENKO + +#ifndef ModelAPI_Expression_H_ +#define ModelAPI_Expression_H_ + +#include "ModelAPI.h" +#include +#include +#include + +/**\class ModelAPI_Expression + * \ingroup DataModel + * \brief Expression for calculated values. + */ +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(); + + /// Returns true if attribute was initialized by some value + MODELAPI_EXPORT virtual bool isInitialized(); + + /// 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; + + /// Returns the text of this Expression + MODELAPI_EXPORT virtual std::string text() const = 0; + + /// Allows to set expression (text) as invalid (by the parameters listener) + MODELAPI_EXPORT virtual void setInvalid(const bool theFlag) = 0; + + /// Returns true if text is invalid + MODELAPI_EXPORT virtual bool isInvalid() = 0; + + /// Allows to set expression (text) error (by the parameters listener) + MODELAPI_EXPORT virtual void setError(const std::string& theError) = 0; + + /// Returns an expression error + MODELAPI_EXPORT virtual std::string error() = 0; + + /// Defines the used parameters (by the parameters listener) + MODELAPI_EXPORT virtual void setUsedParameters(const std::set& theUsedParameters) = 0; + + /// Returns the used parameters + MODELAPI_EXPORT virtual std::set usedParameters() const = 0; + + protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_Expression(); + + friend class Model_Data; +}; + +//! Pointer on Expression object +typedef std::shared_ptr ExpressionPtr; + +#endif -- 2.39.2