使用visualizer库
Visualizer库专用于读取CAE软件的源结果数据,并通过一系列提取手段,获得可视化数据,然后利用illustrator的核心模块构建出渲染场景,将结果在视图区呈现出来。
Visualizer采用基于管线的机制,实现数据源->过滤器->映射器->渲染器的数据流,过滤器类型包括以下几种。
同时也支持时间序列数据,生成结果动画。
读取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中提供的提取数据接口,比如addFringeSurface、addPolygonSurface、addSlice等。
// 创建分析场景,将已经打开的文件作为参数传入
auto scenario = std::make_shared<Scenario>(solution);
// 创建第一个Filter,抽取外表面数据
scenario->addFringeSurface();
// 根据场景生成渲染节点
auto node = scenario->build();
提取接口的属性参数
过滤器的属性分为了几个不同的维度,包括:
-
visible:是否可 见
-
appearence:呈现的材质,可以是某个指定的颜色、或者物理标量映射的颜色分布,也可以是一个其他贴图。
-
Display: 控制可视化数据的呈现方式,比如
Outline、Wireframe、Shaded、Transparent、Sphere等。默认的属性类型是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;