0028945: Visualization - StdPrs_ToolTriangulatedShape::ComputeNormals() is extremely...
[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>
c2f5b821 36#include <XmlLDrivers.hxx>
7fd59977 37
38IMPLEMENT_DOMSTRING (TagString, "tag")
39IMPLEMENT_DOMSTRING (LabelString, "label")
40#define DATATYPE_MIGRATION
41//#define DATATYPE_MIGRATION_DEB
42//=======================================================================
43//function : UnsuppTypesMap
44//purpose :
45//=======================================================================
46
47static TColStd_MapOfTransient& UnsuppTypesMap ()
48{
49 static TColStd_MapOfTransient anUnsuppTypes;
50 return anUnsuppTypes;
51}
52
53//=======================================================================
54//function : FromTo
55//purpose : Paste transient data into DOM_Element
56//=======================================================================
57void XmlMDF::FromTo (const Handle(TDF_Data)& theData,
58 XmlObjMgt_Element& theElement,
59 XmlObjMgt_SRelocationTable& theRelocTable,
60 const Handle(XmlMDF_ADriverTable)& theDrivers)
61{
62 UnsuppTypesMap().Clear();
63// Standard_Integer count =
64 WriteSubTree(theData->Root(), theElement, theRelocTable, theDrivers);
65 UnsuppTypesMap().Clear();
66}
67
68//=======================================================================
69//function : WriteSubTree
70//purpose :
71//=======================================================================
72Standard_Integer XmlMDF::WriteSubTree
73 (const TDF_Label& theLabel,
74 XmlObjMgt_Element& theElement,
75 XmlObjMgt_SRelocationTable& theRelocTable,
76 const Handle(XmlMDF_ADriverTable)& theDrivers)
77{
78 XmlObjMgt_Document aDoc = theElement.getOwnerDocument();
79
80 // create element "label"
81 XmlObjMgt_Element aLabElem = aDoc.createElement (::LabelString());
82
83 // Extraction of the driver subset.
84 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
85
86 // write attributes
87 Standard_Integer count = 0;
88 TDF_AttributeIterator itr1 (theLabel);
89 for ( ; itr1.More(); itr1.Next())
90 {
91 const Handle(TDF_Attribute)& tAtt = itr1.Value();
92 const Handle(Standard_Type)& aType = tAtt->DynamicType();
93 if (aDriverMap.IsBound (aType))
94 {
95 const Handle(XmlMDF_ADriver)& aDriver = aDriverMap.Find (aType);
96 count++;
97
98 // Add source to relocation table
99 Standard_Integer anId = theRelocTable.Add (tAtt);
100
101 // Create DOM data item
102 XmlObjMgt_Persistent pAtt;
c2f5b821 103 // In the document version 8 the attribute TPrsStd_AISPresentation
104 // was replaced by TDataXtd_Presentation. Therefore, for old versions
105 // we write old name of the attribute (TPrsStd_AISPresentation).
106 Standard_CString typeName = aDriver->TypeName().ToCString();
107 if (XmlLDrivers::StorageVersion() < 8 &&
108 strcmp(typeName, "TDataXtd_Presentation") == 0)
109 {
110 typeName = "TPrsStd_AISPresentation";
111 }
112 pAtt.CreateElement (aLabElem, typeName, anId);
7fd59977 113
114 // Paste
115 aDriver -> Paste (tAtt, pAtt, theRelocTable);
116 }
0797d9d3 117#ifdef OCCT_DEBUG
7fd59977 118 else if (!UnsuppTypesMap().Contains (aType))
119 {
120 cout << "attribute driver for type "<< aType -> Name()<< " not found"<< endl;
121 UnsuppTypesMap().Add (aType);
122 }
123#endif
124 }
125
126 // write sub-labels
127 TDF_ChildIterator itr2 (theLabel);
128 for ( ; itr2.More(); itr2.Next())
129 {
130 const TDF_Label& aChildLab = itr2.Value();
131 count += WriteSubTree(aChildLab, aLabElem, theRelocTable, theDrivers);
132 }
133
134 if (count > 0)
135 {
136 theElement.appendChild(aLabElem);
137
138 // set attribute "tag"
139 aLabElem.setAttribute (::TagString(), theLabel.Tag());
140 }
141
142 return count;
143}
144
145//=======================================================================
146//function : FromTo
147//purpose : Paste data from DOM_Element into transient document
148//=======================================================================
149Standard_Boolean XmlMDF::FromTo (const XmlObjMgt_Element& theElement,
150 Handle(TDF_Data)& theData,
151 XmlObjMgt_RRelocationTable& theRelocTable,
152 const Handle(XmlMDF_ADriverTable)& theDrivers)
153{
154 TDF_Label aRootLab = theData->Root();
155 XmlMDF_MapOfDriver aDriverMap;
156 CreateDrvMap (theDrivers, aDriverMap);
157
158 Standard_Integer count = 0;
159
160 LDOM_Node theNode = theElement.getFirstChild();
161 XmlObjMgt_Element anElem = (const XmlObjMgt_Element&)theNode;
162 while ( !anElem.isNull() )
163 {
164 if ( anElem.getNodeName().equals (::LabelString()) )
165 {
166 Standard_Integer subcount =
167 ReadSubTree(anElem, aRootLab, theRelocTable, aDriverMap);
168 // check for error
169 if (subcount < 0)
170 return Standard_False;
171 count += subcount;
172 }
173 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
174 LDOM_Node theNode1 = anElem.getNextSibling();
175 anElem = (const XmlObjMgt_Element &) theNode1;
176 }
177
178 return Standard_True;
179}
180
181//=======================================================================
182//function : ReadSubTree
183//purpose :
184//=======================================================================
185Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement,
186 const TDF_Label& theLabel,
187 XmlObjMgt_RRelocationTable& theRelocTable,
188 const XmlMDF_MapOfDriver& theDriverMap)
189{
190 // Extraction of the driver subset.
191 Standard_Integer count = 0;
192
193 //XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theElement.getFirstChild();
194 LDOM_Node theNode = theElement.getFirstChild();
195 XmlObjMgt_Element anElem = (const XmlObjMgt_Element &) theNode;
196 while ( !anElem.isNull() )
197 {
198 if ( anElem.getNodeType() == LDOM_Node::ELEMENT_NODE )
199 {
200 if ( anElem.getNodeName().equals (::LabelString()) )
201 {
202 // read tag
203 Standard_Integer tag;
204 XmlObjMgt_DOMString aTag (anElem.getAttribute(::TagString()));
205 if ( !aTag.GetInteger (tag) ) {
206 TCollection_ExtendedString anErrorMessage =
207 TCollection_ExtendedString ("Wrong Tag value for OCAF Label: ")
208 + aTag;
209 theDriverMap.Find("TDF_TagSource") -> WriteMessage (anErrorMessage);
210 return -1;
211 }
212 // create label
213 TDF_Label aLab = theLabel.FindChild(tag, Standard_True);
214
215 // read sub-tree
216 Standard_Integer subcount =
217 ReadSubTree(anElem, aLab, theRelocTable, theDriverMap);
218 // check for error
219 if (subcount == -1)
220 return -1;
221 count += subcount;
222 }
223 else
224 {
225 // read attribute
226 XmlObjMgt_DOMString aName = anElem.getNodeName();
227
228#ifdef DATATYPE_MIGRATION
229 TCollection_AsciiString newName;
230 if(Storage_Schema::CheckTypeMigration(aName, newName)) {
0797d9d3 231#ifdef OCCT_DEBUG
7fd59977 232 cout << "CheckTypeMigration:OldType = " <<aName.GetString() << " Len = "<<strlen(aName.GetString())<<endl;
233 cout << "CheckTypeMigration:NewType = " <<newName << " Len = "<< newName.Length()<<endl;
234#endif
235 aName = newName.ToCString();
236 }
237#endif
238
239 if (theDriverMap.IsBound (aName))
240 {
241 count++;
242 const Handle(XmlMDF_ADriver)& driver = theDriverMap.Find(aName);
243 XmlObjMgt_Persistent pAtt (anElem);
244 Standard_Integer anID = pAtt.Id ();
245 if (anID <= 0) { // check for ID validity
246 TCollection_ExtendedString anErrorMessage =
247 TCollection_ExtendedString("Wrong ID of OCAF attribute with type ")
248 + aName;
249 driver -> WriteMessage (anErrorMessage);
250 return -1;
251 }
252 Handle(TDF_Attribute) tAtt;
253 Standard_Boolean isBound = theRelocTable.IsBound(anID);
254 if (isBound)
255 tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID));
256 else
257 tAtt = driver -> NewEmpty();
258 if (tAtt->Label().IsNull())
259 theLabel.AddAttribute (tAtt);
260 else
261 driver->WriteMessage
262 (TCollection_ExtendedString("XmlDriver warning: ") +
263 "attempt to attach attribute " +
264 aName + " to a second label");
265
266 if (! driver -> Paste (pAtt, tAtt, theRelocTable))
267 {
268 // error converting persistent to transient
269 driver->WriteMessage
270 (TCollection_ExtendedString("XmlDriver warning: ") +
271 "failure reading attribute " + aName);
272 }
273 else if (isBound == Standard_False)
274 theRelocTable.Bind (anID, tAtt);
275 }
0797d9d3 276#ifdef OCCT_DEBUG
7fd59977 277 else
278 {
279 const TCollection_AsciiString anAsciiName = aName;
280 cerr << "XmlDriver warning: "
281 << "label contains object of unknown type "<< anAsciiName<< endl;
282 }
283#endif
284 }
285 }
286 //anElem = (const XmlObjMgt_Element &) anElem.getNextSibling();
287 LDOM_Node theNode1 = anElem.getNextSibling();
288 anElem = (const XmlObjMgt_Element &) theNode1;
289 }
290
291 // AfterRetrieval
292 if (count > 0)
293 {
294 }
295
296 return count;
297}
298
299//=======================================================================
300//function : AddDrivers
301//purpose :
302//=======================================================================
303void XmlMDF::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable,
304 const Handle(CDM_MessageDriver)& aMessageDriver)
305{
306 aDriverTable->AddDriver (new XmlMDF_TagSourceDriver(aMessageDriver));
307 aDriverTable->AddDriver (new XmlMDF_ReferenceDriver(aMessageDriver));
308}
309
310//=======================================================================
311//function : CreateDrvMap
312//purpose :
313//=======================================================================
314
315void XmlMDF::CreateDrvMap (const Handle(XmlMDF_ADriverTable)& theDrivers,
316 XmlMDF_MapOfDriver& theAsciiDriverMap)
317{
318 const XmlMDF_TypeADriverMap& aDriverMap = theDrivers->GetDrivers();
319 XmlMDF_DataMapIteratorOfTypeADriverMap anIter (aDriverMap);
320 while (anIter.More()) {
321 const Handle(XmlMDF_ADriver)& aDriver = anIter.Value();
322 const TCollection_AsciiString aTypeName = aDriver -> TypeName();
323 if (theAsciiDriverMap.IsBound (aTypeName) == Standard_False)
324 theAsciiDriverMap.Bind (aTypeName, aDriver);
325 else
326 aDriver -> WriteMessage
327 (TCollection_ExtendedString ("Warning: skipped driver name: \"")
328 + aTypeName + '\"');
329 anIter.Next();
330 }
331}