文件树
示例代码的组织结构如下:
Representation/CMakeLists.txt
该CMake文件中设置了一些编译选项,安装路径,然后调用了paraview_plugin_scan进行插件文件的扫描,最后调用paraview_plugin_build进行插件构建。
cmake_minimum_required(VERSION 3.8)
project(Representation)
find_package(ParaView REQUIRED)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
include(GNUInstallDirs)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set("_paraview_plugin_default_${PROJECT_NAME}" ON)
paraview_plugin_scan(
PLUGIN_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Plugin/paraview.plugin"
PROVIDES_PLUGINS plugins
REQUIRES_MODULES required_modules)
foreach (module IN LISTS required_modules)
if (NOT TARGET "${module}")
message(#FATAL_ERROR
"Skipping example ${PROJECT_NAME}: Missing required module: "
"${module}")
return ()
endif ()
endforeach ()
paraview_plugin_build(
RUNTIME_DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY_SUBDIRECTORY "${PARAVIEW_PLUGIN_SUBDIR}"
PLUGINS ${plugins})
Representation/Plugin/paraview.plugin
该文件定义了paraview插件的名字,描述信息,以及所依赖的插件名字
NAME
Representation
DESCRIPTION
Example plugin for a custom representation.
REQUIRES_MODULES
ParaView::RemotingViews
VTK::CommonCore
VTK::RenderingOpenGL2
Representation/Plugin/CMakeLists.txt
对于paraview插件开发,需要在paraview.plugin统计目录下有CMakeLists.txt文件,该CMake文件调用了paraview_add_plugin进行插件添加。如果需要进行一些其他依赖库或者变量的定义,也可以在该文件中进行定义及操作。
paraview_add_plugin(Representation
REQUIRED_ON_CLIENT
REQUIRED_ON_SERVER
VERSION "1.0"
MODULES GeometryRepresentations
MODULE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/GeometryRepresentations/vtk.module"
XML_DOCUMENTATION OFF)
GeometryRepresentations
该文件夹中为vtk模块源代码。
GeometryRepresentations/vtk.module
该文件是在上一级的CMakeLists.txt中进行加载的。
NAME
GeometryRepresentations
DEPENDS
ParaView::RemotingViews
VTK::RenderingOpenGL2
PRIVATE_DEPENDS
VTK::CommonCore
在vtk.module文件中,声明了该vtk模块的名称(GeometryRepresentations),并指定了该vtk模块所依赖的模块。
GeometryRepresentations/CMakeLists.txt
该文件中调用了vtk_module_add_module,生成的vtk模块名称为GeometryRepresentations,编译成静态库,相关源代码和头文件使用变量 classes 设定。
然后调用了paraview_add_server_manager_xmls指定了xml配置文件。
set(classes
vtkMySpecialPolyDataMapper
vtkMySpecialRepresentation)
vtk_module_add_module(GeometryRepresentations
FORCE_STATIC # Using FORCE_STATIC build the vtk module statically into the plugin library, to avoid confusion when loading
CLASSES ${classes})
paraview_add_server_manager_xmls(
XMLS Representation.xml)
其中vtk_module_add_module函数创建了一个vtk模块库。其定义如下:
vtk_module_add_module(<name>
[NO_INSTALL] [FORCE_STATIC] [HEADER_ONLY] [HEADER_DIRECTORIES]
[EXPORT_MACRO_PREFIX <prefix>]
[HEADERS_SUBDIR <subdir>]
[LIBRARY_NAME_SUFFIX <suffix>]
[CLASSES <class>...]
[TEMPLATE_CLASSES <template class>...]
[NOWRAP_CLASSES <nowrap class>...]
[NOWRAP_TEMPLATE_CLASSES <nowrap template class>...]
[SOURCES <source>...]
[HEADERS <header>...]
[NOWRAP_HEADERS <header>...]
[TEMPLATES <template>...]
[PRIVATE_CLASSES <class>...]
[PRIVATE_TEMPLATE_CLASSES <template class>...]
[PRIVATE_HEADERS <header>...]
[PRIVATE_TEMPLATES <template>...])
其中以前缀“PRIVATE_”开头的参数和无该前缀的参数意义基本相同,PRIVATE表明了相关联的文件不会复制到安装目录(源码总是私有的,即SOURCES不会复制到安装目录)。
NO_INSTALL:跳过安装过程,所有的安装工具都不会调用。主要,如果该模块被其他模块调用,该选择会被停用。因为CMAKE(特别是vtk模块API,比如vtk_module_export_find_packages)会产生该模块的引用,这要求该模块能够满足引用要求。常用的推荐做法是测试该构建,并安装导出项以确定该模块没有被引用。
FORCE_STATIC:强制生成静态库,即将代码加载对应的模块中。如果没有指定该属性,则BUILD_SHARED_LIBS会控制是否生成静态库。
HEADER_ONLY:该模块只包含头文件(或者模板),所以不会进行编译过程。与FORCE_STATIC互斥。
HEADER_DIRECTORIES:这个模块的头文件位于一个目录结构中,这个目录结构应该保存在安装树中。
EXPORT_MACRO_PREFIX:导出宏定义的前缀。默认为全部大写的模块库名。
HEADERS_SUBDIR:安装头文件到安装树的子文件夹。
LIBRARY_NAME_SUFFIX:如果需要其他信息,模块库名称的后缀。
CLASSES:模块中类名字的列表。该参数是一个简写,使用该参数会会添加<class>.cxx到变量SOURCES,以及添加<class>.h到变量HEADERS。
TEMPLATE_CLASSES:模块中的模板类名称列表。该参数是一个简写,使用该参数会添加<class>.txx到TEMPLATES,并添加<class>.h到HEADERS。
SOURCES:源文件列表。
HEADERS:头文件列表。
NOWARP_CLASSES:类名称列表,里面的类不会被复制到安装目录。该参数是一个简写,会将<class>.cxx添加到SOURCES,以及<class>.h>添加到NOWARP_HEADERS。
NOWARP_TEMPLATE_CLASS:模板类名称列表。这些类不会复制到安装目录。该参数是一个简写,使用该参数会将<class>.txx到TEMPLATES,并将<class>.h添加到NOWARP_HEADERS。
NOWARP_HEADER:头文件名称列表,这写头文件不会复制到安装目录中。
TEMPLATES:模板文件列表,会复制到安装目录中。
GeomoetryRepresentations/Representation.xml
该文件中对该模块在服务端管理器配置进行了说明。
<ServerManagerConfiguration>
<ProxyGroup name="representations">
<RepresentationProxy name="MySpecialRepresentation"
class="vtkMySpecialRepresentation"
processes="client|renderserver|dataserver"
base_proxygroup="representations"
base_proxyname="SurfaceRepresentation">
<Documentation>
This is the new representation type we are adding. This is identical to
the SurfaceRepresentation except that we are overriding the mapper with
our mapper.
</Documentation>
<!-- End of MySpecialRepresentation -->
</RepresentationProxy>
<Extension name="GeometryRepresentation">
<Documentation>
Extends standard GeometryRepresentation by adding
MySpecialRepresentation as a new type of representation.
</Documentation>
<!-- this adds to what is already defined in PVRepresentationBase -->
<RepresentationType subproxy="MySpecialRepresentation"
text="Special Mapper" subtype="Surface" />
<SubProxy>
<Proxy name="MySpecialRepresentation"
proxygroup="representations" proxyname="MySpecialRepresentation">
</Proxy>
<ShareProperties subproxy="SurfaceRepresentation">
<Exception name="Input" />
<Exception name="Visibility" />
<Exception name="Representation" />
</ShareProperties>
</SubProxy>
</Extension>
</ProxyGroup>
</ServerManagerConfiguration>
GeomoetryRepresentations/vtkMySpecialPolyDataMapper类
该类继承自vtkCompositePolyDataMapper2。该类只是为了说明插件开发流程,未对父类中原有内容进行修改。
vtkCompositePolyDataMapper2类似于vtkCompositePolyDataMapper,只是它不是为复合数据集中的每个块创建单独的映射器,而是在内部迭代这些块。
vtkCompositePolyDataMapper类使用一组vtkPolyDataMappers来呈现可能是分层的输入数据。此映射器的输入可以是vtkPolyData或从PolyData构建的vtkCompositeDataSet。如果遇到vtkPolyData以外的情况,将会产生一条错误消息。
//vtkMySpecialPolyDataMapper.h
#include "GeometryRepresentationsModule.h" // for export macro
#include "vtkCompositePolyDataMapper2.h"
class GEOMETRYREPRESENTATIONS_EXPORT vtkMySpecialPolyDataMapper : public vtkCompositePolyDataMapper2
{
public:
static vtkMySpecialPolyDataMapper* New();
vtkTypeMacro(vtkMySpecialPolyDataMapper, vtkCompositePolyDataMapper2);
void PrintSelf(ostream& os, vtkIndent indent) override;
protected:
vtkMySpecialPolyDataMapper();
~vtkMySpecialPolyDataMapper();
private:
vtkMySpecialPolyDataMapper(const vtkMySpecialPolyDataMapper&) = delete;
void operator=(const vtkMySpecialPolyDataMapper&) = delete;
};
//vtkMySpecialPolyDataMapper.cxx
#include "vtkMySpecialPolyDataMapper.h"
#include "vtkObjectFactory.h"
vtkStandardNewMacro(vtkMySpecialPolyDataMapper);
//----------------------------------------------------------------------------
vtkMySpecialPolyDataMapper::vtkMySpecialPolyDataMapper() = default;
//----------------------------------------------------------------------------
vtkMySpecialPolyDataMapper::~vtkMySpecialPolyDataMapper() = default;
//----------------------------------------------------------------------------
void vtkMySpecialPolyDataMapper::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
GeomoetryRepresentations/vtkMySpecialRepresentation类
vtkMySpecialRepresentation类继承自vtkGeometryRepresentationWithFaces。该类中只是将this->Mapper以及this->LODMapper修改成自定义的类,即vtkMySpecialPolyDataMapper。
vtkGeometryRepresentationWithFaces扩展了vtkGeometryRepresentation,以添加对分别渲染背面和正面(具有不同的可见性和属性)的支持。
//vtkMySpecialRepresentation.h
#include "GeometryRepresentationsModule.h" // for export macro
#include "vtkGeometryRepresentationWithFaces.h"
class GEOMETRYREPRESENTATIONS_EXPORT vtkMySpecialRepresentation
: public vtkGeometryRepresentationWithFaces
{
public:
static vtkMySpecialRepresentation* New();
vtkTypeMacro(vtkMySpecialRepresentation, vtkGeometryRepresentationWithFaces);
void PrintSelf(ostream& os, vtkIndent indent) override;
protected:
vtkMySpecialRepresentation();
~vtkMySpecialRepresentation();
private:
vtkMySpecialRepresentation(const vtkMySpecialRepresentation&) = delete;
void operator=(const vtkMySpecialRepresentation&) = delete;
};
// vtkMySpecialRepresentation.cxx
vtkStandardNewMacro(vtkMySpecialRepresentation);
//----------------------------------------------------------------------------
vtkMySpecialRepresentation::vtkMySpecialRepresentation()
{
// Replace the mappers created by the superclass.
this->Mapper->Delete();
this->LODMapper->Delete();
this->Mapper = vtkMySpecialPolyDataMapper::New();
this->LODMapper = vtkMySpecialPolyDataMapper::New();
// Since we replaced the mappers, we need to call SetupDefaults() to ensure
// the pipelines are setup correctly.
this->SetupDefaults();
}
//----------------------------------------------------------------------------
vtkMySpecialRepresentation::~vtkMySpecialRepresentation() = default;
//----------------------------------------------------------------------------
void vtkMySpecialRepresentation::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
总结
以上是对paraview插件例子里的Representation例子进行了简单的分析。开发一个paraview的插件与以上分析过程相反:
(1)开发vtk插件。
(2)进行paraview封装。
如果是vtk的插件,可以使用配置文件进行加载。如果是自己使用C++开发的功能库,则需要再次进行封装,使用vtk数据结构及开发规范进行数据输入输出的控制。
所以,vtk的开发是进行paraview开发的前置条件。