ITK 实例 (四)

ITK 官方网址:https://itk.org/ITK/project/project.html

(四)ITK 中的网格

 itk::Mesh 类用来表示空间中的形状。它派生自 itk::PoitnSet 类,因此它集成了与点相关的所有功能以及与点相关的所有像素数据的访问。网格类是 N 维的,它具有很大的灵活性。在实际应用中,网格类也可以被看作是一个点集,其中添加了许多不同维度和形状的单元格。其中,由于网格需要大量的内存,所以需要用 itk::SmartPointers 进行管理。

 (1)创建网格

#include "itkMesh.h"

int main()
{
	using PixelType = float;
	constexpr unsigned int Dimension = 3;

	using MeshType = itk::Mesh<PixelType, Dimension>;
	MeshType::Pointer mesh = MeshType::New();  

	MeshType::PointType p0;
	MeshType::PointType p1;
	MeshType::PointType p2;
	MeshType::PointType p3;

	p0[0] = -1.0; p0[1] = -1.0; p0[2] = 0.0; // 第一个点{-1,-1,0}
	p1[0] = 1.0; p1[1] = -1.0; p1[2] = 0.0;  //第二个点{1,-1,0}
	p2[0] = 1.0; p2[1] = 1.0; p2[2] = 0.0;   //第三个点{1,1,0}
	p3[0] = -1.0; p3[1] = 0.0; p3[2] = 0.0;  // 第四个点{-1,1,0}

	mesh->SetPoint(0, p0);
	mesh->SetPoint(1, p1);
	mesh->SetPoint(2, p2);
	mesh->SetPoint(3, p3);

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

	using PointsIterator = MeshType::PointsContainer::Iterator;
	PointsIterator pointIterator = mesh->GetPoints()->Begin();
	PointsIterator pointEnd = mesh->GetPoints()->End();
	while (pointIterator != pointEnd)
	{
		MeshType::PointType p = pointIterator.Value();
		std::cout << p << std::endl;
		++pointIterator;
	}
	return EXIT_SUCCESS;
}

(2)插入单元

itk::Mesh 可以包含多种类型的单元格,典型的单元类型有:itk::LineCell,itk::TriangleCell,itk::QuadrilateralCell,itk::TetrahedronCell,itk::PolygonCell

网格管理单元和管理点的区别在于,点时以复制的方式存储在点容器(PointContainer)中的,而单元是以指针的形式存储在单元容器中(CellContainer)的。

下面的实例通过建立一条多边形线,案例说明网格中是如何管理最简单的线单元的。

#include "itkMesh.h"
#include "itkLineCell.h"

int main()
{
	using PixelType = float;
	using MeshType = itk::Mesh<PixelType, 3>;

	using CellType = MeshType::CellType;
	using LineType = itk::LineCell<CellType>;
	using CellAutoPointer = CellType::CellAutoPointer;  //

	MeshType::Pointer mesh = MeshType::New();
	MeshType::PointType p0;
	MeshType::PointType p1;
	MeshType::PointType p2;

	p0[0] = -1.0; p0[1] = 0.0; p0[2] = 0.0;  //第一个点{-1,0,0}
	p1[0] = 1.0; p1[1] = 0.0; p1[2] = 0.0; //第二个点{1,0,0}
	p2[0] = 1.0; p2[1] = 1.0; p2[2] = 0.0; //第三个点{1,1,0}

	mesh->SetPoint(0, p0);
	mesh->SetPoint(1, p1);
	mesh->SetPoint(2, p2);

	CellAutoPointer line0;
	CellAutoPointer line1;
	line0.TakeOwnership(new LineType);
	line1.TakeOwnership(new LineType);

	line0->SetPointId(0, 0);
	line0->SetPointId(1, 1);  //点 0 ,1 之间的线

	line1->SetPointId(0, 1);
	line1->SetPointId(1, 2);  //点 1,2 之间的线

	mesh->SetCell(0, line0);
	mesh->SetCell(1, line1);

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

	using CellIterator = MeshType::CellsContainer::Iterator;
	CellIterator cellIterator = mesh->GetCells()->Begin();
	CellIterator cellEnd = mesh->GetCells()->End();

	while (cellIterator != cellEnd)
	{
		MeshType::CellType * cellptr = cellIterator.Value();
		auto * line = dynamic_cast<LineType *>(cellptr);
		if (line == nullptr)
		{
			continue;
		}
		std::cout << line->GetNumberOfPoints() << std::endl;  //两个线单元,每个单元有两个点
		++cellIterator;
	}

	return EXIT_SUCCESS;
}

(3) 管理单元格中的数据

#include "itkMesh.h"
#include "itkLineCell.h"

int main()
{
	using PixelType = float;
	using MeshType = itk::Mesh<PixelType, 2>;

	using CellType = MeshType::CellType;
	using LineType = itk::LineCell<CellType>;

	MeshType::Pointer mesh = MeshType::New();
	using PointType = MeshType::PointType;
	PointType point;

	constexpr unsigned int numberOfPoints = 10;
	for (unsigned int id = 0; id < numberOfPoints; id++)
	{
		point[0] = static_cast<PointType::ValueType>(id);
		point[1] = std::log(static_cast<double>(id) + itk::Math::eps);
		mesh->SetPoint(id, point);
	}

	CellType::CellAutoPointer line;
	const unsigned int numberOfCells = numberOfPoints - 1;
	for (unsigned int cellId = 0; cellId < numberOfCells; cellId++)
	{
		line.TakeOwnership(new LineType);
		line->SetPointId(0, cellId);
		line->SetPointId(1, cellId + 1);
		mesh->SetCell(cellId, line);
	}

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

	for (unsigned int cellId = 0; cellId < numberOfCells; cellId++)
	{
		mesh->SetCellData(cellId, static_cast<PixelType>(cellId * cellId));
	}

	for (unsigned int cellId = 0; cellId < numberOfCells; cellId++)
	{
		auto value = static_cast<PixelType>(0.0);
		mesh->GetCellData(cellId, &value);
		std::cout << "Cell" << cellId << " = " << value << std::endl;
	}

	using CellDataIterator = MeshType::CellDataContainer::ConstIterator;
	CellDataIterator cellDataIterator = mesh->GetCellData()->Begin();
	CellDataIterator end = mesh->GetCellData()->End();

	while (cellDataIterator != end)
	{
		PixelType cellValue = cellDataIterator.Value();
		std::cout << cellValue << std::endl;
		++cellDataIterator;
	}

	return EXIT_SUCCESS;

}

(4)自定义网格 

自定义网格有两种方法,一种是使用现成的类 “itk::DefaultStaticMeshTraits.h” ,并通过修改里面的 六个参数类型来设置。参数包括 PixelType,PointDimension,MaxTopologicalDimension,CoordinateType,InterpolationWeightType,CellDataTYpe,这些参数的顺序不可以改变。

另外一种方法是将上述类 “itk::DefaultStaticMeshTraits.h” 文件复制到其他文件中进行修改,但是一般不建议这样做。

#include "itkMesh.h"
#include "itkDefaultStaticMeshTraits.h"
#include "itkLineCell.h"
#include "itkVector.h"
#include "itkMatrix.h"

int main()
{
	constexpr unsigned int PointDimension = 3;
	constexpr unsigned int MaxTopologicalDimension = 2;

	using PixelType = itk::Vector<double, 4>;
	using CellDataType = itk::Matrix<double, 4, 3>;

	using CoordinateType = double;
	using InterpolationWeightType = double;

	using MeshTraits = itk::DefaultStaticMeshTraits<PixelType,
		PointDimension, MaxTopologicalDimension, CoordinateType,
		InterpolationWeightType, CellDataType>;

	using MeshType = itk::Mesh<PixelType, PointDimension, MeshTraits>;

	using CellType = MeshType::CellType;
	using LineType = itk::LineCell<CellType>;

	MeshType::Pointer mesh = MeshType::New();

	using PointType = MeshType::PointType;
	PointType point;

	constexpr unsigned int numberOfPoints = 10;
	for (unsigned int id = 0; id < numberOfPoints; id++)
	{
		point[0] = 1.565;
		point[1] = 3.647;
		point[2] = 4.129;
		mesh->SetPoint(id, point);
	}

	CellType::CellAutoPointer line;
	const unsigned int numberOfCells = numberOfPoints - 1;
	for (unsigned int cellId = 0; cellId < numberOfCells; cellId++)
	{
		line.TakeOwnership(new LineType);
		line->SetPointId(0, cellId);
		line->SetPointId(1, cellId + 1);
		mesh->SetCell(cellId, line);
	}

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

	for (unsigned int cellId = 0; cellId < numberOfCells; cellId++)
	{
		CellDataType value;
		mesh->SetCellData(cellId, value);
	}

	for (unsigned int cellId = 0; cellId < numberOfCells; cellId++)
	{
		CellDataType value;
		mesh->GetCellData(cellId, &value);
		std::cout << "Cell" << cellId << " = \n" << value << std::endl;
	}

	using CellDataIterator = MeshType::CellDataContainer::ConstIterator;
	CellDataIterator cellDataIterator = mesh->GetCellData()->Begin();
	CellDataIterator end = mesh->GetCellData()->End();

	while (cellDataIterator != end)
	{
		CellDataType cellValue = cellDataIterator.Value();
		std::cout << cellValue << std::endl;
		++cellDataIterator;
	}

	return EXIT_SUCCESS;
}

(5)拓扑与 K-Complex

itk::Mesh 类支持拓扑结构的表示。K-Complex 是一种拓扑结构,其中对于维度为 N 的每个单元,其边界面(维度为 N-1 的单元)也属于该结构。

下面的程序说明如何使用网格实例化 K-Compex 结构,示例结构由一个四面体、四个三角形面、六条边线、四个顶点组成。要理解点(points)和点单元(vertexCell)的区别。点单元可以感知其他单元类型,而点则不行。从拓扑的角度来看,点可以完全不存在于网格结构中,而点单元是表示 K-Complex 结构上完整的邻域关系所必需的的。

#include "itkMesh.h"
#include "itkLineCell.h"
#include "itkTetrahedronCell.h"

int main()
{
	using PixelType = float;
	using MeshType = itk::Mesh<PixelType, 3>;

	using CellType = MeshType::CellType;
	using VertexType = itk::VertexCell<CellType>;
	using LineType = itk::LineCell<CellType>;
	using TriangleType = itk::TriangleCell<CellType>;
	using TetrahedronType = itk::TetrahedronCell<CellType>;

	MeshType::Pointer mesh = MeshType::New();
	MeshType::PointType point0;
	MeshType::PointType point1;
	MeshType::PointType point2;
	MeshType::PointType point3;

	point0[0] = -1; point0[1] = -1; point0[2] = -1;
	point1[0] = 1; point1[1] = 1; point1[2] = -1;
	point2[0] = 1; point2[1] = -1; point2[2] = 1;
	point3[0] = -1; point3[1] = 1; point3[2] = 1;

	mesh->SetPoint(0, point0);
	mesh->SetPoint(1, point1);
	mesh->SetPoint(2, point2);
	mesh->SetPoint(3, point3);

	CellType::CellAutoPointer cellpointer;
	//创建四面体单元
	cellpointer.TakeOwnership(new TetrahedronType);  
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	cellpointer->SetPointId(3, 3);
	mesh->SetCell(0, cellpointer);

	//创建四个三角形面单元
	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);  //连接点 0,1,2
	mesh->SetCell(1, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 3);  //连接点 0,2,3
	mesh->SetCell(2, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 3);
	cellpointer->SetPointId(2, 1);  //连接点 0,3,1
	mesh->SetCell(3, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(4, cellpointer);

	//创建六个线单元
	cellpointer.TakeNoOwnership(new LineType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	mesh->SetCell(5, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(6, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 2);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(7, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 3);
	mesh->SetCell(8, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(9, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(10, cellpointer);

	//创建四点顶点单元
	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 0);
	mesh->SetCell(11, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 1);
	mesh->SetCell(12, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 2);
	mesh->SetCell(13, cellpointer);

	cellpointer.TakeNoOwnership(new VertexType);
	cellpointer->SetPointId(0, 3);
	mesh->SetCell(14, cellpointer);

	std::cout << "# Points = " << mesh->GetNumberOfPoints() << std::endl;
	std::cout << "# Cell = " << mesh->GetNumberOfCells() << std::endl;

	using PointIterator = MeshType::PointsContainer::ConstIterator;
	PointIterator pointIterator = mesh->GetPoints()->Begin();
	PointIterator pointEnd = mesh->GetPoints()->End();
	std::cout << "=========================================" << std::endl;
	while (pointIterator != pointEnd)
	{
		std::cout << pointIterator.Value() << std::endl;
		++pointIterator;
	}

	using CellIterator = MeshType::CellsContainer::ConstIterator;
	CellIterator cellIterator = mesh->GetCells()->Begin();
	CellIterator cellEnd = mesh->GetCells()->End();
	std::cout << "=========================================" << std::endl;
	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		std::cout << cell->GetNumberOfPoints() << std::endl;
		++cellIterator;
	}

	cellIterator = mesh->GetCells()->Begin();
	cellEnd = mesh->GetCells()->End();

	std::cout << "=========================================" << std::endl;
	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		std::cout << "cell with " << cell->GetNumberOfPoints();
		std::cout << " points" << std::endl;

		using PointIdIterator = CellType::PointIdIterator;
		PointIdIterator pointIditer = cell->PointIdsBegin();
		PointIdIterator pointIdend = cell->PointIdsEnd();
		
		while (pointIditer != pointIdend)
		{
			std::cout << *pointIditer << std::endl;
			++pointIditer;
		}
		++cellIterator;
	}

	//单元格间邻域关系的定义
	MeshType::CellIdentifier cellId = 0;  // 四面体单元
	int dimension = 0;  //单元类型维度为 0,点单元
	MeshType::CellFeatureIdentifier featureId = 0;
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 11);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 12);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 13);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 14);

	cellId = 0;  //四面体单元
	dimension = 1;   // 边界特征,维度为 1 的线单元
	featureId = 0;
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 5);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 6);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 7);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 8);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 9);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 10);

	cellId = 0;  //四面体单元
	dimension = 2; //边界特征,维度为 2 的面单元
	featureId = 0;
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 1);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 2);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 3);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 4);

	cellId = 0;  //四面体作为对象
	MeshType::CellFeatureCount n0;  //零维特征的数量
	MeshType::CellFeatureCount n1;  //一维特征的数量
	MeshType::CellFeatureCount n2;  //二维特征的数量

	n0 = mesh->GetNumberOfCellBoundaryFeatures(0, cellId);
	n1 = mesh->GetNumberOfCellBoundaryFeatures(1, cellId);
	n2 = mesh->GetNumberOfCellBoundaryFeatures(1, cellId);

	std::cout << "=========================================" << std::endl;
	std::cout << "Boundary features of dimension 0" << std::endl;
	dimension = 0;
	for (unsigned int b0 = 0; b0 < n0; b0++)
	{
		MeshType::CellIdentifier id;
		bool found = mesh->GetBoundaryAssignment(dimension, cellId, b0, &id);
		if (found)
			std::cout << id << std::endl;
	}

	std::cout << "=========================================" << std::endl;
	std::cout << "Boundary features of dimension 1" << std::endl;
	dimension = 1;
	for (unsigned int b1 = 0; b1 < n1; b1++)
	{
		MeshType::CellIdentifier id;
		bool found = mesh->GetBoundaryAssignment(dimension, cellId, b1, &id);
		if (found)
			std::cout << id << std::endl;
	}

	std::cout << "=========================================" << std::endl;
	std::cout << "Boundary features of dimension 2" << std::endl;
	dimension = 2;
	for (unsigned int b2 = 0; b2 < n2; b2++)
	{
		MeshType::CellIdentifier id;
		bool found = mesh->GetBoundaryAssignment(dimension, cellId, b2, &id);
		if (found)
			std::cout << id << std::endl;
	}

	cellId = 2;  // 2 号面单元
	dimension = 1; // 边界维度
	featureId = 0;

	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 7);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 9);
	mesh->SetBoundaryAssignment(dimension, cellId, featureId++, 10);

	std::cout << "=========================================" << std::endl;
	std::cout << "In cell Id = " << cellId << std::endl;
	std::cout << "Boundary features of dimension " << dimension;
	n1 = mesh->GetNumberOfCellBoundaryFeatures(dimension, cellId);
	std::cout << " = " << n1 << std::endl;

	std::cout << "=========================================" << std::endl;
	for (unsigned int b1 = 0; b1 < n1; b1++)
	{
		MeshType::CellIdentifier id;
		bool found = mesh->GetBoundaryAssignment(dimension, cellId, b1, &id);
		if (found)
			std::cout << id << std::endl;
	}

	return EXIT_SUCCESS;
}

(6) 折线表示

下面的示例展示了如何使用 itk::Mesh 表示经典的多线段结构。折线只涉及零维和一维单元,即 itk::VertexCell,itk::LineCell,但是这种情况下空间的维数应该是 2。 下面的例子将创建三条边形成一条多线段,连接四个顶点,围成一个类似于正方形的形状。

#include "itkMesh.h"
#include "itkLineCell.h"

int main()
{
	using PixelType = float;
	using MeshType = itk::Mesh<PixelType, 2>;

	using CellType = MeshType::CellType;
	using VertexType = itk::VertexCell<CellType>;
	using LineType = itk::LineCell<CellType>;

	MeshType::Pointer mesh = MeshType::New();
	MeshType::PointType point0;
	MeshType::PointType point1;
	MeshType::PointType point2;
	MeshType::PointType point3;

	point0[0] = -1; point0[1] = -1;
	point1[0] = 1; point1[1] = -1;
	point2[0] = 1; point2[1] = 1;
	point3[0] = -1; point3[1] = 1;

	mesh->SetPoint(0, point0);
	mesh->SetPoint(1, point1);
	mesh->SetPoint(2, point2);
	mesh->SetPoint(3, point3);

	CellType::CellAutoPointer cellpointer;
	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	mesh->SetCell(0, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(1, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 2);
	cellpointer->SetPointId(1, 3);
	mesh->SetCell(2, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 0);
	mesh->SetCell(3, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 1);
	mesh->SetCell(4, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 2);
	mesh->SetCell(5, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 3);
	mesh->SetCell(6, cellpointer);

	std::cout << "==============================" << std::endl;
	std::cout << "# points = " << mesh->GetNumberOfPoints() << std::endl;
	std::cout << "# cell = " << mesh->GetNumberOfCells() << std::endl;

	using PointIterator = MeshType::PointsContainer::ConstIterator;
	PointIterator pointIterator = mesh->GetPoints()->Begin();
	PointIterator pointEnd = mesh->GetPoints()->End();
	std::cout << "==============================" << std::endl;
	while (pointIterator != pointEnd)
	{
		std::cout << pointIterator.Value() << std::endl;
		++pointIterator;
	}

	using CellIterator = MeshType::CellsContainer::ConstIterator;
	CellIterator cellIterator = mesh->GetCells()->Begin();
	CellIterator cellEnd = mesh->GetCells()->End();
	std::cout << "==============================" << std::endl;
	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		std::cout << cell->GetNumberOfPoints() << std::endl;
		++cellIterator;
	}

	cellIterator = mesh->GetCells()->Begin();
	cellEnd = mesh->GetCells()->End();
	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		std::cout << "==============================" << std::endl;
		std::cout << "cell with " << cell->GetNumberOfPoints();
		std::cout << " points " << std::endl;

		using PointIdIterator = CellType::PointIdIterator;
		PointIdIterator pointIditer = cell->PointIdsBegin();
		PointIdIterator pointend = cell->PointIdsEnd();

		while (pointIditer != pointend)
		{
			std::cout << *pointIditer << std::endl;
			++pointIditer;
		}
		++cellIterator;
	}
	return EXIT_SUCCESS;
}

(7) 简化网格创建

利用 itk::AutomaticTopologyMeshSource 类 可以根据你添加的单元格自动生成一个 K-Complex 结构。它显式地包含所有边界特征,因此可以轻松地遍历生成的网格。它合并了所有共享的边、顶点、面等,因此不会有几何特征出现一次以上。

#include "itkTriangleCell.h"
#include "itkAutomaticTopologyMeshSource.h"

int main()
{
	using PixelType = float;
	using MeshType = itk::Mesh<PixelType, 3>;

	using PointType = MeshType::PointType;
	using MeshSourceType = itk::AutomaticTopologyMeshSource<MeshType>;
	using IdentifierArrayType = MeshSourceType::IdentifierArrayType;

	MeshSourceType::Pointer meshSource;

	meshSource = MeshSourceType::New();
	meshSource->AddTetrahedron
	(
		meshSource->AddPoint(-1, -1, -1),
		meshSource->AddPoint(1, 1, -1),
		meshSource->AddPoint(1, -1, 1),
		meshSource->AddPoint(-1, 1, 1)
	);

	PointType p;
	IdentifierArrayType idArray(4);

	p[0] = -2;
	p[1] = -2;
	p[2] = -2;
	idArray[0] = meshSource->AddPoint(p);

	p[0] = 2;
	p[1] = 2;
	p[2] = -2;
	idArray[1] = meshSource->AddPoint(p);

	p[0] = 2;
	p[1] = -2;
	p[2] = 2;
	idArray[2] = meshSource->AddPoint(p);

	p[0] = -2;
	p[1] = 2;
	p[2] = 2;
	idArray[3] = meshSource->AddPoint(p);

	meshSource->AddTriangle(idArray[0], idArray[1], idArray[2]);
	meshSource->AddTriangle(idArray[1], idArray[2], idArray[3]);
	meshSource->AddTriangle(idArray[2], idArray[3], idArray[0]);
	meshSource->AddTriangle(idArray[3], idArray[0], idArray[1]);

	MeshType::Pointer mesh = meshSource->GetOutput();  //GetOutPut 不会触发更新过程
	std::cout << mesh << std::endl;

	return EXIT_SUCCESS;
}

(8)遍历单元格

#include "itkMesh.h"
#include "itkLineCell.h"
#include "itkTetrahedronCell.h"

int main()
{
	using PixelType = float;
	using MeshType = itk::Mesh<PixelType, 3>;
	using CellType = MeshType::CellType;

	using VertexType = itk::VertexCell<CellType>;
	using LineType = itk::LineCell<CellType>;
	using TriangleType = itk::TriangleCell<CellType>;
	using TetrahedronType = itk::TetrahedronCell<CellType>;
	
	MeshType::Pointer mesh = MeshType::New();
	MeshType::PointType point0;
	MeshType::PointType point1;
	MeshType::PointType point2;
	MeshType::PointType point3;

	point0[0] = -1; point0[1] = -1; point0[2] = -1;
	point1[0] = 1; point1[1] = 1; point1[2] = -1;
	point2[0] = 1; point2[1] = -1; point2[2] = 1;
	point3[0] = -1; point3[1] = 1; point3[2] = 1;

	mesh->SetPoint(0, point0);
	mesh->SetPoint(1, point1);
	mesh->SetPoint(2, point2);
	mesh->SetPoint(3, point3);

	CellType::CellAutoPointer cellpointer;
	//创建四面体单元
	cellpointer.TakeOwnership(new TetrahedronType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	cellpointer->SetPointId(3, 3);
	mesh->SetCell(0, cellpointer);

	//创建三角面单元
	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	mesh->SetCell(1, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 3);
	mesh->SetCell(2, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 3);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(3, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(4, cellpointer);

	//创建边线单元
	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	mesh->SetCell(5, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(6, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 2);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(7, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 3);
	mesh->SetCell(8, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(9, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(10, cellpointer);

	//创建点单元
	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 0);
	mesh->SetCell(11, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 1);
	mesh->SetCell(12, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 2);
	mesh->SetCell(13, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 3);
	mesh->SetCell(14, cellpointer);

	std::cout << "====================" << std::endl;
	std::cout << "# points = " << mesh->GetNumberOfPoints() << std::endl;
	std::cout << "# cell = " << mesh->GetNumberOfCells() << std::endl;

	using  CellIterator = MeshType::CellsContainer::ConstIterator;
	CellIterator cellIterator = mesh->GetCells()->Begin();
	CellIterator cellEnd = mesh->GetCells()->End();

	std::cout << "====================" << std::endl;
	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		std::cout << cell->GetNumberOfPoints() << std::endl;
		++cellIterator;
	}

	std::cout << "====================" << std::endl;
	std::cout << "Visiting the Line cells: " << std::endl;
	cellIterator = mesh->GetCells()->Begin();
	cellEnd = mesh->GetCells()->End();

	std::cout << "====================" << std::endl;
	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		if (cell->GetType() == CellType::LINE_CELL)
		{
			auto *line = static_cast<LineType *>(cell);
			std::cout << "dimension = " << line->GetDimension() << std::endl;
			std::cout << "# points = " << line->GetNumberOfPoints() << std::endl;
		}
		++cellIterator;
	}

	std::cout << "====================" << std::endl;
	std::cout << "Visiting several celltypes: " << std::endl;
	cellIterator = mesh->GetCells()->Begin();
	cellEnd = mesh->GetCells()->End();

	while (cellIterator != cellEnd)
	{
		CellType *cell = cellIterator.Value();
		switch (cell->GetType())
		{
		case CellType::VERTEX_CELL:
			{
				std::cout << "VertexCell: " << std::endl;
				auto *line = dynamic_cast<VertexType *>(cell);
				std::cout << " dimension = " << line->GetDimension() << std::endl;
				std::cout << " # points = " << line->GetNumberOfPoints() << std::endl;
				break;
			}

		case CellType::LINE_CELL:
		{
			std::cout << "LineCell : " << std::endl;
			auto * line = dynamic_cast<LineType *>(cell);
			std::cout << "dimension = " << line->GetDimension() << std::endl;
			std::cout << "# points  = " << line->GetNumberOfPoints() << std::endl;
			break;
		}

		case CellType::TRIANGLE_CELL:
		{
			std::cout << "TriangleCell : " << std::endl;
			auto * line = dynamic_cast<TriangleType *>(cell);
			std::cout << "dimension = " << line->GetDimension() << std::endl;
			std::cout << "# points  = " << line->GetNumberOfPoints() << std::endl;
			break;
		}
		default:
		{
			std::cout << "Cell with more than three points:" << std::endl;
			std::cout << "dimension = " << cell->GetDimension() << std::endl;
			std::cout << "# points  = " << cell->GetNumberOfPoints() << std::endl;
			break;
		}
		}
		++cellIterator;
	}

	return EXIT_SUCCESS;
}

(9)访问单元

需要自定义 CellVisitor 类。对这个的要求是必须提供名为 Visit( ) 的函数。

#include "itkMesh.h"
#include "itkLineCell.h"
#include "itkTetrahedronCell.h"
#include "itkCellInterfaceVisitor.h"

using PixelType = float;
using MeshType = itk::Mesh<PixelType, 3>;
using CellType = MeshType::CellType;
using VertexType = itk::VertexCell<CellType>;
using LineType = itk::LineCell<CellType>;
using TriangleType = itk::TriangleCell<CellType>;
using TetrahedronType = itk::TetrahedronCell<CellType>;

#ifndef _CUSTONTRIANGLEVISITOR
#define _CUSTONTRIANGLEVISITOR

class CustomTriangleVisitor
{
public:
	void Visit(unsigned long cellId, TriangleType*t)
	{
		std::cout << "Cell # " << cellId << " is a TriangleType, ";
		std::cout << " and number of Points: " << t->GetNumberOfPoints() << std::endl;
	}
	CustomTriangleVisitor() = default;
	virtual ~CustomTriangleVisitor() = default;
};

#endif //_CUSTONTRIANGLEVISITOR

int main()
{
	MeshType::Pointer mesh = MeshType::New();
	MeshType::PointType point0;
	MeshType::PointType point1;
	MeshType::PointType point2;
	MeshType::PointType point3;

	point0[0] = -1; point0[1] = -1; point0[2] = -1;
	point1[0] = 1; point1[1] = 1; point1[2] = -1;
	point2[0] = 1; point2[1] = -1; point2[2] = 1;
	point3[0] = -1; point3[1] = 1; point3[2] = 1;

	mesh->SetPoint(0, point0);
	mesh->SetPoint(1, point1);
	mesh->SetPoint(2, point2);
	mesh->SetPoint(3, point3);

	//创建四面体单元
	CellType::CellAutoPointer cellpointer;

	cellpointer.TakeOwnership(new TetrahedronType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	cellpointer->SetPointId(3, 3);
	mesh->SetCell(0, cellpointer);

	//创建三角面单元
	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	mesh->SetCell(1, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 3);
	mesh->SetCell(2, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 3);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(3, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(4, cellpointer);

	//创建边线单元
	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	mesh->SetCell(5, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(6, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 2);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(7, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 3);
	mesh->SetCell(8, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(9, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(10, cellpointer);

	//创建顶点单元
	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 0);
	mesh->SetCell(11, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 1);
	mesh->SetCell(12, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 2);
	mesh->SetCell(13, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 3);
	mesh->SetCell(14, cellpointer);

	//输出点和单元的个数
	std::cout << "=========================" << std::endl;
	std::cout << "# Points = " << mesh->GetNumberOfPoints() << std::endl;
	std::cout << "# Cell  = " << mesh->GetNumberOfCells() << std::endl;

	using TriangleVisitorInterfaceType =
		itk::CellInterfaceVisitorImplementation
		<
		PixelType,
		MeshType::CellTraits,
		TriangleType,
		CustomTriangleVisitor
		>;

	TriangleVisitorInterfaceType::Pointer triangleVisitor =
		TriangleVisitorInterfaceType::New();

	using CellMultiVisitorType = CellType::MultiVisitor;
	CellMultiVisitorType::Pointer multiVisitor = CellMultiVisitorType::New();
	multiVisitor->AddVisitor(triangleVisitor);
	mesh->Accept(multiVisitor);

	return EXIT_SUCCESS;
}

 (10)有关访问单元格的详细信息

#include "itkMesh.h"
#include "itkLineCell.h"
#include "itkTetrahedronCell.h"
#include "itkCellInterfaceVisitor.h"

using PixelType = float;
using MeshType = itk::Mesh<PixelType, 3>;
using CellType = MeshType::CellType;
using VertexType = itk::VertexCell<CellType>;
using LineType = itk::LineCell<CellType>;
using TriangleType = itk::TriangleCell<CellType>;
using TetrahedronType = itk::TetrahedronCell<CellType>;

class CustomVertexVisitor
{
public:
	void Visit(unsigned long cellId, VertexType *t)
	{
		std::cout << "==============================" << std::endl;
		std::cout << "cell " << cellId << " is a Vertex " << std::endl;
		std::cout << "associated with point id = ";
		std::cout << t->GetPointId() << std::endl;
	}
	virtual ~CustomVertexVisitor() = default;
};

class CustomLineVisitor
{
public:
	CustomLineVisitor() : m_Mesh(nullptr) {};
	virtual ~CustomLineVisitor() = default;

	void SetMesh(MeshType *mesh) { m_Mesh = mesh; }

	void Visit(unsigned long cellId, LineType *t)
	{
		std::cout << "==============================" << std::endl;
		std::cout << "cell " << cellId << " is a Line " << std::endl;
		LineType::PointIdIterator pit = t->PointIdsBegin();
		MeshType::PointType p0;
		MeshType::PointType p1;
		m_Mesh->GetPoint(*pit++, &p0);
		m_Mesh->GetPoint(*pit++, &p1);
		const double length = p0.EuclideanDistanceTo(p1);
		std::cout << "length = " << length << std::endl;
	}

private:
	MeshType::Pointer m_Mesh;
};

#ifndef _CustomTriangleVisitor
#define _CustomTriangleVisitor

class CustomTriangleVisitor
{
public:
	void Visit(unsigned long cellId, TriangleType * t)
	{
		LineType::PointIdIterator pit = t->PointIdsBegin();
		LineType::PointIdIterator end = t->PointIdsEnd();
		std::cout << "==============================" << std::endl;
		std::cout << "cell " << cellId << " is a triangle " << std::endl;
		while (pit != end)
		{
			
			std::cout << "point id = " << *pit << std::endl;
			++pit;
		}
	}
	virtual ~CustomTriangleVisitor() = default;
};

#endif //_CustomTriangleVisitor

class CustomTetrahedronVisitor
{
public:
	void Visit(unsigned long cellId, TetrahedronType *t)
	{
		std::cout << "==============================" << std::endl;
		std::cout << "cell " << cellId << " is a Tetrahedron, " << std::endl;
		std::cout << " number of faces = ";
		std::cout << t->GetNumberOfFaces() << std::endl;
	}
	virtual ~CustomTetrahedronVisitor() = default;
};

int main()
{
	MeshType::Pointer mesh = MeshType::New();

	MeshType::PointType   point0;
	MeshType::PointType   point1;
	MeshType::PointType   point2;
	MeshType::PointType   point3;

	point0[0] = -1; point0[1] = -1; point0[2] = -1;
	point1[0] = 1; point1[1] = 1; point1[2] = -1;
	point2[0] = 1; point2[1] = -1; point2[2] = 1;
	point3[0] = -1; point3[1] = 1; point3[2] = 1;

	mesh->SetPoint(0, point0);
	mesh->SetPoint(1, point1);
	mesh->SetPoint(2, point2);
	mesh->SetPoint(3, point3);

	//创建四面体单元
	CellType::CellAutoPointer cellpointer;

	cellpointer.TakeOwnership(new TetrahedronType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	cellpointer->SetPointId(3, 3);
	mesh->SetCell(0, cellpointer);

	//创建三角形面单元
	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	cellpointer->SetPointId(2, 2);
	mesh->SetCell(1, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 3);
	mesh->SetCell(2, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 3);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(3, cellpointer);

	cellpointer.TakeOwnership(new TriangleType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	cellpointer->SetPointId(2, 1);
	mesh->SetCell(4, cellpointer);

	//创建边线单元
	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 0);
	cellpointer->SetPointId(1, 1);
	mesh->SetCell(5, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(6, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 2);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(7, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 1);
	cellpointer->SetPointId(1, 3);
	mesh->SetCell(8, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 2);
	mesh->SetCell(9, cellpointer);

	cellpointer.TakeOwnership(new LineType);
	cellpointer->SetPointId(0, 3);
	cellpointer->SetPointId(1, 0);
	mesh->SetCell(10, cellpointer);

	//创建点单元
	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 0);
	mesh->SetCell(11, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 1);
	mesh->SetCell(12, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 2);
	mesh->SetCell(13, cellpointer);

	cellpointer.TakeOwnership(new VertexType);
	cellpointer->SetPointId(0, 3);
	mesh->SetCell(14, cellpointer);

	std::cout << "==============================" << std::endl;
	std::cout << "# Points= " << mesh->GetNumberOfPoints() << std::endl;
	std::cout << "# Cell  = " << mesh->GetNumberOfCells() << std::endl;

	using VertexVisitorInterfaceType = itk::CellInterfaceVisitorImplementation
		<PixelType, MeshType::CellTraits, VertexType, CustomVertexVisitor>;

	using LineVisitorInterfaceType = itk::CellInterfaceVisitorImplementation
		<PixelType, MeshType::CellTraits, LineType, CustomLineVisitor>;

	using TriangleVisitorInterfaceType = itk::CellInterfaceVisitorImplementation
		<PixelType, MeshType::CellTraits, TriangleType, CustomTriangleVisitor>;

	using TetrahedronVisitorInterfaceType = itk::CellInterfaceVisitorImplementation
		<PixelType, MeshType::CellTraits, TetrahedronType, CustomTetrahedronVisitor>;

	VertexVisitorInterfaceType::Pointer vertexVisitor =
		VertexVisitorInterfaceType::New();

	LineVisitorInterfaceType::Pointer lineVisitor =
		LineVisitorInterfaceType::New();

	TriangleVisitorInterfaceType::Pointer triangleVisitor =
		TriangleVisitorInterfaceType::New();

	TetrahedronVisitorInterfaceType::Pointer tetrahedronVisitor =
		TetrahedronVisitorInterfaceType::New();

	lineVisitor->SetMesh(mesh);

	using CellMultiVisitorType = CellType::MultiVisitor;
	CellMultiVisitorType::Pointer  multiVisitor = CellMultiVisitorType::New();

	multiVisitor->AddVisitor(vertexVisitor);
	multiVisitor->AddVisitor(lineVisitor);
	multiVisitor->AddVisitor(triangleVisitor);
	multiVisitor->AddVisitor(tetrahedronVisitor);

	mesh->Accept(multiVisitor);

	std::cout << "==============================" << std::endl;
	return EXIT_SUCCESS;
}

(11)路径

 itk::PolyLineParametricPath,该类通常用于以简明的方式表示2D中的图像分割算法的输出。

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkPolyLineParametricPath.h"

int main()
{
	constexpr unsigned int Dimension = 2;
	using ImageType = itk::Image<unsigned char, Dimension>;
	using PathType = itk::PolyLineParametricPath<Dimension>;
	using ReaderType = itk::ImageFileReader<ImageType>;
	ReaderType::Pointer reader = ReaderType::New();
	reader->SetFileName("C:\\xiaonvhai.jpg");
	try
	{
		reader->Update();
	}
	catch (itk::ExceptionObject &excp)
	{
		std::cout << "Problem reading the input image " << std::endl;
		std::cout << excp << std::endl;
		return EXIT_FAILURE;
	}

	ImageType::ConstPointer image = reader->GetOutput();
	PathType::Pointer path = PathType::New();
	path->Initialize();

	using ContinuousIndexType = PathType::ContinuousIndexType;
	ContinuousIndexType cindex;

	using ImagePointType = ImageType::PointType;
	ImagePointType origin = image->GetOrigin();

	ImageType::SpacingType spacing = image->GetSpacing();
	ImageType::SizeType size = image->GetBufferedRegion().GetSize();

	ImagePointType point;
	point[0] = origin[0] + spacing[0] * size[0];
	point[1] = origin[1] + spacing[1] * size[1];

	image->TransformPhysicalPointToContinuousIndex(origin, cindex);
	path->AddVertex(cindex);
	image->TransformPhysicalPointToContinuousIndex(point, cindex);
	path->AddVertex(cindex);

	return EXIT_SUCCESS;
}

(12)容器

下面的程序示例展示了 itk::TreeContainer  和关联的 TreeContainer 的使用,TreeContainer 实现了树的概念。

#include "itkTreeContainer.h"
#include "itkChildTreeIterator.h"
#include "itkLeafTreeIterator.h"
#include "itkLevelOrderTreeIterator.h"
#include "itkInOrderTreeIterator.h"
#include "itkPostOrderTreeIterator.h"
#include "itkRootTreeIterator.h"
#include "itkTreeIteratorClone.h"

int main()
{
	using NodeType = int;
	using TreeType = itk::TreeContainer<NodeType>;
	TreeType::Pointer tree = TreeType::New();
	tree->SetRoot(0);  //添加根节点
	tree->Add(1, 0);
	tree->Add(2, 0);
	tree->Add(3, 0);
	tree->Add(4, 2);
	tree->Add(5, 2);
	tree->Add(6, 5);
	tree->Add(7, 1);

	itk::ChildTreeIterator<TreeType> childIt(tree);
	std::cout << "==============================" << std::endl;
	for (childIt.GoToBegin(); !childIt.IsAtEnd(); ++childIt)
	{
		std::cout << childIt.Get() << std::endl;
	}
	std::cout << std::endl;

	childIt.GoToBegin();
	if (childIt.GetType() != itk::TreeIteratorBase<TreeType>::CHILD)
	{
		std::cout << "==============================" << std::endl;
		std::cerr << "Error: the iterator was not of type CHILD. " << std::endl;
		return EXIT_FAILURE;
	}

	int oldValue = childIt.Get();
	std::cout << "==============================" << std::endl;
	std::cout << "The node's value is " << oldValue << std::endl;
	int newValue = 2;
	childIt.Set(newValue);
	std::cout << "Now the node's value is " << childIt.Get() << std::endl;

	childIt.Set(oldValue);
	std::cout << "==============================" << std::endl;
	std::cout << "Is this a leaf node? " << childIt.IsLeaf() << std::endl;
	std::cout << "Is this the root node? " << childIt.IsRoot() << std::endl;
	std::cout << "Dose this node have a parent? " << childIt.HasParent() << std::endl;
	std::cout << "How many children does this node have? " << childIt.CountChildren() << std::endl;
	std::cout << "Does this node have a child 1? " << childIt.HasChild(1) << std::endl;
	std::cout << std::endl;

	tree->Clear();
	itk::PreOrderTreeIterator<TreeType> it(tree);
	it.GoToBegin();

	it.Add(0);
	it.Add(1);
	it.Add(2);
	it.Add(3);
	it.GoToChild(2);
	it.Add(4);
	it.Add(5);

	itk::TreeIteratorBase<TreeType>* childItClone = childIt.Clone();
	delete childItClone;

	using IteratorType = itk::TreeIteratorBase<TreeType>;
	using IteratorCloneType = itk::TreeIteratorClone<IteratorType>;
	IteratorCloneType anotherChildItClone = childIt;
	
	std::cout << "==============================" << std::endl;
	std::cout << "ChildTreeIterator: " << std::endl;
	for (childIt.GoToBegin(); !childIt.IsAtEnd(); ++childIt)
	{
		std::cout << childIt.Get() << std::endl;
	}
	std::cout << std::endl;

	std::cout << "==============================" << std::endl;
	std::cout << "LeafTreeIterator: " << std::endl;
	itk::LeafTreeIterator<TreeType> leafIt(tree);
	for (leafIt.GoToBegin(); !leafIt.IsAtEnd(); ++leafIt)
	{
		std::cout << leafIt.Get() << std::endl;
	}
	std::cout << std::endl;

	std::cout << "==============================" << std::endl;
	std::cout << "LevelOrderTreeIterator: " << std::endl;
	itk::LevelOrderTreeIterator<TreeType> levelIt(tree, 10, tree->GetNode(0));
	for (levelIt.GoToBegin(); !levelIt.IsAtEnd(); ++levelIt)
	{
		std::cout << levelIt.Get() << "(" << levelIt.GetLevel() << ")" << std::endl;
	}
	std::cout << std::endl;

	std::cout << "==============================" << std::endl;
	std::cout << "InOrderTreeIterator: " << std::endl;
	itk::InOrderTreeIterator<TreeType> inOrderIt(tree);
	for (inOrderIt.GoToBegin(); !inOrderIt.IsAtEnd(); ++inOrderIt)
	{
		std::cout << inOrderIt.Get() << std::endl;
	}
	std::cout << std::endl;

	std::cout << "==============================" << std::endl;
	std::cout << "PreOrderTreeIterator:" << std::endl;
	itk::PreOrderTreeIterator<TreeType> preOrderIt(tree);
	for (preOrderIt.GoToBegin(); !preOrderIt.IsAtEnd(); ++preOrderIt)
	{
		std::cout << preOrderIt.Get() << std::endl;
	}
	std::cout << std::endl;

	std::cout << "==============================" << std::endl;
	std::cout << "PostOrderTreeIterator:" << std::endl;
	itk::PostOrderTreeIterator<TreeType> postOrderIt(tree);
	for (postOrderIt.GoToBegin(); !postOrderIt.IsAtEnd(); ++postOrderIt)
	{
		std::cout << postOrderIt.Get() << std::endl;
	}
	std::cout << std::endl;

	std::cout << "==============================" << std::endl;
	std::cout << "RootTreeIterator: " << std::endl;
	itk::RootTreeIterator<TreeType> rootIt(tree, tree->GetNode(4));
	for (rootIt.GoToBegin(); !rootIt.IsAtEnd(); ++rootIt)
	{
		std::cout << rootIt.Get() << std::endl;
	}
	std::cout << std::endl;

	return EXIT_SUCCESS;
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值