#include "VTKTutorialPlugin.h"
#include "ritkDebugManager.h"
#include "ritkManager.h"
#include "ritkRGBRImage.h"

#include <QFileDialog>

#include <vtkPointLocator.h>
#include <vtkPointData.h>
#include <vtkProperty.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataReader.h>
#include <vtkRendererCollection.h>

#include <vtkPolyDataReader.h>

#include <vtkActor.h>
#include <vtkLODActor.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkLegendScaleActor.h>
#include <vtkConeSource.h>
#include <vtkCubeSource.h>
#include <vtkPointPicker.h>
#include <vtkLine.h>
#include <vtkCellData.h>
#include <vtkFloatArray.h>


#include <itkImageRegionIterator.h>
#include <itkImageFileWriter.h>

#include <vtkDelaunay2D.h>
#include <vtkDelaunay3D.h>

#include <vtkTextProperty.h>

#include "ritkRImageVTKData.h"

#include <itkTriangleMeshToBinaryImageFilter.h>
#include <itkAntiAliasBinaryImageFilter.h>
#include <itkZeroCrossingImageFilter.h>
#include <itkRescaleIntensityImageFilter.h>


VTKTutorialPlugin::VTKTutorialPlugin()
{
	// Create the widget
	m_Widget = new VTKTutorialWidget();

	// We do not have any frame or data atm
	m_CurrentFrame = NULL;
	m_RImageVTKData = vtkSmartPointer<ritk::RImageVTKData>::New();

	// Connnect the widgets
	connect(this, SIGNAL(UpdateGUI()), m_Widget, SLOT(UpdateGUI()));
	connect(m_Widget, SIGNAL(PolyDataTypeChanged(ritk::RImageVTKData::PolyDataType)), this, SLOT(SetPolyDataType(ritk::RImageVTKData::PolyDataType)));
	connect(m_Widget, SIGNAL(VisualizationTypeChanged(VTKTutorialWidget::VisualizationMode, bool)), this, SLOT(SetVisualizationType(VTKTutorialWidget::VisualizationMode, bool)));
	connect(m_Widget, SIGNAL(GetLocalNeighborhood()), this, SLOT(ComputeLocalNeighborhood()));
	//connect(m_Widget->m_RadioButtonViewMode, SIGNAL(clicked()), this, SLOT(SetViewMode()));
	//connect(m_Widget->m_RadioButtonManipulationMode, SIGNAL(clicked()), this, SLOT(SetManipulationMode()));
	connect(m_Widget->m_CheckBoxStereoOn, SIGNAL(stateChanged(int)), this, SLOT(CheckBoxStereoOnStateChanged(int)));

	connect(m_Widget->m_RangeIntervalMinSpinBox, SIGNAL(valueChanged(double)), this, SLOT(RangeIntervalMinChanged(double)));
	connect(m_Widget->m_RangeIntervalMaxSpinBox, SIGNAL(valueChanged(double)), this, SLOT(RangeIntervalMaxChanged(double)));
	connect(m_Widget->m_RangeIntervalClampPushButton, SIGNAL(clicked()), this, SLOT(ClampRangeInterval()));

	connect(m_Widget->m_RGBIntervalMinSpinBox, SIGNAL(valueChanged(double)), this, SLOT(RGBIntervalMinChanged(double)));
	connect(m_Widget->m_RGBIntervalMaxSpinBox, SIGNAL(valueChanged(double)), this, SLOT(RGBIntervalMaxChanged(double)));
	connect(m_Widget->m_RGBIntervalClampPushButton, SIGNAL(clicked()), this, SLOT(ClampRGBInterval()));

	connect(m_Widget->m_SetCurrentFrameAsReferenceFramePushButton, SIGNAL(clicked()), this, SLOT(SetCurrentFrameAsReferenceFrame()));
	
	connect(m_Widget->m_DisplayLegendCheckBox, SIGNAL(stateChanged(int)), this, SLOT(DisplayLegend(int)));

	// t.b.d
	m_NeighborhoodActor = NULL;
	m_SphereActor = NULL;

	// Initialize the range image actor and add it to the 3D visualization widget
	m_Actor = vtkSmartPointer<ritk::RImageActorPipeline>::New();
	m_Actor->GetProperty()->SetPointSize(3.0);
	m_Widget->m_VisualizationWidget3D->AddActor(m_Actor);
	m_Widget->m_VisualizationWidget3D->AddProp(m_Actor->m_ScalarBarActor);

	m_RImageVTKData = vtkSmartPointer<ritk::RImageVTKData>::New();

	m_DisplayFrameDifference = false;
	m_ReferenceFrame = ritk::NewFrameEvent::RImageType::New();

	m_Widget->m_VisualizationWidget3D->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->SetBackground(1,1,1);
	m_Widget->m_VisualizationWidget3D->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->SetBackground2(1,1,1);

	// Point picker
	m_QtSlotConnector = vtkSmartPointer<vtkEventQtSlotConnect>::New();
	m_QtSlotConnector->Connect(
		m_Widget->m_VisualizationWidget3D->GetRenderWindow()->GetInteractor(),
		vtkCommand::RightButtonPressEvent,
        this,
        SLOT(RightButtonPressEventHandling(vtkObject*, unsigned long, void*, void*))
		);

	m_PickPoint1 = new double[3];
	m_PickPoint2 = new double[3];
	
	m_PickPoint1[0] = 0.0;
	m_PickPoint1[1] = 0.0;
	m_PickPoint1[2] = 0.0;

	m_PickPoint2[0] = 0.0;
	m_PickPoint2[1] = 0.0;
	m_PickPoint2[2] = 0.0;

	m_PickPoint1Actor = NULL;
	m_PickPoint2Actor = NULL;
	m_LineActor = NULL;

	UpdatePointPickerGUI();
}

VTKTutorialPlugin::~VTKTutorialPlugin()
{
	// Remove all actors
	

	delete m_Widget;

	
	LOG_DEB("Destructor for VTKTutorialPlugin @" << this << " called...");
}


//----------------------------------------------------------------------------
QString
VTKTutorialPlugin::GetName()
{
	return tr("VTKTutorialPlugin");
}


//----------------------------------------------------------------------------
QWidget*
VTKTutorialPlugin::GetPluginGUI()
{
	return m_Widget;
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::ProcessEvent(ritk::Event::Pointer EventP)
{
	// New frame event
	if ( EventP->type() == ritk::NewFrameEvent::EventType )
	{
		// Cast the event
		ritk::NewFrameEvent::Pointer NewFrameEventP = qSharedPointerDynamicCast<ritk::NewFrameEvent,ritk::Event>(EventP);
		if ( !NewFrameEventP )
		{
			LOG_DEB("Event mismatch detected: Type=" << EventP->type());
			return;
		}

		// Get the current range frame (or image)
		ritk::NewFrameEvent::RImageConstPointer CurrentFrameP = NewFrameEventP->RImage;

		// If we don't have a frame we have to initialize the intervals
		bool IntervalInitRequired = !m_CurrentFrame ? true : false;

		// We have to lock as this member may be used by another thread
		LockPlugin();
		m_CurrentFrame = CurrentFrameP;
		UnlockPlugin();

		// Actual interval initialization
		if ( IntervalInitRequired )
		{
			ClampRangeInterval();
			ClampRGBInterval();
		}

		// Update our RImageActor
		if ( !m_DisplayFrameDifference )
		{
			LockPlugin();
			m_RImageVTKData->GeneratePolyData(m_CurrentFrame);
			m_Actor->SetData(m_RImageVTKData->GetPolyData(),m_CurrentFrame);
#if 0
			// Bounding box of the data
			// Compute the bounding sphere of the scene
			long NumVertices = m_CurrentFrame->GetWorldCoordImage()->GetRequestedRegion().GetNumberOfPixels();
			float BBMin[] = {1e16,1e16,1e16};
			float BBMax[] = {-1e16,-1e16,-1e16};

			float *CoordPtr = (float*)m_CurrentFrame->GetWorldCoordImage()->GetBufferPointer();
			for ( long l = 0; l < NumVertices; l++, CoordPtr += 3 )
			{
				if ( fabsf(*(CoordPtr+2)) < 1e-6 )
					continue;
				if ( *CoordPtr < BBMin[0] )
					BBMin[0] = *CoordPtr;
				if ( *(CoordPtr+1) < BBMin[1] )
					BBMin[1] = *(CoordPtr+1);
				if ( *(CoordPtr+2) < BBMin[2] )
					BBMin[2] = *(CoordPtr+2);

				if ( *CoordPtr > BBMax[0] )
					BBMax[0] = *CoordPtr;
				if ( *(CoordPtr+1) > BBMax[1] )
					BBMax[1] = *(CoordPtr+1);
				if ( *(CoordPtr+2) > BBMax[2] )
					BBMax[2] = *(CoordPtr+2);
			}
			// Margin
			for ( unsigned int dim = 0; dim < 3; dim++ )
			{
				BBMin[dim] -= 50;
				BBMax[dim] += 50;
			}

			// Create itk mesh -> binary image -> (anti-aliasing) -> write
			m_Actor->SetData(m_RImageVTKData->GetPolyData(),m_CurrentFrame);
			MeshType::Pointer Mesh = vtkPolyDataToITKMesh(m_RImageVTKData->GetPolyData());

			typedef itk::Image<unsigned char,3> BinaryImageType;
			typedef itk::TriangleMeshToBinaryImageFilter <MeshType, BinaryImageType> TriangleMeshToBinaryImageFilterType;
			TriangleMeshToBinaryImageFilterType::Pointer MeshFilter = TriangleMeshToBinaryImageFilterType::New();
			BinaryImageType::IndexType OutputIndex;
			OutputIndex[0] = 0;
			OutputIndex[1] = 0;
			OutputIndex[2] = 0;
			BinaryImageType::SizeType OutputSize;
			OutputSize[0] = 512;
			OutputSize[1] = 512;
			OutputSize[2] = 256;
			BinaryImageType::PointType OutputOrigin;
			OutputOrigin[0] = BBMin[0];
			OutputOrigin[1] = BBMin[1];
			OutputOrigin[2] = BBMin[2];
			BinaryImageType::SpacingType OutputSpacing;
			OutputSpacing[0] = (BBMax[0]-BBMin[0])/(1.0 * (OutputSize[0]-1));
			OutputSpacing[1] = (BBMax[1]-BBMin[1])/(1.0 * (OutputSize[1]-1));
			OutputSpacing[2] = (BBMax[2]-BBMin[2])/(1.0 * (OutputSize[2]-1));
			MeshFilter->SetTolerance (1.0);
			MeshFilter->SetSpacing(OutputSpacing);
			MeshFilter->SetOrigin(OutputOrigin);
			MeshFilter->SetSize(OutputSize);
			MeshFilter->SetIndex(OutputIndex);
			MeshFilter->SetInput(Mesh);

			typedef itk::Image<float,3> RealImageType;
			typedef itk::AntiAliasBinaryImageFilter<BinaryImageType, RealImageType> AntiAliasFilterType;
			AntiAliasFilterType::Pointer AntiAliaser = AntiAliasFilterType::New();
			AntiAliaser->SetInput(MeshFilter->GetOutput());
			AntiAliaser->SetMaximumRMSError(0.001);
			//AntiAliaser->SetNumberOfLayers(10);

			/*typedef itk::ZeroCrossingImageFilter<RealImageType, RealImageType> ZeroCrossingFilterType;
			ZeroCrossingFilterType::Pointer ZeroCrossingFilter = ZeroCrossingFilterType::New();
			ZeroCrossingFilter->SetInput(AntiAliaser->GetOutput());
			ZeroCrossingFilter->SetForegroundValue(1.0);
			ZeroCrossingFilter->SetBackgroundValue(-1.0);*/


			typedef itk::RescaleIntensityImageFilter<RealImageType, BinaryImageType> RescalerType;
			RescalerType::Pointer Rescaler = RescalerType::New();
			Rescaler->SetInput(AntiAliaser->GetOutput());
			Rescaler->SetOutputMinimum(0);
			Rescaler->SetOutputMaximum(1);

			typedef itk::ImageFileWriter<BinaryImageType> WriterType;
			WriterType::Pointer Writer = WriterType::New();
			Writer->SetInput(Rescaler->GetOutput());
			Writer->SetFileName("D://Temp//MeshOut.mha");

			try
			{
				MeshFilter->Update();
				std::cout << "MeshFilter updated..." << std::endl;
				AntiAliaser->Update();
				typedef itk::ImageRegionIterator<RealImageType> IteratorType;
				IteratorType it(AntiAliaser->GetOutput(), AntiAliaser->GetOutput()->GetRequestedRegion());
				for ( it.GoToBegin(); !it.IsAtEnd(); ++it )
				{
					if ( it.Value() < 0 )
						it.Value() = 0;
					else
						it.Value() = 1;
				}
				std::cout << "AntiAliaser updated..." << std::endl;
				Rescaler->Update();
				Writer->Update();
			}
			catch ( itk::ExceptionObject &e )
			{
				std::cerr << e << std::endl;
			}

			std::cout << "Finished!" << std::endl;
#endif




#if 0
			// Segment the actor's data
			vtkSmartPointer<vtkPolyData> OldPolyData = vtkSmartPointer<vtkPolyData>::New();
			OldPolyData->DeepCopy(m_Actor->GetData(true));

			m_NewPolyData = vtkSmartPointer<vtkPolyData>::New();
			m_NewPoints = vtkSmartPointer<vtkPoints>::New();
			m_NewCells = vtkSmartPointer<vtkCellArray>::New();
			m_NewScalars = vtkSmartPointer<vtkFloatArray>::New();

			
			if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 1)
			{
				m_NewScalars->SetNumberOfComponents(1);
			}
			else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 3 )
			{
				m_NewScalars->SetNumberOfComponents(3);
			}
			else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 4 )
			{
				m_NewScalars->SetNumberOfComponents(4);
			}

			double * Point = new double[3];
			double * Scalar = new double[3];
			for( vtkIdType i = 0; i < OldPolyData->GetNumberOfPoints(); i++ )
			{
				Point = OldPolyData->GetPoint(i);

				/*if ( Point[2] > -565 && 
					Point[0] > - 92 && Point[0] < 115 &&
					Point[1] > -140 && Point[1] < 111 )*/
				if ( Point[2] > -860 )
				{			
					m_NewPoints->InsertNextPoint(Point);
					
					if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 1 )
					{
						double ScalarValue = OldPolyData->GetPointData()->GetScalars()->GetTuple1(i);
						m_NewScalars->InsertNextTuple1(ScalarValue);
					}
					else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 3 )
					{
						Scalar = OldPolyData->GetPointData()->GetScalars()->GetTuple3(i);
						m_NewScalars->InsertNextTuple3(Scalar[0],Scalar[1],Scalar[2]);
					}
					else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 4 )
					{
						Scalar = OldPolyData->GetPointData()->GetScalars()->GetTuple4(i);
						m_NewScalars->InsertNextTuple4(Scalar[0],Scalar[1],Scalar[2],Scalar[3]);
					}
				}	
			}
			m_NewPolyData->SetPoints(m_NewPoints);

			for ( vtkIdType i = 0; i < m_NewPolyData->GetNumberOfPoints(); i++ )
			{
				m_NewCells->InsertNextCell(1, &i);
			}

			m_NewPolyData->GetPointData()->SetScalars(m_NewScalars);	
			m_NewPolyData->SetVerts(m_NewCells);
			m_NewPolyData->Update();

			vtkSmartPointer<vtkDelaunay2D> Delaunay = vtkSmartPointer<vtkDelaunay2D>::New();
			Delaunay->SetInput(m_NewPolyData);
			Delaunay->Update();
			m_NewPolyData = Delaunay->GetOutput();

			m_Actor->SetData(m_NewPolyData,true);
#endif
			UnlockPlugin();
		}
		else
		{
			LockPlugin();
			// We use the grayscale (in rgb) to store the euclidean distance between the current frames world coords and those of the reference frame
			float min = 1e16;
			float max = -1e16;
			float Mean = 0;
			long Cnt = 0;
			for ( int i = 0; i < m_CurrentFrame->GetRequestedRegion().GetNumberOfPixels(); i++ )
			{
				if ( !(m_CurrentFrame->GetFlagImage()->GetBufferPointer()[i]&ritk::NewFrameEvent::RImageType::VALID) )
				{
					float Dist = 0;
					for ( unsigned int dim = 0; dim < 3; dim++ )
					{
						float f1 = m_CurrentFrame->GetWorldCoordImage()->GetBufferPointer()[i][dim];
						float f2 = m_ReferenceFrame->GetWorldCoordImage()->GetBufferPointer()[i][dim];
						Dist += (f1-f2)*(f1-f2);
					}
				
					Dist = sqrt(Dist);

					ritk::RGBRImageUCF2::Pointer ReferenceFrameRGBP = dynamic_cast<ritk::RGBRImageUCF2*>((ritk::RImageF2*) m_ReferenceFrame);
					if ( !ReferenceFrameRGBP )
					{
						LOG_DEB("Failed to cast.");
						return;
					}
					ReferenceFrameRGBP->GetRGBImage()->GetBufferPointer()[i][0] = Dist;
					ReferenceFrameRGBP->GetRGBImage()->GetBufferPointer()[i][1] = Dist;
					ReferenceFrameRGBP->GetRGBImage()->GetBufferPointer()[i][2] = Dist;

					if ( Dist < min )
						min = Dist;
					if ( Dist > max )
						max = Dist;
					Mean += Dist;
					Cnt++;
				}
				else
				{
					ritk::RGBRImageUCF2::Pointer ReferenceFrameRGBP = dynamic_cast<ritk::RGBRImageUCF2*>((ritk::RImageF2*) m_ReferenceFrame);
					if ( !ReferenceFrameRGBP )
					{
						LOG_DEB("Failed to cast.");
						return;
					}
					ReferenceFrameRGBP->GetRGBImage()->GetBufferPointer()[i][0] = 0;
					ReferenceFrameRGBP->GetRGBImage()->GetBufferPointer()[i][1] = 0;
					ReferenceFrameRGBP->GetRGBImage()->GetBufferPointer()[i][2] = 0;
				}
			}
			Mean /= Cnt;
			float Var = 0;
			for ( int i = 0; i < m_CurrentFrame->GetRequestedRegion().GetNumberOfPixels(); i++ )
			{
				if ( !(m_CurrentFrame->GetFlagImage()->GetBufferPointer()[i]&ritk::NewFrameEvent::RImageType::VALID) )
				{
					float Dist = 0;
					for ( unsigned int dim = 0; dim < 3; dim++ )
					{
						float f1 = m_CurrentFrame->GetWorldCoordImage()->GetBufferPointer()[i][dim];
						float f2 = m_ReferenceFrame->GetWorldCoordImage()->GetBufferPointer()[i][dim];
						Dist += (f1-f2)*(f1-f2);
					}
					Dist = sqrt(Dist);
					Var += (Mean-Dist)*(Mean-Dist);
				}
			}
			Var /= Cnt;
			//std::cout << "Mean=" << Mean << " Var=" << Var << std::endl;


			// Update the actor
			m_Actor->SetVisualizationMode(ritk::RImageActorPipeline::RGB);
			m_Actor->UseLUT(true);
			m_RImageVTKData->GeneratePolyData(m_ReferenceFrame);
			m_Actor->SetRGBInterval(min,7); // why 7? -> bad lut table warning
			m_Actor->SetData(m_RImageVTKData->GetPolyData(),m_ReferenceFrame);
			//m_Actor->m_ScalarBarActor->SetOrientationToHorizontal();
			vtkSmartPointer<vtkTextProperty> SATextProperty = m_Actor->m_ScalarBarActor->GetTitleTextProperty();
			SATextProperty->SetFontSize(10);
			SATextProperty->SetJustificationToCentered();
			SATextProperty->SetColor(0,0,0);
			m_Actor->m_ScalarBarActor->SetTitleTextProperty(SATextProperty);
			SATextProperty = m_Actor->m_ScalarBarActor->GetLabelTextProperty();
			SATextProperty->SetColor(0,0,0);
			m_Actor->m_ScalarBarActor->SetLabelTextProperty(SATextProperty);

#if 0
			// Segment the actor's data
			vtkSmartPointer<vtkPolyData> OldPolyData = vtkSmartPointer<vtkPolyData>::New();
			OldPolyData->DeepCopy(m_Actor->GetData(true));

			m_NewPolyData = vtkSmartPointer<vtkPolyData>::New();
			m_NewPoints = vtkSmartPointer<vtkPoints>::New();
			m_NewCells = vtkSmartPointer<vtkCellArray>::New();
			m_NewScalars = vtkSmartPointer<vtkFloatArray>::New();

			
			if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 1)
			{
				m_NewScalars->SetNumberOfComponents(1);
			}
			else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 3 )
			{
				m_NewScalars->SetNumberOfComponents(3);
			}
			else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 4 )
			{
				m_NewScalars->SetNumberOfComponents(4);
			}

			double * Point = new double[3];
			double * Scalar = new double[3];
			for( vtkIdType i = 0; i < OldPolyData->GetNumberOfPoints(); i++ )
			{
				Point = OldPolyData->GetPoint(i);

				/*if ( Point[2] > -565 && 
					Point[0] > - 92 && Point[0] < 115 &&
					Point[1] > -140 && Point[1] < 111 )*/
				if ( Point[2] > -860 )
				{			
					m_NewPoints->InsertNextPoint(Point);
					
					if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 1 )
					{
						double ScalarValue = OldPolyData->GetPointData()->GetScalars()->GetTuple1(i);
						m_NewScalars->InsertNextTuple1(ScalarValue);
					}
					else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 3 )
					{
						Scalar = OldPolyData->GetPointData()->GetScalars()->GetTuple3(i);
						m_NewScalars->InsertNextTuple3(Scalar[0],Scalar[1],Scalar[2]);
					}
					else if ( OldPolyData->GetPointData()->GetScalars()->GetNumberOfComponents() == 4 )
					{
						Scalar = OldPolyData->GetPointData()->GetScalars()->GetTuple4(i);
						m_NewScalars->InsertNextTuple4(Scalar[0],Scalar[1],Scalar[2],Scalar[3]);
					}
				}	
			}
			m_NewPolyData->SetPoints(m_NewPoints);

			for ( vtkIdType i = 0; i < m_NewPolyData->GetNumberOfPoints(); i++ )
			{
				m_NewCells->InsertNextCell(1, &i);
			}

			m_NewPolyData->GetPointData()->SetScalars(m_NewScalars);	
			m_NewPolyData->SetVerts(m_NewCells);
			m_NewPolyData->Update();

			vtkSmartPointer<vtkDelaunay2D> Delaunay = vtkSmartPointer<vtkDelaunay2D>::New();
			Delaunay->SetInput(m_NewPolyData);
			Delaunay->Update();
			m_NewPolyData = Delaunay->GetOutput();

			m_Actor->SetData(m_NewPolyData,true);
#endif
			UnlockPlugin();
		}

		// Update the GUI
		emit UpdateGUI();
	}
	else
	{
		LOG_DEB("Unknown event");
	}
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::SetPolyDataType(ritk::RImageVTKData::PolyDataType Type)
{
	m_RImageVTKData->SetPolyDataType(Type);
	//m_Actor->SetPolyDataType(Type);
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::SetVisualizationType(VTKTutorialWidget::VisualizationMode Mode, bool UseLUT)
{
	LockPlugin();

	// See below for the FRAMEDIFFERENCE mode
	m_DisplayFrameDifference = false;

	// Disable the button to display the legend by default
	m_Widget->m_DisplayLegendCheckBox->setEnabled(false);

	// Enable additional elements in the widget
	if ( Mode == VTKTutorialWidget::RGB && UseLUT )
	{
		m_Widget->m_RGBIntervalMinSpinBox->setEnabled(true);
		m_Widget->m_RGBIntervalMaxSpinBox->setEnabled(true);
		m_Widget->m_RGBIntervalClampPushButton->setEnabled(true);
		m_Widget->m_DisplayLegendCheckBox->setEnabled(true);
		m_Actor->m_ScalarBarActor->SetTitle("");
	}
	else
	{
		m_Widget->m_RGBIntervalMinSpinBox->setEnabled(false);
		m_Widget->m_RGBIntervalMaxSpinBox->setEnabled(false);
		m_Widget->m_RGBIntervalClampPushButton->setEnabled(false);
	}
	if ( Mode == VTKTutorialWidget::ZBUFFER && UseLUT )
	{
		m_Widget->m_RangeIntervalMinSpinBox->setEnabled(true);
		m_Widget->m_RangeIntervalMaxSpinBox->setEnabled(true);
		m_Widget->m_RangeIntervalClampPushButton->setEnabled(true);
		m_Widget->m_DisplayLegendCheckBox->setEnabled(true);
		m_Actor->m_ScalarBarActor->SetTitle("Depth [mm]");
	}
	else
	{
		m_Widget->m_RangeIntervalMinSpinBox->setEnabled(false);
		m_Widget->m_RangeIntervalMaxSpinBox->setEnabled(false);
		m_Widget->m_RangeIntervalClampPushButton->setEnabled(false);
	}
	if ( Mode == VTKTutorialWidget::FRAMEDIFFERENCE )
	{
		m_Widget->m_DisplayLegendCheckBox->setEnabled(true);
		m_Actor->m_ScalarBarActor->SetTitle("Error [mm]");
	}

	// Cast the widget display mode to the actual RImageActorPipeline visualization mode
	ritk::RImageActorPipeline::VisualizationMode ActorVisMode;
	if ( Mode == VTKTutorialWidget::MONOCHROME )
		ActorVisMode = ritk::RImageActorPipeline::MONOCHROME;
	else if ( Mode == VTKTutorialWidget::ZBUFFER )
		ActorVisMode = ritk::RImageActorPipeline::ZBUFFER;
	else if ( Mode == VTKTutorialWidget::RGB )
		ActorVisMode = ritk::RImageActorPipeline::RGB;
	else if ( Mode == VTKTutorialWidget::FLAGS )
		ActorVisMode = ritk::RImageActorPipeline::FLAGS;
	else if ( Mode == VTKTutorialWidget::FRAMEDIFFERENCE )
	{
		// Trick here: We use the RGB to store the difference measure. However, we need to set an additonal flag
		ActorVisMode = ritk::RImageActorPipeline::RGB;
		m_DisplayFrameDifference = true;
	}

	// Set the actual visualization mode
	m_Actor->SetVisualizationMode(ActorVisMode);
	m_Actor->UseLUT(UseLUT);

	UnlockPlugin();
}



//----------------------------------------------------------------------------
void
VTKTutorialPlugin::RangeIntervalMinChanged(double d)
{
	if ( d >= m_Widget->m_RangeIntervalMaxSpinBox->value() )
		return;

	// Straight forward
	m_Actor->SetRangeInterval(d, m_Widget->m_RangeIntervalMaxSpinBox->value());
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::RangeIntervalMaxChanged(double d)
{
	if ( d <= m_Widget->m_RangeIntervalMinSpinBox->value() )
		return;

	// Straight forward
	m_Actor->SetRangeInterval(m_Widget->m_RangeIntervalMinSpinBox->value(),d); 
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::ClampRangeInterval()
{
	LockPlugin();

	// Get the min and max value from the current frame
	typedef itk::ImageRegionConstIterator<ritk::NewFrameEvent::RImageType::WorldCoordImageType> IteratorType;
	IteratorType it(m_CurrentFrame->GetWorldCoordImage(),m_CurrentFrame->GetWorldCoordImage()->GetRequestedRegion());
	float min = 1e16;
	float max = -1e16;
	for ( it.GoToBegin(); !it.IsAtEnd(); ++it )
	{
		if ( it.Value()[2] < min )
			min = it.Value()[2];
		if ( it.Value()[2] > max )
			max = it.Value()[2];
	}
	m_Actor->SetRangeInterval(min,max);

	m_Widget->m_RangeIntervalMinSpinBox->setValue(min);
	m_Widget->m_RangeIntervalMaxSpinBox->setValue(max);

	UnlockPlugin();
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::RGBIntervalMinChanged(double d)
{
	if ( d >= m_Widget->m_RGBIntervalMaxSpinBox->value() )
		return;

	// Straight forward
	m_Actor->SetRGBInterval(d, m_Widget->m_RGBIntervalMaxSpinBox->value());
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::RGBIntervalMaxChanged(double d)
{
	if ( d <= m_Widget->m_RGBIntervalMinSpinBox->value() )
		return;

	// Straight forward
	m_Actor->SetRGBInterval(m_Widget->m_RGBIntervalMinSpinBox->value(),d); 
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::ClampRGBInterval()
{
	LockPlugin();
/** SVEN das geht jetzt nicht mehr: RGB statt gray
	// Get the min and max value from the current frame
	typedef itk::ImageRegionConstIterator<ritk::NewFrameEvent::RImageType::RangeImageType> IteratorType;
	IteratorType it(m_CurrentFrame->GetRGBImage(),m_CurrentFrame->GetRGBImage()->GetRequestedRegion());
	float min = 1e16;
	float max = -1e16;
	for ( it.GoToBegin(); !it.IsAtEnd(); ++it )
	{
		if ( it.Value() < min )
			min = it.Value();
		if ( it.Value() > max )
			max = it.Value();
	}
	m_Actor->SetGrayscaleInterval(min,max);

	m_Widget->m_RGBIntervalMinSpinBox->setValue(min);
	m_Widget->m_RGBIntervalMaxSpinBox->setValue(max);
*/
	UnlockPlugin();
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::SetCurrentFrameAsReferenceFrame()
{
	LockPlugin();

	//m_ReferenceFrame->DeepCopy(m_CurrentFrame);
  //m_ReferenceFrame->ComputeRangeToWorldCoords();

	ComputeLocalNeighborhood();

	UnlockPlugin();
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::DisplayLegend(int i)
{
	LockPlugin();

	if ( i )
		m_Actor->SetScalarBarVisibility(true);
	else
		m_Actor->SetScalarBarVisibility(false);

	UnlockPlugin();
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::SetViewMode()
{
	// Set the interactor style
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
	m_Widget->m_VisualizationWidget3D->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::SetManipulationMode()
{
	// Set the interactor style
	vtkSmartPointer<vtkInteractorStyleTrackballActor> style = vtkSmartPointer<vtkInteractorStyleTrackballActor>::New();
	m_Widget->m_VisualizationWidget3D->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);	
}


//----------------------------------------------------------------------------
void
VTKTutorialPlugin::ComputeLocalNeighborhood()
{
	// Get file name through dialog
	QString FileName = QFileDialog::getOpenFileName(m_Widget, "Open VTK poly data", "F:/Work/RITK/Data", "VTK poly data (*.vtk)");		

	// Found a valid file name
	if ( !FileName.isEmpty() ) 
	{
		// Read the poly data from file
		vtkSmartPointer<vtkPolyDataReader> Reader = vtkSmartPointer<vtkPolyDataReader>::New();
		Reader->SetFileName(FileName.toStdString().c_str());
		Reader->Update();

		vtkSmartPointer<ritk::ActorPipeline> CTActor = vtkSmartPointer<ritk::ActorPipeline>::New();
		CTActor->SetData(Reader->GetOutput());
		CTActor->SetPickable(true);
		CTActor->GetProperty()->SetColor(1,0,0);

		m_Widget->m_VisualizationWidget3D->AddActor(CTActor);

		emit UpdateGUI();
	}


#if 0
	vtkSmartPointer<vtkPolyData> Neighborhood	= vtkSmartPointer<vtkPolyData>::New();
	vtkSmartPointer<vtkPoints> Points			= vtkSmartPointer<vtkPoints>::New();
	vtkSmartPointer<vtkCellArray> Conn			= vtkSmartPointer<vtkCellArray>::New();
	vtkSmartPointer<vtkUnsignedCharArray> Color = vtkSmartPointer<vtkUnsignedCharArray>::New();
	Color->SetNumberOfComponents(3);
	
	// select a reference point from the point cloud
	unsigned int idx = 20908;
	double x[3];
	m_RImageVTKData->GetPolyData()->GetPoint(idx, x);
	
	// get points within a certain radius to the reference point	
	vtkSmartPointer<vtkPointLocator> NeighborhoodLocator = vtkSmartPointer<vtkPointLocator>::New();
	NeighborhoodLocator->SetDataSet(m_RImageVTKData->GetPolyData());
	NeighborhoodLocator->SetNumberOfPointsPerBucket(1);
	NeighborhoodLocator->BuildLocator();
	
	vtkSmartPointer<vtkIdList> NPoints = vtkSmartPointer<vtkIdList>::New();
	float m_RingRadius = 30.0f;
	NeighborhoodLocator->FindPointsWithinRadius(m_RingRadius, x, NPoints);
	
	// store points in a poly data structure
	double p[3];
	for ( int i = 0; i < NPoints->GetNumberOfIds(); i++)
	{
		m_RImageVTKData->GetPolyData()->GetPoint( NPoints->GetId(i) , p);
		Points->InsertNextPoint(p);
		Conn->InsertNextCell(1, &i);
		Color->InsertNextTuple3(255,0,0);
	}
	Neighborhood->SetPoints(Points);
	Neighborhood->SetVerts(Conn);
	Neighborhood->GetPointData()->SetScalars(Color);

	// Remove the old actors
	if ( m_NeighborhoodActor )
		m_Widget->m_VisualizationWidget3D->RemoveActor(m_NeighborhoodActor);
	if ( m_SphereActor )
		m_Widget->m_VisualizationWidget3D->RemoveActor(m_SphereActor);

	// set up render pipeline for neighborhood visualization
	vtkSmartPointer<vtkPolyDataMapper> NeighborhoodMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    NeighborhoodMapper->SetInput(Neighborhood);

    m_NeighborhoodActor = vtkSmartPointer<vtkActor>::New();
    m_NeighborhoodActor->SetMapper(NeighborhoodMapper);
	m_NeighborhoodActor->GetProperty()->SetPointSize(3.0);

	// in addition, let's render the corresponding sphere
	vtkSmartPointer<vtkSphereSource> SphereSource = vtkSmartPointer<vtkSphereSource>::New();
    SphereSource->SetCenter(x);
    SphereSource->SetRadius(m_RingRadius);
 
    vtkSmartPointer<vtkPolyDataMapper> SphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    SphereMapper->SetInput(SphereSource->GetOutput());
 
    m_SphereActor = vtkSmartPointer<vtkActor>::New();
    m_SphereActor->SetMapper(SphereMapper);
	m_SphereActor->GetProperty()->SetOpacity(0.5);

	// add actors to renderer
	m_Widget->m_VisualizationWidget3D->AddActor(m_NeighborhoodActor);
	m_Widget->m_VisualizationWidget3D->AddActor(m_SphereActor);
#endif
	return;
}

//----------------------------------------------------------------------------
void
VTKTutorialPlugin::CheckBoxStereoOnStateChanged(int State)
{
	m_Widget->m_VisualizationWidget3D->SetStereo(State);
	emit UpdateGUI();
}

void 
VTKTutorialPlugin::UpdatePointPickerGUI()
{
	m_Widget->m_LineEditP1x->setText(QString::number(m_PickPoint1[0]));
	m_Widget->m_LineEditP1y->setText(QString::number(m_PickPoint1[1]));
	m_Widget->m_LineEditP1z->setText(QString::number(m_PickPoint1[2]));

	m_Widget->m_LineEditP2x->setText(QString::number(m_PickPoint2[0]));
	m_Widget->m_LineEditP2y->setText(QString::number(m_PickPoint2[1]));
	m_Widget->m_LineEditP2z->setText(QString::number(m_PickPoint2[2]));	

	m_Widget->m_LineEditDistance->setText(QString::number(m_Distance));
}


void 
VTKTutorialPlugin::RightButtonPressEventHandling(vtkObject* caller, unsigned long vtk_event, void* client_data, void* call_data)
{
	vtkRenderWindowInteractor * iren		=	vtkRenderWindowInteractor::SafeDownCast(caller);
	vtkSmartPointer<vtkPointPicker> picker	=	vtkSmartPointer<vtkPointPicker>::New();
	vtkSmartPointer<vtkPoints> points		=	vtkSmartPointer<vtkPoints>::New();
	int event_pos[2];
	double * Point = new double[3];

	if( vtk_event == vtkCommand::RightButtonPressEvent )
	{		
		iren->GetEventPosition(event_pos);

		if(m_PickPoint1Actor)	m_PickPoint1Actor->VisibilityOff();
		if(m_PickPoint2Actor)	m_PickPoint2Actor->VisibilityOff();
		if(m_LineActor)			m_LineActor->VisibilityOff();

		picker->SetTolerance(0.5);
		if(picker->Pick(event_pos[0], event_pos[1], 0, m_Widget->m_VisualizationWidget3D->GetRenderWindow()->GetRenderers()->GetFirstRenderer() ) != 0)
		{			
			if(*(iren->GetKeySym()) == '1')
			{
				Point = picker->GetPickPosition();
				m_PickPoint1[0] = Point[0];
				m_PickPoint1[1] = Point[1];
				m_PickPoint1[2] = Point[2];

				// Remove old actor
				if(m_PickPoint1Actor) m_Widget->m_VisualizationWidget3D->RemoveActor(m_PickPoint1Actor);
	
				vtkSmartPointer<vtkSphereSource> SphereSource = vtkSmartPointer<vtkSphereSource>::New();
				SphereSource->SetCenter(m_PickPoint1);
				SphereSource->SetRadius(5);
 
				vtkSmartPointer<vtkPolyDataMapper> SphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
				SphereMapper->SetInput(SphereSource->GetOutput());
 
				m_PickPoint1Actor = vtkSmartPointer<vtkActor>::New();
				m_PickPoint1Actor->SetMapper(SphereMapper);
				m_PickPoint1Actor->GetProperty()->SetOpacity(0.8);
				m_PickPoint1Actor->GetProperty()->SetColor(0.0,0.8,0.0);

				// Add sphere actor to renderer
				m_Widget->m_VisualizationWidget3D->AddActor(m_PickPoint1Actor);				
			}
			else if(*(iren->GetKeySym()) == '2')
			{
				Point = picker->GetPickPosition();
				m_PickPoint2[0] = Point[0];
				m_PickPoint2[1] = Point[1];
				m_PickPoint2[2] = Point[2];

				// Remove old actor
				if(m_PickPoint2Actor) m_Widget->m_VisualizationWidget3D->RemoveActor(m_PickPoint2Actor);
	
				vtkSmartPointer<vtkSphereSource> SphereSource = vtkSmartPointer<vtkSphereSource>::New();
				SphereSource->SetCenter(m_PickPoint2);
				SphereSource->SetRadius(5);
 
				vtkSmartPointer<vtkPolyDataMapper> SphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
				SphereMapper->SetInput(SphereSource->GetOutput());
 
				m_PickPoint2Actor = vtkSmartPointer<vtkActor>::New();
				m_PickPoint2Actor->SetMapper(SphereMapper);
				m_PickPoint2Actor->GetProperty()->SetOpacity(0.8);
				m_PickPoint2Actor->GetProperty()->SetColor(0.0,0.0,0.8);

				// Add sphere actor to renderer
				m_Widget->m_VisualizationWidget3D->AddActor(m_PickPoint2Actor);				
			}
				

			// Plot line in between points
				 
			if( !( ((m_PickPoint1[0] == 0.0) && (m_PickPoint1[1] == 0.0) && (m_PickPoint1[2] == 0.0)) ||
				   ((m_PickPoint2[0] == 0.0) && (m_PickPoint2[1] == 0.0) && (m_PickPoint2[2] == 0.0)) ))
			{
				// Remove old actor
				if(m_LineActor) m_Widget->m_VisualizationWidget3D->RemoveActor(m_LineActor);

				//Create a vtkPoints object and store the points in it
				vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
				pts->InsertNextPoint(m_PickPoint1);
				pts->InsertNextPoint(m_PickPoint2);				

				//Setup the colors array
				vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
				colors->SetNumberOfComponents(3);
				colors->SetName("Colors");
				//Add the colors we created to the colors array				
				unsigned char black[3] = {0, 0, 0};
				colors->InsertNextTupleValue(black);

				//Create the first line (between Origin and P0)
				vtkSmartPointer<vtkLine> line0 = vtkSmartPointer<vtkLine>::New();
				line0->GetPointIds()->SetId(0,0); //the second 0 is the index of the Origin in the vtkPoints
				line0->GetPointIds()->SetId(1,1); //the second 1 is the index of P0 in the vtkPoints

				//Create a cell array to store the lines in and add the lines to it
				vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
				lines->InsertNextCell(line0);				

				//Create a polydata to store everything in
				vtkSmartPointer<vtkPolyData> linesPolyData = vtkSmartPointer<vtkPolyData>::New();
				//Add the points to the dataset
				linesPolyData->SetPoints(pts);
				//Add the lines to the dataset
				linesPolyData->SetLines(lines);

				//Color the lines - associate the first component (red) of the
				//colors array with the first component of the cell array (line 0)
				//and the second component (green) of the colors array with the
				//second component of the cell array (line 1)
				linesPolyData->GetCellData()->SetScalars(colors);

				//Setup actor and mapper
				vtkSmartPointer<vtkPolyDataMapper> mapper =	vtkSmartPointer<vtkPolyDataMapper>::New();
				mapper->SetInput(linesPolyData);

				m_LineActor = vtkSmartPointer<vtkActor>::New();
				m_LineActor->SetMapper(mapper);
				m_Widget->m_VisualizationWidget3D->AddActor(m_LineActor);
			}

			if(m_PickPoint1Actor)	m_PickPoint1Actor->VisibilityOn();
			if(m_PickPoint2Actor)	m_PickPoint2Actor->VisibilityOn();
			if(m_LineActor)			m_LineActor->VisibilityOn();

			m_Distance = sqrt(pow((m_PickPoint1[0]-m_PickPoint2[0]),2)+pow((m_PickPoint1[1]-m_PickPoint2[1]),2)+pow((m_PickPoint1[2]-m_PickPoint2[2]),2));

			UpdatePointPickerGUI();
		}
	}
}


//----------------------------------------------------------------------------
VTKTutorialPlugin::MeshType::Pointer 
VTKTutorialPlugin::vtkPolyDataToITKMesh(vtkPolyData *polyData)
{
	std::cout << "VTKPolyDataToITKMesh" << std::endl;

	// Create a new mesh
	MeshType::Pointer mesh = MeshType::New();

	// Transfer the points from the vtkPolyData into the itk::Mesh
	const unsigned int numberOfPoints = polyData->GetNumberOfPoints();
  
	vtkPoints * vtkpoints = polyData->GetPoints();

	std::cout << "	NumPoints=" << numberOfPoints << std::endl;

	mesh->GetPoints()->Reserve( numberOfPoints );
  
	for ( unsigned int p =0; p < numberOfPoints; p++ )
    {
		vtkFloatingPointType *apoint = vtkpoints->GetPoint( p );
		mesh->SetPoint(p,MeshType::PointType(apoint));
	}

	// Transfer the cells from the vtkPolyData into the itk::Mesh
	vtkCellArray * triangleStrips = polyData->GetStrips();
	vtkIdType  * cellPoints;
	vtkIdType    numberOfCellPoints;

	// First count the total number of triangles from all the triangle strips.
	unsigned int numberOfTriangles = 0;
	triangleStrips->InitTraversal();
	while ( triangleStrips->GetNextCell( numberOfCellPoints, cellPoints ) )
	{
		numberOfTriangles += numberOfCellPoints-2;
	}


	vtkCellArray * polygons = polyData->GetPolys();

	polygons->InitTraversal();

	while( polygons->GetNextCell( numberOfCellPoints, cellPoints ) )
	{
		if ( numberOfCellPoints == 3 )
		{
			numberOfTriangles ++;
		}
	}

	// Reserve memory in the itk::Mesh for all those triangles
	mesh->GetCells()->Reserve( numberOfTriangles );

	std::cout << "	NumTriangles=" << numberOfTriangles << std::endl;

  
	// Copy the triangles from vtkPolyData into the itk::Mesh
	int cellId = 0;

	// first copy the triangle strips
	triangleStrips->InitTraversal();
	while ( triangleStrips->GetNextCell( numberOfCellPoints, cellPoints ) )
	{
		unsigned int numberOfTrianglesInStrip = numberOfCellPoints - 2;

		unsigned long pointIds[3];
		pointIds[0] = cellPoints[0];
		pointIds[1] = cellPoints[1];
		pointIds[2] = cellPoints[2];

		for ( unsigned int t=0; t < numberOfTrianglesInStrip; t++ )
		{
			MeshType::CellAutoPointer c;
			TriangleCellType * tcell = new TriangleCellType;
			tcell->SetPointIds( pointIds );
			c.TakeOwnership( tcell );
			mesh->SetCell( cellId, c );
			cellId++;
			pointIds[0] = pointIds[1];
			pointIds[1] = pointIds[2];
			pointIds[2] = cellPoints[t+3];
		}
	}

	// then copy the normal triangles
	polygons->InitTraversal();
	while ( polygons->GetNextCell( numberOfCellPoints, cellPoints ) )
	{
		if ( numberOfCellPoints !=3 ) // skip any non-triangle.
		{
			continue;
		}
		MeshType::CellAutoPointer c;
		TriangleCellType * t = new TriangleCellType;
		t->SetPointIds( (unsigned long*)cellPoints );
		c.TakeOwnership( t );
		mesh->SetCell( cellId, c );
		cellId++;
	}

	return mesh;
}


//----------------------------------------------------------------------------
vtkPolyData*
VTKTutorialPlugin::ITKMeshToVtkPolyData(MeshType::Pointer mesh)
{
  //Creat a new vtkPolyData
  vtkPolyData* newPolyData = vtkPolyData::New();

  //Creat vtkPoints for insertion into newPolyData
  vtkPoints *points = vtkPoints::New();

  // std::cout<<"Points = "<<mesh->GetNumberOfPoints()<<std::endl;

  //Copy all points into the vtkPolyData structure
  PointIterator pntIterator = mesh->GetPoints()->Begin();
  PointIterator pntItEnd = mesh->GetPoints()->End();

  for (int i = 0; pntIterator != pntItEnd; ++i, ++pntIterator)
    {
      ItkPoint pnt = pntIterator.Value();
      points->InsertPoint(i, pnt[0], pnt[1], pnt[2]);
      //       std::cout<<i<<"-th point:  ";
      //       std::cout<<pnt[0]<<std::endl;
      //       std::cout<<"               "<<pntIterator.Value()<<std::endl;
      //      ++pntIterator;
    }
  newPolyData->SetPoints(points);
  points->Delete();


  //Copy all cells into the vtkPolyData structure
  //Creat vtkCellArray into which the cells are copied
  vtkCellArray* triangle = vtkCellArray::New();
  
  CellIterator cellIt = mesh->GetCells()->Begin();
  CellIterator cellItEnd = mesh->GetCells()->End();

  for (int it = 0; cellIt != cellItEnd; ++it, ++cellIt)
    {
      CellType * cellptr = cellIt.Value();
      //    LineType * line = dynamic_cast<LineType *>( cellptr );
      //    std::cout << line->GetNumberOfPoints() << std::endl;
      //      std::cout << cellptr->GetNumberOfPoints() << std::endl;

      PointIdIterator pntIdIter = cellptr->PointIdsBegin();
      PointIdIterator pntIdEnd = cellptr->PointIdsEnd();
      vtkIdList* pts = vtkIdList::New();

      for (; pntIdIter != pntIdEnd; ++pntIdIter)
        {
          pts->InsertNextId( *pntIdIter );
          //          std::cout<<"           "<<tempCell[it1]<<std::endl;
        }
      triangle->InsertNextCell(pts);
    }
  newPolyData->SetPolys(triangle);
  triangle->Delete();

  // return the vtkUnstructuredGrid
  return newPolyData;
}