From 08e9f98f84d290ca90b0add1251e34460fc7d2bb Mon Sep 17 00:00:00 2001
From: Thomas Fischer <thomas.fischer@ufz.de>
Date: Wed, 18 Mar 2015 12:12:09 +0100
Subject: [PATCH] [MeL/ME] Copy MatIDs in simplifyMesh().

---
 MeshLib/MeshEditing/MeshRevision.cpp | 91 ++++++++++++++++++----------
 1 file changed, 60 insertions(+), 31 deletions(-)

diff --git a/MeshLib/MeshEditing/MeshRevision.cpp b/MeshLib/MeshEditing/MeshRevision.cpp
index a57193cbda2..962f56404c4 100644
--- a/MeshLib/MeshEditing/MeshRevision.cpp
+++ b/MeshLib/MeshEditing/MeshRevision.cpp
@@ -67,38 +67,67 @@ MeshLib::Mesh* MeshRevision::simplifyMesh(const std::string &new_mesh_name, doub
 	if (this->_mesh.getNElements() == 0)
 		return nullptr;
 
+	// original data
+	std::vector<MeshLib::Element*> const& elements(this->_mesh.getElements());
+	MeshLib::Properties const& properties(_mesh.getProperties());
+	boost::optional<MeshLib::PropertyVector<int> const&> material_vec(
+		properties.getPropertyVector<int>("MaterialIDs"));
+
+	// data structures for the new mesh
 	std::vector<MeshLib::Node*> new_nodes = this->constructNewNodesArray(this->collapseNodeIndices(eps));
 	std::vector<MeshLib::Element*> new_elements;
+	MeshLib::Properties new_properties;
+	boost::optional<PropertyVector<int> &> new_material_vec;
+	if (material_vec) {
+		new_properties.createNewPropertyVector<int>(
+			"MaterialIDs", MeshItemType::Cell, 1);
+	}
 
-	const std::vector<MeshLib::Element*> &elements(this->_mesh.getElements());
-	for (auto elem = elements.begin(); elem != elements.end(); ++elem)
-	{
-		unsigned n_unique_nodes(this->getNUniqueNodes(*elem));
-		if (n_unique_nodes == (*elem)->getNBaseNodes() && (*elem)->getDimension() >= min_elem_dim)
+	for (std::size_t k(0); k<elements.size(); ++k) {
+		MeshLib::Element const*const elem(elements[k]);
+		unsigned n_unique_nodes(this->getNUniqueNodes(elem));
+		if (n_unique_nodes == elem->getNBaseNodes()
+			&& elem->getDimension() >= min_elem_dim)
 		{
-			ElementErrorCode e((*elem)->validate());
+			ElementErrorCode e(elem->validate());
 			if (e[ElementErrorFlag::NonCoplanar])
 			{
-				if (!this->subdivideElement(*elem, new_nodes, new_elements))
+				std::size_t const n_new_elements(
+					subdivideElement(elem, new_nodes, new_elements));
+				if (n_new_elements == 0)
 				{
-					ERR("Error: Element %d has unknown element type.", std::distance(elements.begin(), elem));
+					ERR("Error: Element %d has unknown element type.", k);
 					this->resetNodeIDs();
 					this->cleanUp(new_nodes, new_elements);
 					return nullptr;
 				}
+				if (!material_vec)
+					continue;
+				new_material_vec->insert(new_material_vec->end(),
+					n_new_elements, (*material_vec)[k]);
+			} else {
+				new_elements.push_back(MeshLib::copyElement(elem, new_nodes));
+				// copy material values
+				if (material_vec)
+					new_material_vec->push_back((*material_vec)[k]);
 			}
-			else
-				new_elements.push_back(MeshLib::copyElement(*elem, new_nodes));
 		}
-		else if (n_unique_nodes < (*elem)->getNBaseNodes() && n_unique_nodes>1)
-			reduceElement(*elem, n_unique_nodes, new_nodes, new_elements, min_elem_dim);
-		else
+		else if (n_unique_nodes < elem->getNBaseNodes() && n_unique_nodes>1) {
+			std::size_t const n_new_elements(reduceElement(
+				elem, n_unique_nodes, new_nodes, new_elements, min_elem_dim)
+			);
+			if (!material_vec)
+				continue;
+			new_material_vec->insert(new_material_vec->end(),
+				n_new_elements, (*material_vec)[k]);
+		} else
 			ERR ("Something is wrong, more unique nodes than actual nodes");
 	}
 
 	this->resetNodeIDs();
 	if (!new_elements.empty())
-		return new MeshLib::Mesh(new_mesh_name, new_nodes, new_elements);
+		return new MeshLib::Mesh(
+			new_mesh_name, new_nodes, new_elements, new_properties);
 
 	this->cleanUp(new_nodes, new_elements);
 	return nullptr;
@@ -109,22 +138,23 @@ MeshLib::Mesh* MeshRevision::subdivideMesh(const std::string &new_mesh_name) con
 	if (this->_mesh.getNElements() == 0)
 		return nullptr;
 
-	// data structures for the new mesh
-	std::vector<MeshLib::Node*> new_nodes = MeshLib::copyNodeVector(_mesh.getNodes());
-	std::vector<MeshLib::Element*> new_elements;
-	MeshLib::Properties new_properties;
-	boost::optional<PropertyVector<int> &> new_material_vec(
-		new_properties.createNewPropertyVector<int>(
-			"MaterialIDs", MeshItemType::Cell, 1
-		)
-	);
-
 	// original data
 	std::vector<MeshLib::Element*> const& elements(this->_mesh.getElements());
 	MeshLib::Properties const& properties(_mesh.getProperties());
 	boost::optional<MeshLib::PropertyVector<int> const&> material_vec(
 		properties.getPropertyVector<int>("MaterialIDs"));
 
+	// data structures for the new mesh
+	std::vector<MeshLib::Node*> new_nodes = MeshLib::copyNodeVector(_mesh.getNodes());
+	std::vector<MeshLib::Element*> new_elements;
+	MeshLib::Properties new_properties;
+	boost::optional<PropertyVector<int> &> new_material_vec;
+	if (material_vec) {
+		new_material_vec = new_properties.createNewPropertyVector<int>(
+			"MaterialIDs", MeshItemType::Cell, 1
+		);
+	}
+
 	for (std::size_t k(0); k<elements.size(); ++k) {
 		MeshLib::Element const*const elem(elements[k]);
 		ElementErrorCode error_code(elem->validate());
@@ -138,17 +168,16 @@ MeshLib::Mesh* MeshRevision::subdivideMesh(const std::string &new_mesh_name) con
 				this->cleanUp(new_nodes, new_elements);
 				return nullptr;
 			}
-			// transmit material values
+			// copy material values
 			if (!material_vec)
 				continue;
-			for (std::size_t j(0); j<n_new_elements; ++j)
-				new_material_vec->push_back((*material_vec)[k]);
+			new_material_vec->insert(new_material_vec->end(), n_new_elements,
+				(*material_vec)[k]);
 		} else {
 			new_elements.push_back(MeshLib::copyElement(elem, new_nodes));
-			// transmit material values
-			if (!material_vec)
-				continue;
-			new_material_vec->push_back((*material_vec)[k]);
+			// copy material values
+			if (material_vec)
+				new_material_vec->push_back((*material_vec)[k]);
 		}
 	}
 
-- 
GitLab