You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
6.9 KiB
C++
207 lines
6.9 KiB
C++
#include "FITKAlgGlyph.h"
|
|
|
|
#include <vtkInformation.h>
|
|
#include <vtkDemandDrivenPipeline.h>
|
|
#include <vtkStreamingDemandDrivenPipeline.h>
|
|
#include <vtkMaskPoints.h>
|
|
#include <vtkArrowSource.h>
|
|
#include <vtkGlyph3D.h>
|
|
#include <vtkPointData.h>
|
|
#include <vtkCellCenters.h>
|
|
#include <vtkCellData.h>
|
|
#include <vtkDataArray.h>
|
|
|
|
#include <QByteArray>
|
|
|
|
namespace Interface
|
|
{
|
|
FITKAlgGlyph * FITKAlgGlyph::New()
|
|
{
|
|
FITKAlgGlyph* glyphAlg = new FITKAlgGlyph();
|
|
glyphAlg->InitializeObjectBase();
|
|
return glyphAlg;
|
|
}
|
|
|
|
void FITKAlgGlyph::PrintSelf(ostream & os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
FITKAlgGlyph::FITKAlgGlyph()
|
|
{
|
|
_polyData = vtkPolyData::New();
|
|
}
|
|
|
|
FITKAlgGlyph::~FITKAlgGlyph()
|
|
{
|
|
if (_polyData) {
|
|
_polyData->Delete();
|
|
_polyData = nullptr;
|
|
}
|
|
}
|
|
|
|
int FITKAlgGlyph::FillOutputPortInformation(int port, vtkInformation * info)
|
|
{
|
|
Q_UNUSED(port);
|
|
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
|
|
return 1;
|
|
}
|
|
|
|
int FITKAlgGlyph::FillInputPortInformation(int port, vtkInformation * info)
|
|
{
|
|
Q_UNUSED(port);
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
|
|
return 1;
|
|
}
|
|
|
|
int FITKAlgGlyph::ProcessRequest(vtkInformation * request, vtkInformationVector ** inputVector, vtkInformationVector * outputVector)
|
|
{
|
|
if (request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION())) {
|
|
return this->RequestInformation(request, inputVector, outputVector);
|
|
}
|
|
if (request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT())) {
|
|
return this->RequestUpdateExtent(request, inputVector, outputVector);
|
|
}
|
|
if (request->Has(vtkDemandDrivenPipeline::REQUEST_DATA())) {
|
|
return this->RequestData(request, inputVector, outputVector);
|
|
}
|
|
return this->Superclass::ProcessRequest(request, inputVector, outputVector);
|
|
}
|
|
|
|
int FITKAlgGlyph::RequestData(vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector * outputVector)
|
|
{
|
|
//获取输入输出数据
|
|
vtkDataSet* inputData = vtkDataSet::GetData(inputVector[0]);
|
|
vtkPolyData* outputData = vtkPolyData::GetData(outputVector);
|
|
if (inputData == nullptr) {
|
|
vtkErrorMacro("InputData is error");
|
|
return 0;
|
|
}
|
|
|
|
if (!extractPoints(inputData))
|
|
{
|
|
vtkErrorMacro("Glyphing faild.");
|
|
return 0;
|
|
}
|
|
|
|
vtkSmartPointer<vtkMaskPoints> maskPoint = vtkSmartPointer<vtkMaskPoints>::New();
|
|
//计算跨行数
|
|
int mRatio = 1;
|
|
if (_pointNum > 20000) {
|
|
mRatio = _pointNum / 20000;
|
|
}
|
|
//设置输入数据
|
|
maskPoint->SetInputData(_polyData);
|
|
//打开每n个点(跨行采样)
|
|
maskPoint->SetOnRatio(mRatio);
|
|
//设置是否开启特殊标志导致点选择的随机化
|
|
maskPoint->RandomModeOn();
|
|
//设置最大采样点数量
|
|
maskPoint->SetMaximumNumberOfPoints(_maxNumber);
|
|
maskPoint->Update();
|
|
|
|
//箭头数据设置
|
|
vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();
|
|
//箭头维度
|
|
arrowSource->SetTipResolution(_tipResolution);
|
|
//箭头半径
|
|
arrowSource->SetTipRadius(_tipRadius);
|
|
//箭头长度
|
|
arrowSource->SetTipLength(_tipLength);
|
|
//箭柄维度
|
|
arrowSource->SetShaftResolution(_shaftResolution);
|
|
//箭柄半径
|
|
arrowSource->SetShaftRadius(_shaftRadius);
|
|
|
|
vtkSmartPointer<vtkGlyph3D> glyph3D = vtkSmartPointer<vtkGlyph3D>::New();
|
|
glyph3D->SetSourceConnection(arrowSource->GetOutputPort());
|
|
glyph3D->SetInputConnection(maskPoint->GetOutputPort());
|
|
//设置模式为法线
|
|
glyph3D->SetVectorMode(VTK_USE_NORMAL);
|
|
//设置比例模式
|
|
glyph3D->SetScaleMode(_scaleMode);
|
|
//设置缩放比例
|
|
glyph3D->SetScaleFactor(_scaleFactor);
|
|
//打开缩放源几何
|
|
glyph3D->ScalingOn();
|
|
//打开输入几何体沿矢量/法线方向。
|
|
glyph3D->OrientOn();
|
|
glyph3D->Update();
|
|
|
|
outputData->CopyStructure(glyph3D->GetOutput());
|
|
outputData->GetPointData()->PassData(glyph3D->GetOutput()->GetPointData());
|
|
|
|
return 1;
|
|
}
|
|
|
|
bool FITKAlgGlyph::extractPoints(vtkDataSet* inputData)
|
|
{
|
|
if (inputData == nullptr)return false;
|
|
QByteArray a = _vectorName.toLocal8Bit();
|
|
char* cName = a.data();
|
|
|
|
if (_pointDataUsed) {
|
|
vtkPointData* pointData = inputData->GetPointData();
|
|
if (pointData == nullptr)return false;
|
|
|
|
extractPointDataArray(inputData);
|
|
_pointNum = inputData->GetNumberOfPoints();
|
|
|
|
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
|
for (vtkIdType i = 0; i < _pointNum; i++) {
|
|
double* p;
|
|
p = inputData->GetPoint(i);
|
|
points->InsertNextPoint(p);
|
|
}
|
|
_polyData->SetPoints(points);
|
|
vtkDataArray* array = pointData->GetArray(cName);
|
|
_polyData->GetPointData()->SetNormals(array);
|
|
}
|
|
else {
|
|
vtkCellData* cellData = inputData->GetCellData();
|
|
if (cellData == nullptr) return false;
|
|
|
|
vtkSmartPointer<vtkCellCenters> cellCenters = vtkSmartPointer<vtkCellCenters>::New();
|
|
cellCenters->SetInputData(inputData);
|
|
//启用生成顶点单元
|
|
cellCenters->VertexCellsOn();
|
|
cellCenters->Update();
|
|
|
|
extractPointDataArray(cellCenters->GetOutput());
|
|
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
|
|
|
|
vtkPolyData* cPolyData = cellCenters->GetOutput();
|
|
if (cPolyData == nullptr) return false;
|
|
|
|
_pointNum = cPolyData->GetNumberOfCells();
|
|
for (vtkIdType i = 0; i < _pointNum; i++) {
|
|
double p[3];
|
|
cPolyData->GetPoint(i, p);
|
|
points->InsertNextPoint(p);
|
|
}
|
|
|
|
_polyData->SetPoints(points);
|
|
vtkDataArray* array = cellData->GetArray(cName);
|
|
_polyData->GetPointData()->SetNormals(array);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void FITKAlgGlyph::extractPointDataArray(vtkDataSet * inputData)
|
|
{
|
|
auto pointData = inputData->GetPointData();
|
|
if (pointData == nullptr || _polyData == nullptr) return;
|
|
|
|
const int nArr = _polyData->GetPointData()->GetNumberOfArrays();
|
|
for (int i = 0; i < nArr; ++i) {
|
|
_polyData->GetPointData()->RemoveArray(i);
|
|
}
|
|
|
|
const int nPointArray = pointData->GetNumberOfArrays();
|
|
for (int i = 0; i < nPointArray; i++) {
|
|
vtkDataArray* array = pointData->GetArray(i);
|
|
_polyData->GetPointData()->AddArray(array);
|
|
}
|
|
}
|
|
}
|