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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haimianjie2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值