由于项目要求,需要自定义锥台的种植体,现将此部分代码贡献出来,希望对大家有用。
#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()
{
}