OGS
VtkImageDataToLinePolyDataFilter.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4// ** INCLUDES **
6
7#include <vtkIdList.h>
8#include <vtkImageData.h>
9#include <vtkInformation.h>
10#include <vtkInformationVector.h>
11#include <vtkLine.h>
12#include <vtkObjectFactory.h>
13#include <vtkPointData.h>
14#include <vtkPolyData.h>
15#include <vtkSmartPointer.h>
16
19
20{
21 this->SetLengthScaleFactor(1.0);
22}
23
25
26void VtkImageDataToLinePolyDataFilter::PrintSelf(ostream& os, vtkIndent indent)
27{
28 this->Superclass::PrintSelf(os, indent);
29 os << indent << "LengthScaleFactor: " << this->LengthScaleFactor << "\n";
30}
31
33 int /*port*/, vtkInformation* info)
34{
35 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
36 return 1;
37}
38
40 vtkInformation* /*request*/,
41 vtkInformationVector** inputVector,
42 vtkInformationVector* outputVector)
43{
44 vtkDebugMacro(<< "Executing VtkImageDataToPolyDataFilter");
45
46 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
47 vtkInformation* outInfo = outputVector->GetInformationObject(0);
48 vtkImageData* input =
49 vtkImageData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
50 vtkPolyData* output =
51 vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
52
53 void* inScalarPtr = input->GetScalarPointer();
54 int numScalarComponents = input->GetNumberOfScalarComponents();
55
56 double spacing[3];
57 input->GetSpacing(spacing);
58 this->ImageSpacing = spacing[0];
59
60 int dimensions[3];
61 input->GetDimensions(dimensions);
62
63 // Skip execution if there are no points
64 vtkIdType numPts = input->GetNumberOfPoints();
65 if (numPts < 1)
66 {
67 vtkDebugMacro("No data to extract lines!");
68 return 1;
69 }
70
71 // Allocate the space needed for the output cells.
72 output->Allocate(numPts);
73
74 // Allocate space for a new set of points
75 vtkSmartPointer<vtkPoints> newPts = vtkSmartPointer<vtkPoints>::New();
76 newPts->SetNumberOfPoints(numPts * 2);
77
78 // Allocate space for the data associated with the new set of points
79 vtkPointData* inPD = input->GetPointData();
80 vtkPointData* outPD = output->GetPointData();
81 outPD->CopyAllocate(inPD, numPts * 16, numPts);
82
83 // Compute scaling factor that max height is 0.1 * longest image dimension
84 double range[2];
85 inPD->GetArray(0)->GetRange(range);
86 double const scalingFactor =
87 (std::max(dimensions[0], dimensions[1]) * spacing[0] * 0.1) /
88 std::max(range[0], range[1]);
89
90 double dir[3] = {0, 0, 1};
91
92 // Traverse all points creating another point with scalar distance in Z
93 // direction
94 for (vtkIdType ptId = 0; ptId < numPts; ++ptId)
95 {
96 // Skip translucent pixels
97 float opacity =
98 (static_cast<float*>(inScalarPtr))[ptId * numScalarComponents + 1];
99 if (opacity < 0.00000001f)
100 {
101 continue;
102 }
103
104 // Compute length of the new line (scalar * LengthScaleFactor)
105 double const length =
106 (static_cast<float*>(inScalarPtr))[ptId * numScalarComponents] *
107 scalingFactor * this->LengthScaleFactor;
108
109 // Skip this line if length is zero
110 if (length < 0.00000001f)
111 {
112 continue;
113 }
114
115 // Get the old point location
116 double p[3];
117 input->GetPoint(ptId, p);
118
119 // Compute the new point location
120 double newPt[3];
121 for (std::size_t i = 0; i < 3; ++i)
122 {
123 newPt[i] = p[i] + dir[i] * length;
124 }
125
126 // Copy the old point
127 newPts->SetPoint(ptId * 2, p);
128 outPD->CopyData(inPD, ptId, ptId * 2);
129
130 // Create the new point
131 newPts->SetPoint(ptId * 2 + 1, newPt);
132 outPD->CopyData(inPD, ptId, ptId * 2 + 1);
133
134 // Create the line
135 vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();
136 line->GetPointIds()->SetId(0, ptId * 2);
137 line->GetPointIds()->SetId(1, ptId * 2 + 1);
138 output->InsertNextCell(line->GetCellType(), line->GetPointIds());
139 }
140
141 // Store the new set of points in the output
142 output->SetPoints(newPts);
143 output->GetPointData()->GetArray(0)->SetName("Colors");
144
145 // Avoid keeping extra memory around
146 output->Squeeze();
147
148 vtkDebugMacro(<< "Created: " << newPts->GetNumberOfPoints() << " points, "
149 << output->GetNumberOfCells() << " lines");
150
151 return 1;
152}
vtkStandardNewMacro(VtkImageDataToLinePolyDataFilter)
Creates lines that stand on top of the image with the length of the corresponding first sub-pixel val...
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
Converts the image data to lines.
void PrintSelf(ostream &os, vtkIndent indent) override
Prints information about itself.
int FillInputPortInformation(int port, vtkInformation *info) override
Sets input port to vtkImageData.
~VtkImageDataToLinePolyDataFilter() override
Destructor.