+#define TEXTURE_LABEL_ID 1
+#define TEXTURE_LABEL_FILE 2
+#define TEXTURE_LABEL_WIDTH 3
+#define TEXTURE_LABEL_HEIGHT 4
+#define TEXTURE_LABEL_DATA 5
+
+int GEOM_Engine::addTexture(int theDocID, int theWidth, int theHeight,
+ const Handle(TDataStd_HArray1OfByte)& theTexture,
+ const TCollection_AsciiString& theFileName)
+{
+ Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
+ Handle(TDataStd_TreeNode) aRoot = TDataStd_TreeNode::Set(aDoc->Main());
+
+ // NPAL18604: use existing label to decrease memory usage,
+ // if this label has been freed (object deleted)
+ bool useExisting = false;
+ TDF_Label aChild;
+ if (_freeLabels.find(theDocID) != _freeLabels.end()) {
+ std::list<TDF_Label>& aFreeLabels = _freeLabels[theDocID];
+ if (!aFreeLabels.empty()) {
+ useExisting = true;
+ aChild = aFreeLabels.front();
+ aFreeLabels.pop_front();
+ }
+ }
+ if (!useExisting) {
+ // create new label
+ aChild = TDF_TagSource::NewChild(aDoc->Main());
+ }
+
+ aChild.ForgetAllAttributes(Standard_True);
+ Handle(TDataStd_TreeNode) node;
+ if ( !aChild.FindAttribute(TDataStd_TreeNode::GetDefaultTreeID(), node ) )
+ node = TDataStd_TreeNode::Set(aChild);
+ TDataStd_UAttribute::Set(aChild, GetTextureGUID());
+
+ static int aTextureID = 0;
+
+ TDataStd_Integer::Set(aChild.FindChild(TEXTURE_LABEL_ID), ++aTextureID);
+ TDataStd_Comment::Set(aChild.FindChild(TEXTURE_LABEL_FILE), theFileName);
+ TDataStd_Integer::Set(aChild.FindChild(TEXTURE_LABEL_WIDTH), theWidth);
+ TDataStd_Integer::Set(aChild.FindChild(TEXTURE_LABEL_HEIGHT), theHeight);
+
+ Handle(TDataStd_ByteArray) anAttr =
+ TDataStd_ByteArray::Set(aChild.FindChild(TEXTURE_LABEL_DATA),
+ theTexture.IsNull() ? 0 : theTexture->Lower(),
+ theTexture.IsNull() ? 0 : theTexture->Upper());
+ anAttr->ChangeArray(theTexture);
+
+ return aTextureID;
+}
+
+Handle(TDataStd_HArray1OfByte) GEOM_Engine::getTexture(int theDocID, int theTextureID,
+ int& theWidth, int& theHeight,
+ TCollection_AsciiString& theFileName)
+{
+ Handle(TDataStd_HArray1OfByte) anArray;
+ theWidth = theHeight = 0;
+
+ Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
+
+ TDF_ChildIterator anIterator(aDoc->Main(), Standard_True);
+ bool found = false;
+ for (; anIterator.More() && !found; anIterator.Next()) {
+ TDF_Label aTextureLabel = anIterator.Value();
+ if (aTextureLabel.IsAttribute( GetTextureGUID())) {
+ TDF_Label anIDLabel = aTextureLabel.FindChild(TEXTURE_LABEL_ID, Standard_False);
+ Handle(TDataStd_Integer) anIdAttr;
+ if(!anIDLabel.IsNull() && anIDLabel.FindAttribute(TDataStd_Integer::GetID(), anIdAttr) &&
+ anIdAttr->Get() == theTextureID) {
+ TDF_Label aFileLabel = aTextureLabel.FindChild(TEXTURE_LABEL_FILE, Standard_False);
+ TDF_Label aWidthLabel = aTextureLabel.FindChild(TEXTURE_LABEL_WIDTH, Standard_False);
+ TDF_Label aHeightLabel = aTextureLabel.FindChild(TEXTURE_LABEL_HEIGHT, Standard_False);
+ TDF_Label aDataLabel = aTextureLabel.FindChild(TEXTURE_LABEL_DATA, Standard_False);
+ Handle(TDataStd_Integer) aWidthAttr, aHeightAttr;
+ Handle(TDataStd_ByteArray) aTextureAttr;
+ Handle(TDataStd_Comment) aFileAttr;
+ if (!aWidthLabel.IsNull() && aWidthLabel.FindAttribute(TDataStd_Integer::GetID(), aWidthAttr) &&
+ !aHeightLabel.IsNull() && aHeightLabel.FindAttribute(TDataStd_Integer::GetID(), aHeightAttr) &&
+ !aDataLabel.IsNull() && aDataLabel.FindAttribute(TDataStd_ByteArray::GetID(), aTextureAttr)) {
+ theWidth = aWidthAttr->Get();
+ theHeight = aHeightAttr->Get();
+ anArray = aTextureAttr->InternalArray();
+ }
+ if (!aFileLabel.IsNull() && aFileLabel.FindAttribute(TDataStd_Comment::GetID(), aFileAttr))
+ theFileName = aFileAttr->Get();
+ found = true;
+ }
+ }
+ }
+ return anArray;
+}
+
+std::list<int> GEOM_Engine::getAllTextures(int theDocID)
+{
+ std::list<int> id_list;
+
+ Handle(TDocStd_Document) aDoc = GetDocument(theDocID);
+
+ TDF_ChildIterator anIterator(aDoc->Main(), Standard_True);
+ for (; anIterator.More(); anIterator.Next()) {
+ TDF_Label aTextureLabel = anIterator.Value();
+ if (aTextureLabel.IsAttribute( GetTextureGUID())) {
+ TDF_Label anIDLabel = aTextureLabel.FindChild(TEXTURE_LABEL_ID, Standard_False);
+ Handle(TDataStd_Integer) anIdAttr;
+ if(!anIDLabel.IsNull() && anIDLabel.FindAttribute(TDataStd_Integer::GetID(), anIdAttr))
+ id_list.push_back((int)anIdAttr->Get());
+ }
+ }
+ return id_list;
+}