osg学习-6《显示三维矩阵》

在三维空间显示三维矩阵,需要显示它的6个外表面。假设xyz三个方向的维数是ni,nj,nk,三个方向的顶点维数是ni+1,nj+1, nk+1。在每个面上分别绘制各自的四边形。每个四边形的颜色根据矩阵的值获取,这个例子采用了离散的数值。使用了之前创建的颜色模板类。

 

void DrawShape::drawDisModel3D(const IModel3D<int>& disM, float dx = 1.0, float dy = 1.0, float dz = 1.0)
{
    // 创建一个节点对象
        osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    //创建一个集合对象
    osg::ref_ptr<osg::Geometry> geom = new osg::Geometry();

    int nk = disM.nk();
    int nj = disM.nj();
    int ni = disM.ni();

    
    //创建顶点数组
    osg::ref_ptr<osg::Vec3Array> vertx = new osg::Vec3Array();
    for (int k = 0; k <= nk; k++) {
        for (int j = 0; j <= nj; j++) {
            for (int i = 0; i <= ni; i++) {
                vertx->push_back(osg::Vec3(i * dx, j * dy, k * dz));
            }
        }
    }

    int vmin = INT32_MAX;
    int vmax = -vmin;
    disM.getMinMax(vmin, vmax);
    std::cout << "vmin: " << vmin << " vmax: " << vmax << std::endl;
    //_colors = ColorTemplate<float>("rainbow");
    _colors = ColorTemplate<float>();

    //设置顶点数据
    geom->setVertexArray(vertx.get());
    //创建颜色数组
    osg::ref_ptr<osg::Vec4Array> vcolor = new osg::Vec4Array();

    progressbar pbar(ni * nj * 2 + ni * nk * 2 + nj * nk * 2);
    int seq = 0;
    int k = 0;
    for (int j = 0; j < nj; j++) {
        for (int i = 0; i < ni; i++) {
            int index = k * (nj+1)*(ni+1) +  j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + ni + 1);
            quad->push_back(index + ni + 2);
            quad->push_back(index + 1);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i,k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
       
    }
    k = nk-1;
    for (int j = 0; j < nj; j++) {
        for (int i = 0; i < ni; i++) {
            int index = k * (nj+1) * (ni+1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + 1);
            quad->push_back(index + ni + 2);
            quad->push_back(index + ni + 1);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    int i = 0;
    for (int j = 0; j < nj; j++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj+1) * (ni+1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            quad->push_back(index + (nj + 1) * (ni + 1) + ni + 1);
            quad->push_back(index + ni + 1);
            
            
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    i = ni-1;
    for (int j = 0; j < nj; j++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj + 1) * (ni + 1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + ni + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + ni + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    int j = 0;
    for (int i = 0; i < ni; i++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj + 1) * (ni + 1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + 1);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }
    j = nj-1;
    for (int i = 0; i < ni; i++) {
        for (int k = 0; k < nk; k++) {
            int index = k * (nj + 1) * (ni + 1) + j * (ni + 1) + i;
            //创建四边形定点数组,指定绘图基元为四边形,注意添加顺序
            osg::ref_ptr<osg::DrawElementsUInt> quad =
                new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
            quad->push_back(index);
            quad->push_back(index + (nj + 1) * (ni + 1) + 0);
            quad->push_back(index + (nj + 1) * (ni + 1) + 1);
            quad->push_back(index + 1);
                       
            //添加到几何体
            geom->addPrimitiveSet(quad.get());
            auto color = _colors.getColor(disM.getValue(j, i, k));
            vcolor->push_back(Vec4f(color.r, color.g, color.b, color.alpha));  //random color
            seq++;
            if (seq % 1000 == 0) {
                pbar.progress = seq;
                pbar.update();
            }
        }
    }

    //设置颜色数组
    geom->setColorArray(vcolor.get());

    //设置颜色的绑定方式为单个顶点
    //geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);

    // 创建法线数组
    osg::ref_ptr<osg::Vec3Array>nc = new osg::Vec3Array();

    //添加法线
    nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
    nc->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
    nc->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
    nc->push_back(osg::Vec3(0.0f, 0.0f, -1.0f));
    nc->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
    nc->push_back(osg::Vec3(-1.0f, 0.0f, 0.0f));

    // 设置法线数组
    geom->setNormalArray(nc.get());
    //设置法线的绑定方式为全部顶点
    geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

    //添加到叶节点
    geode->addDrawable(geom.get());


    osg::ref_ptr < osg::MatrixTransform> scale = new osg::MatrixTransform;
    //scale->setMatrix(osg::Matrix::scale(0.5, 0.5, 0.5) * osg::Matrix::translate(0, 0, -2));
    scale->setMatrix(osg::Matrix::scale(1, 1, 1));

    makeCoordinate(-10, -10, -10, 10,10,10,5);
    _root->addChild(geode);
    _root->addChild(scale);

    _viewer->run();
}

 

posted @ 2022-08-21 10:12  Oliver2022  阅读(182)  评论(0编辑  收藏  举报