MercuryDPM  Alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VTKData.h
Go to the documentation of this file.
1 //Copyright (c) 2015, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #ifndef TOOLS_VTKDATA_H
27 #define TOOLS_VTKDATA_H
28 
29 #include <fstream>
30 #include <iostream>
31 #include <string>
32 #include <sstream>
33 #include <functional>
34 #include <map>
35 #include <vector>
36 #include <type_traits>
37 
38 //Namespace Detail contains black magic.
39 namespace Detail {
43  template<typename T>
45  {
46  std::string name_;
47  public:
52  VTKPointDescriptorEntry(std::string fieldName)
53  : name_(fieldName)
54  {
55  }
56 
58  {
59  }
60 
66  virtual void emit(std::ostream& out, const T& t) const = 0;
71  virtual std::string getTypeName() const = 0;
75  std::string getName() const
76  {
77  return name_;
78  }
82  virtual std::size_t getNumberOfComponents() const = 0;
83  };
84 
86  template<typename V>
87  typename std::enable_if<std::is_floating_point<V>::value, std::string>::type
89  {
90  return "Float32";
91  }
92 
93  template<typename V>
94  typename std::enable_if<std::is_integral<V>::value && std::is_unsigned<V>::value, std::string>::type
96  {
97  return "UInt32";
98  }
99 
100  template<typename V>
101  typename std::enable_if<std::is_integral<V>::value && std::is_signed<V>::value, std::string>::type
103  {
104  return "Int32";
105  }
106 
107  template<typename V>
108  typename std::enable_if<std::is_array<V>::value, std::string>::type
110  {
111  return toVTKDataType< typename std::remove_extent<V>::type >();
112  }
113 
115  template<typename T, typename V>
116  typename std::enable_if<std::is_array<V>::value || std::is_pointer<V>::value, void>::type
117  emitProxy(std::ostream& out, const T& t, std::size_t nComponents, V T::*member)
118  {
119  for (std::size_t i = 0; i < nComponents; i++)
120  {
121  out << (t.*member)[i] << " ";
122  }
123  }
124 
125  template<typename T, typename V>
126  typename std::enable_if<!(std::is_array<V>::value || std::is_pointer<V>::value), void>::type
127  emitProxy(std::ostream& out, const T& t, std::size_t nComponents, V T::*member)
128  {
129  out << t.*member << " ";
130  }
131 
135  template<typename T, typename V>
137  {
138  const V T::* member_;
139  const std::size_t nComponents_;
140  public:
141  VTKPointDescriptorEntryImpl(std::string name, V T::*member, std::size_t nComponents)
142  : VTKPointDescriptorEntry<T>(name), member_(member), nComponents_(nComponents)
143  { }
144 
145  std::string getTypeName() const override
146  {
147  return toVTKDataType<V>();
148  }
149 
150  void emit(std::ostream& out, const T& t) const override
151  {
152  emitProxy(out, t, nComponents_, member_);
153  }
154 
155  std::size_t getNumberOfComponents() const override
156  {
157  return nComponents_;
158  }
159  };
160 }
161 
170 template<typename T>
172 {
173  std::vector< Detail::VTKPointDescriptorEntry<T>* > entries_;
175  public:
177  {
178  }
179 
181  {
182  for (auto * d : entries_)
183  delete d;
184  }
185 
186  template<typename DATATYPE>
187  typename std::enable_if<std::is_array<DATATYPE>::value, VTKPointDescriptor&>::type
188  addProperty(std::string name, DATATYPE T::*m, bool isPrimary = false)
189  {
191  = new Detail::VTKPointDescriptorEntryImpl<T,DATATYPE>(name, m, std::extent<DATATYPE>::value);
192  entries_.push_back(data);
193  if (isPrimary)
194  positionEntry_ = entries_.back();
195 
196  return *this;
197  }
198 
199  template<typename DATATYPE>
200  typename std::enable_if<!std::is_array<DATATYPE>::value, VTKPointDescriptor&>::type
201  addProperty(std::string name, DATATYPE T::*m, bool isPrimary = false)
202  {
205  entries_.push_back(data);
206  if (isPrimary)
207  positionEntry_ = entries_.back();
208 
209  return *this;
210  }
211 
212  template<typename DATATYPE>
213  VTKPointDescriptor& addProperty(std::string name, DATATYPE T::*m, std::size_t nComponents, bool isPrimary = false)
214  {
216  = new Detail::VTKPointDescriptorEntryImpl<T,DATATYPE>(name, m, nComponents);
217  entries_.push_back(data);
218  if (isPrimary)
219  positionEntry_ = entries_.back();
220 
221  return *this;
222  }
223 
224 
225  template<typename VT>
226  friend class VTKUnstructuredGrid;
227 };
228 
229 /* \brief VTKCollection output file writer
230 *
231 * This is templated by the VTKDescriptor DESCR.
232 * \param T the backing output type
233 */
235 {
236  std::ofstream outFile_;
239  std::size_t recordID_;
240 
241  void writeHeader()
242  {
243  outFile_ <<
244  "<?xml version=\"1.0\"?>\n"
245  "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
246  " <Collection>\n";
247  hasHeader_ = true;
248  }
249 
250  void writeFooter()
251  {
252  outFile_ <<
253  " </Collection>\n"
254  "</VTKFile>\n";
255  hasFooter_ = true;
256  }
257 
258  public:
259  VTKCollection(std::string fileName)
260  : outFile_(fileName), hasHeader_(false), hasFooter_(false), recordID_(0)
261  {
262  }
263 
265  {
266  if (hasHeader_ && !hasFooter_)
267  writeFooter();
268  }
269 
270  /* Returns true if the output file is valid and no error bits are set. */
271  operator bool() const
272  {
273  return outFile_.good();
274  }
275 
276  /* Appends the (relative) path to this index file. */
277  void append(std::string filename)
278  {
279  if (!hasHeader_)
280  writeHeader();
281 
282  outFile_ <<
283  "<DataSet group=\"\" part=\"0\" timestep=\"" << recordID_ << "\" file=\"" << filename << "\" />\n";
284 
285  recordID_++;
286  }
287 };
288 
293 template<typename T>
295 {
297  std::ofstream outFile_;
298  public:
303  VTKUnstructuredGrid(std::string filename, const VTKPointDescriptor<T>* descr)
304  : descriptor_(descr), outFile_(filename)
305  {
306  }
307 
309  operator bool() const
310  {
311  return outFile_.good();
312  }
313 
319  template<typename C>
320  void write(const C& container)
321  {
322  outFile_ <<
323  "<?xml version=\"1.0\"?>\n"
324  "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n"
325  " <UnstructuredGrid>\n"
326  " <Piece NumberOfPoints=\"" << container.size() << "\" NumberOfCells=\"0\">\n"
327  " <Cells>\n"
328  " <DataArray type=\"Int32\" name=\"connectivity\" format=\"ascii\">\n"
329  " 0\n"
330  " </DataArray>\n"
331  " <DataArray type=\"Float32\" name=\"offset\" format=\"ascii\">\n"
332  " 0\n"
333  " </DataArray>\n"
334  " <DataArray type=\"UInt8\" name=\"types\" format=\"ascii\">\n"
335  " 1\n"
336  " </DataArray>\n"
337  " </Cells>\n"
338  " <Points>\n";
339  Detail::VTKPointDescriptorEntry<T>* pDescr = descriptor_->positionEntry_;
340  outFile_ << "<DataArray type=\"" << pDescr->getTypeName() << "\" "
341  "NumberOfComponents=\"" << pDescr->getNumberOfComponents() << "\" "
342  "format=\"ascii\">\n";
343  for (const T& mem : container)
344  {
345  pDescr->emit(outFile_, mem);
346  }
347  outFile_ << "\n</DataArray>\n";
348 
349  outFile_ <<
350  " </Points>\n"
351  " <PointData>\n";
352 
353  for (Detail::VTKPointDescriptorEntry<T>* descr : descriptor_->entries_)
354  {
355  outFile_ << "<DataArray type=\"" << descr->getTypeName() << "\" "
356  "Name=\"" << descr->getName() << "\" "
357  "NumberOfComponents=\"" << descr->getNumberOfComponents() << "\" "
358  "format=\"ascii\">\n";
359  for (const T& mem : container)
360  {
361  descr->emit(outFile_, mem);
362  }
363  outFile_ << "\n</DataArray>\n";
364  }
365  outFile_ <<
366  " </PointData>\n"
367  " <CellData/>\n"
368  " </Piece>\n"
369  " </UnstructuredGrid>\n"
370  "</VTKFile>\n";
371  }
372 };
373 
374 #endif
std::string getTypeName() const override
Gives the VTKDataType for VTK.
Definition: VTKData.h:145
const VTKPointDescriptor< T > * descriptor_
Definition: VTKData.h:296
std::size_t getNumberOfComponents() const override
Returns the number of components in this type.
Definition: VTKData.h:155
std::size_t recordID_
Definition: VTKData.h:239
bool hasHeader_
Definition: VTKData.h:237
virtual void emit(std::ostream &out, const T &t) const =0
writes this VTKData to the given output stream for a single T
virtual std::size_t getNumberOfComponents() const =0
Returns the number of components in this type.
void write(const C &container)
Definition: VTKData.h:320
virtual ~VTKPointDescriptorEntry()
Definition: VTKData.h:57
bool hasFooter_
Definition: VTKData.h:238
std::enable_if<!std::is_array< DATATYPE >::value, VTKPointDescriptor & >::type addProperty(std::string name, DATATYPE T::*m, bool isPrimary=false)
Definition: VTKData.h:201
Detail::VTKPointDescriptorEntry< T > * positionEntry_
Definition: VTKData.h:174
void emit(std::ostream &out, const T &t) const override
writes this VTKData to the given output stream for a single T
Definition: VTKData.h:150
std::enable_if< std::is_floating_point< V >::value, std::string >::type toVTKDataType()
Definition: VTKData.h:88
const std::size_t nComponents_
Definition: VTKData.h:139
VTKPointDescriptor & addProperty(std::string name, DATATYPE T::*m, std::size_t nComponents, bool isPrimary=false)
Definition: VTKData.h:213
std::enable_if< std::is_array< V >::value||std::is_pointer< V >::value, void >::type emitProxy(std::ostream &out, const T &t, std::size_t nComponents, V T::*member)
This function actually writes the correct datatype to ostream.
Definition: VTKData.h:117
VTKPointDescriptorEntry(std::string fieldName)
initialises this data member with given name.
Definition: VTKData.h:52
void writeHeader()
Definition: VTKData.h:241
void append(std::string filename)
Definition: VTKData.h:277
~VTKCollection()
Definition: VTKData.h:264
std::string getName() const
Returns the name associated with this field.
Definition: VTKData.h:75
std::vector< Detail::VTKPointDescriptorEntry< T > * > entries_
Definition: VTKData.h:173
void writeFooter()
Definition: VTKData.h:250
VTKUnstructuredGrid(std::string filename, const VTKPointDescriptor< T > *descr)
Definition: VTKData.h:303
std::enable_if< std::is_array< DATATYPE >::value, VTKPointDescriptor & >::type addProperty(std::string name, DATATYPE T::*m, bool isPrimary=false)
Definition: VTKData.h:188
VTKPointDescriptorEntryImpl(std::string name, V T::*member, std::size_t nComponents)
Definition: VTKData.h:141
std::ofstream outFile_
Definition: VTKData.h:236
std::ofstream outFile_
Definition: VTKData.h:297
VTKCollection(std::string fileName)
Definition: VTKData.h:259
virtual std::string getTypeName() const =0
Gives the VTKDataType for VTK.