vtkPVGlyphFilter扩展了vtkGlyph3D,用于添加对使用\\c glyph模式绘制哪些点的控制。现在提供了三种模式:
*\\li ALL_POINTS:输入数据集中的所有点都是图示符。这与直接使用vtkGlyph3D相同。
*\\li EVERY_NTH_POINT:当按顺序迭代输入点时,输入数据集中的每个第n个点都是图示符。对于复合数据集,计数器重置每个on块。同时,在每个列上使用独立计数器。使用\\c跨步控制现在可能需要跳过的点。
*\\li SPATIALLY_UNIFORM_DISTRIBUTION:接近随机采样的点空间分布的点用符号表示。\\c Seed控制随机数生成器(vtkMinimalStandardRandomSequence)的种子点。\\c MaximumNumberOfSamplePoints可用于限制用于随机采样的采样点数量。这并不等于实际图示的点数,因为这取决于几个因素。同时,该过滤器确保在所有列组中收集空间边界,以生成相同的采样点。
*\\li SPATIALLY_UNIFORM_INVERSE_TRANSFORM_SAMPLING_SURFACE:在每个单元的表面积上通过逆变换随机采样的点。与体积数据集一起使用时,将提取曲面网格并用于采样。
*\\c Seed控制随机数生成器的种子点。
*\\c MaximumNumberOfSamplePoints限制用于随机采样的采样点数量。
*由于采样取决于多个因素,因此生成的图示符数量可以更小。
*与复合数据集并行使用时,该过滤器可确保每一块仅采样代表性数量的点。
*请注意,网格将首先进行三角剖分。
*\\li SPATIALLY_UNIFORM_INVERSE_TRANSFORM_SAMPLING_VOLUME:通过每个单元体积上的逆变换随机采样的点。只考虑3D单元。
*\\c Seed控制随机数生成器的种子点。
*\\c MaximumNumberOfSamplePoints限制用于随机采样的采样点数量。
*由于采样取决于多个因素,因此生成的图示符数量可以更小。
*与复合数据集并行使用时,该过滤器可确保每一块仅采样代表性数量的点。
*请注意,网格将首先四面体化。
1.类图结构
vtkGlyph3D的类图继承关系
vtkGlyph3D类协作图
2.代码实现
2.1vtkPVGlyphFilter::Execute( )
Paraview中apply glyph filter时,execute函数的调用堆栈:
Paraview apply glyph调用流程,进入Execute()
1.paraview.exe
paraview_main.cxx main()
2.pqComponents.dll
pqPropertiesPannel
qt_static_metacall
apply
applied
3.pqApplicationComponents.dll
pqApplyBehavior
qt_static_metacall
onApplied
applied
showData
4.vtkRemotingViews.dll
vtkSMParaViewPipelineControllerWithRendering
ShowInPreferredView
UpdatePipelineBeforeDisplay
5.vtkRemotingServerManager.dll
vtkSMSourceProxy
UpdatePipeline
vtkSMOutputPort
UpdatePipeline
UpdatePipelineInternal
vtkSMProxy
ExecuteStream
vtkPVSessionBase
ExecuteStream
vtkSessionCore
ExecuteStream
ExecuteStreamInternal
6.vtkRemotingClientServerStream.dll
vtkClientServerInterpreter
ProcessStream
ProcessOneMessage
ProcessCommandInvoke
CallCommandFunction
7.vtkRemotingApplication.dll
vtkSISourceProxyClientServer
vtkSISourceProxyCommand
8.vtkRemotingServerManager.dll
vtkSISourceProxy
UpdatePipeline
9.vtkCommonExecutionModel.dll
vtkStreamingDemandDrivenPipeline
Update(int port)
Update(int port,vtkInformationVector* request)
vtkDemandDrivenPipeline
UpdateData(int outputPort)
vtkStreamingDemandDrivenPipeline
ProcessRequest
vtkDemandDrivenPipeline
ProcessRequest
vtkCompositeDataPipeline
ForwardUpstream
vtkStreamingDemandDrivenPipeline
ProcessRequest
vtkDemandDrivenPipeline
ProcessRequest
vtkCompositeDataPipeline
ExecuteData
vtkDemandDrivenPipeline
ExecuteData
vtkExecutive
CallAlgorithm
10.vtkPVVTKExtensionsFilterGeneral.dll
vtkPVGlyphFilter
ProcessRequest
11.vtkCommonExecutionModel.dll
vtkPolyDataAlgorithm
ProcessRequest
12.vtkPVVTKExtensionFilterGeneral.dll
vtkPVGlyphFilter
ProcessRequest
Execute,800行
Execute,824行
2.1.1参数vtkInformationVector* sourceVector
2.1.2 trans
auto trans = vtkSmartPointer<vtkTransform>::New();
for (vtkIdType inPtId = 0; inPtId < numPts; inPtId++)
{
// Now begin copying/transforming glyph
trans->Identity();
// translate Source to Input point
double x[3];
input->GetPoint(inPtId, x);
trans->Translate(x[0], x[1], x[2]);
...
trans->RotateWXYZ(180.0, 0, 1, 0);
...
trans->Scale(scalex, scaley, scalez);
...
trans->TransformPoints(sourcePts, newPts);
}
trans->RotateWXYZ
orientArray是Execute()函数的参数vtkDataArray* orientArray:
if (orientArray)
{
double v[3] = { 0.0 };
orientArray->GetTuple(inPtId, v);
double vMag = vtkMath::Norm(v);
if (vMag > 0.0)
{
// if there is no y or z component
if (v[1] == 0.0 && v[2] == 0.0)
{
if (v[0] < 0) // just flip x if we need to
{
trans->RotateWXYZ(180.0, 0, 1, 0);
}
}
else
{
double vNew[3];
vNew[0] = (v[0] + vMag) / 2.0;
vNew[1] = v[1] / 2.0;
vNew[2] = v[2] / 2.0;
trans->RotateWXYZ(180.0, vNew[0], vNew[1], vNew[2]);
}
}
}
2.1.3 output->SetPoints(newPts)
output
output来源于Execute()函数的参数:
vtkPolyData* output
output->Allocate(source, 3 * numPts * numSourceCells, numPts * numSourceCells);
output->SetPoints(newPts);
numPts * numSourceCells=30
numPts
vtkDataSet* input;
vtkIdType numPts = input->GetNumberOfPoints();
input来源于Execute函数的参数vtkDataSet* input,numPts代表输入数据集中Points的个数。
case1:
numPts = 2
numSourceCells
vtkIdType numSourceCells = source->GetNumberOfCells();
case1,numSourceCells=15;
vtkSmartPointer<vtkPolyData> source = this->GetSource(0, sourceVector);
if (source == nullptr)
{
vtkNew<vtkPolyData> defaultSource;
defaultSource->Allocate();
vtkNew<vtkPoints> defaultPoints;
defaultPoints->Allocate(6);
defaultPoints->InsertNextPoint(0, 0, 0);
defaultPoints->InsertNextPoint(1, 0, 0);
vtkIdType defaultPointIds[2];
defaultPointIds[0] = 0;
defaultPointIds[1] = 1;
defaultSource->SetPoints(defaultPoints);
defaultSource->InsertNextCell(VTK_LINE, 2, defaultPointIds);
source = defaultSource;
}
sourceVector来源于Execute的第三个参数
vtkInformationVector* sourceVector
这个sourceVector代表什么含义?
newPts
auto newPts = vtkSmartPointer<vtkPoints>::New();
// Set the desired precision for the points in the output.
if (this->OutputPointsPrecision == vtkAlgorithm::DEFAULT_PRECISION)
{
newPts->SetDataType(VTK_FLOAT);
}
else if (this->OutputPointsPrecision == vtkAlgorithm::SINGLE_PRECISION)
{
newPts->SetDataType(VTK_FLOAT);
}
else if (this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
{
newPts->SetDataType(VTK_DOUBLE);
}
newPts->Allocate(numPts * numSourcePts);
// multiply points and normals by resulting matrix
if (this->SourceTransform)
{
transformedSourcePts->Reset();
this->SourceTransform->TransformPoints(sourcePts, transformedSourcePts);
trans->TransformPoints(transformedSourcePts, newPts);
}
else
{
trans->TransformPoints(sourcePts, newPts);
}
output->SetPoints(newPts);
代码可以简化为:
auto newPts = vtkSmartPointer<vtkPoints>::New();
newPts->SetDataType(VTK_FLOAT);
newPts->Allocate(numPts * numSourcePts);
trans->TransformPoints(sourcePts, newPts);
output->SetPoints(newPts);
numPts
vtkDataSet* input;
vtkIdType numPts = input->GetNumberOfPoints();
input来源于Execute函数的参数vtkDataSet* input,numPts代表输入数据集中Points的个数。
sourcePts和numSourcePts
auto sourcePts = source->GetPoints();
vtkIdType numSourcePts = sourcePts->GetNumberOfPoints();
对于下面的case1,numSourcePts=31;
newPts->Allocate(numPts * numSourcePts)
numPts*numSourcePts=62
暂无评论内容