Salome HOME
Added the initialization of attributes flag and "attributes": method that returns...
authormpv <mikhail.ponikarov@opencascade.com>
Tue, 24 Jun 2014 11:58:18 +0000 (15:58 +0400)
committermpv <mikhail.ponikarov@opencascade.com>
Tue, 24 Jun 2014 11:58:18 +0000 (15:58 +0400)
13 files changed:
src/GeomData/GeomData_Dir.cpp
src/GeomData/GeomData_Point.cpp
src/GeomData/GeomData_Point2D.cpp
src/Model/Model_AttributeBoolean.cpp
src/Model/Model_AttributeDocRef.cpp
src/Model/Model_AttributeDouble.cpp
src/Model/Model_AttributeRefAttr.cpp
src/Model/Model_AttributeRefList.cpp
src/Model/Model_AttributeReference.cpp
src/Model/Model_Data.cpp
src/Model/Model_Data.h
src/ModelAPI/ModelAPI_Attribute.h
src/ModelAPI/ModelAPI_Data.h

index 44f04fe307900b6867a4bba70a6d7bd480b7c984..3800c938ce04ee810e1bca6d6ff858bd83114f28 100644 (file)
@@ -5,26 +5,26 @@
 #include "GeomData_Dir.h"
 #include "GeomAPI_Dir.h"
 #include <gp_Dir.hxx>
-#include "Model_Events.h"
-#include <Events_Loop.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
 
 using namespace std;
 
 void GeomData_Dir::setValue(const double theX, const double theY, const double theZ)
 {
-  if (myCoords->Value(0) != theX || myCoords->Value(1) != theY || myCoords->Value(2) != 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);
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
 void GeomData_Dir::setValue(const boost::shared_ptr<GeomAPI_Dir>& theDir)
 {
   setValue(theDir->x(), theDir->y(), theDir->z());
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 double GeomData_Dir::x() const
@@ -50,8 +50,8 @@ boost::shared_ptr<GeomAPI_Dir> GeomData_Dir::dir()
 
 GeomData_Dir::GeomData_Dir(TDF_Label& theLabel)
 {
-  // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords) == Standard_True;
+  if (!myIsInitialized) {
     // create attribute: not initialized by value yet, just zero
     myCoords = TDataStd_RealArray::Set(theLabel, 0, 2);
   }
index da6299703174b694c2d95b179b905a738c2dfc23..db942aff62389b2ff9f268787954b1ff15a3ed51 100644 (file)
@@ -3,27 +3,27 @@
 // Author:      Mikhail PONIKAROV
 
 #include "GeomData_Point.h"
-#include "Model_Events.h"
-#include <Events_Loop.h>
 #include <GeomAPI_Pnt.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
 
 using namespace std;
 
 void GeomData_Point::setValue(const double theX, const double theY, const double theZ)
 {
-  if (myCoords->Value(0) != theX || myCoords->Value(1) != theY || myCoords->Value(2) != 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);
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
 void GeomData_Point::setValue(const boost::shared_ptr<GeomAPI_Pnt>& thePoint)
 {
   setValue(thePoint->x(), thePoint->y(), thePoint->z());
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 double GeomData_Point::x() const
@@ -50,8 +50,8 @@ boost::shared_ptr<GeomAPI_Pnt> GeomData_Point::pnt()
 
 GeomData_Point::GeomData_Point(TDF_Label& theLabel)
 {
-  // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords) == Standard_True;
+  if (!myIsInitialized) {
     // create attribute: not initialized by value yet, just zero
     myCoords = TDataStd_RealArray::Set(theLabel, 0, 2);
   }
index 334d2070a320b1c19d0f9cf73450d143eca4f868..7e6f889c41fb5698380bed1b4d2a99ee5da12fa5 100644 (file)
@@ -3,9 +3,9 @@
 // Author:      Mikhail PONIKAROV
 
 #include "GeomData_Point2D.h"
-#include "Model_Events.h"
-#include <Events_Loop.h>
 #include <GeomAPI_Pnt2d.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
 
 using namespace std;
 
@@ -14,15 +14,14 @@ void GeomData_Point2D::setValue(const double theX, const double theY)
   if (myCoords->Value(0) != theX || myCoords->Value(1) != theY) {
     myCoords->SetValue(0, theX);
     myCoords->SetValue(1, theY);
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
 void GeomData_Point2D::setValue(const boost::shared_ptr<GeomAPI_Pnt2d>& thePoint)
 {
   setValue(thePoint->x(), thePoint->y());
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 double GeomData_Point2D::x() const
@@ -44,8 +43,8 @@ boost::shared_ptr<GeomAPI_Pnt2d> GeomData_Point2D::pnt()
 
 GeomData_Point2D::GeomData_Point2D(TDF_Label& theLabel)
 {
-  // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_RealArray::GetID(), myCoords) == Standard_True;
+  if (!myIsInitialized) {
     // create attribute: not initialized by value yet, just zero
     myCoords = TDataStd_RealArray::Set(theLabel, 0, 1);
   }
index 5472dadf255f13feac8b09704726979751f0d191..07c482b0741e5aa055866ff295f77a3cde81f79a 100644 (file)
@@ -3,19 +3,17 @@
 // Author:      Vitaly Smetannikov
 
 #include "Model_AttributeBoolean.h"
-#include "Model_Events.h"
-#include <Events_Loop.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
 
 using namespace std;
 
 void Model_AttributeBoolean::setValue(bool theValue)
 {
   Standard_Boolean aValue = theValue ? Standard_True : Standard_False;
-  if (myBool->Get() != aValue) {
+  if (!myIsInitialized || myBool->Get() != aValue) {
     myBool->Set(aValue);
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
@@ -27,7 +25,8 @@ bool Model_AttributeBoolean::value()
 Model_AttributeBoolean::Model_AttributeBoolean(TDF_Label& theLabel)
 {
   // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_Integer::GetID(), myBool)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_Integer::GetID(), myBool) == Standard_True;
+  if (!myIsInitialized) {
     // create attribute: not initialized by value yet, just zero
     myBool = TDataStd_Integer::Set(theLabel, 0);
   }
index dfb307f4dbfe0981cc8915fc838cea6a798540a4..83615e30ec458bd63417ebc210e95a03b4558ee4 100644 (file)
@@ -4,20 +4,17 @@
 
 #include "Model_AttributeDocRef.h"
 #include "Model_Application.h"
-#include "Model_Events.h"
-#include <Events_Loop.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
 
 using namespace std;
 
 void Model_AttributeDocRef::setValue(boost::shared_ptr<ModelAPI_Document> theDoc)
 {
   TCollection_ExtendedString aNewID(theDoc->id().c_str());
-  if (myComment->Get() != aNewID) {
+  if (!myIsInitialized || myComment->Get() != aNewID) {
     myComment->Set(TCollection_ExtendedString(theDoc->id().c_str()));
-
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
@@ -32,8 +29,8 @@ boost::shared_ptr<ModelAPI_Document> Model_AttributeDocRef::value()
 
 Model_AttributeDocRef::Model_AttributeDocRef(TDF_Label& theLabel)
 {
-  // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_Comment::GetID(), myComment)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_Comment::GetID(), myComment) == Standard_True;
+  if (!myIsInitialized) {
     // create attribute: not initialized by value yet, just empty string
     myComment = TDataStd_Comment::Set(theLabel, "");
   } else { // document was already referenced: try to set it as loaded by demand
index 88b4352a56d288dd8b3b0c81a7acfdc28e5ce82f..13b976c2e1e57e74e19cd51a0168e4ddb6dbd611 100644 (file)
@@ -3,18 +3,16 @@
 // Author:      Mikhail PONIKAROV
 
 #include "Model_AttributeDouble.h"
-#include "Model_Events.h"
-#include <Events_Loop.h>
+#include <ModelAPI_Feature.h>
+#include <ModelAPI_Data.h>
 
 using namespace std;
 
 void Model_AttributeDouble::setValue(const double theValue)
 {
-  if (myReal->Get() != theValue) {
+  if (!myIsInitialized || myReal->Get() != theValue) {
     myReal->Set(theValue);
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
@@ -26,7 +24,8 @@ double Model_AttributeDouble::value()
 Model_AttributeDouble::Model_AttributeDouble(TDF_Label& theLabel)
 {
   // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_Real::GetID(), myReal)) {
+  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.);
   }
index 39797722609130ae4fc3d7cf42ee4bcb5dcce231..24bcddec1a7e63378c7ed4e5fd3f24462f323295 100644 (file)
@@ -4,10 +4,8 @@
 
 #include "Model_AttributeRefAttr.h"
 #include "Model_Application.h"
-#include "Model_Events.h"
 #include "Model_Data.h"
 #include <ModelAPI_Feature.h>
-#include <Events_Loop.h>
 
 using namespace std;
 
@@ -21,15 +19,12 @@ void Model_AttributeRefAttr::setAttr(boost::shared_ptr<ModelAPI_Attribute> theAt
   boost::shared_ptr<Model_Data> aData = 
     boost::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
   string anID = aData->id(theAttr);
-  if (feature() == theAttr->owner() && myID->Get().IsEqual(anID.c_str()))
+  if (myIsInitialized && feature() == theAttr->owner() && myID->Get().IsEqual(anID.c_str()))
     return; // nothing is changed
 
   myRef->Set(aData->label());
   myID->Set(aData->id(theAttr).c_str());
-
-  static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-  Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-  Events_Loop::loop()->send(aMsg);
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 boost::shared_ptr<ModelAPI_Attribute> Model_AttributeRefAttr::attr()
@@ -46,15 +41,12 @@ boost::shared_ptr<ModelAPI_Attribute> Model_AttributeRefAttr::attr()
 
 void Model_AttributeRefAttr::setFeature(FeaturePtr theFeature)
 {
-  if (myID->Get().Length() != 0 || feature() != theFeature) {
+  if (!myIsInitialized || myID->Get().Length() != 0 || feature() != theFeature) {
     boost::shared_ptr<Model_Data> aData = 
       boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
     myRef->Set(aData->label());
     myID->Set(""); // feature is identified by the empty ID
-
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
@@ -75,8 +67,8 @@ FeaturePtr Model_AttributeRefAttr::feature()
 
 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)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_Comment::GetID(), myID) == Standard_True;
+  if (!myIsInitialized) {
     // create attribute: not initialized by value yet
     myID = TDataStd_Comment::Set(theLabel, "");
     myRef = TDF_Reference::Set(theLabel, theLabel); // not initialized: reference to itself
index af4cbd3ea6246983a910f4bc3f177540ebe8d1e5..9e4dc839688cda9f7ec6d7f6326337220641eaa4 100644 (file)
@@ -4,10 +4,8 @@
 
 #include "Model_AttributeRefList.h"
 #include "Model_Application.h"
-#include "Model_Events.h"
 #include "Model_Data.h"
 #include <ModelAPI_Feature.h>
-#include <Events_Loop.h>
 #include <TDF_ListIteratorOfLabelList.hxx>
 
 using namespace std;
@@ -18,9 +16,7 @@ void Model_AttributeRefList::append(FeaturePtr theFeature)
     boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
   myRef->Append(aData->label());
 
-  static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-  Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-  Events_Loop::loop()->send(aMsg);
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 void Model_AttributeRefList::remove(FeaturePtr theFeature)
@@ -29,6 +25,7 @@ void Model_AttributeRefList::remove(FeaturePtr theFeature)
     boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
   myRef->Remove(aData->label());
 
+  owner()->data()->sendAttributeUpdated(this);
 }
 
 int Model_AttributeRefList::size()
@@ -52,8 +49,8 @@ list<FeaturePtr > Model_AttributeRefList::list()
 
 Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel)
 {
-  // check the attribute could be already presented in this doc (after load document)
-  if (!theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef)) {
+  myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True;
+  if (!myIsInitialized) {
     myRef = TDataStd_ReferenceList::Set(theLabel);
   }
 }
index adcfe4ab46e0b1d62d038f8408dd7568a029afe7..e2ff01ce7798975aa6e11d829c86281f6bfc99f5 100644 (file)
@@ -7,13 +7,12 @@
 #include "Model_Events.h"
 #include "Model_Data.h"
 #include <ModelAPI_Feature.h>
-#include <Events_Loop.h>
 
 using namespace std;
 
 void Model_AttributeReference::setValue(FeaturePtr theFeature)
 {
-  if (value() != theFeature) {
+  if (!myIsInitialized || value() != theFeature) {
     boost::shared_ptr<Model_Data> aData = 
       boost::dynamic_pointer_cast<Model_Data>(theFeature->data());
     if (myRef.IsNull()) {
@@ -23,10 +22,7 @@ void Model_AttributeReference::setValue(FeaturePtr theFeature)
     } else {
       myRef->Set(aData->label());
     }
-
-    static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
-    Model_FeatureUpdatedMessage aMsg(owner(), anEvent);
-    Events_Loop::loop()->send(aMsg);
+    owner()->data()->sendAttributeUpdated(this);
   }
 }
 
@@ -46,8 +42,6 @@ FeaturePtr Model_AttributeReference::value()
 
 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!
-  }
+  // not initialized by value yet: attribute is not set to the label!
+  myIsInitialized = theLabel.FindAttribute(TDF_Reference::GetID(), myRef) == Standard_True;
 }
index 31f9f36a03eab9542a8410a4e753c2d83248fda6..60b7b540e7c4f554d12e3cab5924a5b2f89cf5f4 100644 (file)
@@ -207,6 +207,25 @@ bool Model_Data::isValid()
   return !myLab.IsNull() && myLab.HasAttribute();
 }
 
+list<boost::shared_ptr<ModelAPI_Attribute> > Model_Data::attributes(const string theType)
+{
+  list<boost::shared_ptr<ModelAPI_Attribute> > aResult;
+  map<string, boost::shared_ptr<ModelAPI_Attribute> >::iterator anAttrsIter = myAttrs.begin();
+  for(; anAttrsIter != myAttrs.end(); anAttrsIter++) {
+    if (theType.empty() || anAttrsIter->second->attributeType() == theType) {
+    }
+  }
+  return aResult;
+}
+
+void Model_Data::sendAttributeUpdated(ModelAPI_Attribute* theAttr)
+{
+  theAttr->setInitialized();
+  static const Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
+  Model_FeatureUpdatedMessage aMsg(myFeature, anEvent);
+  Events_Loop::loop()->send(aMsg);
+}
+
 #include <TNaming_Builder.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TopoDS_Shape.hxx>
index 36f5f361463d7372cef018a00f687bebf9c23d65..eca52e960c44d99464996994eca977ac8d041634 100644 (file)
@@ -63,6 +63,11 @@ public:
   /// Returns the generic attribute by identifier
   /// \param theID identifier of the attribute
   MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Attribute> attribute(const std::string theID);
+  /// Returns all attributes ofthe feature of the given type
+  /// or all attributes if "theType" is empty
+  MODEL_EXPORT virtual std::list<boost::shared_ptr<ModelAPI_Attribute> >
+    attributes(const std::string theType);
+
   /// 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<ModelAPI_Attribute> theAttr);
@@ -82,6 +87,10 @@ public:
   /// \param theAttrType type of the created attribute (received from the type method)
   MODEL_EXPORT virtual void addAttribute(std::string theID, std::string theAttrType);
 
+  /// Useful method for "set" methods of the attributes: sends an UPDATE event and
+  /// makes attribute initialized
+  MODEL_EXPORT virtual void sendAttributeUpdated(ModelAPI_Attribute* theAttr);
+
   /// Puts feature to the document data sub-structure
   MODEL_EXPORT void setLabel(TDF_Label& theLab);
 
index acea353df4d61d3be87566b1ea1da3232a3fe844..4a15abb88c718b680beeff2b45d323c3020426e2 100644 (file)
@@ -19,6 +19,8 @@ class ModelAPI_Attribute
 {
   ///< needed here to emit signal that feature changed on change of the attribute
   boost::shared_ptr<ModelAPI_Feature> myFeature;
+protected: // accessible from the attributes
+  bool myIsInitialized;
 public:
   
   /// Returns the type of this class of attributes, not static method
@@ -34,9 +36,16 @@ public:
   /// Returns the owner of this attribute
   MODELAPI_EXPORT const boost::shared_ptr<ModelAPI_Feature>& owner()
   {return myFeature;}
+
+  /// Returns true if attribute was  initialized by some value
+  MODELAPI_EXPORT bool isInitialized() {return myIsInitialized;}
+
+  /// Makes attribute initialized
+  MODELAPI_EXPORT void setInitialized() {myIsInitialized = true;}
+
 protected:
   /// Objects are created for features automatically
-  ModelAPI_Attribute(){}
+  ModelAPI_Attribute() {myIsInitialized = false;}
 
 };
 
index 76967d18143f6e50c00374755a0ad13fa5f6f110..5d6e36d5f8e7a9293b47180b3f84a85c3c76be23 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "ModelAPI.h"
 #include <string>
+#include <list>
 #include <boost/shared_ptr.hpp>
 
 class ModelAPI_AttributeDocRef;
@@ -51,6 +52,10 @@ public:
   /// Returns the generic attribute by identifier
   /// \param theID identifier of the attribute
   virtual boost::shared_ptr<ModelAPI_Attribute> attribute(const std::string theID) = 0;
+  /// Returns all attributes ofthe feature of the given type
+  /// or all attributes if "theType" is empty
+  virtual std::list<boost::shared_ptr<ModelAPI_Attribute> >
+    attributes(const std::string theType) = 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<ModelAPI_Attribute> theAttr) = 0;
@@ -70,6 +75,10 @@ public:
   /// \param theAttrType type of the created attribute (received from the type method)
   virtual void addAttribute(std::string theID, std::string theAttrType) = 0;
 
+  /// Useful method for "set" methods of the attributes: sends an UPDATE event and
+  /// makes attribute initialized
+  virtual void sendAttributeUpdated(ModelAPI_Attribute* theAttr) = 0;
+
   /// To virtually destroy the fields of successors
   virtual ~ModelAPI_Data() {}