Exemple #1
0
void Sector::Reset()
{
	for( unsigned int x=0; x<SECTOR_HEIGHT_SIZE*SECTOR_HEIGHT_SIZE; ++x )
	{
		zHeightMap[x] = 0.0f;
	}

	for( unsigned int x=0; x<SECTOR_BLEND_SIZE*SECTOR_BLEND_SIZE; ++x )
	{
		zBlendMap[x*4] = 1.0f;
		zBlendMap[x*4+1] = 0.0f;
		zBlendMap[x*4+2] = 0.0f;
		zBlendMap[x*4+3] = 0.0f;

		zBlendMap2[x*4] = 0.0f;
		zBlendMap2[x*4+1] = 0.0f;
		zBlendMap2[x*4+2] = 0.0f;
		zBlendMap2[x*4+3] = 0.0f;
	}

	SetTextureName(0, "TerrainTexture.png");
	SetTextureName(1, "Green.png");
	SetTextureName(2, "Blue.png");
	SetTextureName(3, "Red.png");

	SetTextureName(4, "TerrainTexture.png");
	SetTextureName(5, "Green.png");
	SetTextureName(6, "Blue.png");
	SetTextureName(7, "Red.png");

	zAmbient[0] = 0.0f;
	zAmbient[1] = 0.0f;
	zAmbient[2] = 0.0f;

	ResetNormals();

	SetEdited(false);
}
void mitk::SurfaceRefinementTool::SubdivideByPoint()
{
	std::cout << "hi from " << __FUNCSIG__ << std::endl;

	std::vector<vtkIdType> cellsToBeRemoved;
	// For all selected cells:
	for(std::vector<vtkIdType>::iterator it = m_SelectedCells.begin(); it != m_SelectedCells.end(); it++)
	{
		// Get Points of hit cell
		vtkIdType ntps, *pts;
		m_Ext->GetSurfacePolyData()->GetCellPoints(*it, ntps, pts);
		//std::cout << "Number of Points in Cell: " << ntps << "\n";
		if(ntps != 3)
			std::cout << "Error -> Triangulate!\n"; // TODO
		double pt1[3], pt2[3], pt3[3];
		m_Ext->GetSurfacePolyData()->GetPoint(pts[0], pt1);
		m_Ext->GetSurfacePolyData()->GetPoint(pts[1], pt2);
		m_Ext->GetSurfacePolyData()->GetPoint(pts[2], pt3);
		
		// Mark old cell for deletion
		cellsToBeRemoved.push_back(*it);

		// Calculate centroid of the cell
		double weightSum = 0.0;
		double centroid[3] = {0.0, 0.0, 0.0};
		std::cout << "Centroid: " << centroid[0] << " " << centroid[0] << " " << centroid[0] << "\n";

		double currentWeight12 = sqrt(vtkMath::Distance2BetweenPoints(pt1, pt2));
		double currentWeight13 = sqrt(vtkMath::Distance2BetweenPoints(pt1, pt3));
		double currentWeight23 = sqrt(vtkMath::Distance2BetweenPoints(pt2, pt3));

		centroid[0] += pt1[0] * (currentWeight12 + currentWeight13); // Produkt oder Summe der Gewichte?
		centroid[1] += pt1[1] * (currentWeight12 + currentWeight13);
		centroid[2] += pt1[2] * (currentWeight12 + currentWeight13);

		centroid[0] += pt2[0] * (currentWeight12 + currentWeight23);
		centroid[1] += pt2[1] * (currentWeight12 + currentWeight23);
		centroid[2] += pt2[2] * (currentWeight12 + currentWeight23);

		centroid[0] += pt3[0] * (currentWeight13 + currentWeight23);
		centroid[1] += pt3[1] * (currentWeight13 + currentWeight23);
		centroid[2] += pt3[2] * (currentWeight13 + currentWeight23);

		weightSum = currentWeight12 + currentWeight13 + currentWeight23;
		
		if(0)
		{
			std::cout << "Point 1: " << pt1[0] << " " << pt1[1] << " " << pt1[2] << "\n";
			std::cout << "Point 2: " << pt2[0] << " " << pt2[1] << " " << pt2[2] << "\n";
			std::cout << "Distance between two points: " << sqrt(vtkMath::Distance2BetweenPoints(pt1, pt2)) << "\n";
		}

		centroid[0] /= (weightSum * 2);
		centroid[1] /= (weightSum * 2);
		centroid[2] /= (weightSum * 2);

		// Add three new cells with new point
		vtkIdType *pts1, *pts2, *pts3, ptsNewPoint, pt1Id, pt2Id, pt3Id;
		pts1 = new vtkIdType[3];
		pts2 = new vtkIdType[3];
		pts3 = new vtkIdType[3];		

		vtkSmartPointer<vtkPolyData> newTriangles = vtkSmartPointer<vtkPolyData>::New();
		vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
		ptsNewPoint = points->InsertNextPoint(centroid[0], centroid[1], centroid[2]);
		pt1Id = points->InsertNextPoint(pt1);
		pt2Id = points->InsertNextPoint(pt2);
		pt3Id = points->InsertNextPoint(pt3);

		pts1[0] = ptsNewPoint;
		pts1[1] = pt2Id;
		pts1[2] = pt3Id; 
		pts2[0] = pt1Id;
		pts2[1] = ptsNewPoint;
		pts2[2] = pt3Id; 
		pts3[0] = pt1Id;
		pts3[1] = pt2Id;
		pts3[2] = ptsNewPoint;
		newTriangles->SetPoints ( points );
		
		newTriangles->Allocate();
		newTriangles->InsertNextCell(VTK_TRIANGLE, 3, pts1);
		newTriangles->InsertNextCell(VTK_TRIANGLE, 3, pts2);
		newTriangles->InsertNextCell(VTK_TRIANGLE, 3, pts3);

		vtkAppendPolyData *app = vtkAppendPolyData::New();
		app->AddInput(m_Ext->GetSurfacePolyData());
		app->AddInput(newTriangles);
		app->Update();
		m_Ext->SetSurfacePolyData(app->GetOutput());

		// Fill generated holes
		m_Ext->GetSurfacePolyData()->BuildCells();
		m_Ext->GetSurfacePolyData()->BuildCells();
	}

	// Forum Thread: easiest to rebuild polydata from scratch
	vtkSmartPointer<vtkPolyData> newSurface = vtkSmartPointer<vtkPolyData>::New();
	newSurface->Allocate(10000,10000); 
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	points->Allocate(10000);

	vtkCellArray* cells = m_Ext->GetSurfacePolyData()->GetPolys();
	vtkIdType *pts, npts, cellId;

	for(cellId=0, cells->InitTraversal(); cells->GetNextCell(npts,pts); cellId++)
	{
		if(!std::binary_search(cellsToBeRemoved.begin(),cellsToBeRemoved.end(), cellId))
		{
			// CellId is not deleted -> add to new mesh
			double pt1[3], pt2[3], pt3[3];
			vtkIdType t1, t2, t3;
			m_Ext->GetSurfacePolyData()->GetPoint(pts[0], pt1);
			m_Ext->GetSurfacePolyData()->GetPoint(pts[1], pt2);
			m_Ext->GetSurfacePolyData()->GetPoint(pts[2], pt3);
			
			t1 = points->InsertNextPoint(pt1);
			t2 = points->InsertNextPoint(pt2);
			t3 = points->InsertNextPoint(pt3);

			vtkIdList* newPts = vtkIdList::New();
			newPts->InsertNextId(t1);
			newPts->InsertNextId(t2);
			newPts->InsertNextId(t3);

			newSurface->SetPoints(points);			
			newSurface->InsertNextCell(VTK_TRIANGLE, newPts);
		}
		else
		{
			//std::cout << "Vector includes cell.\n";
			// add clipped part
		}
	}

	vtkSmartPointer<vtkCleanPolyData> removeDuplicatedPoints = vtkSmartPointer<vtkCleanPolyData>::New(); 
	removeDuplicatedPoints->SetInput(newSurface);
	removeDuplicatedPoints->Update();
	newSurface = removeDuplicatedPoints->GetOutput();

	m_Ext->SetSurfacePolyData(newSurface);

	ResetNormals();
	UpdateRenderer();

	std::cout << "ciao from " << __FUNCSIG__ << std::endl;
}
void mitk::SurfaceRefinementTool::SubdivideByEdge()
{
	std::cout << "hi from " << __FUNCSIG__ << std::endl;

	std::vector<vtkIdType> cellsToBeRemoved;
	// For all selected cells:
	for(std::vector<vtkIdType>::iterator it = m_SelectedCells.begin(); it != m_SelectedCells.end(); it++)
	{
		if(!std::binary_search(cellsToBeRemoved.begin(),cellsToBeRemoved.end(), *it))
		{
			std::cout << "Subdivide cell: " << *it << "\n";

			// Get Points of hit cell
			int pointDistribution;
			vtkIdType ntps, *pts, *pts2;
			m_Ext->GetSurfacePolyData()->GetCellPoints(*it, ntps, pts);
			//std::cout << "Number of Points in Cell: " << ntps << "\n";
			if(ntps != 3)
				std::cout << "Error -> Triangulate!\n"; // TODO
			double pt1[3], pt2[3], pt3[3], tmp1[3], tmp2[3], tmp3[3], pt4[3], newPt[3];
			m_Ext->GetSurfacePolyData()->GetPoint(pts[0], pt1);
			m_Ext->GetSurfacePolyData()->GetPoint(pts[1], pt2);
			m_Ext->GetSurfacePolyData()->GetPoint(pts[2], pt3);
			
			// Calculate longest edge
			double edge12 = sqrt(vtkMath::Distance2BetweenPoints(pt1, pt2));
			double edge13 = sqrt(vtkMath::Distance2BetweenPoints(pt1, pt3));
			double edge23 = sqrt(vtkMath::Distance2BetweenPoints(pt2, pt3));
			int longestEdge = 0;
			vtkIdList *otherEdge = vtkIdList::New();
			if(edge12 > edge13 && edge12> edge23)
			{
				// 1
				std::cout << "Edge 1.\n";
				pointDistribution = 1;
				newPt[0] = 0.5 * (pt1[0] + pt2[0]);
				newPt[1] = 0.5 * (pt1[1] + pt2[1]);
				newPt[2] = 0.5 * (pt1[2] + pt2[2]);
				// get other cell edge
				m_Ext->GetSurfacePolyData()->BuildLinks();	
				m_Ext->GetSurfacePolyData()->GetCellEdgeNeighbors(*it, pts[0], pts[1], otherEdge);	// get other cell
				//m_Ext->GetSurfacePolyData()->GetCellEdgeNeighbors(*it, pts[0], pts[1], otherEdge);	// get both cells
			}
			else if(edge13 > edge23)
			{
				// 2
				std::cout << "Edge 2.\n";
				pointDistribution = 2;
				newPt[0] = 0.5 * (pt1[0] + pt3[0]);
				newPt[1] = 0.5 * (pt1[1] + pt3[1]);
				newPt[2] = 0.5 * (pt1[2] + pt3[2]);
				// get other cell edge
				m_Ext->GetSurfacePolyData()->BuildLinks();
				m_Ext->GetSurfacePolyData()->GetCellEdgeNeighbors(*it, pts[0], pts[2], otherEdge);
			}
			else 
			{
				// 3
				std::cout << "Edge 3.\n";
				pointDistribution = 3;
				newPt[0] = 0.5 * (pt2[0] + pt3[0]);
				newPt[1] = 0.5 * (pt2[1] + pt3[1]);
				newPt[2] = 0.5 * (pt2[2] + pt3[2]);
				// get other cell edge
				m_Ext->GetSurfacePolyData()->BuildLinks();
				m_Ext->GetSurfacePolyData()->GetCellEdgeNeighbors(*it, pts[1], pts[2], otherEdge);
			}
				
			// Get first point
			//otherEdge->Print(std::cout);
			if(otherEdge->GetNumberOfIds() == 0)
			{
				std::cout << "Number of Edge Neighbours = 0 -> Boundary: Triangle is skipped!\n";
				continue;
			}
			if(otherEdge->GetNumberOfIds() != 1)
			{
				std::cout << "Number of Edge Neighbours = " << otherEdge->GetNumberOfIds() << " != 1 -> Error!\n";
				continue;
			}
			else
			{
				;//std::cout << "Number of Edge Neighbours = 1 -> ok!\n";
			}
			vtkIdType first = otherEdge->GetId(0);
			//vtkIdType second = otherEdge->GetId(1);

			std::cout << "Current Cell: " << *it << "\n";
			std::cout << "first: " << first << "\n";			

			// If one of the cells has already been modified don't modify
			std::cout << "Cells to be removed: ";
			for(std::vector<vtkIdType>::iterator it2 = cellsToBeRemoved.begin(); it2 != cellsToBeRemoved.end(); it2++)
			{
				std::cout << *it2 << " ";
			}
			std::cout << "\n";

			// if(std::binary_search(cellsToBeRemoved.begin(),cellsToBeRemoved.end(), *it)) -> tuts nicht
			bool skipLoop = false; 
			for(std::vector<vtkIdType>::iterator it2 = cellsToBeRemoved.begin(); it2 != cellsToBeRemoved.end(); it2++)
			{
				if(*it == *it2)
				{
					std::cout << "Cell: " << *it << " has already been modified.\n";
					skipLoop = true;
					break;
				}
				if(first == *it2)
				{						
					std::cout << "Cell: " << first << " has already been modified.\n";
					skipLoop = true;
					break;
				}	
			}
			if(skipLoop)
				continue;

			m_Ext->GetSurfacePolyData()->GetCellPoints(first, ntps, pts2);
			m_Ext->GetSurfacePolyData()->GetPoint(pts2[0], tmp1);
			m_Ext->GetSurfacePolyData()->GetPoint(pts2[1], tmp2);
			m_Ext->GetSurfacePolyData()->GetPoint(pts2[2], tmp3);

			if(!m_Ext->UniquePoint(pt1, tmp1) && !m_Ext->UniquePoint(pt2, tmp1) && !m_Ext->UniquePoint(pt3, tmp1))
			{
				pt4[0] = tmp1[0];
				pt4[1] = tmp1[1];
				pt4[2] = tmp1[2];
				std::cout << "pt4 = tmp1\n";
			}
			if(!m_Ext->UniquePoint(pt1, tmp2) && !m_Ext->UniquePoint(pt2, tmp2) && !m_Ext->UniquePoint(pt3, tmp2))
			{
				pt4[0] = tmp2[0];
				pt4[1] = tmp2[1];
				pt4[2] = tmp2[2];
				std::cout << "pt4 = tmp2\n";
			}
			if(!m_Ext->UniquePoint(pt1, tmp3) && !m_Ext->UniquePoint(pt2, tmp3) && !m_Ext->UniquePoint(pt3, tmp3))
			{
				pt4[0] = tmp3[0];
				pt4[1] = tmp3[1];
				pt4[2] = tmp3[2];
				std::cout << "pt4 = tmp3\n";
			}
			
			if(0) // print 4 points
			{
				std::cout << "P1: " << pt1[0] << " " << pt1[1] << " " << pt1[2] << "\n";
				std::cout << "P2: " << pt2[0] << " " << pt2[1] << " " << pt2[2] << "\n";
				std::cout << "P3: " << pt3[0] << " " << pt3[1] << " " << pt3[2] << "\n";
				std::cout << "P4: " << pt4[0] << " " << pt4[1] << " " << pt4[2] << "\n";
			}

			// Build 4 new triangles
			vtkSmartPointer<vtkPolyData> newTriangles = vtkSmartPointer<vtkPolyData>::New();
			vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
			vtkIdType pt1Id, pt2Id, pt3Id, pt4Id, ptNewId;

			// pointDistribution == 1 -> subdivided edge has point 1 & point 2
			// pointDistribution == 2 -> subdivided edge has point 1 & point 3
			// pointDistribution == 3 -> subdivided edge has point 2 & point 3
			// arrange point 1, point 2 and point 3 according to subdivided edge (fixed scheme)
			if(pointDistribution == 1)
			{
				std::cout << "Point distribution: 1\n";
				pt1Id = points->InsertNextPoint(pt1);
				pt2Id = points->InsertNextPoint(pt2);
				pt3Id = points->InsertNextPoint(pt3);
			}
			else if(pointDistribution == 2)
			{
				std::cout << "Point distribution: 2\n";
				pt1Id = points->InsertNextPoint(pt1);						
				pt2Id = points->InsertNextPoint(pt3);
				pt3Id = points->InsertNextPoint(pt2);
			}
			else
			{
				std::cout << "Point distribution: 3\n";
				pt1Id = points->InsertNextPoint(pt2);
				pt2Id = points->InsertNextPoint(pt3);
				pt3Id = points->InsertNextPoint(pt1);
			}

			pt4Id = points->InsertNextPoint(pt4);
			ptNewId =  points->InsertNextPoint(newPt);
			newTriangles->SetPoints(points);
			newTriangles->Allocate();

			vtkIdList* newPts1 = vtkIdList::New();
			newPts1->InsertNextId(pt1Id); newPts1->InsertNextId(pt3Id); newPts1->InsertNextId(ptNewId);			
			newTriangles->InsertNextCell(VTK_TRIANGLE, newPts1);

			vtkIdList* newPts2 = vtkIdList::New();
			newPts2->InsertNextId(pt3Id); newPts2->InsertNextId(pt2Id); newPts2->InsertNextId(ptNewId);			
			newTriangles->InsertNextCell(VTK_TRIANGLE, newPts2);

			vtkIdList* newPts3 = vtkIdList::New();
			newPts3->InsertNextId(pt2Id); newPts3->InsertNextId(pt4Id); newPts3->InsertNextId(ptNewId);			
			newTriangles->InsertNextCell(VTK_TRIANGLE, newPts3); 

			vtkIdList* newPts4 = vtkIdList::New();
			newPts4->InsertNextId(pt1Id); newPts4->InsertNextId(pt4Id); newPts4->InsertNextId(ptNewId);			
			newTriangles->InsertNextCell(VTK_TRIANGLE, newPts4);
			
			vtkAppendPolyData *app = vtkAppendPolyData::New();
			app->AddInput(m_Ext->GetSurfacePolyData());
			app->AddInput(newTriangles);
			app->Update();
			m_Ext->SetSurfacePolyData(app->GetOutput());
			
			cellsToBeRemoved.push_back(first);
			cellsToBeRemoved.push_back(*it);

			// Fill generated holes
			m_Ext->GetSurfacePolyData()->BuildCells();
			m_Ext->GetSurfacePolyData()->BuildLinks();
		}
		else
		{
			std::cout << "Cell is already subdivided, due to neighbour cells!\n";
		}
	}

	// Rebuild mesh without cells to remove
	m_Ext->GetSurfacePolyData()->BuildCells();
	m_Ext->GetSurfacePolyData()->BuildLinks();

	// make cellsToBeRemoved vector unique, if there are dublicated entries 
	std::sort(cellsToBeRemoved.begin(), cellsToBeRemoved.end());
	std::vector<vtkIdType>::iterator it;
	it = std::unique(cellsToBeRemoved.begin(), cellsToBeRemoved.end()); 
	cellsToBeRemoved.resize(it - cellsToBeRemoved.begin());  
	
	if(0) // printing
	{
		std::cout << "Vector.size: (2) " << cellsToBeRemoved.size() << "\n";
		for(std::vector<vtkIdType>::iterator it = cellsToBeRemoved.begin(); it != cellsToBeRemoved.end(); it++)
		{
			std::cout << "Entries: " << *it << "\n";
		}
	}

	// Forum Thread: easiest to rebuild polydata from scratch
	vtkSmartPointer<vtkPolyData> newSurface = vtkSmartPointer<vtkPolyData>::New();
	newSurface->Allocate(10000,10000); 
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	points->Allocate(10000);

	vtkCellArray* cells = m_Ext->GetSurfacePolyData()->GetPolys();
	vtkIdType *pts, npts, cellId;

	for(cellId=0, cells->InitTraversal(); cells->GetNextCell(npts,pts); cellId++)
	{
		if(!std::binary_search(cellsToBeRemoved.begin(),cellsToBeRemoved.end(), cellId))
		{
			// CellId is not deleted -> add to new mesh
			double pt1[3], pt2[3], pt3[3];
			vtkIdType t1, t2, t3;
			m_Ext->GetSurfacePolyData()->GetPoint(pts[0], pt1);
			m_Ext->GetSurfacePolyData()->GetPoint(pts[1], pt2);
			m_Ext->GetSurfacePolyData()->GetPoint(pts[2], pt3);
			
			t1 = points->InsertNextPoint(pt1);
			t2 = points->InsertNextPoint(pt2);
			t3 = points->InsertNextPoint(pt3);

			vtkIdList* newPts = vtkIdList::New();
			newPts->InsertNextId(t1);
			newPts->InsertNextId(t2);
			newPts->InsertNextId(t3);

			newSurface->SetPoints(points);			
			newSurface->InsertNextCell(VTK_TRIANGLE, newPts);
		}
		else
		{
			//std::cout << "Vector includes cell.\n";
			// add clipped part
		}
	}

	vtkSmartPointer<vtkCleanPolyData> removeDuplicatedPoints = vtkSmartPointer<vtkCleanPolyData>::New(); 
	removeDuplicatedPoints->SetInput(newSurface);
	removeDuplicatedPoints->Update();
	newSurface = removeDuplicatedPoints->GetOutput();

	m_Ext->SetSurfacePolyData(newSurface);

	ResetNormals();

	std::cout << "ciao from " << __FUNCSIG__ << std::endl;
}