OGS
MeshLib::RasterToMesh Class Reference

Detailed Description

Converts raster data into an OGS mesh.

Definition at line 31 of file RasterToMesh.h.

#include <RasterToMesh.h>

Static Public Member Functions

static std::unique_ptr< MeshLib::Meshconvert (GeoLib::Raster const &raster, MeshElemType elem_type, UseIntensityAs intensity_type, std::string const &array_name="Colour")
 
static std::unique_ptr< MeshLib::Meshconvert (vtkImageData *img, const double origin[3], const double scalingFactor, MeshElemType elem_type, UseIntensityAs intensity_type, std::string const &array_name="Colour")
 
static std::unique_ptr< MeshLib::Meshconvert (const double *const img, GeoLib::RasterHeader const &header, MeshElemType elem_type, UseIntensityAs intensity_type, std::string const &array_name="Colour")
 

Static Private Member Functions

template<typename T >
static void fillPropertyVector (MeshLib::PropertyVector< T > &prop_vec, double const *const img, GeoLib::RasterHeader const &header, MeshElemType elem_type)
 

Member Function Documentation

◆ convert() [1/3]

std::unique_ptr< MeshLib::Mesh > MeshLib::RasterToMesh::convert ( const double *const  img,
GeoLib::RasterHeader const &  header,
MeshElemType  elem_type,
UseIntensityAs  intensity_type,
std::string const &  array_name = "Colour" 
)
static

Converts double array with raster values into a mesh.

Parameters
imginput image.
headerraster header information.
elem_typedefines if elements of the new mesh should be triangles or quads (or hexes for 3D).
intensity_typedefines how image intensities are interpreted.
array_namemesh property name, defaults to "Colour" if not given.

Definition at line 120 of file RasterToMesh.cpp.

126 {
127  if ((elem_type != MeshElemType::TRIANGLE) &&
128  (elem_type != MeshElemType::QUAD) &&
129  (elem_type != MeshElemType::HEXAHEDRON) &&
130  (elem_type != MeshElemType::PRISM))
131  {
132  ERR("Invalid Mesh Element Type.");
133  return nullptr;
134  }
135 
136  if (((elem_type == MeshElemType::TRIANGLE) ||
137  (elem_type == MeshElemType::QUAD)) &&
138  header.n_depth != 1)
139  {
140  ERR("Triangle or Quad elements cannot be used to construct meshes from "
141  "3D rasters.");
142  return nullptr;
143  }
144 
145  if (intensity_type == UseIntensityAs::ELEVATION &&
146  ((elem_type == MeshElemType::PRISM) ||
147  (elem_type == MeshElemType::HEXAHEDRON)))
148  {
149  ERR("Elevation mapping can only be performed for 2D meshes.");
150  return nullptr;
151  }
152 
153  std::unique_ptr<MeshLib::Mesh> mesh;
154  if (elem_type == MeshElemType::TRIANGLE)
155  {
156  mesh.reset(
158  header.n_rows,
159  header.cell_size,
160  header.origin,
161  "RasterDataMesh"));
162  }
163  else if (elem_type == MeshElemType::QUAD)
164  {
165  mesh.reset(
167  header.n_rows,
168  header.cell_size,
169  header.origin,
170  "RasterDataMesh"));
171  }
172  else if (elem_type == MeshElemType::PRISM)
173  {
174  mesh.reset(
176  header.n_rows,
177  header.n_depth,
178  header.cell_size,
179  header.origin,
180  "RasterDataMesh"));
181  }
182  else if (elem_type == MeshElemType::HEXAHEDRON)
183  {
184  mesh.reset(
186  header.n_rows,
187  header.n_depth,
188  header.cell_size,
189  header.origin,
190  "RasterDataMesh"));
191  }
192 
193  std::unique_ptr<MeshLib::Mesh> new_mesh;
194  std::vector<std::size_t> elements_to_remove;
195  if (intensity_type == UseIntensityAs::ELEVATION)
196  {
197  std::vector<MeshLib::Node*> const& nodes(mesh->getNodes());
198  std::vector<MeshLib::Element*> const& elems(mesh->getElements());
199  std::size_t const n_nodes(elems[0]->getNumberOfNodes());
200  bool const double_idx = (elem_type == MeshElemType::TRIANGLE) ||
201  (elem_type == MeshElemType::PRISM);
202  std::size_t const m = (double_idx) ? 2 : 1;
203  for (std::size_t k = 0; k < header.n_depth; k++)
204  {
205  std::size_t const layer_idx = (k * header.n_rows * header.n_cols);
206  for (std::size_t i = 0; i < header.n_cols; i++)
207  {
208  std::size_t const idx(i * header.n_rows + layer_idx);
209  for (std::size_t j = 0; j < header.n_rows; j++)
210  {
211  double const val(img[idx + j]);
212  if (val == header.no_data)
213  {
214  elements_to_remove.push_back(m * (idx + j));
215  if (double_idx)
216  {
217  elements_to_remove.push_back(m * (idx + j) + 1);
218  }
219  continue;
220  }
221  for (std::size_t n = 0; n < n_nodes; ++n)
222  {
223  (*(nodes[getNodeIndex(*elems[m * (idx + j)], n)]))[2] =
224  val;
225  if (double_idx)
226  {
227  (*(nodes[getNodeIndex(*elems[m * (idx + j) + 1],
228  n)]))[2] = val;
229  }
230  }
231  }
232  }
233  }
234  }
235  else
236  {
237  MeshLib::Properties& properties = mesh->getProperties();
238  MeshLib::ElementSearch ex(*mesh);
239  if (array_name == "MaterialIDs")
240  {
241  auto* const prop_vec = properties.createNewPropertyVector<int>(
242  array_name, MeshLib::MeshItemType::Cell, 1);
243  fillPropertyVector<int>(*prop_vec, img, header, elem_type);
244  ex.searchByPropertyValue<int>(array_name,
245  static_cast<int>(header.no_data));
246  }
247  else
248  {
249  auto* const prop_vec = properties.createNewPropertyVector<double>(
250  array_name, MeshLib::MeshItemType::Cell, 1);
251  fillPropertyVector<double>(*prop_vec, img, header, elem_type);
252  ex.searchByPropertyValue<double>(array_name, header.no_data);
253  }
254  elements_to_remove = ex.getSearchedElementIDs();
255  }
256  if (!elements_to_remove.empty())
257  {
258  new_mesh.reset(MeshLib::removeElements(
259  *mesh, elements_to_remove, mesh->getName()));
260  }
261  else
262  {
263  new_mesh = std::move(mesh);
264  }
265 
266  if (intensity_type == UseIntensityAs::NONE)
267  {
268  new_mesh->getProperties().removePropertyVector(array_name);
269  }
270 
271  return new_mesh;
272 }
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
Element search class.
Definition: ElementSearch.h:28
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition: Properties.h:36
PropertyVector< T > * createNewPropertyVector(std::string const &name, MeshItemType mesh_item_type, std::size_t n_components=1)
Mesh * generateRegularPrismMesh(const double x_length, const double y_length, const double z_length, const std::size_t x_subdivision, const std::size_t y_subdivision, const std::size_t z_subdivision, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
Mesh * generateRegularTriMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
Mesh * generateRegularQuadMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
Mesh * generateRegularHexMesh(const BaseLib::ISubdivision &div_x, const BaseLib::ISubdivision &div_y, const BaseLib::ISubdivision &div_z, MathLib::Point3d const &origin=MathLib::ORIGIN, std::string const &mesh_name="mesh")
MeshLib::Mesh * removeElements(const MeshLib::Mesh &mesh, const std::vector< std::size_t > &removed_element_ids, const std::string &new_mesh_name)
std::size_t getNodeIndex(Element const &element, unsigned const idx)
Definition: Element.cpp:225

References MeshLib::Cell, GeoLib::RasterHeader::cell_size, MeshLib::Properties::createNewPropertyVector(), MeshLib::ELEVATION, ERR(), MeshLib::MeshGenerator::generateRegularHexMesh(), MeshLib::MeshGenerator::generateRegularPrismMesh(), MeshLib::MeshGenerator::generateRegularQuadMesh(), MeshLib::MeshGenerator::generateRegularTriMesh(), MeshLib::getNodeIndex(), MeshLib::ElementSearch::getSearchedElementIDs(), MeshLib::HEXAHEDRON, GeoLib::RasterHeader::n_cols, GeoLib::RasterHeader::n_depth, GeoLib::RasterHeader::n_rows, GeoLib::RasterHeader::no_data, MeshLib::NONE, GeoLib::RasterHeader::origin, MeshLib::PRISM, MeshLib::QUAD, MeshLib::removeElements(), MeshLib::ElementSearch::searchByPropertyValue(), and MeshLib::TRIANGLE.

◆ convert() [2/3]

std::unique_ptr< MeshLib::Mesh > MeshLib::RasterToMesh::convert ( GeoLib::Raster const &  raster,
MeshElemType  elem_type,
UseIntensityAs  intensity_type,
std::string const &  array_name = "Colour" 
)
static

Converts greyscale raster into a mesh.

Parameters
rasterinput raster.
elem_typedefines if elements of the new mesh should be triangles or quads (or hexes for 3D).
intensity_typedefines how image intensities are interpreted.
array_namemesh property name, defaults to "Colour" if not given.

Definition at line 30 of file RasterToMesh.cpp.

35 {
36  return convert(raster.begin(),
37  raster.getHeader(),
38  elem_type,
39  intensity_type,
40  array_name);
41 }
static std::unique_ptr< MeshLib::Mesh > convert(GeoLib::Raster const &raster, MeshElemType elem_type, UseIntensityAs intensity_type, std::string const &array_name="Colour")

References GeoLib::Raster::begin(), and GeoLib::Raster::getHeader().

Referenced by convert(), convert(), NetCdfConfigureDialog::createDataObject(), main(), VtkVisPipelineView::showImageToMeshConversionDialog(), and writeDataToMesh().

◆ convert() [3/3]

std::unique_ptr< MeshLib::Mesh > MeshLib::RasterToMesh::convert ( vtkImageData *  img,
const double  origin[3],
const double  scalingFactor,
MeshElemType  elem_type,
UseIntensityAs  intensity_type,
std::string const &  array_name = "Colour" 
)
static

Converts a vtkImageData into a mesh.

Parameters
imginput image.
origincoordinates of image's origin, lower left corner.
scalingFactoredge length of each pixel
elem_typedefines if elements of the new mesh should be triangles or quads (or hexes for 3D).
intensity_typedefines how image intensities are interpreted.
array_namemesh property name, defaults to "Colour" if not given.

Definition at line 43 of file RasterToMesh.cpp.

50 {
51  if ((elem_type != MeshElemType::TRIANGLE) &&
52  (elem_type != MeshElemType::QUAD) &&
53  (elem_type != MeshElemType::HEXAHEDRON) &&
54  (elem_type != MeshElemType::PRISM))
55  {
56  ERR("Invalid Mesh Element Type.");
57  return nullptr;
58  }
59 
60  int* dims = img->GetDimensions();
61  if (((elem_type == MeshElemType::TRIANGLE) ||
62  (elem_type == MeshElemType::QUAD)) &&
63  dims[2] != 1)
64  {
65  ERR("Triangle or Quad elements cannot be used to construct meshes from "
66  "3D rasters.");
67  return nullptr;
68  }
69 
70  vtkSmartPointer<vtkDataArray> pixelData =
71  vtkSmartPointer<vtkDataArray>(img->GetPointData()->GetScalars());
72  int nTuple = pixelData->GetNumberOfComponents();
73  if (nTuple < 1 || nTuple > 4)
74  {
75  ERR("VtkMeshConverter::convertImgToMesh(): Unsupported pixel "
76  "composition!");
77  return nullptr;
78  }
79 
80  MathLib::Point3d const orig(
81  std::array<double, 3>{{origin[0] - 0.5 * scalingFactor,
82  origin[1] - 0.5 * scalingFactor, origin[2]}});
83  GeoLib::RasterHeader const header = {static_cast<std::size_t>(dims[0]),
84  static_cast<std::size_t>(dims[1]),
85  static_cast<std::size_t>(dims[2]),
86  orig,
87  scalingFactor,
88  -9999};
89 
90  std::vector<double> pix(header.n_cols * header.n_rows * header.n_depth, 0);
91  for (std::size_t k = 0; k < header.n_depth; k++)
92  {
93  std::size_t const layer_idx = (k * header.n_rows * header.n_cols);
94  for (std::size_t i = 0; i < header.n_rows; i++)
95  {
96  std::size_t const idx = i * header.n_cols + layer_idx;
97  for (std::size_t j = 0; j < header.n_cols; j++)
98  {
99  double* colour = pixelData->GetTuple(idx + j);
100  bool const visible = (nTuple == 2 || nTuple == 4)
101  ? (colour[nTuple - 1] != 0)
102  : true;
103  if (!visible)
104  {
105  pix[idx + j] = header.no_data;
106  }
107  else
108  {
109  pix[idx + j] = (nTuple < 3) ? colour[0] : // grey (+ alpha)
110  (0.3 * colour[0] + 0.6 * colour[1] +
111  0.1 * colour[2]); // rgb(a)
112  }
113  }
114  }
115  }
116 
117  return convert(pix.data(), header, elem_type, intensity_type, array_name);
118 }
Contains the relevant information when storing a geoscientific raster data.
Definition: Raster.h:25

References convert(), ERR(), MeshLib::HEXAHEDRON, MeshLib::PRISM, MeshLib::QUAD, and MeshLib::TRIANGLE.

◆ fillPropertyVector()

template<typename T >
static void MeshLib::RasterToMesh::fillPropertyVector ( MeshLib::PropertyVector< T > &  prop_vec,
double const *const  img,
GeoLib::RasterHeader const &  header,
MeshElemType  elem_type 
)
inlinestaticprivate

Definition at line 87 of file RasterToMesh.h.

92  {
93  for (std::size_t k = 0; k < header.n_depth; k++)
94  {
95  std::size_t const layer_idx = (k*header.n_rows*header.n_cols);
96  for (std::size_t i = 0; i < header.n_cols; i++)
97  {
98  std::size_t idx(i * header.n_rows + layer_idx);
99  for (std::size_t j = 0; j < header.n_rows; j++)
100  {
101  auto val(static_cast<T>(img[idx + j]));
102  prop_vec.push_back(val);
103  if (elem_type == MeshElemType::TRIANGLE ||
104  elem_type == MeshElemType::PRISM)
105  {
106  prop_vec.push_back(val); // because each pixel is represented by two cells
107  }
108  }
109  }
110  }
111  }

References GeoLib::RasterHeader::n_cols, GeoLib::RasterHeader::n_depth, GeoLib::RasterHeader::n_rows, MeshLib::PRISM, and MeshLib::TRIANGLE.


The documentation for this class was generated from the following files: