Salome HOME
Merge branch 'master' into Dev_1.1.0
[modules/shaper.git] / src / Model / Model_Data.cpp
index f280f8fc6f3670e3709a5ca9eabb77a504c627e5..d537db894aa04f9a905c4a8339b9c7ddfbaa555f 100644 (file)
@@ -15,6 +15,7 @@
 #include <Model_AttributeString.h>
 #include <Model_AttributeSelection.h>
 #include <Model_AttributeSelectionList.h>
+#include <Model_AttributeIntArray.h>
 #include <Model_Events.h>
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Result.h>
@@ -28,6 +29,9 @@
 #include <Events_Error.h>
 
 #include <TDataStd_Name.hxx>
+#include <TDF_AttributeIterator.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_RelocationTable.hxx>
 
 #include <string>
 
@@ -66,8 +70,9 @@ void Model_Data::setName(const std::string& theName)
   }
 }
 
-void Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
+AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
 {
+  AttributePtr aResult;
   TDF_Label anAttrLab = myLab.FindChild(myAttrs.size() + 1);
   ModelAPI_Attribute* anAttr = 0;
   if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
@@ -90,6 +95,8 @@ void Model_Data::addAttribute(const std::string& theID, const std::string theAtt
     anAttr = new Model_AttributeRefAttr(anAttrLab);
   } else if (theAttrType == ModelAPI_AttributeRefList::typeId()) {
     anAttr = new Model_AttributeRefList(anAttrLab);
+  } else if (theAttrType == ModelAPI_AttributeIntArray::typeId()) {
+    anAttr = new Model_AttributeIntArray(anAttrLab);
   } 
   // create also GeomData attributes here because only here the OCAF strucure is known
   else if (theAttrType == GeomData_Point::typeId()) {
@@ -100,12 +107,14 @@ void Model_Data::addAttribute(const std::string& theID, const std::string theAtt
     anAttr = new GeomData_Point2D(anAttrLab);
   }
   if (anAttr) {
-    myAttrs[theID] = std::shared_ptr<ModelAPI_Attribute>(anAttr);
+    aResult = std::shared_ptr<ModelAPI_Attribute>(anAttr);
+    myAttrs[theID] = aResult;
     anAttr->setObject(myObject);
     anAttr->setID(theID);
   } else {
     Events_Error::send("Can not create unknown type of attribute " + theAttrType);
   }
+  return aResult;
 }
 
 // macro for gthe generic returning of the attribute by the ID
@@ -130,6 +139,7 @@ GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeSelection, selection);
 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeSelectionList, selectionList);
 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeRefAttr, refattr);
 GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeRefList, reflist);
+GET_ATTRIBUTE_BY_ID(ModelAPI_AttributeIntArray, intArray);
 
 std::shared_ptr<ModelAPI_Attribute> Model_Data::attribute(const std::string& theID)
 {
@@ -297,3 +307,36 @@ void Model_Data::referencesToObjects(
     }
   }
 }
+
+/// makes copy of all attributes on the given label and all sub-labels
+static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
+  TDF_AttributeIterator anAttrIter(theSource);
+  for(; anAttrIter.More(); anAttrIter.Next()) {
+    Handle(TDF_Attribute) aTargetAttr;
+    if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
+      // create a new attribute if not yet exists in the destination
+           aTargetAttr = anAttrIter.Value()->NewEmpty();
+      theDestination.AddAttribute(aTargetAttr);
+    }
+    Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); // no relocation, empty map
+    anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
+  }
+  // copy the sub-labels content
+  TDF_ChildIterator aSubLabsIter(theSource);
+  for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+    copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
+  }
+}
+
+void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
+{
+  TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
+  copyAttrs(myLab, aTargetRoot);
+  // make initialized the initialized attributes
+  std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator aMyIter = myAttrs.begin();
+  for(; aMyIter != myAttrs.end(); aMyIter++) {
+    if (aMyIter->second->isInitialized()) {
+      theTarget->attribute(aMyIter->first)->setInitialized();
+    }
+  }
+}