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