0027925: Visualization - implement order-independent transparency algorithm within...
[occt.git] / src / XmlMDF / XmlMDF.cxx
CommitLineData
b311480e 1// Created on: 2001-07-09
2// Created by: Julia DOROVSKIKH
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
42cf5bc1 17#include <CDM_MessageDriver.hxx>
7fd59977 18#include <Storage_Schema.hxx>
42cf5bc1 19#include <TColStd_MapOfTransient.hxx>
ec357c5c 20#include <TDF_Attribute.hxx>
42cf5bc1 21#include <TDF_AttributeIterator.hxx>
22#include <TDF_ChildIterator.hxx>
23#include <TDF_Data.hxx>
24#include <TDF_Label.hxx>
25#include <TDF_TagSource.hxx>
26#include <TDF_Tool.hxx>
27#include <XmlMDF.hxx>
28#include <XmlMDF_ADriver.hxx>
29#include <XmlMDF_ADriverTable.hxx>
30#include <XmlMDF_DataMapIteratorOfTypeADriverMap.hxx>
31#include <XmlMDF_ReferenceDriver.hxx>
32#include <XmlMDF_TagSourceDriver.hxx>
33#include <XmlObjMgt_Document.hxx>
34#include <XmlObjMgt_DOMString.hxx>
35#include <XmlObjMgt_Persistent.hxx>
7fd59977 36
37IMPLEMENT_DOMSTRING (TagString, "tag")
38IMPLEMENT_DOMSTRING (LabelString, "label")
39#define DATATYPE_MIGRATION
40//#define DATATYPE_MIGRATION_DEB
41//=======================================================================
42//function : UnsuppTypesMap
43//purpose :
44//=======================================================================
45
46static TColStd_MapOfTransient& UnsuppTypesMap ()
47{
48 static TColStd_MapOfTransient anUnsuppTypes;
49 return anUnsuppTypes;
50}
51
52//=======================================================================
53//function : FromTo
54//purpose : Paste transient data into DOM_Element
55//=======================================================================
56void XmlMDF::FromTo (const Handle(TDF_Data)& theData,
57 XmlObjMgt_Element& theElement,
58 XmlObjMgt_SRelocationTable& theRelocTable,
59 const Handle(XmlMDF_ADriverTable)& theDrivers)
60{
61 UnsuppTypesMap().Clear();
62// Standard_Integer count =
63 WriteSubTree(theData->Root(), theElement, theRelocTable, theDrivers);
64 UnsuppTypesMap().Clear();
65}
66
67//=======================================================================
68//function : WriteSubTree
69//purpose :
70//=======================================================================
71Standard_Integer XmlMDF::WriteSubTree
72 (const TDF_Label& theLabel,
73 XmlObjMgt_Element& theElement,
74 XmlObjMgt_SRelocationTable& theRelocTable,
75 const Handle(XmlMDF_ADriverTable)& theDrivers)
76{
77 XmlObjMgt_Document aDoc = theElement.getOwnerDocument();
78
79 // create element "label"
80 XmlObjMgt_Element aLabElem = aDoc.createElement (::LabelString());
81
82 // Extraction of the driver subset.
83 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
84
85 // write attributes
86 Standard_Integer count = 0;
87 TDF_AttributeIterator itr1 (theLabel);
88 for ( ; itr1.More(); itr1.Next())
89 {
90 const Handle(TDF_Attribute)& tAtt = itr1.Value();
91 const Handle(Standard_Type)& aType = tAtt->DynamicType();
92 if (aDriverMap.IsBound (aType))
93 {
94 const Handle(XmlMDF_ADriver)& aDriver = aDriverMap.Find (aType);
95 count++;
96
97 // Add source to relocation table
98 Standard_Integer anId = theRelocTable.Add (tAtt);
99
100 // Create DOM data item
101 XmlObjMgt_Persistent pAtt;
102 pAtt.CreateElement (aLabElem, aDriver->TypeName().ToCString(), anId);
103
104 // Paste
105 aDriver -> Paste (tAtt, pAtt, theRelocTable);
106 }
0797d9d3 107#ifdef OCCT_DEBUG
7fd59977 108 else if (!UnsuppTypesMap().Contains (aType))
109 {
110 cout << "attribute driver for type "<< aType -> Name()<< " not found"<< endl;
111 UnsuppTypesMap().Add (aType);
112 }
113#endif
114 }
115
116 // write sub-labels
117 TDF_ChildIterator itr2 (theLabel);
118 for ( ; itr2.More(); itr2.Next())
119 {
120 const TDF_Label& aChildLab = itr2.Value();
121 count += WriteSubTree(aChildLab, aLabElem, theRelocTable, theDrivers);
122 }
123
124 if (count > 0)
125 {
126 theElement.appendChild(aLabElem);
127
128 // set attribute "tag"
129 aLabElem.setAttribute (::TagString(), theLabel.Tag());
130 }
131
132 return count;
133}
134
135//=======================================================================
136//function : FromTo
137//purpose : Paste data from DOM_Element into transient document
138//=======================================================================
139Standard_Boolean XmlMDF::FromTo (const XmlObjMgt_Element& theElement,
140 Handle(TDF_Data)& theData,
141 XmlObjMgt_RRelocationTable& theRelocTable,
142 const Handle(XmlMDF_ADriverTable)& theDrivers)
143{
144 TDF_Label aRootLab = theData->Root();
145 XmlMDF_MapOfDriver aDriverMap;
146 CreateDrvMap (theDrivers, aDriverMap);
147
148 Standard_Integer count = 0;
149
150 LDOM_Node theNode = theElement.getFirstChild();
151 XmlObjMgt_Element anElem = (const XmlObjMgt_Element&)theNode;
152 while ( !anElem.isNull() )
153 {
154 if ( anElem.getNodeName().equals (::LabelString()) )
155 {
156 Standard_Integer subcount =
157 ReadSubTree(anElem, aRootLab, theRelocTable, aDriverMap);
158 // check for error
159 if (subcount < 0)
160 return Standard_False;
161 count += subcount;
162 }
163 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
164 LDOM_Node theNode1 = anElem.getNextSibling();
165 anElem = (const XmlObjMgt_Element &) theNode1;
166 }
167
168 return Standard_True;
169}
170
171//=======================================================================
172//function : ReadSubTree
173//purpose :
174//=======================================================================
175Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement,
176 const TDF_Label& theLabel,
177 XmlObjMgt_RRelocationTable& theRelocTable,
178 const XmlMDF_MapOfDriver& theDriverMap)
179{
180 // Extraction of the driver subset.
181 Standard_Integer count = 0;
182
183 //XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theElement.getFirstChild();
184 LDOM_Node theNode = theElement.getFirstChild();
185 XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theNode;
186 while ( !anElem.isNull() )
187 {
188 if ( anElem.getNodeType() == LDOM_Node::ELEMENT_NODE )
189 {
190 if ( anElem.getNodeName().equals (::LabelString()) )
191 {
192 // read tag
193 Standard_Integer tag;
194 XmlObjMgt_DOMString aTag (anElem.getAttribute(::TagString()));
195 if ( !aTag.GetInteger (tag) ) {
196 TCollection_ExtendedString anErrorMessage =
197 TCollection_ExtendedString ("Wrong Tag value for OCAF Label: ")
198 + aTag;
199 theDriverMap.Find("TDF_TagSource") -> WriteMessage (anErrorMessage);
200 return -1;
201 }
202 // create label
203 TDF_Label aLab = theLabel.FindChild(tag, Standard_True);
204
205 // read sub-tree
206 Standard_Integer subcount =
207 ReadSubTree(anElem, aLab, theRelocTable, theDriverMap);
208 // check for error
209 if (subcount == -1)
210 return -1;
211 count += subcount;
212 }
213 else
214 {
215 // read attribute
216 XmlObjMgt_DOMString aName = anElem.getNodeName();
217
218#ifdef DATATYPE_MIGRATION
219 TCollection_AsciiString newName;
220 if(Storage_Schema::CheckTypeMigration(aName, newName)) {
0797d9d3 221#ifdef OCCT_DEBUG
7fd59977 222 cout << "CheckTypeMigration:OldType = " <<aName.GetString() << " Len = "<<strlen(aName.GetString())<<endl;
223 cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl;
224#endif
225 aName = newName.ToCString();
226 }
227#endif
228
229 if (theDriverMap.IsBound (aName))
230 {
231 count++;
232 const Handle(XmlMDF_ADriver)& driver = theDriverMap.Find(aName);
233 XmlObjMgt_Persistent pAtt (anElem);
234 Standard_Integer anID = pAtt.Id ();
235 if (anID <= 0) { // check for ID validity
236 TCollection_ExtendedString anErrorMessage =
237 TCollection_ExtendedString("Wrong ID of OCAF attribute with type ")
238 + aName;
239 driver -> WriteMessage (anErrorMessage);
240 return -1;
241 }
242 Handle(TDF_Attribute) tAtt;
243 Standard_Boolean isBound = theRelocTable.IsBound(anID);
244 if (isBound)
245 tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID));
246 else
247 tAtt = driver -> NewEmpty();
248 if (tAtt->Label().IsNull())
249 theLabel.AddAttribute (tAtt);
250 else
251 driver->WriteMessage
252 (TCollection_ExtendedString("XmlDriver warning: ") +
253 "attempt to attach attribute " +
254 aName + " to a second label");
255
256 if (! driver -> Paste (pAtt, tAtt, theRelocTable))
257 {
258 // error converting persistent to transient
259 driver->WriteMessage
260 (TCollection_ExtendedString("XmlDriver warning: ") +
261 "failure reading attribute " + aName);
262 }
263 else if (isBound == Standard_False)
264 theRelocTable.Bind (anID, tAtt);
265 }
0797d9d3 266#ifdef OCCT_DEBUG
7fd59977 267 else
268 {
269 const TCollection_AsciiString anAsciiName = aName;
270 cerr << "XmlDriver warning: "
271 << "label contains object of unknown type "<< anAsciiName<< endl;
272 }
273#endif
274 }
275 }
276 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
277 LDOM_Node theNode1 = anElem.getNextSibling();
278 anElem = (const XmlObjMgt_Element &) theNode1;
279 }
280
281 // AfterRetrieval
282 if (count > 0)
283 {
284 }
285
286 return count;
287}
288
289//=======================================================================
290//function : AddDrivers
291//purpose :
292//=======================================================================
293void XmlMDF::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
294 const Handle(CDM_MessageDriver)& aMessageDriver)
295{
296 aDriverTable->AddDriver (new XmlMDF_TagSourceDriver(aMessageDriver));
297 aDriverTable->AddDriver (new XmlMDF_ReferenceDriver(aMessageDriver));
298}
299
300//=======================================================================
301//function : CreateDrvMap
302//purpose :
303//=======================================================================
304
305void XmlMDF::CreateDrvMap (const Handle(XmlMDF_ADriverTable)& theDrivers,
306 XmlMDF_MapOfDriver& theAsciiDriverMap)
307{
308 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
309 XmlMDF_DataMapIteratorOfTypeADriverMap anIter (aDriverMap);
310 while (anIter.More()) {
311 const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
312 const TCollection_AsciiString aTypeName = aDriver -> TypeName();
313 if (theAsciiDriverMap.IsBound (aTypeName) == Standard_False)
314 theAsciiDriverMap.Bind (aTypeName, aDriver);
315 else
316 aDriver -> WriteMessage
317 (TCollection_ExtendedString ("Warning: skipped driver name: \"")
318 + aTypeName + '\"');
319 anIter.Next();
320 }
321}