1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkX3DExporterXMLWriter.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen, Kristian Sons
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkX3DExporterXMLWriter.h"
16
17 #include "vtkX3D.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkDataArray.h"
20 #include "vtkUnsignedCharArray.h"
21 #include "vtkPoints.h"
22 #include "vtkCellArray.h"
23 #include "vtkMath.h"
24
25 #include <sstream>
26 #include <fstream>
27 #include <string>
28 #include <cassert>
29
30 using namespace vtkX3D;
31
32 struct XMLInfo {
33
XMLInfoXMLInfo34 XMLInfo(int _elementId)
35 {
36 this->elementId = _elementId;
37 this->endTagWritten = false;
38 }
39 int elementId;
40 bool endTagWritten;
41 };
42
43 typedef std::vector<XMLInfo> vtkX3DExporterXMLNodeInfoStackBase;
44 class vtkX3DExporterXMLNodeInfoStack: public vtkX3DExporterXMLNodeInfoStackBase
45 {};
46
47 //-----------------------------------------------------------------------------
48 vtkStandardNewMacro(vtkX3DExporterXMLWriter);
49 //-----------------------------------------------------------------------------
~vtkX3DExporterXMLWriter()50 vtkX3DExporterXMLWriter::~vtkX3DExporterXMLWriter()
51 {
52 delete this->InfoStack;
53 delete this->OutputStream;
54 this->OutputStream = nullptr;
55 }
56
57 //-----------------------------------------------------------------------------
vtkX3DExporterXMLWriter()58 vtkX3DExporterXMLWriter::vtkX3DExporterXMLWriter()
59 {
60 this->OutputStream = nullptr;
61 this->InfoStack = new vtkX3DExporterXMLNodeInfoStack();
62 this->Depth = 0;
63 this->ActTab = "";
64 }
65
66 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)67 void vtkX3DExporterXMLWriter::PrintSelf(ostream& os, vtkIndent indent)
68 {
69 this->Superclass::PrintSelf(os, indent);
70 }
71
72 //----------------------------------------------------------------------------
OpenFile(const char * file)73 int vtkX3DExporterXMLWriter::OpenFile(const char* file)
74 {
75 this->CloseFile();
76 this->WriteToOutputString = 0;
77 std::fstream* fileStream = new std::fstream();
78 fileStream->open (file, ios::out);
79 if(fileStream->fail())
80 {
81 delete fileStream;
82 return 0;
83 }
84 else
85 {
86 this->OutputStream = fileStream;
87 return 1;
88 }
89 }
90
91 //----------------------------------------------------------------------------
OpenStream()92 int vtkX3DExporterXMLWriter::OpenStream()
93 {
94 this->CloseFile();
95
96 this->WriteToOutputString = 1;
97 this->OutputStream = new std::ostringstream();
98 return 1;
99 }
100
101 //----------------------------------------------------------------------------
CloseFile()102 void vtkX3DExporterXMLWriter::CloseFile()
103 {
104 if(this->OutputStream != nullptr)
105 {
106 if(this->WriteToOutputString)
107 {
108 std::ostringstream *ostr =
109 static_cast<std::ostringstream*>(this->OutputStream);
110
111 delete [] this->OutputString;
112 this->OutputStringLength = static_cast<int>(ostr->str().size());
113 this->OutputString = new char[ostr->str().size()];
114 memcpy(this->OutputString, ostr->str().c_str(),
115 this->OutputStringLength);
116 }
117
118 delete this->OutputStream;
119 this->OutputStream = nullptr;
120 }
121 }
122
123 //-----------------------------------------------------------------------------
StartDocument()124 void vtkX3DExporterXMLWriter::StartDocument()
125 {
126 this->Depth = 0;
127 *this->OutputStream << "<?xml version=\"1.0\" encoding =\"UTF-8\"?>"
128 << endl << endl;
129 }
130
131 //-----------------------------------------------------------------------------
EndDocument()132 void vtkX3DExporterXMLWriter::EndDocument()
133 {
134 assert(this->Depth == 0);
135 }
136
137 //-----------------------------------------------------------------------------
StartNode(int elementID)138 void vtkX3DExporterXMLWriter::StartNode(int elementID)
139 {
140 // End last tag, if this is the first child
141 if (!this->InfoStack->empty())
142 {
143 if (!this->InfoStack->back().endTagWritten)
144 {
145 *this->OutputStream << ">" << this->GetNewline();
146 this->InfoStack->back().endTagWritten = true;
147 }
148 }
149
150 this->InfoStack->push_back(XMLInfo(elementID));
151 *this->OutputStream << this->ActTab << "<" << x3dElementString[elementID];
152 this->AddDepth();
153 }
154
155 //-----------------------------------------------------------------------------
EndNode()156 void vtkX3DExporterXMLWriter::EndNode()
157 {
158 assert(!this->InfoStack->empty());
159 this->SubDepth();
160 int elementID = this->InfoStack->back().elementId;
161
162 // There were no childs
163 if (!this->InfoStack->back().endTagWritten)
164 {
165 *this->OutputStream << "/>" << this->GetNewline();
166 }
167 else
168 {
169 *this->OutputStream << this->ActTab << "</" << x3dElementString[elementID]
170 << ">" << this->GetNewline();
171 }
172
173 this->InfoStack->pop_back();
174 }
175
176 //-----------------------------------------------------------------------------
SetField(int attributeID,int type,const double * d)177 void vtkX3DExporterXMLWriter::SetField(int attributeID, int type, const double* d)
178 {
179 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"";
180 switch (type)
181 {
182 case(SFVEC3F):
183 case(SFCOLOR):
184 *this->OutputStream << d[0]
185 << " "
186 << d[1]
187 << " "
188 << d[2];
189 break;
190 case(SFROTATION):
191 *this->OutputStream << d[1]
192 << " "
193 << d[2]
194 << " "
195 << d[3]
196 << " "
197 << vtkMath::RadiansFromDegrees( -d[0] );
198 break;
199 default:
200 *this->OutputStream << "UNKNOWN DATATYPE";
201 }
202 *this->OutputStream << "\"";
203 }
204
205 //-----------------------------------------------------------------------------
SetField(int attributeID,int type,vtkDataArray * a)206 void vtkX3DExporterXMLWriter::SetField(int attributeID, int type, vtkDataArray* a)
207 {
208 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"" << this->GetNewline();
209 switch (type)
210 {
211 case(MFVEC3F):
212 for (vtkIdType i = 0; i < a->GetNumberOfTuples(); i++)
213 {
214 double* d = a->GetTuple(i);
215 *this->OutputStream << this->ActTab << d[0] << " " << d[1] << " " << d[2] << "," << this->GetNewline();
216 }
217 break;
218 case(MFVEC2F):
219 for (vtkIdType i = 0; i < a->GetNumberOfTuples(); i++)
220 {
221 double* d = a->GetTuple(i);
222 *this->OutputStream << this->ActTab << d[0] << " " << d[1] << "," << this->GetNewline();
223 }
224 break;
225 default:
226 *this->OutputStream << "UNKNOWN DATATYPE";
227 }
228 *this->OutputStream << this->ActTab << "\"";
229 }
230
231 //-----------------------------------------------------------------------------
SetField(int attributeID,const double * values,size_t size)232 void vtkX3DExporterXMLWriter::SetField(int attributeID, const double* values, size_t size)
233 {
234 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"" << this->GetNewline() << this->ActTab;
235
236 unsigned int i = 0;
237 while (i < size)
238 {
239 *this->OutputStream << values[i];
240 if ((i+1)%3)
241 {
242 *this->OutputStream << " ";
243 }
244 else
245 {
246 *this->OutputStream << "," << this->GetNewline() << this->ActTab;
247 }
248 i++;
249 }
250 *this->OutputStream << "\"";
251 }
252
253 //-----------------------------------------------------------------------------
SetField(int attributeID,const int * values,size_t size,bool image)254 void vtkX3DExporterXMLWriter::SetField(int attributeID, const int* values, size_t size, bool image)
255 {
256 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"" << this->GetNewline() << this->ActTab;
257
258 unsigned int i = 0;
259 if (image)
260 {
261 assert(size > 2);
262 char buffer[20];
263 *this->OutputStream << values[0] << " "; // width
264 *this->OutputStream << values[1] << " "; // height
265 int bpp = values[2]; *this->OutputStream << bpp << "\n"; // bpp
266
267 i = 3;
268 unsigned int j = 0;
269
270 while (i < size)
271 {
272 snprintf(buffer,sizeof(buffer),"0x%.8x",values[i]);
273 *this->OutputStream << buffer;
274
275 if (j%(8*bpp))
276 {
277 *this->OutputStream << " ";
278 }
279 else
280 {
281 *this->OutputStream << this->GetNewline();// << this->ActTab;
282 }
283 i++; j+=bpp;
284 }
285 *this->OutputStream << dec;
286 }
287 else
288 while (i < size)
289 {
290 *this->OutputStream << values[i] << " ";
291 if (values[i] == -1)
292 {
293 *this->OutputStream << this->GetNewline() << this->ActTab;
294 }
295 i++;
296 }
297 *this->OutputStream << "\"";
298 }
299
300 //-----------------------------------------------------------------------------
SetField(int attributeID,int value)301 void vtkX3DExporterXMLWriter::SetField(int attributeID, int value)
302 {
303 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"" << value << "\"";
304 }
305
306 //-----------------------------------------------------------------------------
SetField(int attributeID,float value)307 void vtkX3DExporterXMLWriter::SetField(int attributeID, float value)
308 {
309 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"" << value << "\"";
310 }
311
312 //-----------------------------------------------------------------------------
SetField(int attributeID,double vtkNotUsed (value))313 void vtkX3DExporterXMLWriter::SetField(int attributeID, double vtkNotUsed(value))
314 {
315 *this->OutputStream << " " << x3dAttributeString[attributeID] << "=\"" << "WHY DOUBLE?" << "\"";
316 assert(false);
317 }
318
319 //-----------------------------------------------------------------------------
SetField(int attributeID,bool value)320 void vtkX3DExporterXMLWriter::SetField(int attributeID, bool value)
321 {
322 *this->OutputStream << " "
323 << x3dAttributeString[attributeID] << "=\"" << (value ? "true" : "false" ) << "\"";
324 }
325
326 //-----------------------------------------------------------------------------
SetField(int attributeID,const char * value,bool mfstring)327 void vtkX3DExporterXMLWriter::SetField(int attributeID, const char* value, bool mfstring)
328 {
329 if (mfstring)
330 {
331 *this->OutputStream << " "
332 << x3dAttributeString[attributeID] << "='" << value << "'";
333 }
334 else
335 {
336 *this->OutputStream
337 << " " << x3dAttributeString[attributeID] << "=\"" << value << "\"";
338 }
339 }
340
341
342 //-----------------------------------------------------------------------------
Flush()343 void vtkX3DExporterXMLWriter::Flush()
344 {
345 this->OutputStream->flush();
346 }
347
348 //-----------------------------------------------------------------------------
AddDepth()349 void vtkX3DExporterXMLWriter::AddDepth()
350 {
351 this->ActTab += " ";
352 }
353
354 //-----------------------------------------------------------------------------
SubDepth()355 void vtkX3DExporterXMLWriter::SubDepth()
356 {
357 this->ActTab.erase(0, 2);
358 }
359
360