From e9da4a58641d63176d3214d2f5e3440b917f611d Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 8 May 2014 10:19:00 +0400 Subject: [PATCH] Reference attributes added --- src/Model/CMakeLists.txt | 4 ++ src/Model/Model_AttributeRefAttr.cpp | 59 ++++++++++++++++++++++ src/Model/Model_AttributeRefAttr.h | 38 ++++++++++++++ src/Model/Model_AttributeReference.cpp | 53 +++++++++++++++++++ src/Model/Model_AttributeReference.h | 35 +++++++++++++ src/Model/Model_Data.cpp | 47 +++++++++++++++++ src/Model/Model_Data.h | 12 +++++ src/ModelAPI/CMakeLists.txt | 2 + src/ModelAPI/ModelAPI.i | 6 +++ src/ModelAPI/ModelAPI_AttributeRefAttr.h | 40 +++++++++++++++ src/ModelAPI/ModelAPI_AttributeReference.h | 39 ++++++++++++++ src/ModelAPI/ModelAPI_Data.h | 9 ++++ src/ModelAPI/ModelAPI_PluginManager.cpp | 2 + 13 files changed, 346 insertions(+) create mode 100644 src/Model/Model_AttributeRefAttr.cpp create mode 100644 src/Model/Model_AttributeRefAttr.h create mode 100644 src/Model/Model_AttributeReference.cpp create mode 100644 src/Model/Model_AttributeReference.h create mode 100644 src/ModelAPI/ModelAPI_AttributeRefAttr.h create mode 100644 src/ModelAPI/ModelAPI_AttributeReference.h diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index ea081fac1..872f089f6 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -9,6 +9,8 @@ SET(PROJECT_HEADERS Model_Data.h Model_AttributeDouble.h Model_AttributeDocRef.h + Model_AttributeReference.h + Model_AttributeRefAttr.h Model_Events.h ) @@ -19,6 +21,8 @@ SET(PROJECT_SOURCES Model_Data.cpp Model_AttributeDouble.cpp Model_AttributeDocRef.cpp + Model_AttributeReference.cpp + Model_AttributeRefAttr.cpp Model_Events.cpp ) diff --git a/src/Model/Model_AttributeRefAttr.cpp b/src/Model/Model_AttributeRefAttr.cpp new file mode 100644 index 000000000..bedda92d5 --- /dev/null +++ b/src/Model/Model_AttributeRefAttr.cpp @@ -0,0 +1,59 @@ +// File: ModelAPI_AttributeRefAttr.cxx +// Created: 2 Apr 2014 +// Author: Mikhail PONIKAROV + +#include "Model_AttributeRefAttr.h" +#include "Model_Application.h" +#include "Model_Events.h" +#include "Model_Data.h" +#include +#include + +using namespace std; + +void Model_AttributeRefAttr::setValue(boost::shared_ptr theAttr) +{ + if (value() != theAttr) { + boost::shared_ptr aData = + boost::dynamic_pointer_cast(theAttr->feature()->data()); + if (myRef.IsNull()) { + boost::shared_ptr aMyData = + boost::dynamic_pointer_cast(feature()->data()); + TDF_Reference::Set(aMyData->label(), aData->label()); + } else { + myRef->Set(aData->label()); + } + myID->Set(aData->id(theAttr).c_str()); + + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } +} + +boost::shared_ptr Model_AttributeRefAttr::value() +{ + if (!myRef.IsNull()) { + boost::shared_ptr aDoc = + boost::dynamic_pointer_cast(feature()->document()); + if (aDoc) { + TDF_Label aRefLab = myRef->Get(); + TDF_Label aFeatureLab = aRefLab.Father(); + boost::shared_ptr aData = + boost::dynamic_pointer_cast(aDoc->feature(aRefLab)->data()); + return aData->attribute(TCollection_AsciiString(myID->Get()).ToCString()); + } + } + // not initialized + return boost::shared_ptr(); +} + +Model_AttributeRefAttr::Model_AttributeRefAttr(TDF_Label& theLabel) +{ + // check the attribute could be already presented in this doc (after load document) + if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myID)) { + // create attribute: not initialized by value yet + TDataStd_Comment::Set(theLabel, ""); + // reference attribute is not set to the label! + } +} diff --git a/src/Model/Model_AttributeRefAttr.h b/src/Model/Model_AttributeRefAttr.h new file mode 100644 index 000000000..842296672 --- /dev/null +++ b/src/Model/Model_AttributeRefAttr.h @@ -0,0 +1,38 @@ +// File: Model_AttributeRefAttr.h +// Created: 8 May 2014 +// Author: Mikhail PONIKAROV + +#ifndef Model_AttributeRefAttr_HeaderFile +#define Model_AttributeRefAttr_HeaderFile + +#include "Model.h" +#include "ModelAPI_AttributeRefAttr.h" +#include +#include +#include + +/**\class Model_AttributeRefAttr + * \ingroup DataModel + * \brief Attribute that contains reference to an attribute of a feature + * (located in the same document). + */ + +class Model_AttributeRefAttr : public ModelAPI_AttributeRefAttr +{ + Handle_TDF_Reference myRef; ///< reference to the feature label + Handle_TDataStd_Comment myID; ///< ID of the referenced attirbute +public: + /// Defines the attribute referenced from this attribute + MODEL_EXPORT virtual void setValue(boost::shared_ptr theAttr); + + /// Returns attribute referenced from this attribute + MODEL_EXPORT virtual boost::shared_ptr value(); + +protected: + /// Objects are created for features automatically + MODEL_EXPORT Model_AttributeRefAttr(TDF_Label& theLabel); + + friend class Model_Data; +}; + +#endif diff --git a/src/Model/Model_AttributeReference.cpp b/src/Model/Model_AttributeReference.cpp new file mode 100644 index 000000000..ab247fdc9 --- /dev/null +++ b/src/Model/Model_AttributeReference.cpp @@ -0,0 +1,53 @@ +// File: ModelAPI_AttributeReference.cxx +// Created: 2 Apr 2014 +// Author: Mikhail PONIKAROV + +#include "Model_AttributeReference.h" +#include "Model_Application.h" +#include "Model_Events.h" +#include "Model_Data.h" +#include +#include + +using namespace std; + +void Model_AttributeReference::setValue(boost::shared_ptr theFeature) +{ + if (value() != theFeature) { + boost::shared_ptr aData = + boost::dynamic_pointer_cast(theFeature->data()); + if (myRef.IsNull()) { + boost::shared_ptr aMyData = + boost::dynamic_pointer_cast(feature()->data()); + TDF_Reference::Set(aMyData->label(), aData->label()); + } else { + myRef->Set(aData->label()); + } + + static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED); + Model_FeatureUpdatedMessage aMsg(feature(), anEvent); + Events_Loop::loop()->send(aMsg); + } +} + +boost::shared_ptr Model_AttributeReference::value() +{ + if (!myRef.IsNull()) { + boost::shared_ptr aDoc = + boost::dynamic_pointer_cast(feature()->document()); + if (aDoc) { + TDF_Label aRefLab = myRef->Get(); + return aDoc->feature(aRefLab); + } + } + // not initialized + return boost::shared_ptr(); +} + +Model_AttributeReference::Model_AttributeReference(TDF_Label& theLabel) +{ + // check the attribute could be already presented in this doc (after load document) + if (!theLabel.FindAttribute(TDF_Reference::GetID(), myRef)) { + // create attribute: not initialized by value yet: attribute is not set to the label! + } +} diff --git a/src/Model/Model_AttributeReference.h b/src/Model/Model_AttributeReference.h new file mode 100644 index 000000000..e17855e48 --- /dev/null +++ b/src/Model/Model_AttributeReference.h @@ -0,0 +1,35 @@ +// File: Model_AttributeReference.h +// Created: 8 May 2014 +// Author: Mikhail PONIKAROV + +#ifndef Model_AttributeReference_HeaderFile +#define Model_AttributeReference_HeaderFile + +#include "Model.h" +#include "ModelAPI_AttributeReference.h" +#include +#include + +/**\class Model_AttributeReference + * \ingroup DataModel + * \brief Attribute that contains reference to feature (located in the same document). + */ + +class Model_AttributeReference : public ModelAPI_AttributeReference +{ + Handle_TDF_Reference myRef; ///< references to the feature label +public: + /// Defines the feature referenced from this attribute + MODEL_EXPORT virtual void setValue(boost::shared_ptr theFeature); + + /// Returns feature referenced from this attribute + MODEL_EXPORT virtual boost::shared_ptr value(); + +protected: + /// Objects are created for features automatically + MODEL_EXPORT Model_AttributeReference(TDF_Label& theLabel); + + friend class Model_Data; +}; + +#endif diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 5b26417a2..0c8f77bdf 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -42,6 +44,10 @@ void Model_Data::addAttribute(string theID, string theAttrType) anAttr = new Model_AttributeDocRef(anAttrLab); else if (theAttrType == ModelAPI_AttributeDouble::type()) anAttr = new Model_AttributeDouble(anAttrLab); + else if (theAttrType == ModelAPI_AttributeReference::type()) + anAttr = new Model_AttributeReference(anAttrLab); + else if (theAttrType == ModelAPI_AttributeRefAttr::type()) + anAttr = new Model_AttributeRefAttr(anAttrLab); else if (theAttrType == GeomData_Point::type()) anAttr = new GeomData_Point(anAttrLab); else if (theAttrType == GeomData_Dir::type()) @@ -87,6 +93,36 @@ boost::shared_ptr Model_Data::real(const string theID) return aRes; } +boost::shared_ptr Model_Data::reference(const string theID) +{ + map >::iterator aFound = myAttrs.find(theID); + if (aFound == myAttrs.end()) { + // TODO: generate error on unknown attribute request and/or add mechanism for customization + return boost::shared_ptr(); + } + boost::shared_ptr aRes = + boost::dynamic_pointer_cast(aFound->second); + if (!aRes) { + // TODO: generate error on invalid attribute type request + } + return aRes; +} + +boost::shared_ptr Model_Data::refattr(const string theID) +{ + map >::iterator aFound = myAttrs.find(theID); + if (aFound == myAttrs.end()) { + // TODO: generate error on unknown attribute request and/or add mechanism for customization + return boost::shared_ptr(); + } + boost::shared_ptr aRes = + boost::dynamic_pointer_cast(aFound->second); + if (!aRes) { + // TODO: generate error on invalid attribute type request + } + return aRes; +} + boost::shared_ptr Model_Data::attribute(const std::string theID) { boost::shared_ptr aResult; @@ -94,3 +130,14 @@ boost::shared_ptr Model_Data::attribute(const std::string th return aResult; return myAttrs[theID]; } + +const string& Model_Data::id(const boost::shared_ptr theAttr) +{ + map >::iterator anAttr = myAttrs.begin(); + for(; anAttr != myAttrs.end(); anAttr++) { + if (anAttr->second == theAttr) return anAttr->first; + } + // not found + static string anEmpty; + return anEmpty; +} diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 0cb633666..56d81e123 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -31,9 +31,12 @@ class Model_Data: public ModelAPI_Data Model_Data(); + /// Returns label of this feature TDF_Label label() {return myLab;} friend class Model_Document; + friend class Model_AttributeReference; + friend class Model_AttributeRefAttr; public: /// Returns the name of the feature visible by the user in the object browser @@ -44,9 +47,18 @@ public: MODEL_EXPORT virtual boost::shared_ptr docRef(const std::string theID); /// Returns the attribute that contains real value with double precision MODEL_EXPORT virtual boost::shared_ptr real(const std::string theID); + /// Returns the attribute that contains reference to a feature + MODEL_EXPORT virtual boost::shared_ptr + reference(const std::string theID); + /// Returns the attribute that contains reference to an attribute of a feature + MODEL_EXPORT virtual boost::shared_ptr + refattr(const std::string theID); /// Returns the generic attribute by identifier /// \param theID identifier of the attribute MODEL_EXPORT virtual boost::shared_ptr attribute(const std::string theID); + /// Identifier by the id (not fast, iteration by map) + /// \param theAttr attribute already created in this data + MODEL_EXPORT virtual const std::string& id(const boost::shared_ptr theAttr); /// Initializes object by the attributes: must be called just after the object is created /// for each attribute of the object diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 2fe5b5359..9c6015acd 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -12,6 +12,8 @@ SET(PROJECT_HEADERS ModelAPI_Attribute.h ModelAPI_AttributeDouble.h ModelAPI_AttributeDocRef.h + ModelAPI_AttributeReference.h + ModelAPI_AttributeRefAttr.h ) SET(PROJECT_SOURCES diff --git a/src/ModelAPI/ModelAPI.i b/src/ModelAPI/ModelAPI.i index 119f73d16..097bdcfd2 100644 --- a/src/ModelAPI/ModelAPI.i +++ b/src/ModelAPI/ModelAPI.i @@ -9,6 +9,8 @@ #include "ModelAPI_Attribute.h" #include "ModelAPI_AttributeDocRef.h" #include "ModelAPI_AttributeDouble.h" + #include "ModelAPI_AttributeReference.h" + #include "ModelAPI_AttributeRefAttr.h" %} // to avoid error on this @@ -28,6 +30,8 @@ %shared_ptr(ModelAPI_Attribute) %shared_ptr(ModelAPI_AttributeDocRef) %shared_ptr(ModelAPI_AttributeDouble) +%shared_ptr(ModelAPI_AttributeReference) +%shared_ptr(ModelAPI_AttributeRefAttr) // all supported interfaces %include "ModelAPI_Document.h" @@ -37,3 +41,5 @@ %include "ModelAPI_Attribute.h" %include "ModelAPI_AttributeDocRef.h" %include "ModelAPI_AttributeDouble.h" +%include "ModelAPI_AttributeReference.h" +%include "ModelAPI_AttributeRefAttr.h" diff --git a/src/ModelAPI/ModelAPI_AttributeRefAttr.h b/src/ModelAPI/ModelAPI_AttributeRefAttr.h new file mode 100644 index 000000000..d9c5f3a60 --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeRefAttr.h @@ -0,0 +1,40 @@ +// File: ModelAPI_AttributeRefAttr.h +// Created: 8 May 2014 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_AttributeRefAttr_HeaderFile +#define ModelAPI_AttributeRefAttr_HeaderFile + +#include "ModelAPI_Attribute.h" + +/**\class ModelAPI_AttributeRefAttr + * \ingroup DataModel + * \brief Attribute that contains reference to an attribute of a feature + * (located in the same document). + */ + +class ModelAPI_AttributeRefAttr : public ModelAPI_Attribute +{ +public: + /// Defines the attribute referenced from this attribute + MODELAPI_EXPORT virtual void setValue(boost::shared_ptr theAttr) = 0; + + /// Returns attribute referenced from this attribute + MODELAPI_EXPORT virtual boost::shared_ptr value() = 0; + + /// Returns the type of this class of attributes + MODELAPI_EXPORT static std::string type() {return "RefAttr";} + + /// Returns the type of this class of attributes, not static method + MODELAPI_EXPORT virtual std::string attributeType() {return type();} + + /// To virtually destroy the fields of successors + MODELAPI_EXPORT virtual ~ModelAPI_AttributeRefAttr() {} + +protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_AttributeRefAttr() + {} +}; + +#endif diff --git a/src/ModelAPI/ModelAPI_AttributeReference.h b/src/ModelAPI/ModelAPI_AttributeReference.h new file mode 100644 index 000000000..37b22560c --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeReference.h @@ -0,0 +1,39 @@ +// File: ModelAPI_AttributeReference.h +// Created: 8 May 2014 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_AttributeReference_HeaderFile +#define ModelAPI_AttributeReference_HeaderFile + +#include "ModelAPI_Attribute.h" + +/**\class ModelAPI_AttributeReference + * \ingroup DataModel + * \brief Attribute that contains reference to feature (located in the same document). + */ + +class ModelAPI_AttributeReference : public ModelAPI_Attribute +{ +public: + /// Defines the feature referenced from this attribute + MODELAPI_EXPORT virtual void setValue(boost::shared_ptr theFeature) = 0; + + /// Returns feature referenced from this attribute + MODELAPI_EXPORT virtual boost::shared_ptr value() = 0; + + /// Returns the type of this class of attributes + MODELAPI_EXPORT static std::string type() {return "Reference";} + + /// Returns the type of this class of attributes, not static method + MODELAPI_EXPORT virtual std::string attributeType() {return type();} + + /// To virtually destroy the fields of successors + MODELAPI_EXPORT virtual ~ModelAPI_AttributeReference() {} + +protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_AttributeReference() + {} +}; + +#endif diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 2922f6d9b..86fc56409 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -11,6 +11,8 @@ class ModelAPI_AttributeDocRef; class ModelAPI_AttributeDouble; +class ModelAPI_AttributeReference; +class ModelAPI_AttributeRefAttr; class ModelAPI_Document; class ModelAPI_Attribute; @@ -34,10 +36,17 @@ public: virtual boost::shared_ptr docRef(const std::string theID) = 0; /// Returns the attribute that contains real value with double precision virtual boost::shared_ptr real(const std::string theID) = 0; + /// Returns the attribute that contains reference to a feature + virtual boost::shared_ptr reference(const std::string theID) = 0; + /// Returns the attribute that contains reference to an attribute of a feature + virtual boost::shared_ptr refattr(const std::string theID) = 0; /// Returns the generic attribute by identifier /// \param theID identifier of the attribute virtual boost::shared_ptr attribute(const std::string theID) = 0; + /// Identifier by the id (not fast, iteration by map) + /// \param theAttr attribute already created in this data + virtual const std::string& id(const boost::shared_ptr theAttr) = 0; /// Initializes object by the attributes: must be called just after the object is created /// for each attribute of the object diff --git a/src/ModelAPI/ModelAPI_PluginManager.cpp b/src/ModelAPI/ModelAPI_PluginManager.cpp index 285bb4031..554c1c228 100644 --- a/src/ModelAPI/ModelAPI_PluginManager.cpp +++ b/src/ModelAPI/ModelAPI_PluginManager.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #ifdef WIN32 #include -- 2.39.2