VTK—vtkQuadraticHexahedron细分

目录

1.提取单元格点和索引

2.用vtkUnstructuredGrid表达

3.显示效果,此时直边,细分无效

4.每个点位置添加球(字形)

5.折断直边,准备细分

6.细分过滤器vtkTessellatorFilter

7.使用vtkSliderWidget动态细分

8.完整代码


vtkQuadraticHexahedron是非线性的二次六面体单元格,就是普通的六面体每个边中间多了一个控制点。可以把点提取出来用vtkUnstructuredGrid显示。

1.提取单元格点和索引

cpp 复制代码
Create(vtkQuadraticHexahedron, hexadron);
    double *coord = hexadron->GetParametricCoords();
    int num = hexadron->GetNumberOfPoints();
    /*
     * 这两行无法获取数据
    hexadron->GetPoints();
    hexadron->GetPointIds();
    */

2.用vtkUnstructuredGrid表达

cpp 复制代码
for(int i = 0; i < num; i++)
    {
        double point[3] = {coord[i * 3 + 0], coord[i * 3 + 1], coord[i * 3 + 2]};
        points->InsertNextPoint(point);
        ids->InsertNextId(i);
    }
    Create(vtkUnstructuredGrid, grid);
    grid->SetPoints(points);
    grid->InsertNextCell(hexadron->GetCellType(), ids);

3.显示效果,此时直边,细分无效

4.每个点位置添加球(字形)

cpp 复制代码
Create(vtkPolyData, polydata);
    polydata->SetPoints(points);
    Create(vtkSphereSource, sphere);
    sphere->SetRadius(0.02);

    Create(vtkGlyph3D, glyph);
    glyph->SetInputData(polydata);
    glyph->SetSourceConnection(sphere->GetOutputPort());

    Create(vtkPolyDataMapper, gMapper);
    gMapper->SetInputConnection(glyph->GetOutputPort());

    Create(vtkActor, gActor);
    gActor->SetMapper(gMapper);

vtkGlyph3D有两个输入,setInputData()设置的其实点位置,setSourceConnection()设置的是要放在点位置的字形,此处是球。

5.折断直边,准备细分

cpp 复制代码
Create(vtkMinimalStandardRandomSequence, sequence);
    sequence->SetSeed(5);
    for(int i = 0; i < num; i++)
    {
        double point[3] = {coord[i * 3 + 0], coord[i * 3 + 1], coord[i * 3 + 2]};
        for(int j = 0; j < 3; j++)
        {
            point[j] = point[j] + sequence->GetRangeValue(-0.1, 0.1);
            sequence->Next();
        }
        points->InsertNextPoint(point);
        ids->InsertNextId(i);
    }

6.细分过滤器vtkTessellatorFilter

cpp 复制代码
Create(vtkTessellatorFilter, tessellator);
    tessellator->SetInputData(grid);
    tessellator->SetChordError(0.03);
    tessellator->Update();

    Create(vtkDataSetMapper, mapper);
    mapper->SetInputData(tessellator->GetOutput());

setChordError()能控制细分精细程度,目前还没理解参数含义(猜测是单元对角线的比例值)。

7.使用vtkSliderWidget动态细分

cpp 复制代码
Create(vtkSliderWidget, widget);
    widget->SetInteractor(inter);
    vtkSliderRepresentation3D *rep = (vtkSliderRepresentation3D *)widget->GetRepresentation();
    rep->GetPoint1Coordinate()->SetValue(-1, -1, 0);
    rep->GetPoint2Coordinate()->SetValue(2, -1, 0);
    rep->SetMaximumValue(0.1);
    rep->SetMinimumValue(0.001);
    rep->SetValue(tessellator->GetChordError());
    widget->SetEnabled(true);


    Create(myCallback, callback);
    callback->m_tessellator = tessellator;
    callback->m_mapper = mapper;
    callback->m_actor = actor;
    widget->AddObserver(vtkCommand::InteractionEvent, callback);

8.完整代码

cpp 复制代码
#include<vtkIdList.h>
#include<vtkPoints.h>
#include<vtkGlyph3D.h>
#include<vtkProperty.h>
#include<vtkSliderWidget.h>
#include<vtkSphereSource.h>
#include<vtkDataSetMapper.h>
#include<vtkUnstructuredGrid.h>
#include<vtkTessellatorFilter.h>
#include<vtkQuadraticHexahedron.h>
#include<vtkSliderRepresentation3D.h>
#include<vtkMinimalStandardRandomSequence.h>
#include<vtkCommand.h>


#include<vtkNew.h>
#include<vtkRenderer.h>
#include<vtkRenderWindow.h>
#include<vtkPolyDataMapper.h>
#include<vtkRenderWindowInteractor.h>

#define Create(type,name)    vtkNew<type> name


#include<vtkAutoInit.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)


//用于交互回调的类
class myCallback: public vtkCommand
{
public:
    static myCallback *New() {
        return new myCallback;
    }

    vtkTypeMacro(myCallback, vtkCommand);

    void Execute(vtkObject *caller, unsigned long eventId, void *callData)override {
        vtkSliderWidget *slider = (vtkSliderWidget *)caller;
        m_tessellator->SetChordError(slider->GetSliderRepresentation()->GetValue());
        m_tessellator->Update();

    }

    vtkTessellatorFilter *m_tessellator;


private:
    myCallback() {
        m_tessellator = nullptr;

    }
    ~myCallback() {

    }
};

int main()
{

    Create(vtkQuadraticHexahedron, hexadron);
    double *coord = hexadron->GetParametricCoords();
    int num = hexadron->GetNumberOfPoints();
    /*
     * 这两行无法获取数据
    hexadron->GetPoints();
    hexadron->GetPointIds();
    */

    Create(vtkPoints, points);
    Create(vtkIdList, ids);
    
    //最常用的随机类
    Create(vtkMinimalStandardRandomSequence, sequence);
    sequence->SetSeed(5);
    for(int i = 0; i < num; i++)
    {
        double point[3] = {coord[i * 3 + 0], coord[i * 3 + 1], coord[i * 3 + 2]};
        for(int j = 0; j < 3; j++)
        {
            point[j] = point[j] + sequence->GetRangeValue(-0.1, 0.1);
            sequence->Next();
        }
        points->InsertNextPoint(point);
        ids->InsertNextId(i);
    }
    
    
    Create(vtkUnstructuredGrid, grid);
    grid->SetPoints(points);
    grid->InsertNextCell(hexadron->GetCellType(), ids);
    
    //用简式逼近非线性有限元单元
    Create(vtkTessellatorFilter, tessellator);
    tessellator->SetInputData(grid);
    tessellator->SetChordError(0.03);
    tessellator->Update();

    Create(vtkDataSetMapper, mapper);
    mapper->SetInputData(tessellator->GetOutput());


    Create(vtkActor, actor);
    actor->SetMapper(mapper);
    actor->GetProperty()->SetEdgeVisibility(true);
    actor->GetProperty()->SetRepresentationToSurface();

    Create(vtkPolyData, polydata);
    polydata->SetPoints(points);
    
    //放在每个点位置的字形(球)
    Create(vtkSphereSource, sphere);
    sphere->SetRadius(0.02);
    
    //将字形(球)放在每个点位置
    Create(vtkGlyph3D, glyph);
    glyph->SetInputData(polydata);
    glyph->SetSourceConnection(sphere->GetOutputPort());

    Create(vtkPolyDataMapper, gMapper);
    gMapper->SetInputConnection(glyph->GetOutputPort());

    Create(vtkActor, gActor);
    gActor->SetMapper(gMapper);

    Create(vtkRenderer, render);
    render->AddActor(actor);
    render->AddActor(gActor);

    Create(vtkRenderWindow, window);
    window->AddRenderer(render);

    Create(vtkRenderWindowInteractor, inter);
    inter->SetRenderWindow(window);
    
    
    //滑动条
    Create(vtkSliderWidget, widget);
    widget->SetInteractor(inter);
    vtkSliderRepresentation3D *rep = (vtkSliderRepresentation3D *)widget->GetRepresentation();
    rep->GetPoint1Coordinate()->SetValue(-1, -1, 0);
    rep->GetPoint2Coordinate()->SetValue(2, -1, 0);
    rep->SetMaximumValue(0.1);
    rep->SetMinimumValue(0.001);
    rep->SetValue(tessellator->GetChordError());
    widget->SetEnabled(true);
    
    
    //交互回调
    Create(myCallback, callback);
    callback->m_tessellator = tessellator;

    widget->AddObserver(vtkCommand::InteractionEvent, callback);

    inter->Start();


    return 0;
}
相关推荐
AC赳赳老秦6 小时前
采集行为合规自检:OpenClaw 自动校验 robots 协议与采集频率,规避违规采集风险
java·开发语言·c++·python·php·deepseek·openclaw
无名猿6 小时前
C++ 查找算法:std::find 与容器成员 find 的性能差距
c++·性能优化·stl·标准库
程序猿编码7 小时前
工业视觉多任务方案:可编程梯度信息视觉框架,训练评估 + C++ 部署完整实战
开发语言·c++·视觉·推理引擎
朝朝辞暮i8 小时前
C++ 第 21 课:struct —— 把一组相关数据打包在一起
开发语言·c++·算法
SHARK_pssm9 小时前
【C++——类和对象(下)】
开发语言·c++·经验分享·笔记
汉克老师9 小时前
GESP2026年9月认证C++二级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
沫璃染墨10 小时前
《从零入门Linux系统篇(五十四):线程篇·七——互斥锁底层原理:从原子交换到线程竞争与锁实现》
linux·运维·服务器·开发语言·c++·驱动开发·系统架构
可乐ea11 小时前
GitHub Security Lab 开源 Fuzzing Taskflow:让 LLM 智能体自己跑完 C/C++ 模糊测试
jvm·c++·github·模糊测试·mcp·代码agent·智能体自动化
朝朝辞暮i11 小时前
C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?
java·c++·算法
无忧.芙桃13 小时前
C++语言原理与实践(十):vector类的底层实现
开发语言·c++·算法