VTK|.obj文件数据处理+Jet/Viridis/CoolToWarm/Grayscale/Rainbow/风格颜色渲染

.obj 数据进行 Elevation 着色并可视化渲染的完整流程

和.ply文件处理方式一样

处理OBJ文件


void ThreeDimensionalDisplayPage::loadObjFile(vtkSmartPointer<vtkPolyData> _poly_data)
{
    renderer_->RemoveAllViewProps();
    renderer_->SetBackground(1.0, 1.0, 1.0); // 白色背景

    // 获取边界和中心
    double bounds[6];
    _poly_data->GetBounds(bounds);
    double center[3] = {
        (bounds[0] + bounds[1]) / 2.0,
        (bounds[2] + bounds[3]) / 2.0,
        (bounds[4] + bounds[5]) / 2.0};

    // Elevation Filter 按 Z 值添加标量
    vtkNew<vtkElevationFilter> elevationFilter;
    elevationFilter->SetInputData(_poly_data);
    elevationFilter->SetLowPoint(0, 0, bounds[4]);  // 最低Z
    elevationFilter->SetHighPoint(0, 0, bounds[5]); // 最高Z
    elevationFilter->Update();

    // 获取标量范围
    double scalarRange[2];
    elevationFilter->GetOutput()->GetScalarRange(scalarRange);

    vtkSmartPointer<vtkLookupTable> colorLookupTable = createJetLookupTable(scalarRange[0], scalarRange[1]);

    // 映射器
    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(elevationFilter->GetOutputPort());
    mapper->SetScalarRange(scalarRange);
    mapper->SetLookupTable(colorLookupTable);
    mapper->SetColorModeToMapScalars();
    mapper->ScalarVisibilityOn();

    // 面Actor
    surfaceActor_ = vtkSmartPointer<vtkActor>::New();
    surfaceActor_->SetMapper(mapper);
    surfaceActor_->GetProperty()->SetOpacity(1.0);
    renderer_->AddActor(surfaceActor_);
    surfaceActor_->SetVisibility(is_surface_visible_);

    // 线框Actor
    wireframeActor_ = vtkSmartPointer<vtkActor>::New();
    wireframeActor_->SetMapper(mapper);
    wireframeActor_->GetProperty()->SetRepresentationToWireframe();
    wireframeActor_->GetProperty()->SetColor(0.2, 0.2, 0.2);
    wireframeActor_->GetProperty()->SetLineWidth(1.0);
    renderer_->AddActor(wireframeActor_);
    wireframeActor_->SetVisibility(is_wireframe_visible_);

    // 点Actor
    pointsActor_ = vtkSmartPointer<vtkActor>::New();
    pointsActor_->SetMapper(mapper);
    pointsActor_->GetProperty()->SetRepresentationToPoints();
    pointsActor_->GetProperty()->SetPointSize(6);
    pointsActor_->GetProperty()->SetColor(0.0, 0.0, 1.0);
    renderer_->AddActor(pointsActor_);
    pointsActor_->SetVisibility(is_points_visible_);

    renderer_->ResetCamera();
    renderWindow_->Render();
    m_pScene->update();
}

将jet风格渲染封装成了一个函数,统一调用

Jet渲染风格


vtkSmartPointer<vtkLookupTable> ThreeDimensionalDisplayPage::createJetLookupTable(double minValue, 
double maxValue, double gamma)
{
    auto lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(256);
    lut->SetRange(minValue, maxValue); // 设置标量范围

    for (int i = 0; i < 256; ++i)
    {
        double t = static_cast<double>(i) / 255.0;

        // 非线性调整 t,使颜色更集中于中间值
        t = std::pow(t, gamma);

        // Jet 配色映射:蓝 → 青 → 绿 → 黄 → 红
        double r = std::clamp(1.5 - std::abs(4.0 * t - 3.0), 0.0, 1.0);
        double g = std::clamp(1.5 - std::abs(4.0 * t - 2.0), 0.0, 1.0);
        double b = std::clamp(1.5 - std::abs(4.0 * t - 1.0), 0.0, 1.0);

        lut->SetTableValue(i, r, g, b);
    }

    lut->Build();
    return lut;
}

在这里插入图片描述

Viridis渲染风格

vtkSmartPointer<vtkLookupTable> ThreeDimensionalDisplayPage::createViridisLookupTable(double minValue,
 double maxValue)
{
    auto lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(256);
    lut->SetRange(minValue, maxValue);

    for (int i = 0; i < 256; ++i)
    {
        double t = i / 255.0;
        // 近似 Matplotlib Viridis 色带(更精确的RGB值可参考官方定义)
        double r = 0.2795 + 0.4702 * t + 0.1649 * t * t - 0.0008 * t * t * t;
        double g = 0.0021 + 0.7047 * t + 0.0704 * t * t - 0.0053 * t * t * t;
        double b = 0.3904 + 0.1066 * t + 0.1968 * t * t - 0.0641 * t * t * t;
        lut->SetTableValue(i, r, g, b);
    }
    lut->Build();
    return lut;
}

在这里插入图片描述

CoolToWarm渲染风格

vtkSmartPointer<vtkLookupTable> ThreeDimensionalDisplayPage::createCoolToWarmLookupTable(double minValue,
 double maxValue)
{
    auto lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(256);
    lut->SetRange(minValue, maxValue);

    for (int i = 0; i < 256; ++i)
    {
        double t = i / 255.0;
        double r = t;                     // 红:从0→1
        double g = 1 - fabs(t - 0.5) * 2; // 绿:中间最亮
        double b = 1 - t;                 // 蓝:从1→0
        lut->SetTableValue(i, r, g, b);
    }
    lut->Build();
    return lut;
}

在这里插入图片描述

Grayscale渲染风格

vtkSmartPointer<vtkLookupTable> ThreeDimensionalDisplayPage::createGrayscaleLookupTable(double minValue, 
double maxValue)
{
    auto lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(256);
    lut->SetRange(minValue, maxValue);

    for (int i = 0; i < 256; ++i)
    {
        double gray = i / 255.0; // 从黑→白
        lut->SetTableValue(i, gray, gray, gray);
    }
    lut->Build();
    return lut;
}

在这里插入图片描述

Rainbow渲染风格


vtkSmartPointer<vtkLookupTable> ThreeDimensionalDisplayPage::createRainbowLookupTable(double minValue,
 double maxValue)
{
    auto lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(256);
    lut->SetHueRange(0.666, 0.0); // 色相从蓝(0.666)→红(0.0)
    lut->SetSaturationRange(1.0, 1.0);
    lut->SetValueRange(1.0, 1.0);
    lut->SetRange(minValue, maxValue);
    lut->Build();
    return lut;
}

在这里插入图片描述

切换风格按钮槽函数(可优化)

void ThreeDimensionalDisplayPage::updateColorStyle(int style)
{
    current_color_style = style;
    if (ply_point_actor_) // PLY点云模型
    {
        auto mapper = vtkPolyDataMapper::SafeDownCast(ply_point_actor_->GetMapper());
        if (mapper)
        {
            vtkSmartPointer<vtkLookupTable> new_lut;
            switch (style)
            {
            case 0:
                new_lut = createJetLookupTable(current_scalar_range[0], current_scalar_range[1], 1.0);
                break;
            case 1:
                new_lut = createViridisLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 2:
                new_lut = createCoolToWarmLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 3:
                new_lut = createGrayscaleLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 4:
                new_lut = createRainbowLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            }
            mapper->SetLookupTable(new_lut);
            renderWindow_->Render();
        }
    }
    if (surfaceActor_) // OBJ网格模型
    {
        auto mapper = vtkPolyDataMapper::SafeDownCast(surfaceActor_->GetMapper());
        if (mapper)
        {
            vtkSmartPointer<vtkLookupTable> new_lut;
            switch (style)
            {
            case 0:
                new_lut = createJetLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 1:
                new_lut = createViridisLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 2:
                new_lut = createCoolToWarmLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 3:
                new_lut = createGrayscaleLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            case 4:
                new_lut = createRainbowLookupTable(current_scalar_range[0], current_scalar_range[1]);
                break;
            }
            mapper->SetLookupTable(new_lut);
            renderWindow_->Render();
        }
    }
}

相关代码git链接

https://gitee.com/strange-tree-qian/vtktest

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奇树谦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值