1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkXMLPDataWriter.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 "vtkXMLPDataWriter.h"
16 
17 #include "vtkCallbackCommand.h"
18 #include "vtkDataSet.h"
19 #include "vtkDoubleArray.h"
20 #include "vtkErrorCode.h"
21 #include "vtkFieldData.h"
22 #include "vtkInformation.h"
23 #include "vtkNew.h"
24 #include "vtkStreamingDemandDrivenPipeline.h"
25 
26 #include <vtksys/SystemTools.hxx>
27 
28 //------------------------------------------------------------------------------
29 vtkXMLPDataWriter::vtkXMLPDataWriter() = default;
30 
31 //------------------------------------------------------------------------------
32 vtkXMLPDataWriter::~vtkXMLPDataWriter() = default;
33 
34 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)35 void vtkXMLPDataWriter::PrintSelf(ostream& os, vtkIndent indent)
36 {
37   this->Superclass::PrintSelf(os, indent);
38 }
39 
40 //------------------------------------------------------------------------------
WritePData(vtkIndent indent)41 void vtkXMLPDataWriter::WritePData(vtkIndent indent)
42 {
43   vtkDataSet* input = this->GetInputAsDataSet();
44 
45   // We want to avoid using appended data mode as it
46   // is not supported in meta formats.
47   int dataMode = this->DataMode;
48   if (dataMode == vtkXMLWriter::Appended)
49   {
50     this->DataMode = vtkXMLWriter::Binary;
51   }
52 
53   vtkFieldData* fieldData = input->GetFieldData();
54 
55   vtkInformation* meta = input->GetInformation();
56   bool hasTime = meta->Has(vtkDataObject::DATA_TIME_STEP()) ? true : false;
57   if ((fieldData && fieldData->GetNumberOfArrays()) || hasTime)
58   {
59     vtkNew<vtkFieldData> fieldDataCopy;
60     fieldDataCopy->ShallowCopy(fieldData);
61     if (hasTime)
62     {
63       vtkNew<vtkDoubleArray> time;
64       time->SetNumberOfTuples(1);
65       time->SetTypedComponent(0, 0, meta->Get(vtkDataObject::DATA_TIME_STEP()));
66       time->SetName("TimeValue");
67       fieldDataCopy->AddArray(time);
68     }
69     this->WriteFieldDataInline(fieldDataCopy, indent);
70   }
71 
72   this->DataMode = dataMode;
73 
74   this->WritePPointData(input->GetPointData(), indent);
75   if (this->ErrorCode == vtkErrorCode::OutOfDiskSpaceError)
76   {
77     return;
78   }
79   this->WritePCellData(input->GetCellData(), indent);
80 }
81 
82 //------------------------------------------------------------------------------
WritePieceInternal()83 int vtkXMLPDataWriter::WritePieceInternal()
84 {
85   int piece = this->GetCurrentPiece();
86 
87   vtkDataSet* inputDS = this->GetInputAsDataSet();
88   if (inputDS && (inputDS->GetNumberOfPoints() > 0 || inputDS->GetNumberOfCells() > 0))
89   {
90     if (!this->WritePiece(piece))
91     {
92       vtkErrorMacro("Ran out of disk space; deleting file(s) already written");
93       this->DeleteFiles();
94       return 0;
95     }
96     this->PieceWrittenFlags[piece] = static_cast<unsigned char>(0x1);
97   }
98 
99   return 1;
100 }
101 
102 //------------------------------------------------------------------------------
WritePiece(int index)103 int vtkXMLPDataWriter::WritePiece(int index)
104 {
105   // Create the writer for the piece.  Its configuration should match
106   // our own writer.
107   vtkXMLWriter* pWriter = this->CreatePieceWriter(index);
108   pWriter->AddObserver(vtkCommand::ProgressEvent, this->InternalProgressObserver);
109 
110   char* fileName = this->CreatePieceFileName(index, this->PathName);
111   std::string path = vtksys::SystemTools::GetParentDirectory(fileName);
112   if (!path.empty() && !vtksys::SystemTools::PathExists(path))
113   {
114     vtksys::SystemTools::MakeDirectory(path);
115   }
116   pWriter->SetFileName(fileName);
117   delete[] fileName;
118 
119   // Copy the writer settings.
120   pWriter->SetDebug(this->Debug);
121   pWriter->SetCompressor(this->Compressor);
122   pWriter->SetDataMode(this->DataMode);
123   pWriter->SetByteOrder(this->ByteOrder);
124   pWriter->SetEncodeAppendedData(this->EncodeAppendedData);
125   pWriter->SetHeaderType(this->HeaderType);
126   pWriter->SetBlockSize(this->BlockSize);
127 
128   // Write the piece.
129   int result = pWriter->Write();
130   this->SetErrorCode(pWriter->GetErrorCode());
131 
132   // Cleanup.
133   pWriter->RemoveObserver(this->InternalProgressObserver);
134   pWriter->Delete();
135 
136   return result;
137 }
138 
139 //------------------------------------------------------------------------------
WritePrimaryElementAttributes(std::ostream & vtkNotUsed (os),vtkIndent vtkNotUsed (indent))140 void vtkXMLPDataWriter::WritePrimaryElementAttributes(
141   std::ostream& vtkNotUsed(os), vtkIndent vtkNotUsed(indent))
142 {
143   this->WriteScalarAttribute("GhostLevel", this->GhostLevel);
144 }
145 
146 //------------------------------------------------------------------------------
SetupPieceFileNameExtension()147 void vtkXMLPDataWriter::SetupPieceFileNameExtension()
148 {
149   this->Superclass::SetupPieceFileNameExtension();
150 
151   // Create a temporary piece writer and then initialize the extension.
152   vtkXMLWriter* writer = this->CreatePieceWriter(0);
153   const char* ext = writer->GetDefaultFileExtension();
154   this->PieceFileNameExtension = new char[strlen(ext) + 2];
155   this->PieceFileNameExtension[0] = '.';
156   strcpy(this->PieceFileNameExtension + 1, ext);
157   writer->Delete();
158 }
159