reader的父类的选择是基于reader的输出的类型的,这些父类在VTK中由相对应vtkAlgorithm提供。例如输出vtkPolyData,则父类选择vtkPolyDataAlgorithm。
reader主要有以下五个方法:
ProcessRequest:流水线的接口,就是整个reader的主函数
RequestInformation:提供数据的信息,当ProcessRequest收到REQUEST_INFORMATION关键字(具体啥需要进一步探究)
RequestData:提供数据,当ProcessRequest收到REQUEST_DATA关键字,从文件中读取数据,并存储到相应数据对象中。这个数据对象应该在这之前已经由流水线创建了。
CanReadFile:定义这个reader是否可以读某种文件类型
SetFileName:?读取特定文件名?
多组读取(多块和AMR)reader:
multi-block readers:作为的vtkMultiBlockDataSetAlgorithm子类
AMR readers:作为vtkHierarchicalDataSetAlgorithm的子类
如果不用以上两个:则要实现; CreateDefaultExecutive(), FillOutputPortInformation(), and FillInputPortInformation()
并行reader:(由结构化数据或者非机构化数据类型决定)在头进程读取所有数据然后分发到所有的进程中,等同于并行读取
改变RequestInformation和RequestData
int vtkDEMReader::RequestInformation ( vtkInformation * vtkNotUsed(request), vtkInformationVector ** vtkNotUsed( inputVector ), vtkInformationVector *outputVector) { vtkInformation* outInfo = outputVector->GetInformationObject(0); int extent[6]; //Read entire extent from file. ... outInfo->Set (vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent,6); return 1; }
int vtkDEMReader::RequestData( vtkInformation* vtkNotUsed( request ), vtkInformationVector** vtkNotUsed( inputVector ), vtkInformationVector* outputVector) { // get the data object and find out what part we need to // read now vtkInformation *outInfo = outputVector->GetInformationObject(0); int subext[6]; outInfo->Get (vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), subext); //read that part of the data in from the file //and put it in the output data ... return 1; }
int vtkUnstructuredGridReader::RequestData( vtkInformation *, vtkInformationVector **, vtkInformationVector *outputVector) { vtkInformation *outInfo = outputVector->GetInformationObject(0); int piece, numPieces; piece = outInfo->Get (vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()); numPieces = outInfo->Get (vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES()); //skip to proper offset in the file and read piece ... return 1; }当划分的块数小于你的处理器的个数时,则多出来的处理器要调用 Initialize()作为输出,如果大于,则再一次重新分配。
<SourceProxy name="XMLPolyDataReader"class="vtkXMLPolyDataReader"label="XML Polydata reader"> <StringVectorProperty name="FileName" command="SetFileName" animateable="0" number_of_elements="1"> <FileListDomain name="files"/> </StringVectorProperty> <StringVectorProperty name="CellArrayInfo" information_only="1"> <ArraySelectionInformationHelper attribute_name="Cell"/> </StringVectorProperty> <StringVectorProperty name="CellArrayStatus" command="SetCellArrayStatus" number_of_elements="0" repeat_command="1" number_of_elements_per_command="2" element_types="2 0" information_property="CellArrayInfo" label="Cell Arrays"> <ArraySelectionDomain name="array_list"> <RequiredProperties> <Property name="CellArrayInfo" function="ArrayList"/> </RequiredProperties> </ArraySelectionDomain> </StringVectorProperty> </SourceProxy>
<SourceProxy name="XMLPolyDataReader"class="vtkXMLPolyDataReader"label="XML Polydata reader">一个reader定义的开始,定义这个reader的名字,和在vtk中的类
<StringVectorProperty name="FileName" command="SetFileName" animateable="0" number_of_elements="1"> <FileListDomain name="files"/> </StringVectorProperty>这是一个模式,一般都这样,SetFileName命令用来告诉reader什么样的文件他应该检查。告诉reader文件名,然后调用CanReadFile检测能不能读这个文件,如果成功,则 调用RequestInformation获得文件中数据的一些总体信息。最后调用RequestData读取文件,并且创建一个vtkDataObject。
接下来的两个属性,用来使用户选择特定的组来读取文件,可以使以单元格或者以点'cell' with 'point'。
CellArrayStatus命令使Paraview客户端在服务器端调用SetCellArrayStatus方法。对于数据文件的每一个组,reader应该怎么做,有两个参数:名字,是否要读这个组
'CellArrayInfo'是一个信息属性,Paraview的客户端收集所有的信息从服务器端,集中所有的cell-centered arrays的名字。因此,两个方法被用于这里:GetNumberOfCellArrays返回文件中能够得到的cell-centered arrays的个数。GetCellArrayName返回当前数组序列的名字,如果没有返回NULL。