1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageAppendComponents.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 "vtkImageAppendComponents.h"
16
17 #include "vtkAlgorithmOutput.h"
18 #include "vtkDataSetAttributes.h"
19 #include "vtkImageData.h"
20 #include "vtkImageProgressIterator.h"
21 #include "vtkInformation.h"
22 #include "vtkInformationVector.h"
23 #include "vtkObjectFactory.h"
24 #include "vtkStreamingDemandDrivenPipeline.h"
25
26 vtkStandardNewMacro(vtkImageAppendComponents);
27
28 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)29 void vtkImageAppendComponents::PrintSelf(ostream& os, vtkIndent indent)
30 {
31 this->Superclass::PrintSelf(os, indent);
32 }
33
34 //------------------------------------------------------------------------------
ReplaceNthInputConnection(int idx,vtkAlgorithmOutput * input)35 void vtkImageAppendComponents::ReplaceNthInputConnection(int idx, vtkAlgorithmOutput* input)
36 {
37 if (idx < 0 || idx >= this->GetNumberOfInputConnections(0))
38 {
39 vtkErrorMacro("Attempt to replace connection idx "
40 << idx << " of input port " << 0 << ", which has only "
41 << this->GetNumberOfInputConnections(0) << " connections.");
42 return;
43 }
44
45 if (!input || !input->GetProducer())
46 {
47 vtkErrorMacro("Attempt to replace connection index "
48 << idx << " for input port " << 0 << " with "
49 << (!input ? "a null input." : "an input with no producer."));
50 return;
51 }
52
53 this->SetNthInputConnection(0, idx, input);
54 }
55
56 //------------------------------------------------------------------------------
57 // The default vtkImageAlgorithm semantics are that SetInput() puts
58 // each input on a different port, we want all the image inputs to
59 // go on the first port.
SetInputData(int idx,vtkDataObject * input)60 void vtkImageAppendComponents::SetInputData(int idx, vtkDataObject* input)
61 {
62 this->SetInputDataInternal(idx, input);
63 }
64
65 //------------------------------------------------------------------------------
GetInput(int idx)66 vtkDataObject* vtkImageAppendComponents::GetInput(int idx)
67 {
68 if (this->GetNumberOfInputConnections(0) <= idx)
69 {
70 return nullptr;
71 }
72 return vtkImageData::SafeDownCast(this->GetExecutive()->GetInputData(0, idx));
73 }
74
75 //------------------------------------------------------------------------------
76 // This method tells the output it will have more components
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)77 int vtkImageAppendComponents::RequestInformation(vtkInformation* vtkNotUsed(request),
78 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
79 {
80 // get the info objects
81 vtkInformation* outInfo = outputVector->GetInformationObject(0);
82 vtkInformation* inScalarInfo;
83
84 int idx1, num;
85 num = 0;
86 for (idx1 = 0; idx1 < this->GetNumberOfInputConnections(0); ++idx1)
87 {
88 inScalarInfo =
89 vtkDataObject::GetActiveFieldInformation(inputVector[0]->GetInformationObject(idx1),
90 vtkDataObject::FIELD_ASSOCIATION_POINTS, vtkDataSetAttributes::SCALARS);
91 if (inScalarInfo && inScalarInfo->Has(vtkDataObject::FIELD_NUMBER_OF_COMPONENTS()))
92 {
93 num += inScalarInfo->Get(vtkDataObject::FIELD_NUMBER_OF_COMPONENTS());
94 }
95 }
96
97 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, -1, num);
98 return 1;
99 }
100
101 //------------------------------------------------------------------------------
102 // This templated function executes the filter for any type of data.
103 template <class T>
vtkImageAppendComponentsExecute(vtkImageAppendComponents * self,vtkImageData * inData,vtkImageData * outData,int outComp,int outExt[6],int id,T *)104 void vtkImageAppendComponentsExecute(vtkImageAppendComponents* self, vtkImageData* inData,
105 vtkImageData* outData, int outComp, int outExt[6], int id, T*)
106 {
107 vtkImageIterator<T> inIt(inData, outExt);
108 vtkImageProgressIterator<T> outIt(outData, outExt, self, id);
109 int numIn = inData->GetNumberOfScalarComponents();
110 int numSkip = outData->GetNumberOfScalarComponents() - numIn;
111 int i;
112
113 // Loop through output pixels
114 while (!outIt.IsAtEnd())
115 {
116 T* inSI = inIt.BeginSpan();
117 T* outSI = outIt.BeginSpan() + outComp;
118 T* outSIEnd = outIt.EndSpan();
119 while (outSI < outSIEnd)
120 {
121 // now process the components
122 for (i = 0; i < numIn; ++i)
123 {
124 *outSI = *inSI;
125 ++outSI;
126 ++inSI;
127 }
128 outSI = outSI + numSkip;
129 }
130 inIt.NextSpan();
131 outIt.NextSpan();
132 }
133 }
134
135 //------------------------------------------------------------------------------
FillInputPortInformation(int i,vtkInformation * info)136 int vtkImageAppendComponents::FillInputPortInformation(int i, vtkInformation* info)
137 {
138 info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
139 return this->Superclass::FillInputPortInformation(i, info);
140 }
141
142 //------------------------------------------------------------------------------
143 // This method is passed a input and output regions, and executes the filter
144 // algorithm to fill the output from the inputs.
145 // It just executes a switch statement to call the correct function for
146 // the regions data types.
ThreadedRequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * vtkNotUsed (outputVector),vtkImageData *** inData,vtkImageData ** outData,int outExt[6],int id)147 void vtkImageAppendComponents::ThreadedRequestData(vtkInformation* vtkNotUsed(request),
148 vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* vtkNotUsed(outputVector),
149 vtkImageData*** inData, vtkImageData** outData, int outExt[6], int id)
150 {
151 int idx1, outComp;
152
153 outComp = 0;
154 for (idx1 = 0; idx1 < this->GetNumberOfInputConnections(0); ++idx1)
155 {
156 if (inData[0][idx1] != nullptr)
157 {
158 // this filter expects that input is the same type as output.
159 if (inData[0][idx1]->GetScalarType() != outData[0]->GetScalarType())
160 {
161 vtkErrorMacro(<< "Execute: input" << idx1 << " ScalarType ("
162 << inData[0][idx1]->GetScalarType() << "), must match output ScalarType ("
163 << outData[0]->GetScalarType() << ")");
164 return;
165 }
166 switch (inData[0][idx1]->GetScalarType())
167 {
168 vtkTemplateMacro(vtkImageAppendComponentsExecute(
169 this, inData[0][idx1], outData[0], outComp, outExt, id, static_cast<VTK_TT*>(nullptr)));
170 default:
171 vtkErrorMacro(<< "Execute: Unknown ScalarType");
172 return;
173 }
174 outComp += inData[0][idx1]->GetNumberOfScalarComponents();
175 }
176 }
177 }
178