/** * \file * \author Karsten Rink * \date 2011-08-23 * \brief Definition of the VtkMeshConverter class. * * \copyright * Copyright (c) 2012-2022, OpenGeoSys Community (http://www.opengeosys.org) * Distributed under a Modified BSD License. * See accompanying file LICENSE.txt or * http://www.opengeosys.org/project/license * */ #pragma once #include #include #include "BaseLib/Logging.h" #include "GeoLib/Raster.h" #include "MeshLib/Location.h" #include "MeshLib/MeshEnums.h" #include "MeshLib/Properties.h" #include "MeshLib/PropertyVector.h" class vtkUnstructuredGrid; // For conversion vom vtk to ogs mesh class vtkDataArray; // For node/cell properties namespace MeshLib { class Mesh; class Element; class Node; /** * \brief Converter for VtkUnstructured Grids to OGS meshes */ class VtkMeshConverter { public: /// Converts a vtkUnstructuredGrid object to a Mesh static MeshLib::Mesh* convertUnstructuredGrid( vtkUnstructuredGrid* grid, std::string const& mesh_name = "vtkUnstructuredGrid"); private: static void convertScalarArrays(vtkUnstructuredGrid& grid, MeshLib::Mesh& mesh); static std::vector createNodeVector( std::vector const& elevation, std::vector& node_idx_map, GeoLib::RasterHeader const& header, bool use_elevation); /// Creates a mesh element vector based on image data static std::vector createElementVector( std::vector const& pix_val, std::vector const& pix_vis, std::vector const& nodes, std::vector const& node_idx_map, std::size_t const imgHeight, std::size_t const imgWidth, MeshElemType elem_type); /// Creates a scalar array/mesh property based on pixel values template static void fillPropertyVector(MeshLib::PropertyVector& prop_vec, std::vector const& pix_val, std::vector const& pix_vis, const std::size_t& imgHeight, const std::size_t& imgWidth, MeshElemType elem_type) { for (std::size_t i = 0; i < imgHeight; i++) { for (std::size_t j = 0; j < imgWidth; j++) { if (!pix_vis[i * imgWidth + j]) { continue; } T val(static_cast(pix_val[i * (imgWidth + 1) + j])); if (elem_type == MeshElemType::TRIANGLE) { prop_vec.push_back(val); prop_vec.push_back(val); } else if (elem_type == MeshElemType::QUAD) { prop_vec.push_back(val); } } } } static void convertArray(vtkDataArray& array, MeshLib::Properties& properties, MeshLib::MeshItemType type); template static void convertTypedArray(vtkDataArray& array, MeshLib::Properties& properties, MeshLib::MeshItemType type) { // Keep for debugging purposes, since the vtk array type and the end // type T are not always the same. // DBUG( // "Converting a vtk array '{:s}' with data type '{:s}' of " // "size {:d} to a type '{:s}' of size {:d}.", // array.GetName(), array.GetDataTypeAsString(), // array.GetDataTypeSize(), typeid(T).name(), sizeof(T)); if (sizeof(T) != array.GetDataTypeSize()) { OGS_FATAL( "Trying to convert a vtk array '{:s}' with data type '{:s}' of " "size {:d} to a different sized type '{:s}' of size {:d}.", array.GetName(), array.GetDataTypeAsString(), array.GetDataTypeSize(), typeid(T).name(), sizeof(T)); } vtkIdType const nTuples(array.GetNumberOfTuples()); int const nComponents(array.GetNumberOfComponents()); char const* const array_name(array.GetName()); auto* const vec = properties.createNewPropertyVector( array_name, type, nComponents); if (!vec) { WARN("Array {:s} could not be converted to PropertyVector.", array_name); return; } vec->reserve(nTuples * nComponents); auto* data_array = static_cast(array.GetVoidPointer(0)); std::copy(&data_array[0], &data_array[nTuples * nComponents], std::back_inserter(*vec)); return; } }; } // end namespace MeshLib