跳到主要内容

使用visualizer库

Visualizer库专用于读取CAE软件的源结果数据,并通过一系列提取手段,获得可视化数据,然后利用illustrator的核心模块构建出渲染场景,将结果在视图区呈现出来。

Visualizer采用基于管线的机制,实现数据源->过滤器->映射器->渲染器的数据流,过滤器类型包括以下几种。

texture

同时也支持时间序列数据,生成结果动画。

读取VTK支持类型的文件

通过openSolution接口,将一个完整的CAE案例结果文件读取进来,创建一个DataSolution类的对象。该对象中包含了CAE结果中的网格数据,以及每个网格顶点上的标量、矢量信息。


// 读取VTK支持类型的文件,格式包括Ensighter、VTK、VTU、VTI、VTP、VTS、VTR、VTM、OpenFoam、CGNS、DICOM、LSDYNA、STL、OBJ、GAMBIT、TECPLOT等
auto solution = openSolution("C:/illustrator/test/model/PuppetValve/PuppetValve.xml.case");

从CAE源场中提取数据

使用提取外表面数据接口

首先需要创建一个场景Scenario,它可以管理一系列提取结果数据,并构建渲染节点。然后可以使用visualizer中提供的提取数据接口,比如addFringeSurfaceaddPolygonSurfaceaddSlice等。

// 创建分析场景,将已经打开的文件作为参数传入
auto scenario = std::make_shared<Scenario>(solution);
// 创建第一个Filter,抽取外表面数据
scenario->addFringeSurface();

// 根据场景生成渲染节点
auto node = scenario->build();

提取接口的属性参数

过滤器的属性分为了几个不同的维度,包括:

  • visible:是否可见

  • appearence:呈现的材质,可以是某个指定的颜色、或者物理标量映射的颜色分布,也可以是一个其他贴图。

  • Display: 控制可视化数据的呈现方式,比如OutlineWireframeShadedTransparentSphere等。默认的属性类型是Shaded_Wireframe

  • Scalar:控制呈现哪个物理标量信息,如压力、速度分量和速度值等。

  • Vector:控制呈现哪个物理矢量信息,可以是空,也可以选择模型中含有的某个矢量。

  • Color:如果appearence选择了指定颜色,那么就使用该属性中定义的颜色来呈现。

// 创建Filter,抽取外表面数据
auto filter = scenario->addFringeSurface();
// 修改Filter中的属性,设置display为Wireframe的属性
filter->attributes()->display = PolygonAttributes::Display::Wireframe;

绘制提取数据

和其他教程中绘制渲染场景的方法一样,我们搭建好背景、相机,并组织好渲染通道,形成一个含有CAE外表面数据的渲染场景。

Application app;

auto widget = std::make_shared<OpenGLWidget>();
widget->setTitle("tutorial110_vtk-exam01");

auto pixelSize = widget->pixelSize();
auto background = _simpleBackground(_ivec2(pixelSize), _clr4(0.9, 0.8, 0.7, 1.0));
auto camera = _camera();
auto pass = _pass(node, background, camera);
auto scene = _scene({ pass });

const auto& boundingBox = solution->boundingBox;
*camera->orbitPoint = boundingBox->center();
home(camera, *boundingBox, *background->size);

auto renderer = std::make_shared<OpenGLRenderer>(widget);
renderer->render(scene);
widget->update();

auto windowSize = _ivec2(widget->size());
widget->onResize = [&](ResizeEvent* event) -> void {
*windowSize = widget->size();
auto pixelSize = widget->pixelSize();
*background->size = pixelSize;
setAspect(*camera->projectionMatrix, float(pixelSize[0]) / float(pixelSize[1]));
renderer->render(scene);
widget->update();
};

auto getButton = [](MouseButton mouseButton) -> MouseManipulator::Button {
MouseManipulator::Button button = MouseManipulator::Button::None;
switch (mouseButton)
{
case MouseButton::Left: button = MouseManipulator::Button::Left; break;
case MouseButton::Middle: button = MouseManipulator::Button::Middle; break;
case MouseButton::Right: button = MouseManipulator::Button::Right; break;
default: break;
}

return button;
};

auto getModifier = [](Modifier modifier) -> MouseManipulator::Modifier {
MouseManipulator::Modifier result = MouseManipulator::Modifier::None;
switch (modifier)
{
case Modifier::Shift: result = MouseManipulator::Modifier::Shift; break;
case Modifier::Ctrl: result = MouseManipulator::Modifier::Ctrl; break;
case Modifier::Alt: result = MouseManipulator::Modifier::Alt; break;
default: break;
}

return result;
};

auto navigation = _manipulator_navigation(camera, windowSize, boundingBox);
navigation->bind("triggered", [&](MouseAction* action) -> void {
renderer->render(scene);
widget->update();
});

widget->onMouseDown = [&](MouseEvent* event) -> void {
auto button = getButton(event->button);
auto modifier = getModifier(event->modifier);
navigation->mouseDown(ivec2(event->x, event->y), button, modifier);
};

widget->onMouseDrag = [&](MouseEvent* event) -> void {
auto button = getButton(event->button);
auto modifier = getModifier(event->modifier);
navigation->mouseMove(ivec2(event->x, event->y), button, modifier);
};

widget->onMouseUp = [&](MouseEvent* event) -> void {
auto button = getButton(event->button);
auto modifier = getModifier(event->modifier);
navigation->mouseUp(ivec2(event->x, event->y), button, modifier);
};

widget->onWheel = [&](WheelEvent* event) -> void {
auto modifier = getModifier(event->modifier);
navigation->mouseWheel(ivec2(event->x, event->y), modifier, event->up);
};

app.exec();

return 0;

绘制结果

  • Shaded_Wireframe(默认)
texture
  • Wireframe
texture