使用VTK实现自定义简单锥台种植体

1 篇文章 0 订阅

由于项目要求,需要自定义锥台的种植体,现将此部分代码贡献出来,希望对大家有用。

#include "vtkPolyDataAlgorithm.h"
#include "vtkCell.h"

class vtkTruncatedConeSource : public vtkPolyDataAlgorithm
{
public:
	static vtkTruncatedConeSource* New()
	{
		return new vtkTruncatedConeSource();
	}

	void				SetRadius1(double);
	void				SetRadius2(double);
	void				SetLength(double);
	void				SetResolution(unsigned int);
	double				GetRadius1();
	double				GetRadius2();
	double				GetLength();
	unsigned int		GetResolution();
	
	virtual void		Modified() override;
protected:
	vtkTruncatedConeSource();
	~vtkTruncatedConeSource();

	double				Radius1;
	double				Radius2;
	double				Length;
	unsigned int		Resolution;
	double				Direction[3];
	double				Center[3];

	/**
	* This is called by the superclass.
	* This is the method you should override.
	*/
	virtual int RequestData(vtkInformation* request,
		vtkInformationVector** inputVector,
		vtkInformationVector* outputVector) override;

	/**
	* This is called by the superclass.
	* This is the method you should override.
	*/
	virtual int RequestInformation(vtkInformation *, 
		vtkInformationVector **, 
		vtkInformationVector *) override;
private:
	vtkTruncatedConeSource(const vtkTruncatedConeSource&) = delete;
	void	operator=(const vtkTruncatedConeSource&) = delete;
};
#include "vtkTruncatedConeSource.h"
#include "vtkLine.h"
#include "vtkMath.h"
#include "vtkPolygon.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPolydata.h"
#include "vtkTransform.h"
#include "vtkCellArray.h"
#include "vtkAlgorithm.h"
#include "vtkStreamingDemandDrivenPipeline.h"

vtkTruncatedConeSource::vtkTruncatedConeSource() :
	Radius1(1.5),
	Radius2(1.5),
	Length(10),
	Resolution(1000)
{
	this->Direction[0] = 0;
	this->Direction[1] = 0;
	this->Direction[2] = 1;
	
	this->Center[0] = 0;
	this->Center[1] = 0;
	this->Center[2] = 0;

	this->SetNumberOfInputPorts(0);
}

void	vtkTruncatedConeSource::SetRadius1(double radius)
{
	if (this->Radius1 == radius)
		return;
	this->Radius1 = radius;
	this->Modified();
	this->Update();
}

void	vtkTruncatedConeSource::SetRadius2(double radius)
{
	if (this->Radius2 == radius)
		return;
	this->Radius2 = radius;
	this->Modified();
	this->Update();
}

void	vtkTruncatedConeSource::SetLength(double length)
{
	if (this->Length == length)
		return;
	this->Length = length;
	this->Modified();
	this->Update();
}

void	vtkTruncatedConeSource::SetResolution(unsigned int lines)
{
	if (this->Resolution == lines)
		return;
	this->Resolution = lines;
	this->Modified();
	this->Update();
}

double	vtkTruncatedConeSource::GetRadius1()
{
	return  this->Radius1;
}

double	vtkTruncatedConeSource::GetRadius2()
{
	return this->Radius2;
}

double	vtkTruncatedConeSource::GetLength()
{
	return this->Length;
}

unsigned int	vtkTruncatedConeSource::GetResolution()
{
	return this->Resolution;
}

void		vtkTruncatedConeSource::Modified()
{
	this->Superclass::Modified();
}

/**
* This is called by the superclass.
* This is the method you should override.
*/
int vtkTruncatedConeSource::RequestData(
	vtkInformation *vtkNotUsed(request),
	vtkInformationVector** vtkNotUsed(inputVector), 
	vtkInformationVector* outputVector)
{
	vtkInformation *outInfo = outputVector->GetInformationObject(0);
	vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

	vtkPoints* newPoints = vtkPoints::New();								//点数据分配;
	//vtkCellArray* newLines = vtkCellArray::New();								//线数据分配;
	vtkCellArray* newPolys = vtkCellArray::New();								//面数据分配;

	double center1[3] = { 0x0 };								//下多边形;
	double center2[3] = { 0x0 };								//上多边形;
	double normal[3] = {
		this->Direction[0], this->Direction[1], this->Direction[2] };

	vtkMath::MultiplyScalar(normal, this->Length * 0.5);
	vtkMath::Subtract(this->Center, normal, center1);
	vtkMath::Add(this->Center, normal, center2);

	double theta = 0;
	double point[3] = { 0x0 };
	double angle = 2 * vtkMath::Pi() / this->Resolution;
	for (int index = 0; index < this->Resolution; ++index)			//点计算;
	{
		normal[0] = cos(theta);
		normal[1] = sin(theta);
		normal[2] = 0;
		vtkMath::MultiplyScalar(normal, Radius1);
		vtkMath::Add(center1, normal, point);
		newPoints->InsertNextPoint(point);

		vtkMath::Normalize(normal);
		vtkMath::MultiplyScalar(normal, Radius2);
		vtkMath::Add(center2, normal, point);
		newPoints->InsertNextPoint(point);
		theta += angle;
	}
	//构建线数据;
	//for (int index = 0; index < this->Resolution; ++index)
	//{
	//	vtkLine* edge_line = vtkLine::New();
	//	edge_line->GetPointIds()->SetId(0, index * 2);
	//	edge_line->GetPointIds()->SetId(1, index * 2 + 1);
	//	newLines->InsertNextCell(edge_line);

	//	vtkLine*	line1 = vtkLine::New();
	//	vtkLine*	line2 = vtkLine::New();
	//	line1->GetPointIds()->SetId(0, index * 2);
	//	line2->GetPointIds()->SetId(0, index * 2 + 1);
	//	if (index == this->Resolution - 1)
	//	{
	//		line1->GetPointIds()->SetId(1, 0);
	//		line2->GetPointIds()->SetId(1, 1);
	//	}
	//	else
	//	{
	//		line1->GetPointIds()->SetId(1, (index + 1) * 2);
	//		line2->GetPointIds()->SetId(1, (index + 1) * 2 + 1);
	//	}
	//	newLines->InsertNextCell(line1);
	//	newLines->InsertNextCell(line2);
	//	newLines->InsertNextCell(edge_line);
	//	line1->Delete(); line2->Delete(); edge_line->Delete();
	//}
	//构建上下两个圆面和侧面数据;
	vtkPolygon*		circle1 = vtkPolygon::New();
	vtkPolygon*		circle2 = vtkPolygon::New();
	circle1->GetPointIds()->SetNumberOfIds(this->Resolution);
	circle2->GetPointIds()->SetNumberOfIds(this->Resolution);
	for (int index = 0; index < this->Resolution; ++index)
	{
		circle1->GetPointIds()->SetId(index, index * 2);
		circle2->GetPointIds()->SetId(index, index * 2 + 1);
		vtkPolygon*		polygon = vtkPolygon::New();
		polygon->GetPointIds()->SetNumberOfIds(4);
		polygon->GetPointIds()->SetId(0, index * 2);
		polygon->GetPointIds()->SetId(1, index * 2 + 1);
		if (index == this->Resolution - 1)
		{
			polygon->GetPointIds()->SetId(2, 1);
			polygon->GetPointIds()->SetId(3, 0);
		}
		else
		{
			polygon->GetPointIds()->SetId(2, (index + 1) * 2 + 1);
			polygon->GetPointIds()->SetId(3, (index + 1) * 2);
		}
		newPolys->InsertNextCell(polygon);
		polygon->Delete();
	}
	newPolys->InsertNextCell(circle1);
	newPolys->InsertNextCell(circle2);
	circle1->Delete(); circle2->Delete();

	output->SetPoints(newPoints);
	output->SetPolys(newPolys);
	output->Modified();

	newPolys->Delete();
	//newLines->Delete();
	newPoints->Delete();

	return 1;
}

/**
* This is called by the superclass.
* This is the method you should override.
*/
int vtkTruncatedConeSource::RequestInformation(
	vtkInformation *vtkNotUsed(request),
	vtkInformationVector **vtkNotUsed(inputVector),
	vtkInformationVector *outputVector)
{
	vtkInformation *outInfo = outputVector->GetInformationObject(0);
	outInfo->Set(vtkAlgorithm::CAN_HANDLE_PIECE_REQUEST(), 1);
	return 1;
}

vtkTruncatedConeSource::~vtkTruncatedConeSource()
{


}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值