1 /*=========================================================================
2 
3   Program:   ParaView
4   Module:    vtkXMLCompositeDataReader.h
5 
6   Copyright (c) Kitware, Inc.
7   All rights reserved.
8   See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 /**
16  * @class   vtkXMLCompositeDataReader
17  * @brief   Reader for multi-group datasets
18  *
19  * vtkXMLCompositeDataReader reads the VTK XML multi-group data file
20  * format. XML multi-group data files are meta-files that point to a list
21  * of serial VTK XML files. When reading in parallel, it will distribute
22  * sub-blocks among processor. If the number of sub-blocks is less than
23  * the number of processors, some processors will not have any sub-blocks
24  * for that group. If the number of sub-blocks is larger than the
25  * number of processors, each processor will possibly have more than
26  * 1 sub-block.
27 */
28 
29 #ifndef vtkXMLCompositeDataReader_h
30 #define vtkXMLCompositeDataReader_h
31 
32 #include "vtkIOXMLModule.h" // For export macro
33 #include "vtkXMLReader.h"
34 
35 class vtkCompositeDataSet;
36 class vtkInformationIntegerKey;
37 class vtkInformationIntegerVectorKey;
38 
39 struct vtkXMLCompositeDataReaderInternals;
40 
41 class VTKIOXML_EXPORT vtkXMLCompositeDataReader : public vtkXMLReader
42 {
43 public:
44   vtkTypeMacro(vtkXMLCompositeDataReader,vtkXMLReader);
45   void PrintSelf(ostream& os, vtkIndent indent) override;
46 
47   enum
48   {
49     Block,
50     Interleave
51   };
52 
53   /**
54    * Set the strategy for assigning files to parallel readers. The default is
55    * @a Block.
56    *
57    * Let @a X be the rank of a specific reader, and @a N be the number of
58    * reader, then:
59    * @arg @c Block Each processor is assigned a contiguous block of files,
60    *      [@a X * @a N, ( @a X + 1) * @a N ).
61    * @arg @c Interleave The files are interleaved across readers,
62    * @a i * @a N + @a X.
63    * @{
64    */
65   vtkSetClampMacro(PieceDistribution, int, Block, Interleave)
66   vtkGetMacro(PieceDistribution, int)
67   /**@}*/
68 
69   //@{
70   /**
71    * Get the output data object for a port on this algorithm.
72    */
73   vtkCompositeDataSet* GetOutput();
74   vtkCompositeDataSet* GetOutput(int);
75   //@}
76 
77 protected:
78   vtkXMLCompositeDataReader();
79   ~vtkXMLCompositeDataReader() override;
80 
81   // Get the name of the data set being read.
82   const char* GetDataSetName() override;
83 
84   // Returns the primary element pass to ReadPrimaryElement().
85   vtkXMLDataElement* GetPrimaryElement();
86 
87   void ReadXMLData() override;
88   int ReadPrimaryElement(vtkXMLDataElement* ePrimary) override;
89 
90   // Setup the output with no data available.  Used in error cases.
91   void SetupEmptyOutput() override;
92 
93   int FillOutputPortInformation(int, vtkInformation* info) override;
94 
95   // Create a default executive.
96   vtkExecutive* CreateDefaultExecutive() override;
97 
98   // Find the path to this file in case the internal files are
99   // specified as relative paths.
100   std::string GetFilePath();
101 
102   std::string GetFileNameFromXML(vtkXMLDataElement *xmlElem,
103                                  const std::string &filePath);
104 
105   vtkXMLReader* GetReaderOfType(const char* type);
106   vtkXMLReader* GetReaderForFile(const std::string &filename);
107 
108   int RequestInformation(vtkInformation*,
109                                  vtkInformationVector**,
110                                  vtkInformationVector*) override;
111 
112   void SyncDataArraySelections(vtkXMLReader *accum,
113                                vtkXMLDataElement *xmlElem,
114                                const std::string &filePath);
115 
116   // Adds a child data object to the composite parent. childXML is the XML for
117   // the child data object need to obtain certain meta-data about the child.
118   void AddChild(vtkCompositeDataSet* parent,
119     vtkDataObject* child, vtkXMLDataElement* childXML);
120 
121   // Read the XML element for the subtree of a the composite dataset.
122   // dataSetIndex is used to rank the leaf nodes in an inorder traversal.
123   virtual void ReadComposite(vtkXMLDataElement* element,
124     vtkCompositeDataSet* composite, const char* filePath,
125     unsigned int &dataSetIndex)=0;
126 
127   // Read the vtkDataSet (a leaf) in the composite dataset.
128   virtual vtkDataSet* ReadDataset(vtkXMLDataElement* xmlElem, const char* filePath);
129 
130   // Read the vtkDataObject (a leaf) in the composite dataset.
131   virtual vtkDataObject* ReadDataObject(vtkXMLDataElement* xmlElem, const char* filePath);
132 
133   // Counts "DataSet" elements in the subtree.
134   unsigned int CountLeaves(vtkXMLDataElement* elem);
135 
136   /**
137    * Given the inorder index for a leaf node, this method tells if the current
138    * process should read the dataset.
139    */
140   int ShouldReadDataSet(unsigned int datasetIndex);
141 
142   bool DataSetIsValidForBlockStrategy(unsigned int datasetIndex);
143   bool DataSetIsValidForInterleaveStrategy(unsigned int datasetIndex);
144 
145 private:
146   vtkXMLCompositeDataReader(const vtkXMLCompositeDataReader&) = delete;
147   void operator=(const vtkXMLCompositeDataReader&) = delete;
148 
149   int PieceDistribution;
150 
151   vtkXMLCompositeDataReaderInternals* Internal;
152 };
153 
154 #endif
155