VTK笔记-可视化管线-总结

  VTK是一个可视化工具包,将数据展现为二维或三维图像,依赖于可视化管线,用于获取或创建数据,处理数据,以及把数据写入文件或者把数据传递给渲染引擎进行显示,如图一所示。数据对象(Data Object)、处理对象(Process Object)和数据流方向(Direction of Data Flow)是可视化管线的三个基本要素。每个VTK程序都会有可视化管线存在。
可视化管线是由四个关键的类构成的,这四个类分别是:vtkInformationvtkDataObjectvtkAlgorithm
vtkExecutive

图一

图一:可视化管线流程图

vtkInformation

  vtkInformation存储vtkAlgorithm输入/输出信息,用于存储和传递管线执行过程中的信息、请求和数据,实现执行管线的连接和控制。
  vtkInformation表示vtkAlgorithm的一个输入或一个输出的信息和/或数据。它从映射到几种数据类型的,即是key-value的映射形式。vtkInformation类的实例收集在vtkInformationVector实例中,并传递给vtkAlgorithm::ProcessRequest调用。vtkInformation实例在特定输入或输出上引用的信息和数据定义了对vtkAlgorithm实例的请求。
  为扩展增加了灵活性。大部分的方法和头信息的存储都会用到vtkInformation。vtkInformation是一个基于Map的数据结构,它支持与编译时类型检查异构的键值操作。这也是一个用于存储information数据体的向量类vtkInformationVector。当向管道的上方或下方传递信息时(或从执行到算法),这个类将会被用到。
  vtkInformation使用 vtkInformationInternals中的Map保存vtkInformation记录的Key-Value信息;
vtkInformationKey是vtkInformation中Key的基类,派生了各种Key信息类,可以参考vtkInformationKey Class Reference查看vtkInformation继承类图;

// vtkInformationInternals.h
typedef vtkInformationKey* KeyType;
typedef vtkObjectBase* DataType;
struct HashFun
{
	size_t operator()(KeyType key) const { return static_cast<size_t>(key - KeyType(nullptr)); }
};
typedef std::unordered_map<KeyType, DataType, HashFun> MapType;
MapType Map;

  使用Has、Remove和Append对Map内的不同种类的Key-Value进行管理;

CopyEntry

  CopyEntry提供了将vtkInformation信息复制给key对应的value,如果deep是1的话,将进行深拷贝,默认为0;

void Copy(vtkInformation* from, int deep = 0);  
void Append(vtkInformation* from, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationDataObjectKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationDoubleVectorKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationVariantKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationVariantVectorKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationInformationKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationInformationVectorKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationIntegerKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationIntegerVectorKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationObjectBaseVectorKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationRequestKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationStringKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationStringVectorKey* key, int deep = 0);
void CopyEntry(vtkInformation* from, vtkInformationUnsignedLongKey* key, int deep = 0);  
void CopyEntries(vtkInformation* from, vtkInformationKeyVectorKey* key, int deep = 0);

Get接口

  Get函数可以根据输入不同类型的Key返回对应的Value值,然后向下转换后获取具体类型,得到相关信息,一般配合vtkDataObject类使用;

int Get(vtkInformationIntegerKey* key);
double Get(vtkInformationDoubleKey* key);
vtkIdType Get(vtkInformationIdTypeKey* key); 
int* Get(vtkInformationIntegerVectorKey* key);
int Get(vtkInformationIntegerVectorKey* key, int idx);
void Get(vtkInformationIntegerVectorKey* key, int* value);
int* Get(vtkInformationIntegerPointerKey* key);
void Get(vtkInformationIntegerPointerKey* key, int* value);
double* Get(vtkInformationDoubleVectorKey* key);
double Get(vtkInformationDoubleVectorKey* key, int idx);
void Get(vtkInformationDoubleVectorKey* key, double* value);
void Get(vtkInformationVariantVectorKey* key, vtkVariant* value);
void Get(vtkInformationKeyVectorKey* key, vtkInformationKey** value);
const vtkVariant& Get(vtkInformationVariantKey* key);
unsigned long Get(vtkInformationUnsignedLongKey* key);
const char* Get(vtkInformationStringVectorKey* key, int idx = 0);
const vtkVariant* Get(vtkInformationVariantVectorKey* key);
const vtkVariant& Get(vtkInformationVariantVectorKey* key, int idx);
vtkInformationKey** Get(vtkInformationKeyVectorKey* key);
vtkInformationKey* Get(vtkInformationKeyVectorKey* key, int idx);
const char* Get(vtkInformationStringKey* key);
vtkInformation* Get(vtkInformationInformationKey* key);
vtkInformationVector* Get(vtkInformationInformationVectorKey* key);
vtkObjectBase* Get(vtkInformationObjectBaseKey* key);
vtkObjectBase* Get(vtkInformationObjectBaseVectorKey* key, int idx = 0);
vtkDataObject VTK_WRAP_EXTERN* Get(vtkInformationDataObjectKey* key);

每个vtkInformationKey子类对应信息

  通过使用vtkDataObject类提供的方法获取想要获取值的Key,然后通过调用vtkInformation的Get函数获取对应的数据信息;

static vtkInformationStringKey * 	DATA_TYPE_NAME () 
static vtkInformationDataObjectKey * 	DATA_OBJECT () 
static vtkInformationIntegerKey * 	DATA_EXTENT_TYPE () 
static vtkInformationIntegerPointerKey * 	DATA_EXTENT () 
static vtkInformationIntegerVectorKey * 	ALL_PIECES_EXTENT () 
static vtkInformationIntegerKey * 	DATA_PIECE_NUMBER () 
static vtkInformationIntegerKey * 	DATA_NUMBER_OF_PIECES () 
static vtkInformationIntegerKey * 	DATA_NUMBER_OF_GHOST_LEVELS () 
static vtkInformationDoubleKey * 	DATA_TIME_STEP () 
static vtkInformationInformationVectorKey * 	POINT_DATA_VECTOR () 
static vtkInformationInformationVectorKey * 	CELL_DATA_VECTOR () 
static vtkInformationInformationVectorKey * 	VERTEX_DATA_VECTOR () 
static vtkInformationInformationVectorKey * 	EDGE_DATA_VECTOR () 
static vtkInformationIntegerKey * 	FIELD_ARRAY_TYPE () 
static vtkInformationIntegerKey * 	FIELD_ASSOCIATION () 
static vtkInformationIntegerKey * 	FIELD_ATTRIBUTE_TYPE () 
static vtkInformationIntegerKey * 	FIELD_ACTIVE_ATTRIBUTE () 
static vtkInformationIntegerKey * 	FIELD_NUMBER_OF_COMPONENTS () 
static vtkInformationIntegerKey * 	FIELD_NUMBER_OF_TUPLES () 
static vtkInformationIntegerKey * 	FIELD_OPERATION () 
static vtkInformationDoubleVectorKey * 	FIELD_RANGE () 
static vtkInformationIntegerVectorKey * 	PIECE_EXTENT () 
static vtkInformationStringKey * 	FIELD_NAME () 
static vtkInformationDoubleVectorKey * 	ORIGIN () 
static vtkInformationDoubleVectorKey * 	SPACING () 
static vtkInformationDoubleVectorKey * 	DIRECTION () 
static vtkInformationDoubleVectorKey * 	BOUNDING_BOX () 
static vtkInformationDataObjectKey * 	SIL ()

  从输入和输出的vtkInformation中获取数据集vtkPolyData;

vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkPolyData *input = vtkPolyData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

for(vtkIdType i = 0; i < input->GetNumberOfPoints(); i++){
	this->UpdateProgress(static_cast<double>(i)/input->GetNumberOfPoints());
}
output->ShallowCopy(input);

vtkDataObject

  在过去,这个类既存储数据又处理一些管道逻辑。在新的管道中,这个类只应该存储数据。实际上,类中有一些用于向后兼容的管道方法,这样就不会破坏所有的VTK,但目标是vtkDataObject应该只用于存储数据。vtkDataObject有一个vtkInformation实例,可用于存储键值对。例如,存储了数据对象的当前范围,但没有存储整个范围,因为这是一个包含特定管道拓扑信息的管道属性。

vtkAlgorithm

  vtkAlgorithm是VTK中所有sources, filters, and sinks的基类。它定义了一个用于执行数据处理算法的通用接口。管道连接与输入和输出端口相关联,这些端口独立于通过连接的数据类型。
  vtkAlgorithm实例可以独立使用,也可以在管道内使用,管道中可以使用各种架构和更新机制。管道由vtkExecutive实例控制。当在管道中使用时,每个vtkAlgorithm实例都有一个关联的vtkExecutive。执行人员负责数据流。
  和vtkDataObject一样,vtkAlgorithm不应该知道关于pipeline的任何环节,而仅仅只是一个algorithm/function/filter。输入正确的参数调用它,它便会产生结果。它也有一个vtkInformation的实例,用来描述算法的特征和属性,而且拥有描述算法输入和输出端口属性的信息。
  SetInput和GetOutput,用于串联起来数据源、Filter和渲染管线;

void RemoveAllInputs();  
vtkDataObject* GetOutputDataObject(int port);  
vtkDataObject* GetInputDataObject(int port, int connection);  
  
virtual void SetInputConnection(int port, vtkAlgorithmOutput* input);
virtual void SetInputConnection(vtkAlgorithmOutput* input);

virtual void AddInputConnection(int port, vtkAlgorithmOutput* input);
virtual void AddInputConnection(vtkAlgorithmOutput* input);
  
virtual void RemoveInputConnection(int port, vtkAlgorithmOutput* input);  
virtual void RemoveInputConnection(int port, int idx);  
virtual void RemoveAllInputConnections(int port);
  
virtual void SetInputDataObject(int port, vtkDataObject* data);
virtual void SetInputDataObject(vtkDataObject* data) { this->SetInputDataObject(0, data); }
  
virtual void AddInputDataObject(int port, vtkDataObject* data);
virtual void AddInputDataObject(vtkDataObject* data) { this->AddInputDataObject(0, data); }
  
vtkAlgorithmOutput* GetOutputPort(int index);
vtkAlgorithmOutput* GetOutputPort() { return this->GetOutputPort(0); }
  
int GetNumberOfInputConnections(int port);  
int GetTotalNumberOfInputConnections();  
vtkAlgorithmOutput* GetInputConnection(int port, int index);

vtkExecutive

  vtkExecutive是VTK中所有管道执行类的基类。vtkExecutive负责控制vtkAlgorithm的一个实例。管道由一个或多个控制数据流的vtkExecutive组成。管道中的每个reader, source, writer或数据处理算法都在vtkAlgorithm的一个实例中实现。

vtkAlgorithmOutput

  vtkAlgorithmOutput用于连接输入/输出端口的代理对象。
  vtkAlgorithmOutput是vtkAlgorithm的GetOutputPort方法返回的代理对象。它可以传递给另一个vtkAlgorithm的SetInputConnection、AddInputConnection或RemoveInputConnection方法,以在输出和输入端口之间建立连接。连接不存储在代理对象中:它只是方便创建或删除连接。

总结

  VTK框架里,大多数的类都是从vtkObject派生,vtkObject实现了观察者/命令(Observer/Command)设计模式,内部维护一个修改时间,用于控制可视化管线的执行。可视化管线是VTK里的重要概念,管线的连接应该使用SetInputConnection()/GetOutputPort()接口进行连接。VTK采用“惰性赋值”(Lazy Evaluation)的方案来控制管线的执行,只有当发出“请求数据”时,管线才会被执行。

参考文献

1.VTK修炼之道82:VTK管线机制_信息对象类VTKInformation
2.VTK/Tutorials/New Pipeline文档翻译
3.04-VTK可视化管线(2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

黑山老妖的笔记本

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

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

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

打赏作者

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

抵扣说明:

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

余额充值