1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkMultiBlockMergeFilter.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 "vtkMultiBlockMergeFilter.h"
16
17 #include "vtkCellData.h"
18 #include "vtkDataSet.h"
19 #include "vtkMultiBlockDataSet.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkStreamingDemandDrivenPipeline.h"
24
25 vtkStandardNewMacro(vtkMultiBlockMergeFilter);
26 //-----------------------------------------------------------------------------
vtkMultiBlockMergeFilter()27 vtkMultiBlockMergeFilter::vtkMultiBlockMergeFilter()
28 {
29 }
30
31 //-----------------------------------------------------------------------------
~vtkMultiBlockMergeFilter()32 vtkMultiBlockMergeFilter::~vtkMultiBlockMergeFilter()
33 {
34 }
35
36 //-----------------------------------------------------------------------------
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)37 int vtkMultiBlockMergeFilter::RequestData(
38 vtkInformation *vtkNotUsed(request),
39 vtkInformationVector **inputVector,
40 vtkInformationVector *outputVector)
41 {
42 vtkInformation* info = outputVector->GetInformationObject(0);
43 vtkMultiBlockDataSet *output = vtkMultiBlockDataSet::SafeDownCast(
44 info->Get(vtkDataObject::DATA_OBJECT()));
45 if (!output) {return 0;}
46
47 int numInputs = inputVector[0]->GetNumberOfInformationObjects();
48 if (numInputs<0)
49 {
50 vtkErrorMacro("Too many inputs to algorithm.")
51 return 0;
52 }
53 unsigned int usNInputs = static_cast<unsigned int>(numInputs);
54
55 int first = 1;
56 for (int idx = 0; idx < numInputs; ++idx)
57 {
58 vtkMultiBlockDataSet* input = 0;
59 vtkInformation* inInfo = inputVector[0]->GetInformationObject(idx);
60 if (inInfo)
61 {
62 input = vtkMultiBlockDataSet::SafeDownCast(
63 inInfo->Get(vtkDataObject::DATA_OBJECT()));
64 }
65 if (input)
66 {
67 if (first)
68 {
69 //shallow copy first input to output to start off with
70 //cerr << "Copy first input" << endl;
71 output->ShallowCopy(vtkMultiBlockDataSet::SafeDownCast(input));
72 first = 0;
73 }
74 else
75 {
76 if (!this->Merge(usNInputs, idx, output, input))
77 {
78 return 0;
79 }
80 /*
81 //merge in the inputs data sets into the proper places in the output
82 for (unsigned int blk = 0; blk < input->GetNumberOfBlocks(); blk++)
83 {
84 //inputs are allowed to have either 1 or N datasets in each group
85 unsigned int dsId = 0;
86 if (input->GetNumberOfDataSets(blk) == usNInputs)
87 {
88 dsId = idx;
89 }
90 //cerr << "Copying blk " << blk << " index " << idx << endl;
91 vtkDataObject* inblk = input->GetDataSet(blk, dsId);
92 vtkDataObject* dsCopy = inblk->NewInstance();
93 dsCopy->ShallowCopy(inblk);
94 //output will always have N datasets in each group
95 if (output->GetNumberOfDataSets(blk) != usNInputs)
96 {
97 output->SetNumberOfDataSets(blk, numInputs);
98 }
99 output->SetDataSet(blk, idx, dsCopy);
100 dsCopy->Delete();
101 }
102 */
103 }
104 }
105 }
106
107 return !first;
108 }
109
110 //-----------------------------------------------------------------------------
IsMultiPiece(vtkMultiBlockDataSet * mb)111 int vtkMultiBlockMergeFilter::IsMultiPiece(vtkMultiBlockDataSet* mb)
112 {
113 unsigned int numBlocks = mb->GetNumberOfBlocks();
114 for (unsigned int cc=0; cc < numBlocks; cc++)
115 {
116 vtkDataObject* block = mb->GetBlock(cc);
117 if (block && !block->IsA("vtkDataSet"))
118 {
119 return 0;
120 }
121 }
122 return 1;
123 }
124
125 //-----------------------------------------------------------------------------
Merge(unsigned int numPieces,unsigned int pieceNo,vtkMultiBlockDataSet * output,vtkMultiBlockDataSet * input)126 int vtkMultiBlockMergeFilter::Merge(unsigned int numPieces, unsigned int pieceNo,
127 vtkMultiBlockDataSet* output,
128 vtkMultiBlockDataSet* input)
129 {
130 if (!input && !output)
131 {
132 return 1;
133 }
134
135 if (!input || !output)
136 {
137 vtkErrorMacro("Case not handled");
138 return 0;
139 }
140
141 unsigned int numInBlocks = input->GetNumberOfBlocks();
142 unsigned int numOutBlocks = output->GetNumberOfBlocks();
143
144 // Current limitation of this filter is that all blocks must either be
145 // vtkMultiBlockDataSet or vtkDataSet not a mixture of the two.
146 // a vtkMultiBlockDataSet with all child blocks as vtkDataSet is a multipiece
147 // dataset. This filter merges pieces together.
148 int mpInput = this->IsMultiPiece(input);
149 int mpOutput = this->IsMultiPiece(output);
150
151 if (!mpInput && !mpOutput && (numInBlocks == numOutBlocks))
152 {
153 for (unsigned int cc=0; cc < numInBlocks; cc++)
154 {
155 if (!this->Merge(numPieces, pieceNo,
156 vtkMultiBlockDataSet::SafeDownCast(output->GetBlock(cc)),
157 vtkMultiBlockDataSet::SafeDownCast(input->GetBlock(cc))))
158 {
159 return 0;
160 }
161 }
162 return 1;
163 }
164 else if (mpInput && mpOutput)
165 {
166 output->SetNumberOfBlocks(numPieces);
167 unsigned int inIndex = 0;
168 //inputs are allowed to have either 1 or N datasets in each group
169 if (numInBlocks == numPieces)
170 {
171 inIndex = pieceNo;
172 }
173 else if (numInBlocks != 1)
174 {
175 vtkErrorMacro("Case not currently handled.");
176 return 0;
177 }
178 output->SetBlock(pieceNo, vtkDataSet::SafeDownCast(input->GetBlock(inIndex)));
179 return 1;
180 }
181
182 vtkErrorMacro("Case not currently handled.");
183 return 0;
184 }
185
186
187 //-----------------------------------------------------------------------------
AddInputData(vtkDataObject * input)188 void vtkMultiBlockMergeFilter::AddInputData(vtkDataObject* input)
189 {
190 this->AddInputData(0, input);
191 }
192
193 //-----------------------------------------------------------------------------
AddInputData(int index,vtkDataObject * input)194 void vtkMultiBlockMergeFilter::AddInputData(int index, vtkDataObject* input)
195 {
196 this->AddInputDataInternal(index, input);
197 }
198
199 //-----------------------------------------------------------------------------
FillInputPortInformation(int,vtkInformation * info)200 int vtkMultiBlockMergeFilter::FillInputPortInformation(
201 int, vtkInformation *info)
202 {
203 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkMultiBlockDataSet");
204 info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
205 info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
206 return 1;
207 }
208
209 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)210 void vtkMultiBlockMergeFilter::PrintSelf(ostream& os, vtkIndent indent)
211 {
212 this->Superclass::PrintSelf(os,indent);
213 }
214