3#include <vtkImageData.h>
4#include <vtkInformation.h>
5#include <vtkInformationVector.h>
6#include <vtkMultiBlockDataSet.h>
7#include <vtkObjectFactory.h>
8#include <vtkPointData.h>
9#include <vtkUnsignedCharArray.h>
19 this->SetNumberOfInputPorts(1);
20 this->SetNumberOfOutputPorts(1);
26 int port, vtkInformation *info) {
28 info->Remove(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE());
30 vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkMultiBlockDataSet");
31 info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkImageData");
32 info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
42 const size_t nPixels) {
43 for(
size_t i = 0; i < nPixels; i++) {
44 mask[i] = depth0[i] > depth1[i] ? 1 : 0;
51 const unsigned char *mask,
54 const size_t nComponents) {
55 for(
size_t i = 0; i < nPixels; i++) {
57 for(
size_t j = i * nComponents, k = j + nComponents; j < k; j++)
58 array0[j] = array1[j];
66 vtkInformationVector **inputVector,
67 vtkInformationVector *outputVector) {
69 const size_t nInputs = inputVector[0]->GetNumberOfInformationObjects();
79 auto firstInput = vtkDataObject::GetData(inputVector[0], 0);
81 if(firstInput->IsA(
"vtkImageData")) {
83 for(
size_t i = 0; i < nInputs; i++) {
85 auto image = vtkImageData::GetData(inputVector[0], i);
87 this->
printErr(
"Input is not a list of vtkImageData objects.");
90 collection->SetBlock(0, image);
91 inputAsMB->SetBlock(i, collection);
93 }
else if(nInputs == 1 && firstInput->IsA(
"vtkMultiBlockDataSet")) {
95 auto temp = vtkMultiBlockDataSet::SafeDownCast(firstInput);
96 auto nBlocks = temp->GetNumberOfBlocks();
99 if(vtkMultiBlockDataSet::SafeDownCast(temp->GetBlock(0))) {
100 inputAsMB->ShallowCopy(firstInput);
103 for(
size_t i = 0; i < nBlocks; i++) {
105 auto image = vtkImageData::SafeDownCast(temp->GetBlock(i));
108 "Input is not a single list of vtkImageData objects.");
111 collection->SetBlock(0, image);
112 inputAsMB->SetBlock(i, collection);
116 }
else if(firstInput->IsA(
"vtkMultiBlockDataSet")) {
118 for(
size_t i = 0; i < nInputs; i++) {
119 auto list = vtkMultiBlockDataSet::GetData(inputVector[0], i);
122 "Inputs are not multiple lists of vtkImageData objects.");
125 inputAsMB->SetBlock(i, list);
128 this->
printErr(
"Unsupported input data structure.");
132 const size_t nImagesPerCompositingStep = inputAsMB->GetNumberOfBlocks();
133 const size_t nCompositingSteps
134 = vtkMultiBlockDataSet::SafeDownCast(inputAsMB->GetBlock(0))
135 ->GetNumberOfBlocks();
138 this->
printMsg(
"Compositing " + std::to_string(nCompositingSteps) +
"x"
139 + std::to_string(nImagesPerCompositingStep) +
" Images",
142 auto getImage = [](vtkMultiBlockDataSet *root,
int i,
int j) {
143 return (vtkImageData *)((vtkMultiBlockDataSet *)root->GetBlock(i))
147 for(
size_t i = 0; i < nCompositingSteps; i++) {
149 auto firstImage = getImage(inputAsMB, 0, i);
152 output->DeepCopy(firstImage);
154 for(
size_t j = 1; j < nImagesPerCompositingStep; j++) {
155 auto image = getImage(inputAsMB, j, i);
157 this->
printErr(
"Unsupported input data structure.");
162 auto depth0Array = this->GetInputArrayToProcess(0, output);
163 auto depth1Array = this->GetInputArrayToProcess(0, image);
164 if(!depth0Array || !depth1Array) {
165 this->
printErr(
"Unable to retrieve depth arrays.");
169 const size_t nPixels = depth0Array->GetNumberOfTuples();
173 mask->SetNumberOfTuples(nPixels);
174 switch(depth0Array->GetDataType()) {
175 vtkTemplateMacro(computeMask<VTK_TT>(
182 auto outputPD = output->GetPointData();
183 auto inputPD = image->GetPointData();
185 for(
int a = 0; a < outputPD->GetNumberOfArrays(); a++) {
186 auto outputArray = outputPD->GetArray(a);
189 auto inputArray = inputPD->GetArray(outputArray->GetName());
193 switch(outputArray->GetDataType()) {
194 vtkTemplateMacro(compositeArray<VTK_TT>(
198 nPixels, outputArray->GetNumberOfComponents()));
203 outputAsMB->SetBlock(i, output);
206 this->
printMsg(
"Compositing " + std::to_string(nCompositingSteps) +
"x"
207 + std::to_string(nImagesPerCompositingStep) +
" Images",
212 this->
printMsg(
"Compositing " + std::to_string(nCompositingSteps) +
"x"
213 + std::to_string(nImagesPerCompositingStep) +
" Images",
216 auto output = vtkDataObject::GetData(outputVector);
217 if(firstInput->IsA(
"vtkImageData")) {
218 output->ShallowCopy(outputAsMB->GetBlock(0));
220 output->ShallowCopy(outputAsMB);
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Composites multiple vtkImageData objects base on depth values.
ttkCinemaDarkroomCompositing()
~ttkCinemaDarkroomCompositing() override
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
int printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void setDebugMsgPrefix(const std::string &prefix)
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
vtkStandardNewMacro(ttkCinemaDarkroomCompositing)
int computeMask(unsigned char *mask, const DT *depth0, const DT *depth1, const size_t nPixels)
int compositeArray(DT *array0, const unsigned char *mask, const DT *array1, const size_t nPixels, const size_t nComponents)