qt + osg 根据高程变色之 渐变色

本文介绍了如何使用两种色卡对点云数据进行颜色映射,并结合osg::PageLOD技术,实现根据高程动态调整颜色效果,同时支持自定义色卡和循环变色功能。通过VBO更新实时响应模型变化。
该文章已生成可运行项目,

 两种色卡,读取点云中的坐标颜色等顶点信息,构建osg::pagelod显示,根据高程VBO动态变色

色卡1

循环高程20

起始高度50

 色卡2

void changeColor()
{
    VertexVisitor visitor = VertexVisitor();
    m_totalRoot->accept(visitor);    // 自定义遍历,获取所有结点xyz最大最小值

    double min, max;
    switch (filtering_axis_)     // 选择按x.y或z坐标系变色
    {
    case 0:  // x
        min = visitor.min_x();
        max = visitor.max_x();
        break;
    case 1:  // y
        min = visitor.min_y();
        max = visitor.max_y();
        break;
    default:  // z
        min = visitor.min_z();
        max = visitor.max_z();
        break;
    }

    if(color_mode_2 == 0)   // 不选择 “循环变色”
    {
        grading_height_ = max - min;    // grading_height_ 为 “循环变色”循环高度
    }
    if(ui->lineEdit_startHeight2->text().isEmpty() || color_mode_2 == 0)
    {
        start_height_ = min;   // start_height_ 为自定义色卡起始高度,色卡循环
    }

    double lut_scale = 1.0 / grading_height_;
    if (min == max)  lut_scale = 0.01;          

    if(color_mode_2 == 1)        // 选择 “循环变色”
    {
        while( start_height_ > min )
        {
            start_height_ -= grading_height_;
        }
        min = start_height_;    //找到最低色卡起始位置
    }

    // 定义相机位置,模型显示居中
    m_pOsgQOpenGLWidget->getOsgViewer()->getCameraManipulator()->computeHomePosition();
    m_pOsgQOpenGLWidget->getOsgViewer()->getCameraManipulator()->home( 0.0 );
    
    std::vector<osg::Geometry*> geomArray = visitor.getGeometryArray();
    for(unsigned int i = 0; i<geomArray.size(); i++)
    {
        osg::Geometry *geometry = geomArray.at(i);
        geometry->setDataVariance(osg::Object::DYNAMIC);  //动态更新,随时变色,不用从新构建lod
        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
        osg::Vec4Array* color = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());

        for(int j = 0; j<vertices->size(); j++)
        {
            osg::Vec3 vertexT = vertices->at(j);
            osg::Vec4 colorT = color->at(j);
            double value;
            switch (filtering_axis_)
            {
            case 0:  // x
                if(color_mode_2 == 1)
                {
                    value = fmod((vertexT.x() - min), grading_height_) * lut_scale;  // Round the number to the closest integer
                }
                else
                    value = (vertexT.x() - min) * lut_scale;  // Round the number to the closest integer
                break;
            case 1:  // y
                if(color_mode_2 == 1)
                {
                    value = fmod((vertexT.y() - min), grading_height_) * lut_scale;
                }
                else
                    value = (vertexT.y() - min) * lut_scale;
                break;
            default:  // z
                if(color_mode_2 == 1)
                {
                    value = fmod((vertexT.z() - min), grading_height_) * lut_scale;  //循环着色
                }
                else
                    value = (vertexT.z() - min) * lut_scale;
                break;
            }
// 色卡1,颜色较少
            colorT.r() = value > 0.5 ? (value - 0.5) * 2 : 0;  // r[0.5] = 0, r[1] = 1
            colorT.g() = value < 0.5 ? 2 * value : 1 - ( (value - 0.5) * 2);  // g[0] = 0, g[0.5] = 1, g[1] = 0
            colorT.b() = value < 0.5 ? 1 - (2 * value) : 0;  // b[0] = 1, b[0.5] = 0

//色卡2,颜色多
//  value *= 6.0;
//            if(value <1)
//            {
//                colorT.r() = 1;
//                colorT.g() = 0;
//                colorT.b() = value;
//            }
//            else if(value <2 )
//            {
//                value = value-1;
//                colorT.r() = 1 - value;
//                colorT.g() = 0;
//                colorT.b() = 1;
//            }
//            else if(value <3)
//            {
//                value = value-2;
//                colorT.r() = 0;
//                colorT.g() = value;
//                colorT.b() = 1;
//            }
//            else if(value <4)
//            {
//                value = value-3;
//                colorT.r() = 0;
//                colorT.g() = 1;
//                colorT.b() = 1 - value;
//            }
//            else if(value <5)
//            {
//                value = value-4;
//                colorT.r() = value;
//                colorT.g() = 1;
//                colorT.b() = 0;
//            }
//            else
//            {
//                value = value-5;
//                colorT.r() = 1;
//                colorT.g() = 1 - value;
//                colorT.b() = 0;
//            }
            colorT.a() = 1;  //透明度
            vertices->at(j).set(vertexT.x(), vertexT.y(), vertexT.z());
            color->at(j) = colorT;
        }

        // 更新显示列表
        geometry->dirtyDisplayList();//使用VBO来更新几何对象
        vertices->dirty();
    }
    ui->pointsViewer->update();
}

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值