Paraview源码解析8: vtkPVGlyphFilter类

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

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片