From 6e3ef00f8741d83ca2eb193d38e493c1a02ceb36 Mon Sep 17 00:00:00 2001
From: Lars Bilke <lars.bilke@ufz.de>
Date: Fri, 17 Oct 2014 11:40:16 +0200
Subject: [PATCH] Added element values to the mapped mesh source.

This is an intermediate implementation until there is the final cell
data implementation in MeshLib.

I had to introduce a const reference value access method to Element.
---
 .../VtkMappedElementDataArrayTemplate-impl.h  | 481 ++++++++++++++++++
 InSituLib/VtkMappedElementDataArrayTemplate.h | 119 +++++
 InSituLib/VtkMappedMesh.cpp                   |   2 +-
 InSituLib/VtkMappedMesh.h                     |   2 +-
 InSituLib/VtkMappedMeshSource.cpp             |  13 +-
 InSituLib/VtkMappedMeshSource.h               |   2 +-
 .../VtkMeshNodalCoordinatesTemplate-impl.h    |   2 +-
 InSituLib/VtkMeshNodalCoordinatesTemplate.h   |   2 +-
 MeshLib/Elements/Element.h                    |   7 +-
 Tests/InSituLib/TestVtkMappedMeshSource.cpp   |  32 +-
 10 files changed, 643 insertions(+), 19 deletions(-)
 create mode 100644 InSituLib/VtkMappedElementDataArrayTemplate-impl.h
 create mode 100644 InSituLib/VtkMappedElementDataArrayTemplate.h

diff --git a/InSituLib/VtkMappedElementDataArrayTemplate-impl.h b/InSituLib/VtkMappedElementDataArrayTemplate-impl.h
new file mode 100644
index 00000000000..78612ff52ac
--- /dev/null
+++ b/InSituLib/VtkMappedElementDataArrayTemplate-impl.h
@@ -0,0 +1,481 @@
+/**
+ * \file
+ * \author Lars Bilke
+ * \date   2014-10-17
+ * \brief  Implementation of the VtkMappedElementDataArrayTemplate class.
+ *
+ * \copyright
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#include "VtkMappedElementDataArrayTemplate.h"
+
+#include <vtkIdList.h>
+#include <vtkObjectFactory.h>
+#include <vtkVariant.h>
+#include <vtkVariantCast.h>
+
+// Can't use vtkStandardNewMacro on a templated class.
+template <class Scalar> VtkMappedElementDataArrayTemplate<Scalar> *
+VtkMappedElementDataArrayTemplate<Scalar>::New()
+{
+	VTK_STANDARD_NEW_BODY(VtkMappedElementDataArrayTemplate<Scalar>)
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::PrintSelf(ostream &os, vtkIndent indent)
+{
+	this->VtkMappedElementDataArrayTemplate<Scalar>::Superclass::PrintSelf(
+		os, indent);
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetElements(std::vector<MeshLib::Element *> const * elements, vtkIdType numTuples)
+{
+	this->Initialize();
+	this->NumberOfComponents = static_cast<int>(1);
+	this->_elements = elements;
+	this->Size = this->NumberOfComponents * numTuples;
+	this->MaxId = this->Size - 1;
+	this->Modified();
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetElements(std::vector<MeshLib::Element *> const * elements, vtkIdType numTuples,
+						bool save)
+{
+	this->SetElements(elements, numTuples);
+	this->Save = save;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::Initialize()
+{
+	this->_elements = NULL;
+
+	this->MaxId = -1;
+	this->Size = 0;
+	this->NumberOfComponents = 1;
+	// the default is to have this class delete the arrays when done with them.
+	this->Save = false;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::GetTuples(vtkIdList *ptIds, vtkAbstractArray *output)
+{
+	vtkDataArray *da = vtkDataArray::FastDownCast(output);
+	if (!da)
+	{
+		vtkWarningMacro(<<"Input is not a vtkDataArray");
+		return;
+	}
+
+	if (da->GetNumberOfComponents() != this->GetNumberOfComponents())
+	{
+		vtkWarningMacro(<<"Incorrect number of components in input array.");
+		return;
+	}
+
+	const vtkIdType numPoints = ptIds->GetNumberOfIds();
+	for (vtkIdType i = 0; i < numPoints; ++i)
+	{
+		da->SetTuple(i, this->GetTuple(ptIds->GetId(i)));
+	}
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::GetTuples(vtkIdType p1, vtkIdType p2, vtkAbstractArray *output)
+{
+	vtkDataArray *da = vtkDataArray::FastDownCast(output);
+	if (!da)
+	{
+		vtkErrorMacro(<<"Input is not a vtkDataArray");
+		return;
+	}
+
+	if (da->GetNumberOfComponents() != this->GetNumberOfComponents())
+	{
+		vtkErrorMacro(<<"Incorrect number of components in input array.");
+		return;
+	}
+
+	for (vtkIdType daTupleId = 0; p1 <= p2; ++p1)
+	{
+		da->SetTuple(daTupleId++, this->GetTuple(p1));
+	}
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::Squeeze()
+{
+	// noop
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkArrayIterator*
+VtkMappedElementDataArrayTemplate<Scalar>::NewIterator()
+{
+	vtkErrorMacro(<<"Not implemented.");
+	return NULL;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::LookupValue(vtkVariant value)
+{
+	bool valid = true;
+	Scalar val = vtkVariantCast<Scalar>(value, &valid);
+	if (valid)
+	{
+		return this->Lookup(val, 0);
+	}
+	return -1;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::LookupValue(vtkVariant value, vtkIdList *ids)
+{
+	bool valid = true;
+	Scalar val = vtkVariantCast<Scalar>(value, &valid);
+	ids->Reset();
+	if (valid)
+	{
+		vtkIdType index = 0;
+		while ((index = this->Lookup(val, index)) >= 0)
+		{
+			ids->InsertNextId(index);
+			++index;
+		}
+	}
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkVariant VtkMappedElementDataArrayTemplate<Scalar>
+::GetVariantValue(vtkIdType idx)
+{
+	return vtkVariant(this->GetValueReference(idx));
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::ClearLookup()
+{
+	// no-op, no fast lookup implemented.
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> double* VtkMappedElementDataArrayTemplate<Scalar>
+::GetTuple(vtkIdType i)
+{
+	this->TempDouble = (*this->_elements)[i]->getValue();
+	return &this->TempDouble;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::GetTuple(vtkIdType i, double *tuple)
+{
+	*tuple = (*this->_elements)[i]->getValue();
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::LookupTypedValue(Scalar value)
+{
+	return this->Lookup(value, 0);
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::LookupTypedValue(Scalar value, vtkIdList *ids)
+{
+	ids->Reset();
+	vtkIdType index = 0;
+	while ((index = this->Lookup(value, index)) >= 0)
+	{
+		ids->InsertNextId(index);
+		++index;
+	}
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> Scalar VtkMappedElementDataArrayTemplate<Scalar>
+::GetValue(vtkIdType idx)
+{
+	return (*this->_elements)[idx]->getValue();
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> Scalar& VtkMappedElementDataArrayTemplate<Scalar>
+::GetValueReference(vtkIdType idx)
+{
+	// VTK has no concept of 'const', so we'll just cross our fingers
+	// that no one writes to the returned reference.
+	Scalar& value = const_cast<Scalar&>((*this->_elements)[idx]->getValueReference());
+	return value;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::GetTupleValue(vtkIdType tupleId, Scalar *tuple)
+{
+	*tuple = (*this->_elements)[tupleId]->getValue();
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> int VtkMappedElementDataArrayTemplate<Scalar>
+::Allocate(vtkIdType, vtkIdType)
+{
+	vtkErrorMacro("Read only container.")
+	return 0;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> int VtkMappedElementDataArrayTemplate<Scalar>
+::Resize(vtkIdType)
+{
+	vtkErrorMacro("Read only container.")
+	return 0;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetNumberOfTuples(vtkIdType)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetTuple(vtkIdType, vtkIdType, vtkAbstractArray *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetTuple(vtkIdType, const float *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetTuple(vtkIdType, const double *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InsertTuple(vtkIdType, vtkIdType, vtkAbstractArray *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InsertTuple(vtkIdType, const float *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InsertTuple(vtkIdType, const double *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InsertTuples(vtkIdList *, vtkIdList *, vtkAbstractArray *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::InsertNextTuple(vtkIdType, vtkAbstractArray *)
+{
+	vtkErrorMacro("Read only container.")
+	return -1;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::InsertNextTuple(const float *)
+{
+
+	vtkErrorMacro("Read only container.")
+	return -1;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::InsertNextTuple(const double *)
+{
+	vtkErrorMacro("Read only container.")
+	return -1;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::DeepCopy(vtkAbstractArray *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::DeepCopy(vtkDataArray *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InterpolateTuple(vtkIdType, vtkIdList *, vtkAbstractArray *, double *)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InterpolateTuple(vtkIdType, vtkIdType, vtkAbstractArray*, vtkIdType,
+				   vtkAbstractArray*, double)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetVariantValue(vtkIdType, vtkVariant)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::RemoveTuple(vtkIdType)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::RemoveFirstTuple()
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::RemoveLastTuple()
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetTupleValue(vtkIdType, const Scalar*)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InsertTupleValue(vtkIdType, const Scalar*)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::InsertNextTupleValue(const Scalar *)
+{
+	vtkErrorMacro("Read only container.")
+	return -1;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::SetValue(vtkIdType, Scalar)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::InsertNextValue(Scalar)
+{
+	vtkErrorMacro("Read only container.")
+	return -1;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> void VtkMappedElementDataArrayTemplate<Scalar>
+::InsertValue(vtkIdType, Scalar)
+{
+	vtkErrorMacro("Read only container.")
+	return;
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> VtkMappedElementDataArrayTemplate<Scalar>
+::VtkMappedElementDataArrayTemplate()
+  : Save(false)
+{
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> VtkMappedElementDataArrayTemplate<Scalar>
+::~VtkMappedElementDataArrayTemplate()
+{
+
+}
+
+//------------------------------------------------------------------------------
+template <class Scalar> vtkIdType VtkMappedElementDataArrayTemplate<Scalar>
+::Lookup(const Scalar &val, vtkIdType index)
+{
+	while (index <= this->MaxId)
+	{
+		if (this->GetValueReference(index++) == val)
+		{
+			return index;
+		}
+	}
+	return -1;
+}
diff --git a/InSituLib/VtkMappedElementDataArrayTemplate.h b/InSituLib/VtkMappedElementDataArrayTemplate.h
new file mode 100644
index 00000000000..2d02a4a12d1
--- /dev/null
+++ b/InSituLib/VtkMappedElementDataArrayTemplate.h
@@ -0,0 +1,119 @@
+/**
+ * \file
+ * \author Lars Bilke
+ * \date   2014-10-17
+ * \brief  VtkMappedElementDataArrayTemplate is a adapter for cell data
+ *         on elements of OGS meshes to VTK unstructured grids.
+ *
+ * \copyright
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
+ *            Distributed under a Modified BSD License.
+ *              See accompanying file LICENSE.txt or
+ *              http://www.opengeosys.org/project/license
+ *
+ */
+
+#ifndef VTKMAPPEDELEMENTDATAARRAY_H_
+#define VTKMAPPEDELEMENTDATAARRAY_H_
+
+#include <vtkMappedDataArray.h>
+#include <vtkTypeTemplate.h>  // For templated vtkObject API
+#include <vtkObjectFactory.h> // for vtkStandardNewMacro
+
+#include "MeshLib/Elements/Element.h"
+
+namespace InSituLib {
+
+template <class Scalar>
+class VtkMappedElementDataArrayTemplate:
+	public vtkTypeTemplate<VtkMappedElementDataArrayTemplate<Scalar>,
+	                       vtkMappedDataArray<Scalar> >
+{
+public:
+	vtkMappedDataArrayNewInstanceMacro(VtkMappedElementDataArrayTemplate<Scalar>)
+	static VtkMappedElementDataArrayTemplate *New();
+	virtual void PrintSelf(ostream &os, vtkIndent indent);
+
+	// Description:
+	// Set the raw scalar arrays for the coordinate set. This class takes
+	// ownership of the arrays and deletes them with delete[].
+	void SetElements(std::vector<MeshLib::Element *> const * elements, vtkIdType numTuples);
+	void SetElements(std::vector<MeshLib::Element *> const * elements, vtkIdType numTuples, bool save);
+
+	// Reimplemented virtuals -- see superclasses for descriptions:
+	void Initialize();
+	void GetTuples(vtkIdList *ptIds, vtkAbstractArray *output);
+	void GetTuples(vtkIdType p1, vtkIdType p2, vtkAbstractArray *output);
+	void Squeeze();
+	vtkArrayIterator *NewIterator();
+	vtkIdType LookupValue(vtkVariant value);
+	void LookupValue(vtkVariant value, vtkIdList *ids);
+	vtkVariant GetVariantValue(vtkIdType idx);
+	void ClearLookup();
+	double* GetTuple(vtkIdType i);
+	void GetTuple(vtkIdType i, double *tuple);
+	vtkIdType LookupTypedValue(Scalar value);
+	void LookupTypedValue(Scalar value, vtkIdList *ids);
+	Scalar GetValue(vtkIdType idx);
+	Scalar& GetValueReference(vtkIdType idx);
+	void GetTupleValue(vtkIdType idx, Scalar *t);
+
+	// Description:
+	// This container is read only -- this method does nothing but print a
+	// warning.
+	int Allocate(vtkIdType sz, vtkIdType ext);
+	int Resize(vtkIdType numTuples);
+	void SetNumberOfTuples(vtkIdType number);
+	void SetTuple(vtkIdType i, vtkIdType j, vtkAbstractArray *source);
+	void SetTuple(vtkIdType i, const float *source);
+	void SetTuple(vtkIdType i, const double *source);
+	void InsertTuple(vtkIdType i, vtkIdType j, vtkAbstractArray *source);
+	void InsertTuple(vtkIdType i, const float *source);
+	void InsertTuple(vtkIdType i, const double *source);
+	void InsertTuples(vtkIdList *dstIds, vtkIdList *srcIds,
+	                  vtkAbstractArray *source);
+	vtkIdType InsertNextTuple(vtkIdType j, vtkAbstractArray *source);
+	vtkIdType InsertNextTuple(const float *source);
+	vtkIdType InsertNextTuple(const double *source);
+	void DeepCopy(vtkAbstractArray *aa);
+	void DeepCopy(vtkDataArray *da);
+	void InterpolateTuple(vtkIdType i, vtkIdList *ptIndices,
+	                      vtkAbstractArray* source, double* weights);
+	void InterpolateTuple(vtkIdType i, vtkIdType id1, vtkAbstractArray *source1,
+	                      vtkIdType id2, vtkAbstractArray *source2, double t);
+	void SetVariantValue(vtkIdType idx, vtkVariant value);
+	void RemoveTuple(vtkIdType id);
+	void RemoveFirstTuple();
+	void RemoveLastTuple();
+	void SetTupleValue(vtkIdType i, const Scalar *t);
+	void InsertTupleValue(vtkIdType i, const Scalar *t);
+	vtkIdType InsertNextTupleValue(const Scalar *t);
+	void SetValue(vtkIdType idx, Scalar value);
+	vtkIdType InsertNextValue(Scalar v);
+	void InsertValue(vtkIdType idx, Scalar v);
+
+protected:
+	VtkMappedElementDataArrayTemplate();
+	~VtkMappedElementDataArrayTemplate();
+
+	//Scalar *Array;
+	std::vector<MeshLib::Element*> const * _elements;
+
+private:
+	VtkMappedElementDataArrayTemplate(
+		const VtkMappedElementDataArrayTemplate &); // Not implemented.
+	void operator=(
+		const VtkMappedElementDataArrayTemplate &); // Not implemented.
+
+	vtkIdType Lookup(const Scalar &val, vtkIdType startIndex);
+	double TempDouble;
+	// Description: If Save is true then this class won't delete that memory.
+	// By default Save is false.
+	bool Save;
+};
+
+#include "VtkMappedElementDataArrayTemplate-impl.h"
+
+} // end namespace InSituLib
+
+#endif // VTKMAPPEDELEMENTDATAARRAY_H_
diff --git a/InSituLib/VtkMappedMesh.cpp b/InSituLib/VtkMappedMesh.cpp
index b7a1cd4678e..a533a0e2dee 100644
--- a/InSituLib/VtkMappedMesh.cpp
+++ b/InSituLib/VtkMappedMesh.cpp
@@ -5,7 +5,7 @@
  * \brief  Implementation of the VtkMappedMesh class.
  *
  * \copyright
- * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
  *            Distributed under a Modified BSD License.
  *              See accompanying file LICENSE.txt or
  *              http://www.opengeosys.org/project/license
diff --git a/InSituLib/VtkMappedMesh.h b/InSituLib/VtkMappedMesh.h
index 7535891b8f0..4dc7aecc0ea 100644
--- a/InSituLib/VtkMappedMesh.h
+++ b/InSituLib/VtkMappedMesh.h
@@ -7,7 +7,7 @@
  *         without node coordinates. See VtkMeshNodalCoordinatesTemplate.
  *
  * \copyright
- * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
  *            Distributed under a Modified BSD License.
  *              See accompanying file LICENSE.txt or
  *              http://www.opengeosys.org/project/license
diff --git a/InSituLib/VtkMappedMeshSource.cpp b/InSituLib/VtkMappedMeshSource.cpp
index 70f97d59453..e78d64f3fa0 100644
--- a/InSituLib/VtkMappedMeshSource.cpp
+++ b/InSituLib/VtkMappedMeshSource.cpp
@@ -5,7 +5,7 @@
  * \brief  Implementation of the VtkMappedMeshSource class.
  *
  * \copyright
- * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
  *            Distributed under a Modified BSD License.
  *              See accompanying file LICENSE.txt or
  *              http://www.opengeosys.org/project/license
@@ -30,6 +30,7 @@
 
 #include "VtkMappedMesh.h"
 #include "VtkMeshNodalCoordinatesTemplate.h"
+#include "VtkMappedElementDataArrayTemplate.h"
 
 namespace InSituLib {
 
@@ -72,7 +73,7 @@ int VtkMappedMeshSource::RequestData(vtkInformation *,
 {
 	vtkSmartPointer<vtkInformation> outInfo = outputVector->GetInformationObject(0);
 	vtkSmartPointer<vtkUnstructuredGrid> output = vtkUnstructuredGrid::SafeDownCast(
-	        outInfo->Get(vtkDataObject::DATA_OBJECT()));
+		outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
 	if (outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
 		return 1;
@@ -92,11 +93,15 @@ int VtkMappedMeshSource::RequestData(vtkInformation *,
 	 // Use the mapped point container for the block points
 	elems->SetPoints(this->Points.GetPointer());
 
-	// TODO cell vals
-
 	output->Allocate(elems->GetNumberOfCells());
 	output->ShallowCopy(elems.GetPointer());
 
+	// Mapped data array for material ids
+	vtkNew<VtkMappedElementDataArrayTemplate<unsigned> > materialIds;
+	materialIds->SetElements(&_mesh->getElements(), _mesh->getNElements());
+	materialIds->SetName("MaterialIDs");
+	output->GetCellData()->AddArray(materialIds.GetPointer());
+
 	return 1;
 }
 
diff --git a/InSituLib/VtkMappedMeshSource.h b/InSituLib/VtkMappedMeshSource.h
index f0b52eca23b..1a0f963de4b 100644
--- a/InSituLib/VtkMappedMeshSource.h
+++ b/InSituLib/VtkMappedMeshSource.h
@@ -13,7 +13,7 @@
  * \endcode
  *
  * \copyright
- * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
  *            Distributed under a Modified BSD License.
  *              See accompanying file LICENSE.txt or
  *              http://www.opengeosys.org/project/license
diff --git a/InSituLib/VtkMeshNodalCoordinatesTemplate-impl.h b/InSituLib/VtkMeshNodalCoordinatesTemplate-impl.h
index 9f6851a7f96..73b0b0f2b0c 100644
--- a/InSituLib/VtkMeshNodalCoordinatesTemplate-impl.h
+++ b/InSituLib/VtkMeshNodalCoordinatesTemplate-impl.h
@@ -5,7 +5,7 @@
  * \brief  Definition of the VtkMeshNodalCoordinatesTemplate class.
  *
  * \copyright
- * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
  *            Distributed under a Modified BSD License.
  *              See accompanying file LICENSE.txt or
  *              http://www.opengeosys.org/project/license
diff --git a/InSituLib/VtkMeshNodalCoordinatesTemplate.h b/InSituLib/VtkMeshNodalCoordinatesTemplate.h
index 2a4c58ba65a..663c87e8c0f 100644
--- a/InSituLib/VtkMeshNodalCoordinatesTemplate.h
+++ b/InSituLib/VtkMeshNodalCoordinatesTemplate.h
@@ -6,7 +6,7 @@
  *         OGS meshes to VTK unstructured grids.
  *
  * \copyright
- * Copyright (c) 2013, OpenGeoSys Community (http://www.opengeosys.org)
+ * Copyright (c) 2014, OpenGeoSys Community (http://www.opengeosys.org)
  *            Distributed under a Modified BSD License.
  *              See accompanying file LICENSE.txt or
  *              http://www.opengeosys.org/project/license
diff --git a/MeshLib/Elements/Element.h b/MeshLib/Elements/Element.h
index 9d2d6f08d2d..deb21931ee6 100644
--- a/MeshLib/Elements/Element.h
+++ b/MeshLib/Elements/Element.h
@@ -142,6 +142,11 @@ public:
 	 */
 	unsigned getValue() const { return _value; }
 
+	/**
+	 * Get the value for this element as a const reference.
+	 */
+	unsigned const& getValueReference() const { return _value; }
+
 	/**
 	 * Returns true if the element has zero length/area/volume.
 	 */
@@ -193,7 +198,7 @@ public:
 
 	/// Returns the ID of a face given an array of nodes.
 	virtual unsigned identifyFace(Node* nodes[3]) const = 0;
-	
+
 	/**
 	 * Checks if the node order of an element is correct by testing surface normals.
 	 */
diff --git a/Tests/InSituLib/TestVtkMappedMeshSource.cpp b/Tests/InSituLib/TestVtkMappedMeshSource.cpp
index 98fce5b606a..058c7e98054 100644
--- a/Tests/InSituLib/TestVtkMappedMeshSource.cpp
+++ b/Tests/InSituLib/TestVtkMappedMeshSource.cpp
@@ -11,21 +11,24 @@
  *              http://www.opengeosys.org/project/license
  *
  */
-#include "gtest/gtest.h"
 
 #include "BaseLib/BuildInfo.h"
-#include "Mesh.h"
-#include "MeshGenerators/MeshGenerator.h"
-#include "MeshGenerators/VtkMeshConverter.h"
+#include "MeshLib/Elements/Element.h"
+#include "MeshLib/Mesh.h"
+#include "MeshLib/MeshGenerators/MeshGenerator.h"
+#include "MeshLib/MeshGenerators/VtkMeshConverter.h"
+
+#include "InSituLib/VtkMappedMesh.h"
+#include "InSituLib/VtkMappedMeshSource.h"
 
-#include "VtkMappedMesh.h"
-#include "VtkMappedMeshSource.h"
+#include "gtest/gtest.h"
 
 #include <vtkNew.h>
 #include <vtkUnstructuredGrid.h>
 #include <vtkSmartPointer.h>
 #include <vtkXMLUnstructuredGridWriter.h>
 #include <vtkXMLUnstructuredGridReader.h>
+#include <vtkCellData.h>
 
 class InSituMesh : public ::testing::Test
 {
@@ -34,6 +37,8 @@ class InSituMesh : public ::testing::Test
 	 : mesh(nullptr)
 	{
 		mesh = MeshLib::MeshGenerator::generateRegularQuadMesh(this->length, this->subdivisions);
+		for(MeshLib::Element* element: mesh->getElements())
+			element->setValue(0);
 	}
 
 	~InSituMesh()
@@ -79,16 +84,25 @@ TEST_F(InSituMesh, MappedMeshSourceRoundtrip)
 	ASSERT_TRUE(mesh != nullptr);
 	std::string test_data_file(BaseLib::BuildInfo::tests_tmp_path + "/MappedMeshSourceRoundtrip.vtu");
 
-	// Test VtkMappedMeshSource, i.e. OGS mesh to VTK mesh
+	// -- Test VtkMappedMeshSource, i.e. OGS mesh to VTK mesh
 	vtkNew<InSituLib::VtkMappedMeshSource> vtkSource;
 	vtkSource->SetMesh(mesh);
 	vtkSource->Update();
 	vtkUnstructuredGrid* output = vtkSource->GetOutput();
 
+	// Point and cell numbers
 	ASSERT_EQ((subdivisions+1)*(subdivisions+1), output->GetNumberOfPoints());
 	ASSERT_EQ(subdivisions*subdivisions, output->GetNumberOfCells());
 
-	// Write VTK mesh to file
+	// Cell data array
+	vtkDataArray* matIdsArray = output->GetCellData()->GetScalars("MaterialIDs");
+	ASSERT_EQ(matIdsArray->GetSize(), mesh->getNElements());
+	ASSERT_EQ((unsigned)matIdsArray->GetComponent(0, 0), 0);
+	double* range = matIdsArray->GetRange(0);
+	ASSERT_EQ((unsigned)range[0], 0);
+	ASSERT_EQ((unsigned)range[1], 0);
+
+	// -- Write VTK mesh to file
 	vtkSmartPointer<vtkXMLUnstructuredGridWriter> vtuWriter =
 		vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
 	// Setting binary file  mode, otherwise corrupted output due to VTK bug
@@ -98,7 +112,7 @@ TEST_F(InSituMesh, MappedMeshSourceRoundtrip)
 	vtuWriter->SetInputConnection(vtkSource->GetOutputPort());
 	vtuWriter->Write();
 
-	// Read back VTK mesh
+	// -- Read back VTK mesh
 	vtkSmartPointer<vtkXMLUnstructuredGridReader> reader =
 		vtkSmartPointer<vtkXMLUnstructuredGridReader>::New();
 	reader->SetFileName(test_data_file.c_str());
-- 
GitLab