1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkXMLPolyDataWriter.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
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 "vtkXMLPolyDataWriter.h"
16
17 #include "vtkCellArray.h"
18 #include "vtkCellData.h"
19 #include "vtkErrorCode.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationIntegerKey.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24 #include "vtkPolyData.h"
25 #include "vtkStreamingDemandDrivenPipeline.h"
26 #define vtkXMLOffsetsManager_DoNotInclude
27 #include "vtkXMLOffsetsManager.h"
28 #undef vtkXMLOffsetsManager_DoNotInclude
29
30 vtkStandardNewMacro(vtkXMLPolyDataWriter);
31
32 //----------------------------------------------------------------------------
vtkXMLPolyDataWriter()33 vtkXMLPolyDataWriter::vtkXMLPolyDataWriter()
34 {
35 this->VertsOM = new OffsetsManagerArray;
36 this->LinesOM = new OffsetsManagerArray;
37 this->StripsOM = new OffsetsManagerArray;
38 this->PolysOM = new OffsetsManagerArray;
39 }
40
41 //----------------------------------------------------------------------------
~vtkXMLPolyDataWriter()42 vtkXMLPolyDataWriter::~vtkXMLPolyDataWriter()
43 {
44 delete this->VertsOM;
45 delete this->LinesOM;
46 delete this->StripsOM;
47 delete this->PolysOM;
48 }
49
50 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)51 void vtkXMLPolyDataWriter::PrintSelf(ostream& os, vtkIndent indent)
52 {
53 this->Superclass::PrintSelf(os, indent);
54 }
55
56 //----------------------------------------------------------------------------
GetInput()57 vtkPolyData* vtkXMLPolyDataWriter::GetInput()
58 {
59 return static_cast<vtkPolyData*>(this->Superclass::GetInput());
60 }
61
62 //----------------------------------------------------------------------------
GetDataSetName()63 const char* vtkXMLPolyDataWriter::GetDataSetName()
64 {
65 return "PolyData";
66 }
67
68 //----------------------------------------------------------------------------
GetDefaultFileExtension()69 const char* vtkXMLPolyDataWriter::GetDefaultFileExtension()
70 {
71 return "vtp";
72 }
73
74 //----------------------------------------------------------------------------
AllocatePositionArrays()75 void vtkXMLPolyDataWriter::AllocatePositionArrays()
76 {
77 this->Superclass::AllocatePositionArrays();
78
79 this->NumberOfVertsPositions = new unsigned long[this->NumberOfPieces];
80 this->NumberOfLinesPositions = new unsigned long[this->NumberOfPieces];
81 this->NumberOfStripsPositions = new unsigned long[this->NumberOfPieces];
82 this->NumberOfPolysPositions = new unsigned long[this->NumberOfPieces];
83
84 this->VertsOM->Allocate(this->NumberOfPieces, 2, this->NumberOfTimeSteps);
85 this->LinesOM->Allocate(this->NumberOfPieces, 2, this->NumberOfTimeSteps);
86 this->StripsOM->Allocate(this->NumberOfPieces, 2, this->NumberOfTimeSteps);
87 this->PolysOM->Allocate(this->NumberOfPieces, 2, this->NumberOfTimeSteps);
88 }
89
90 //----------------------------------------------------------------------------
DeletePositionArrays()91 void vtkXMLPolyDataWriter::DeletePositionArrays()
92 {
93 this->Superclass::DeletePositionArrays();
94
95 delete[] this->NumberOfVertsPositions;
96 delete[] this->NumberOfLinesPositions;
97 delete[] this->NumberOfStripsPositions;
98 delete[] this->NumberOfPolysPositions;
99 }
100
101 //----------------------------------------------------------------------------
WriteInlinePieceAttributes()102 void vtkXMLPolyDataWriter::WriteInlinePieceAttributes()
103 {
104 this->Superclass::WriteInlinePieceAttributes();
105 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
106 {
107 return;
108 }
109
110 vtkPolyData* input = this->GetInput();
111 this->WriteScalarAttribute("NumberOfVerts",
112 input->GetVerts()->GetNumberOfCells());
113 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
114 {
115 return;
116 }
117 this->WriteScalarAttribute("NumberOfLines",
118 input->GetLines()->GetNumberOfCells());
119 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
120 {
121 return;
122 }
123 this->WriteScalarAttribute("NumberOfStrips",
124 input->GetStrips()->GetNumberOfCells());
125 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
126 {
127 return;
128 }
129 this->WriteScalarAttribute("NumberOfPolys",
130 input->GetPolys()->GetNumberOfCells());
131 }
132
133 //----------------------------------------------------------------------------
WriteInlinePiece(vtkIndent indent)134 void vtkXMLPolyDataWriter::WriteInlinePiece(vtkIndent indent)
135 {
136 // Split progress range by the approximate fraction of data written
137 // by each step in this method.
138 float progressRange[2] = { 0.f, 0.f };
139 this->GetProgressRange(progressRange);
140 float fractions[6];
141 this->CalculateSuperclassFraction(fractions);
142
143 // Set the range of progress for superclass.
144 this->SetProgressRange(progressRange, 0, fractions);
145
146 // Let the superclass write its data.
147 this->Superclass::WriteInlinePiece(indent);
148 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
149 {
150 return;
151 }
152
153 vtkPolyData* input = this->GetInput();
154
155 // Set the range of progress for Verts.
156 this->SetProgressRange(progressRange, 1, fractions);
157
158 // Write the Verts.
159 this->WriteCellsInline("Verts", input->GetVerts(), 0, indent);
160 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
161 {
162 return;
163 }
164
165 // Set the range of progress for Lines.
166 this->SetProgressRange(progressRange, 2, fractions);
167
168 // Write the Lines.
169 this->WriteCellsInline("Lines", input->GetLines(), 0, indent);
170 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
171 {
172 return;
173 }
174
175 // Set the range of progress for Strips.
176 this->SetProgressRange(progressRange, 3, fractions);
177
178 // Write the Strips.
179 this->WriteCellsInline("Strips", input->GetStrips(), 0, indent);
180 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
181 {
182 return;
183 }
184
185 // Set the range of progress for Polys.
186 this->SetProgressRange(progressRange, 4, fractions);
187
188 // Write the Polys.
189 this->WriteCellsInline("Polys", input->GetPolys(), 0, indent);
190 }
191
192 //----------------------------------------------------------------------------
WriteAppendedPieceAttributes(int index)193 void vtkXMLPolyDataWriter::WriteAppendedPieceAttributes(int index)
194 {
195 this->Superclass::WriteAppendedPieceAttributes(index);
196 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
197 {
198 return;
199 }
200 this->NumberOfVertsPositions[index] =
201 this->ReserveAttributeSpace("NumberOfVerts");
202 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
203 {
204 return;
205 }
206 this->NumberOfLinesPositions[index] =
207 this->ReserveAttributeSpace("NumberOfLines");
208 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
209 {
210 return;
211 }
212 this->NumberOfStripsPositions[index] =
213 this->ReserveAttributeSpace("NumberOfStrips");
214 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
215 {
216 return;
217 }
218 this->NumberOfPolysPositions[index] =
219 this->ReserveAttributeSpace("NumberOfPolys");
220 }
221
222 //----------------------------------------------------------------------------
WriteAppendedPiece(int index,vtkIndent indent)223 void vtkXMLPolyDataWriter::WriteAppendedPiece(int index, vtkIndent indent)
224 {
225 this->Superclass::WriteAppendedPiece(index, indent);
226 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
227 {
228 return;
229 }
230
231 this->WriteCellsAppended("Verts", 0, indent,
232 &this->VertsOM->GetPiece(index));
233 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
234 {
235 return;
236 }
237
238 this->WriteCellsAppended("Lines", 0, indent ,
239 &this->LinesOM->GetPiece(index));
240 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
241 {
242 return;
243 }
244
245 this->WriteCellsAppended("Strips", 0, indent,
246 &this->StripsOM->GetPiece(index));
247 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
248 {
249 return;
250 }
251
252 this->WriteCellsAppended("Polys", 0, indent,
253 &this->PolysOM->GetPiece(index));
254 }
255
256 //----------------------------------------------------------------------------
WriteAppendedPieceData(int index)257 void vtkXMLPolyDataWriter::WriteAppendedPieceData(int index)
258 {
259 ostream& os = *(this->Stream);
260 vtkPolyData* input = this->GetInput();
261
262 unsigned long returnPosition = os.tellp();
263 os.seekp(this->NumberOfVertsPositions[index]);
264 this->WriteScalarAttribute("NumberOfVerts",
265 input->GetVerts()->GetNumberOfCells());
266 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
267 {
268 return;
269 }
270
271 os.seekp(this->NumberOfLinesPositions[index]);
272 this->WriteScalarAttribute("NumberOfLines",
273 input->GetLines()->GetNumberOfCells());
274 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
275 {
276 return;
277 }
278
279 os.seekp(this->NumberOfStripsPositions[index]);
280 this->WriteScalarAttribute("NumberOfStrips",
281 input->GetStrips()->GetNumberOfCells());
282 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
283 {
284 return;
285 }
286
287 os.seekp(this->NumberOfPolysPositions[index]);
288 this->WriteScalarAttribute("NumberOfPolys",
289 input->GetPolys()->GetNumberOfCells());
290 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
291 {
292 return;
293 }
294 os.seekp(returnPosition);
295
296 // Split progress range by the approximate fraction of data written
297 // by each step in this method.
298 float progressRange[2] = { 0.f, 0.f };
299 this->GetProgressRange(progressRange);
300 float fractions[6];
301 this->CalculateSuperclassFraction(fractions);
302
303 // Set the range of progress for superclass.
304 this->SetProgressRange(progressRange, 0, fractions);
305
306 // Let the superclass write its data.
307 this->Superclass::WriteAppendedPieceData(index);
308 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
309 {
310 return;
311 }
312
313 // Set the range of progress for Verts.
314 this->SetProgressRange(progressRange, 1, fractions);
315
316 // Write the Verts.
317 this->WriteCellsAppendedData(input->GetVerts(), 0,
318 this->CurrentTimeIndex,
319 &this->VertsOM->GetPiece(index));
320 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
321 {
322 return;
323 }
324
325 // Set the range of progress for Lines.
326 this->SetProgressRange(progressRange, 2, fractions);
327
328 // Write the Lines.
329 this->WriteCellsAppendedData(input->GetLines(), 0,
330 this->CurrentTimeIndex,
331 &this->LinesOM->GetPiece(index));
332 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
333 {
334 return;
335 }
336
337 // Set the range of progress for Strips.
338 this->SetProgressRange(progressRange, 3, fractions);
339
340 // Write the Strips.
341 this->WriteCellsAppendedData(input->GetStrips(), 0,
342 this->CurrentTimeIndex,
343 &this->StripsOM->GetPiece(index));
344 if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
345 {
346 return;
347 }
348
349 // Set the range of progress for Polys.
350 this->SetProgressRange(progressRange, 4, fractions);
351
352 // Write the Polys.
353 this->WriteCellsAppendedData(input->GetPolys(), 0,
354 this->CurrentTimeIndex,
355 &this->PolysOM->GetPiece(index));
356 }
357
358 //----------------------------------------------------------------------------
GetNumberOfInputCells()359 vtkIdType vtkXMLPolyDataWriter::GetNumberOfInputCells()
360 {
361 vtkPolyData* input = this->GetInput();
362 return (input->GetVerts()->GetNumberOfCells()+
363 input->GetLines()->GetNumberOfCells()+
364 input->GetStrips()->GetNumberOfCells()+
365 input->GetPolys()->GetNumberOfCells());
366 }
367
368 //----------------------------------------------------------------------------
CalculateSuperclassFraction(float * fractions)369 void vtkXMLPolyDataWriter::CalculateSuperclassFraction(float* fractions)
370 {
371 vtkPolyData* input = this->GetInput();
372
373 // The superclass will write point/cell data and point specifications.
374 int pdArrays = input->GetPointData()->GetNumberOfArrays();
375 int cdArrays = input->GetCellData()->GetNumberOfArrays();
376 vtkIdType pdSize = pdArrays*this->GetNumberOfInputPoints();
377 vtkIdType cdSize = cdArrays*this->GetNumberOfInputCells();
378 vtkIdType pointsSize = this->GetNumberOfInputPoints();
379
380 // This class will write cell specifications.
381 vtkIdType connectSizeV = (input->GetVerts()->GetData()->GetNumberOfTuples() -
382 input->GetVerts()->GetNumberOfCells());
383 vtkIdType connectSizeL = (input->GetLines()->GetData()->GetNumberOfTuples() -
384 input->GetLines()->GetNumberOfCells());
385 vtkIdType connectSizeS = (input->GetStrips()->GetData()->GetNumberOfTuples() -
386 input->GetStrips()->GetNumberOfCells());
387 vtkIdType connectSizeP = (input->GetPolys()->GetData()->GetNumberOfTuples() -
388 input->GetPolys()->GetNumberOfCells());
389 vtkIdType offsetSizeV = input->GetVerts()->GetNumberOfCells();
390 vtkIdType offsetSizeL = input->GetLines()->GetNumberOfCells();
391 vtkIdType offsetSizeS = input->GetStrips()->GetNumberOfCells();
392 vtkIdType offsetSizeP = input->GetPolys()->GetNumberOfCells();
393 fractions[0] = 0;
394 fractions[1] = fractions[0] + pdSize+cdSize+pointsSize;
395 fractions[2] = fractions[1] + connectSizeV+offsetSizeV;
396 fractions[3] = fractions[2] + connectSizeL+offsetSizeL;
397 fractions[4] = fractions[3] + connectSizeS+offsetSizeS;
398 fractions[5] = fractions[4] + connectSizeP+offsetSizeP;
399 if (fractions[5] == 0)
400 {
401 fractions[5] = 1;
402 }
403 for (int i = 0; i < 5; ++i)
404 {
405 fractions[i+1] = fractions[i+1] / fractions[5];
406 }
407 }
408
409 //----------------------------------------------------------------------------
FillInputPortInformation(int,vtkInformation * info)410 int vtkXMLPolyDataWriter::FillInputPortInformation(int, vtkInformation* info)
411 {
412 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
413 return 1;
414 }
415