OGS
VtkImageDataToSurfacePointsFilter.cpp
Go to the documentation of this file.
1 
11 // ** INCLUDES **
13 
14 #include <vtkIdList.h>
15 #include <vtkImageData.h>
16 #include <vtkInformation.h>
17 #include <vtkInformationVector.h>
18 #include <vtkLine.h>
19 #include <vtkObjectFactory.h>
20 #include <vtkPointData.h>
21 #include <vtkPolyData.h>
22 #include <vtkSmartPointer.h>
23 
24 #include <algorithm>
25 #include <vector>
26 
28 
30  default;
31 
32 void VtkImageDataToSurfacePointsFilter::PrintSelf(ostream& os, vtkIndent indent)
33 {
34  this->Superclass::PrintSelf(os, indent);
35 }
36 
38  int /*port*/, vtkInformation* info)
39 {
40  info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
41  return 1;
42 }
43 
45  vtkInformation* /*request*/,
46  vtkInformationVector** inputVector,
47  vtkInformationVector* outputVector)
48 {
49  vtkDebugMacro(<< "Executing VtkImageDataToSurfacePointsFilter");
50 
51  vtkInformation* input_info = inputVector[0]->GetInformationObject(0);
52  vtkInformation* output_info = outputVector->GetInformationObject(0);
53  vtkImageData* input = vtkImageData::SafeDownCast(
54  input_info->Get(vtkDataObject::DATA_OBJECT()));
55  vtkPolyData* output = vtkPolyData::SafeDownCast(
56  output_info->Get(vtkDataObject::DATA_OBJECT()));
57 
58  void* pixvals = input->GetScalarPointer();
59  int n_comp = input->GetNumberOfScalarComponents();
60  if (n_comp < 1)
61  {
62  vtkDebugMacro("Error reading number of components.");
63  }
64  if (n_comp > 2)
65  {
66  vtkDebugMacro(
67  "RGB colours detected. Using only first channel for computation.");
68  }
69 
70  auto const n_points = static_cast<std::size_t>(input->GetNumberOfPoints());
71  if (n_points == 0)
72  {
73  vtkDebugMacro("No data found!");
74  return -1;
75  }
76 
77  double spacing[3];
78  input->GetSpacing(spacing);
79  int dimensions[3];
80  input->GetDimensions(dimensions);
81  double origin[3];
82  input->GetOrigin(origin);
83  MathLib::Point3d const ll(
84  std::array<double, 3>{{origin[0], origin[1], origin[2]}});
85 
86  std::vector<double> pixels;
87  pixels.reserve(n_points);
88  for (std::size_t i = 0; i < n_points; ++i)
89  {
90  if ((n_comp == 2 || n_comp == 4) &&
91  ((static_cast<float*>(pixvals))[(i + 1) * n_comp - 1] <
92  0.00000001f))
93  {
94  pixels.push_back(-9999);
95  }
96  else
97  {
98  pixels.push_back((static_cast<float*>(pixvals))[i * n_comp]);
99  }
100  }
101  GeoLib::Raster const* const raster(new GeoLib::Raster(
102  {static_cast<std::size_t>(dimensions[0]),
103  static_cast<std::size_t>(dimensions[1]), 1, ll, spacing[0], -9999},
104  pixels.begin(),
105  pixels.end()));
106 
107  vtkSmartPointer<vtkPoints> new_points = vtkSmartPointer<vtkPoints>::New();
108  new_points->SetNumberOfPoints(PointsPerPixel * n_points);
109  vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
110  cells->Allocate(PointsPerPixel * n_points);
111 
112  double const half_cellsize(spacing[0] / 2.0);
113  std::size_t pnt_idx(0);
114  for (std::size_t i = 0; i < static_cast<std::size_t>(n_points); ++i)
115  {
116  // Skip transparent pixels
117  if (n_comp == 2 || n_comp == 4)
118  {
119  if ((static_cast<float*>(pixvals))[(i + 1) * n_comp - 1] <
120  0.00000001f)
121  {
122  continue;
123  }
124  }
125 
126  double p[3];
127  input->GetPoint(i, p);
128  MathLib::Point3d min_pnt{std::array<double, 3>{
129  {p[0] - half_cellsize, p[1] - half_cellsize, 0}}};
130  MathLib::Point3d max_pnt{std::array<double, 3>{
131  {p[0] + half_cellsize, p[1] + half_cellsize, 0}}};
133  new_points, cells, pnt_idx, min_pnt, max_pnt, *raster);
134  pnt_idx += PointsPerPixel;
135  }
136 
137  output->SetPoints(new_points);
138  output->SetVerts(cells);
139  output->Squeeze();
140 
141  vtkDebugMacro(<< "Created " << new_points->GetNumberOfPoints()
142  << " points.");
143  return 1;
144 }
145 
147  vtkSmartPointer<vtkPoints>& points,
148  vtkSmartPointer<vtkCellArray>& cells,
149  std::size_t pnt_idx,
150  MathLib::Point3d const& min_pnt,
151  MathLib::Point3d const& max_pnt,
152  GeoLib::Raster const& raster)
153 {
154  auto const n_points(static_cast<std::size_t>(this->GetPointsPerPixel()));
155  for (std::size_t i = 0; i < n_points; ++i)
156  {
157  double p[3];
158  p[0] = getRandomNumber(min_pnt[0], max_pnt[0]);
159  p[1] = getRandomNumber(min_pnt[1], max_pnt[1]);
160  p[2] = raster.interpolateValueAtPoint(
161  MathLib::Point3d(std::array<double, 3>{{p[0], p[1], 0}}));
162  points->SetPoint(pnt_idx + i, p);
163  cells->InsertNextCell(1);
164  cells->InsertCellPoint(pnt_idx + i);
165  }
166 }
167 
169  double const& min, double const& max) const
170 {
171  return (static_cast<double>(std::rand()) / RAND_MAX) * (max - min) + min;
172 }
vtkStandardNewMacro(VtkImageDataToSurfacePointsFilter)
Class Raster is used for managing raster data.
Definition: Raster.h:42
double interpolateValueAtPoint(const MathLib::Point3d &pnt) const
Interpolates the elevation of the given point based on the 8-neighbourhood of the raster cell it is l...
Definition: Raster.cpp:92
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
Updates the graphical object.
void createPointSurface(vtkSmartPointer< vtkPoints > &points, vtkSmartPointer< vtkCellArray > &cells, std::size_t pnt_idx, MathLib::Point3d const &min_pnt, MathLib::Point3d const &max_pnt, GeoLib::Raster const &raster)
Creates the point objects based on the parameters set by the user.
void PrintSelf(ostream &os, vtkIndent indent) override
Prints information about itself.
int FillInputPortInformation(int port, vtkInformation *info) override
Sets input port to vtkImageData.
double getRandomNumber(double const &min, double const &max) const
Returns a random number in [min, max].
static const double p