#include "FITKAlgGlyph.h" #include #include #include #include #include #include #include #include #include #include #include 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 maskPoint = vtkSmartPointer::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 arrowSource = vtkSmartPointer::New(); //箭头维度 arrowSource->SetTipResolution(_tipResolution); //箭头半径 arrowSource->SetTipRadius(_tipRadius); //箭头长度 arrowSource->SetTipLength(_tipLength); //箭柄维度 arrowSource->SetShaftResolution(_shaftResolution); //箭柄半径 arrowSource->SetShaftRadius(_shaftRadius); vtkSmartPointer glyph3D = vtkSmartPointer::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 points = vtkSmartPointer::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 cellCenters = vtkSmartPointer::New(); cellCenters->SetInputData(inputData); //启用生成顶点单元 cellCenters->VertexCellsOn(); cellCenters->Update(); extractPointDataArray(cellCenters->GetOutput()); vtkSmartPointer points = vtkSmartPointer::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); } } }