From 32549bd6afabbfa210327652e3499fc8fa6bea17 Mon Sep 17 00:00:00 2001
From: rinkk <karsten.rink@ufz.de>
Date: Fri, 29 Jan 2016 12:21:57 +0100
Subject: [PATCH] restructured img to mesh conversion, added distinction
 between materials and double vectors

---
 .../DataExplorer/VtkVis/MeshFromRaster.ui     | 125 ++++---
 .../VtkVis/MeshFromRasterDialog.cpp           |   3 +-
 .../DataExplorer/VtkVis/VtkRaster.cpp         |   2 +-
 MeshLib/MeshEnums.h                           |   1 +
 MeshLib/MeshGenerators/VtkMeshConverter.cpp   | 305 +++++++++---------
 MeshLib/MeshGenerators/VtkMeshConverter.h     |  68 +++-
 6 files changed, 292 insertions(+), 212 deletions(-)

diff --git a/Applications/DataExplorer/VtkVis/MeshFromRaster.ui b/Applications/DataExplorer/VtkVis/MeshFromRaster.ui
index 32c88e9b8e6..61a16073870 100644
--- a/Applications/DataExplorer/VtkVis/MeshFromRaster.ui
+++ b/Applications/DataExplorer/VtkVis/MeshFromRaster.ui
@@ -6,10 +6,22 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>350</width>
-    <height>220</height>
+    <width>450</width>
+    <height>270</height>
    </rect>
   </property>
+  <property name="minimumSize">
+   <size>
+    <width>450</width>
+    <height>270</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>450</width>
+    <height>270</height>
+   </size>
+  </property>
   <property name="windowTitle">
    <string>Create mesh from raster...</string>
   </property>
@@ -29,37 +41,76 @@
      <property name="title">
       <string>Interpret intensities as</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <property name="verticalSpacing">
+       <number>10</number>
+      </property>
+      <item row="4" column="0" colspan="2">
+       <widget class="QRadioButton" name="ignoreButton">
+        <property name="text">
+         <string>Ignore</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0" colspan="2">
+       <widget class="QRadioButton" name="otherButton">
+        <property name="text">
+         <string>Other</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QLineEdit" name="arrayNameEdit"/>
+      </item>
+      <item row="0" column="0" colspan="2">
        <widget class="QRadioButton" name="elevationButton">
         <property name="text">
          <string>Elevation</string>
         </property>
        </widget>
       </item>
-      <item>
-       <widget class="QRadioButton" name="materialButton">
+      <item row="3" column="0">
+       <widget class="QLabel" name="arrayNameLabel">
         <property name="text">
-         <string>Materials</string>
+         <string>Name:</string>
         </property>
        </widget>
       </item>
-      <item>
-       <widget class="QRadioButton" name="ignoreButton">
+      <item row="1" column="0" colspan="2">
+       <widget class="QRadioButton" name="materialButton">
         <property name="text">
-         <string>Ignore</string>
+         <string>Materials</string>
         </property>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="mshNameLabel">
+     <property name="layoutDirection">
+      <enum>Qt::LeftToRight</enum>
+     </property>
+     <property name="text">
+      <string>    Name of mesh:</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="mshNameEdit"/>
+   </item>
    <item row="0" column="1">
     <widget class="QGroupBox" name="elementTypeGroupBox">
      <property name="title">
       <string>Represent pixels as</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_2">
+      <property name="spacing">
+       <number>10</number>
+      </property>
       <item>
        <widget class="QRadioButton" name="triButton">
         <property name="text">
@@ -84,40 +135,36 @@
         </property>
        </widget>
       </item>
+      <item>
+       <spacer name="verticalSpacer">
+        <property name="orientation">
+         <enum>Qt::Vertical</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>20</width>
+          <height>40</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
      </layout>
     </widget>
    </item>
-   <item row="2" column="0">
-    <spacer name="horizontalSpacer">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>40</width>
-       <height>20</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
-   <item row="1" column="0">
-    <widget class="QLabel" name="mshNameLabel">
-     <property name="layoutDirection">
-      <enum>Qt::LeftToRight</enum>
-     </property>
-     <property name="text">
-      <string>    Name of mesh:</string>
-     </property>
-     <property name="alignment">
-      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="1">
-    <widget class="QLineEdit" name="mshNameEdit"/>
-   </item>
   </layout>
  </widget>
+ <tabstops>
+  <tabstop>elevationButton</tabstop>
+  <tabstop>materialButton</tabstop>
+  <tabstop>otherButton</tabstop>
+  <tabstop>arrayNameEdit</tabstop>
+  <tabstop>ignoreButton</tabstop>
+  <tabstop>triButton</tabstop>
+  <tabstop>quadButton</tabstop>
+  <tabstop>hexButton</tabstop>
+  <tabstop>mshNameEdit</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
  <resources/>
  <connections>
   <connection>
diff --git a/Applications/DataExplorer/VtkVis/MeshFromRasterDialog.cpp b/Applications/DataExplorer/VtkVis/MeshFromRasterDialog.cpp
index 79dc999b45b..fd0cada94d1 100644
--- a/Applications/DataExplorer/VtkVis/MeshFromRasterDialog.cpp
+++ b/Applications/DataExplorer/VtkVis/MeshFromRasterDialog.cpp
@@ -43,7 +43,8 @@ void MeshFromRasterDialog::accept()
 	_new_mesh_name = this->mshNameEdit->text().toStdString();
 
 	_intensity_selection = MeshLib::UseIntensityAs::ELEVATION;
-	if (this->materialButton->isChecked()) _intensity_selection  = MeshLib::UseIntensityAs::DATAVECTOR;
+	if (this->materialButton->isChecked()) _intensity_selection  = MeshLib::UseIntensityAs::MATERIALS;
+	else if (this->otherButton->isChecked()) _intensity_selection  = MeshLib::UseIntensityAs::DATAVECTOR;
 	else if (this->ignoreButton->isChecked()) _intensity_selection  = MeshLib::UseIntensityAs::NONE;
 
 	_element_selection = MeshLib::MeshElemType::TRIANGLE;
diff --git a/Applications/DataExplorer/VtkVis/VtkRaster.cpp b/Applications/DataExplorer/VtkVis/VtkRaster.cpp
index f8d64c9c9ce..dea54ab1f38 100644
--- a/Applications/DataExplorer/VtkVis/VtkRaster.cpp
+++ b/Applications/DataExplorer/VtkVis/VtkRaster.cpp
@@ -97,7 +97,7 @@ vtkImageImport* VtkRaster::loadImageFromArray(double const*const data_array, dou
 		image->SetDataSpacing(delta, delta, delta);
 		image->SetDataOrigin(x0+(delta/2.0), y0+(delta/2.0), 0);	// translate whole mesh by half a pixel in x and y
 		image->SetWholeExtent(0, width-1, 0, height-1, 0, 0);
-		image->SetDataExtent(0, width-1, 0, height-1-1, 0, 0);
+		image->SetDataExtent(0, width-1, 0, height-1, 0, 0);
 		image->SetDataExtentToWholeExtent();
 		image->SetDataScalarTypeToFloat();
 		image->SetNumberOfScalarComponents(2);
diff --git a/MeshLib/MeshEnums.h b/MeshLib/MeshEnums.h
index c98f072dc99..3ba1e3c2fd3 100644
--- a/MeshLib/MeshEnums.h
+++ b/MeshLib/MeshEnums.h
@@ -82,6 +82,7 @@ enum class MeshQualityType
 enum class UseIntensityAs
 {
 	ELEVATION,
+	MATERIALS,
 	DATAVECTOR,
 	NONE
 };
diff --git a/MeshLib/MeshGenerators/VtkMeshConverter.cpp b/MeshLib/MeshGenerators/VtkMeshConverter.cpp
index cd59ae9145d..18e876aba01 100644
--- a/MeshLib/MeshGenerators/VtkMeshConverter.cpp
+++ b/MeshLib/MeshGenerators/VtkMeshConverter.cpp
@@ -75,203 +75,186 @@ MeshLib::Mesh* VtkMeshConverter::convertImgToMesh(vtkImageData* img,
 	const std::size_t imgWidth  = dims[1];
 	const std::size_t incHeight = imgHeight+1;
 	const std::size_t incWidth  = imgWidth+1;
-	double* pixVal (new double[incHeight * incWidth]);
-	bool* visNodes(new bool[incWidth * incHeight]);
-	int* node_idx_map(new int[incWidth * incHeight]);
+	std::vector<double> pix_val (incHeight * incWidth, std::numeric_limits<double>::max());
+	std::vector<bool> pix_vis (imgHeight * imgWidth, false);
 
-	for (std::size_t j = 0; j < incHeight; j++)
-	{
-		pixVal[j]=0;
-		visNodes[j]=false;
-		node_idx_map[j]=-1;
-	}
 	for (std::size_t i = 0; i < imgWidth; i++)
 	{
 		for (std::size_t j = 0; j < imgHeight; j++)
 		{
-			const std::size_t img_idx = i * imgHeight + j;
-			const std::size_t index = (i+1) * incHeight + j;
+			std::size_t const img_idx = i*imgHeight + j;
+			std::size_t const fld_idx = i*incHeight + j;
+
+			// colour of current pixel
 			double* colour = pixelData->GetTuple(img_idx);
-			if (nTuple < 3)	// Grey (+ Alpha)
-				pixVal[index] = colour[0];
-			else			// RGB(A)
-				pixVal[index] = 0.3 * colour[0] + 0.6 * colour[1] + 0.1 * colour[2];
-
-			// is current pixel visible
-			if (nTuple == 2 || nTuple == 4)
-				visNodes[index] = (colour[nTuple-1] != 0);
-			else
-				visNodes[index] = true;
-
-			node_idx_map[index]=-1;
+			// is current pixel visible?
+			bool const visible = (nTuple == 2 || nTuple == 4) ? (colour[nTuple-1] != 0) : true;
+			if (!visible)
+				continue;
+
+			double const value = (nTuple < 3) ? 
+				colour[0] : // grey (+ alpha)
+				(0.3 * colour[0] + 0.6 * colour[1] + 0.1 * colour[2]); // rgb(a)
+			pix_vis[img_idx] = true;
+			pix_val[fld_idx] = value;
+			pix_val[fld_idx+1] = value;
+			pix_val[fld_idx+incHeight] = value;
+			pix_val[fld_idx+incHeight+1] = value;
 		}
-		pixVal[(i+2)*incHeight-1]=0;
-		visNodes[(i+2)*incHeight-1]=false;
-		node_idx_map[(i+2)*incHeight-1]=-1;
 	}
-
-	MeshLib::Mesh* mesh = constructMesh(pixVal, node_idx_map, visNodes, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type);
-
-	delete [] pixVal;
-	delete [] visNodes;
-	delete [] node_idx_map;
-
-	return mesh;
+	
+	return constructMesh(pix_val, pix_vis, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type);
 }
 
-MeshLib::Mesh* VtkMeshConverter::convertImgToMesh(const double* img,
-                                                  const double origin[3],
-                                                  const std::size_t imgHeight,
-                                                  const std::size_t imgWidth,
-                                                  const double &scalingFactor,
-                                                  MeshElemType elem_type,
-                                                  UseIntensityAs intensity_type)
+MeshLib::Mesh* VtkMeshConverter::convertImgToMesh(
+	const double* img,
+	const double origin[3],
+	const std::size_t imgHeight,
+	const std::size_t imgWidth,
+	const double &scalingFactor,
+	MeshElemType elem_type,
+	UseIntensityAs intensity_type)
 {
-	const std::size_t incHeight = imgHeight+1;
-	const std::size_t incWidth  = imgWidth+1;
-	double* pixVal (new double[incHeight * incWidth]);
-	bool* visNodes(new bool[incWidth * incHeight]);
-	int* node_idx_map(new int[incWidth * incHeight]);
-
-	double noDataValue = getExistingValue(img, imgWidth*imgHeight);
-
-	for (std::size_t j = 0; j < imgHeight; j++)
+	if ((elem_type != MeshElemType::TRIANGLE) && (elem_type != MeshElemType::QUAD))
 	{
-		pixVal[j]=0;
-		visNodes[j]=false;
-		node_idx_map[j]=-1;
+		ERR("Invalid Mesh Element Type.");
+		return nullptr;
 	}
+
+	std::size_t const incHeight (imgHeight+1);
+	std::size_t const incWidth (imgWidth+1);
+	std::vector<double> pix_val (incHeight * incWidth, std::numeric_limits<double>::max());
+	std::vector<bool> pix_vis (incHeight * incWidth, false);
+
 	for (std::size_t i = 0; i < imgWidth; i++)
-	{
 		for (std::size_t j = 0; j < imgHeight; j++)
 		{
-			const std::size_t img_idx = i * imgHeight + j;
-			const std::size_t index = (i+1) * incHeight + j;
+			std::size_t const img_idx = i*imgHeight + j;
+			std::size_t const fld_idx = i*incHeight + j;
 			if (img[img_idx] == -9999)
-			{
-				visNodes[index] = false;
-				pixVal[index] = noDataValue;
-			}
-			else
-			{
-				pixVal[index] = img[img_idx];
-				visNodes[index] = true;
-			}
+				continue;
 
-			node_idx_map[index]=-1;
+			pix_vis[img_idx] = true;
+			pix_val[fld_idx] = img[img_idx];
+			pix_val[fld_idx+1] = img[img_idx];
+			pix_val[fld_idx+incHeight] = img[img_idx];
+			pix_val[fld_idx+incHeight+1] = img[img_idx];
 		}
-		pixVal[(i+2)*incHeight-1]=0;
-		visNodes[(i+2)*incHeight-1]=false;
-		node_idx_map[(i+2)*incHeight-1]=-1;
-	}
 
-	MeshLib::Mesh* mesh = constructMesh(pixVal, node_idx_map, visNodes, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type);
+	return constructMesh(pix_val, pix_vis, origin, imgHeight, imgWidth, scalingFactor, elem_type, intensity_type);
+}
 
-	delete [] pixVal;
-	delete [] visNodes;
-	delete [] node_idx_map;
+MeshLib::Mesh* VtkMeshConverter::constructMesh(
+	std::vector<double> const& pix_val,
+	std::vector<bool> const& pix_vis,
+	double const origin[3],
+	std::size_t const imgHeight,
+	std::size_t const imgWidth,
+	double const scalingFactor,
+	MeshLib::MeshElemType elem_type,
+	MeshLib::UseIntensityAs intensity_type)
+{
+	std::vector<int> node_idx_map ((imgHeight+1) * (imgWidth+1), -1);
+	bool const use_elevation (intensity_type == MeshLib::UseIntensityAs::ELEVATION);
+	std::vector<MeshLib::Node*> nodes (createNodeVector(pix_val, node_idx_map, imgHeight, imgWidth, origin, scalingFactor, use_elevation));
+	if (nodes.empty())
+		return nullptr;
 
-	return mesh;
+	std::vector<MeshLib::Element*> elements (createElementVector(pix_val, pix_vis, nodes, node_idx_map, imgHeight, imgWidth, elem_type));
+	if (elements.empty())
+		return nullptr;
+
+	MeshLib::Properties properties;
+	if (intensity_type == MeshLib::UseIntensityAs::MATERIALS)
+	{
+		boost::optional< MeshLib::PropertyVector<int>& > prop_vec =
+			properties.createNewPropertyVector<int>("MaterialIDs", MeshLib::MeshItemType::Cell, 1);
+		fillPropertyVector<int>(*prop_vec, pix_val, pix_vis, imgHeight, imgWidth, elem_type); 
+	}	
+	else if (intensity_type == MeshLib::UseIntensityAs::DATAVECTOR)
+	{
+		boost::optional< MeshLib::PropertyVector<double>& > prop_vec =
+			properties.createNewPropertyVector<double>("Colour", MeshLib::MeshItemType::Cell, 1);
+		fillPropertyVector<double>(*prop_vec, pix_val, pix_vis, imgHeight, imgWidth, elem_type); 
+	}
+
+	return new MeshLib::Mesh("RasterDataMesh", nodes, elements, properties);
 }
 
-MeshLib::Mesh* VtkMeshConverter::constructMesh(const double* pixVal,
-                                               int* node_idx_map,
-                                               const bool* visNodes,
-                                               const double origin[3],
-                                               const std::size_t &imgHeight,
-                                               const std::size_t &imgWidth,
-                                               const double &scalingFactor,
-                                               MeshElemType elem_type,
-                                               UseIntensityAs intensity_type)
+std::vector<MeshLib::Node*> VtkMeshConverter::createNodeVector(
+	std::vector<double> const&  elevation,
+	std::vector<int> & node_idx_map,
+	std::size_t const imgHeight,
+	std::size_t const imgWidth,
+	double const origin[3],
+	double const scalingFactor,
+	bool use_elevation)
 {
-	const std::size_t incHeight = imgHeight+1;
-	const std::size_t incWidth  = imgWidth+1;
 	std::size_t node_idx_count(0);
-	const double x_offset(origin[0] - scalingFactor/2.0);
-	const double y_offset(origin[1] - scalingFactor/2.0);
-
+	double const x_offset(origin[0] - scalingFactor/2.0);
+	double const y_offset(origin[1] - scalingFactor/2.0);
 	std::vector<MeshLib::Node*> nodes;
-	std::vector<MeshLib::Element*> elements;
-
-	for (std::size_t i = 0; i < incWidth; i++)
-		for (std::size_t j = 0; j < incHeight; j++)
+	for (std::size_t i = 0; i < (imgWidth+1); i++)
+		for (std::size_t j = 0; j < (imgHeight+1); j++)
 		{
-			const std::size_t index = i * incHeight + j;
-
-			bool set_node (false);
-			if (j==0 && i==imgWidth) set_node = visNodes[index];
-			else if (j==0)			 set_node = (visNodes[index] || visNodes[index+incHeight]);
-			else if (i==imgWidth)	 set_node = (visNodes[index] || visNodes[index-1]);
-			else					 set_node = (visNodes[index] || visNodes[index-1] || visNodes[index+incHeight] || visNodes[index+incHeight-1]);
-
-			if (set_node)
-			{
-				double zValue = (intensity_type == UseIntensityAs::ELEVATION) ? pixVal[index] : 0;
-				MeshLib::Node* node (new MeshLib::Node(x_offset + (scalingFactor * j), y_offset + (scalingFactor * i), zValue));
-				nodes.push_back(node);
-				node_idx_map[index] = node_idx_count;
-				node_idx_count++;
-			}
+			std::size_t const index = i * (imgHeight+1) + j;
+			if (elevation[index] == std::numeric_limits<double>::max())
+				continue;
+
+			double const zValue = (use_elevation) ? elevation[index] : 0;
+			MeshLib::Node* node (new MeshLib::Node(x_offset + (scalingFactor * j), y_offset + (scalingFactor * i), zValue));
+			nodes.push_back(node);
+			node_idx_map[index] = node_idx_count;
+			node_idx_count++;
 		}
+	return nodes;
+}
 
-	MeshLib::Properties properties;
-	boost::optional< MeshLib::PropertyVector<double>& > value_vec =
-		properties.createNewPropertyVector<double>("Colour", MeshLib::MeshItemType::Cell, 1);
-
-	// set mesh elements
+std::vector<MeshLib::Element*> VtkMeshConverter::createElementVector(
+	std::vector<double> const&  pix_val,
+	std::vector<bool> const& pix_vis,
+	std::vector<MeshLib::Node*> const& nodes,
+	std::vector<int> const&node_idx_map,
+	std::size_t const imgHeight,
+	std::size_t const imgWidth,
+	MeshElemType elem_type)
+{
+	std::vector<MeshLib::Element*> elements;
+	std::size_t const incHeight (imgHeight+1);
+	std::size_t const incWidth (imgWidth+1);
 	for (std::size_t i = 0; i < imgWidth; i++)
 		for (std::size_t j = 0; j < imgHeight; j++)
 		{
-			int const index = i * incHeight + j;
-			if ((node_idx_map[index]!=-1) && (node_idx_map[index+1]!=-1) && (node_idx_map[index+incHeight]!=-1) && (node_idx_map[index+incHeight+1]!=-1) && (visNodes[index+incHeight]))
+			if (!pix_vis[i*imgHeight+j])
+				continue;
+
+			int const idx = i * incHeight + j;
+			if (elem_type == MeshElemType::TRIANGLE)
+			{
+				MeshLib::Node** tri1_nodes = new MeshLib::Node*[3];
+				tri1_nodes[0] = nodes[node_idx_map[idx]];
+				tri1_nodes[1] = nodes[node_idx_map[idx+1]];
+				tri1_nodes[2] = nodes[node_idx_map[idx+incHeight]];
+
+				MeshLib::Node** tri2_nodes = new MeshLib::Node*[3];
+				tri2_nodes[0] = nodes[node_idx_map[idx+1]];
+				tri2_nodes[1] = nodes[node_idx_map[idx+incHeight+1]];
+				tri2_nodes[2] = nodes[node_idx_map[idx+incHeight]];
+
+				elements.push_back(new MeshLib::Tri(tri1_nodes)); // upper left triangle
+				elements.push_back(new MeshLib::Tri(tri2_nodes)); // lower right triangle
+			}
+			else if (elem_type == MeshElemType::QUAD)
 			{
-				if (elem_type == MeshElemType::TRIANGLE)
-				{
-					MeshLib::Node** tri1_nodes = new MeshLib::Node*[3];
-					tri1_nodes[0] = nodes[node_idx_map[index]];
-					tri1_nodes[1] = nodes[node_idx_map[index+1]];
-					tri1_nodes[2] = nodes[node_idx_map[index+incHeight]];
-
-					MeshLib::Node** tri2_nodes = new MeshLib::Node*[3];
-					tri2_nodes[0] = nodes[node_idx_map[index+1]];
-					tri2_nodes[1] = nodes[node_idx_map[index+incHeight+1]];
-					tri2_nodes[2] = nodes[node_idx_map[index+incHeight]];
-
-					elements.push_back(new MeshLib::Tri(tri1_nodes)); // upper left triangle
-					elements.push_back(new MeshLib::Tri(tri2_nodes)); // lower right triangle
-					if (intensity_type == UseIntensityAs::DATAVECTOR)
-					{
-						value_vec->push_back(pixVal[index+incHeight]);
-						value_vec->push_back(pixVal[index+incHeight]);
-					}
-				}
-				if (elem_type == MeshElemType::QUAD)
-				{
-					MeshLib::Node** quad_nodes = new MeshLib::Node*[4];
-					quad_nodes[0] = nodes[node_idx_map[index]];
-					quad_nodes[1] = nodes[node_idx_map[index + 1]];
-					quad_nodes[2] = nodes[node_idx_map[index + incHeight + 1]];
-					quad_nodes[3] = nodes[node_idx_map[index + incHeight]];
-					elements.push_back(new MeshLib::Quad(quad_nodes));
-					if (intensity_type == UseIntensityAs::DATAVECTOR)
-						value_vec->push_back(pixVal[index+incHeight]);
-				}
+				MeshLib::Node** quad_nodes = new MeshLib::Node*[4];
+				quad_nodes[0] = nodes[node_idx_map[idx]];
+				quad_nodes[1] = nodes[node_idx_map[idx + 1]];
+				quad_nodes[2] = nodes[node_idx_map[idx + incHeight + 1]];
+				quad_nodes[3] = nodes[node_idx_map[idx + incHeight]];
+				elements.push_back(new MeshLib::Quad(quad_nodes));
 			}
 		}
-
-	if (elements.empty())
-		return nullptr;
-
-	if (value_vec->empty())
-		properties.removePropertyVector("Colour");
-
-	boost::optional< MeshLib::PropertyVector<int>& > materials =
-		properties.createNewPropertyVector<int>("MaterialIDs", MeshLib::MeshItemType::Cell, 1);
-	assert(materials != boost::none);
-	materials->resize(elements.size(), 0);
-
-	// the name is only a temp-name, the name given in the dialog is set later
-	return new MeshLib::Mesh("RasterDataMesh", nodes, elements, properties);
+	return elements;
 }
 
 MeshLib::Mesh* VtkMeshConverter::convertUnstructuredGrid(vtkUnstructuredGrid* grid, std::string const& mesh_name)
diff --git a/MeshLib/MeshGenerators/VtkMeshConverter.h b/MeshLib/MeshGenerators/VtkMeshConverter.h
index 9433d2c8382..c8db6ed8b08 100644
--- a/MeshLib/MeshGenerators/VtkMeshConverter.h
+++ b/MeshLib/MeshGenerators/VtkMeshConverter.h
@@ -22,6 +22,7 @@
 
 #include "logog/include/logog.hpp"
 
+#include "MeshLib/Node.h"
 #include "MeshLib/Location.h"
 #include "MeshLib/MeshEnums.h"
 #include "MeshLib/Properties.h"
@@ -72,19 +73,66 @@ public:
 	                                              std::string const& mesh_name = "vtkUnstructuredGrid");
 
 private:
-	/// Does the actual mesh generation based on the data given to the public methods.
-	static MeshLib::Mesh* constructMesh(const double* pixVal,
-	                                    int* node_idx_map,
-	                                    const bool* visNodes,
-	                                    const double origin[3],
-	                                    const std::size_t &imgHeight,
-	                                    const std::size_t &imgWidth,
-	                                    const double &scalingFactor,
-	                                    MeshElemType elem_type,
-	                                    UseIntensityAs intensity_type);
+	/// Constructs mesh components based on image data.
+	static MeshLib::Mesh* constructMesh(
+		std::vector<double> const& pix_val,
+		std::vector<bool> const& pix_vis,
+		double const origin[3],
+		std::size_t const imgHeight,
+		std::size_t const imgWidth,
+		double const scalingFactor,
+		MeshLib::MeshElemType elem_type,
+		MeshLib::UseIntensityAs intensity_type);
 
 	static void convertScalarArrays(vtkUnstructuredGrid &grid, MeshLib::Mesh &mesh);
 
+	/// Creates a mesh node vector based on image data
+	static std::vector<MeshLib::Node*> createNodeVector(
+		std::vector<double> const& elevation,
+		std::vector<int> &node_idx_map,
+		std::size_t const incHeight,
+		std::size_t const incWidth,
+		double const origin[3],
+		double const scalingFactor,
+		bool use_elevation);
+
+	/// Creates a mesh element vector based on image data
+	static std::vector<MeshLib::Element*> createElementVector(
+		std::vector<double> const&  pix_val,
+		std::vector<bool> const& pix_vis,
+		std::vector<MeshLib::Node*> const& nodes,
+		std::vector<int> 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<typename T>
+	static void fillPropertyVector(
+		MeshLib::PropertyVector<T> &prop_vec,
+		std::vector<double> const& pix_val,
+		std::vector<bool> const& pix_vis,
+		const std::size_t &imgHeight,
+		const std::size_t &imgWidth,
+		MeshElemType elem_type)
+	{
+		for (std::size_t i = 0; i < imgWidth; i++)
+			for (std::size_t j = 0; j < imgHeight; j++)
+			{
+				std::size_t const idx (i*imgHeight+j);
+				if (!pix_vis[i*imgHeight+j])
+					continue;
+				T val (static_cast<T>(pix_val[i*(imgHeight+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);
-- 
GitLab