QT opengl 模仿CC~现在可以显示彩色点云啦

13 篇文章 2 订阅
12 篇文章 4 订阅

那么话不多说了啊,最近发现代码链接失效问题,那么没关系,全部源码已经分享到我置顶的文章上面了。

如果仍然发现失效问题(博主也是个白痴呢),请务必加我QQ 498771026

相信很多人用过CC,也就是CloudCompare。这款软件对于点云的读取和显示有点厉害。

我相信每一个学QT的孩纸都想有自己的点云软件。那么这一次我就来模仿CloudCompare,基本完成。

我不可能把所有代码都贴到博客里面来,但是我可以把这个大工程全部分享给大家。

http://download.csdn.net/download/qq_30547073/9997224

因为有的时候一件事情会花去很多精力,如果花费过多时间在写博客上,就没有时间学习更多东西了,毕竟我本身也是菜鸟。

但是我会吧思路给大家说清楚,贴一点核心代码,大家可以慢慢琢磨,也省了不少事情。

思路主要是这样的:

(1)首先你必须自己写一个点云读取类,可以使用文件映射高速读取ptx、pts、txt、asc、ply、pcd格式的点云。并可以判断任意字段长度,是否有RGB等。这一个文件我已经写好并放在工程目录下了。好像叫qscarlet_CloudIO什么的。

(2)进行opengl显示。这就必须去学opengl了,只是为了显示外包核和点云的话不是那么难。

(3)其余的杂七杂八的逻辑判断,比方说,QTreeView只有当单击的时候才显示外包核,用Checkbox判断是否显示点云等。这个必须多看看connect函数还有模型视图等。。。

(4)利用滚轮可以控制缩放,利用鼠标可以进行旋转。
目前opengl的相机模块研究不是很透彻,我会继续学习的。


//============读取并绘制点云
bool GL_SortPtID(const VertexPositionColor &P1, const VertexPositionColor &P2)//自定义排序
{
    return(P2.PtID > P1.PtID);//小到大
    //return(P1.PtID > P2.PtID);//大到小
}
void DrawStationPoint(std::vector<Station> Stations)
{
    for(int i=0;i<Stations.size();i++)
    {
        Station OneStation = Stations[i];
        if(OneStation.ifshowCloud!=true)//响应树节点的checkbox
            continue;
        VertexPositionColor gravity = OneStation.Gravity;

        VertexPositionColor *Cloud = OneStation.PointIO.PtCloud().PointCloud;
        int Num = OneStation.PointIO.PtCloud().PointNum;
        for(int i=0;i<Num;i++)
        {
            GLdouble x =Cloud[i].x- gravity.x;//减去重心
            GLdouble y =Cloud[i].y- gravity.y;
            GLdouble z =Cloud[i].z- gravity.z;
            GLdouble r = Cloud[i].R;
            GLdouble g = Cloud[i].G;
            GLdouble b = Cloud[i].B;
            if(r>=0.0&&r<=1.0&&g>=0.0&&g<=1.0&&b>=0.0&&b<=1.0)
            {
                glColor3f( r, g, b );
                glVertex3d(x,y,z);
            }
            else if(r>=0.0&&r<=255.0&&g>=0.0&&g<=255.0&&b>=0.0&&b<=255.0)
            {
                glColor3f( r/255.0, g/255.0, b/255.0 );
                glVertex3d(x,y,z);
            }
            else
            {
                glVertex3d(x,y,z);
            }
        }
    }

}
void DrawStationBox(std::vector<Station> Stations)
{
    for(int i=0;i<Stations.size();i++)
    {
        Station OneStation = Stations[i];
        if(OneStation.ifshowCloud!=true)//如果这块点云不让显示,自然也不能显示外包核
            continue;
        if(OneStation.ifshowBox!=true)//响应树节点的checkbox
            continue;
        VertexPositionColor BoxMa = OneStation.m_box.MaxPoint;
        VertexPositionColor BoxMi = OneStation.m_box.MinPoint;
        VertexPositionColor gravity = OneStation.Gravity;
        BoxMa.x -= gravity.x; BoxMi.x -= gravity.x;
        BoxMa.y -= gravity.y; BoxMi.y -= gravity.y;
        BoxMa.z -= gravity.z; BoxMi.z -= gravity.z;
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMi.x,BoxMi.y,BoxMi.z); glVertex3d(BoxMa.x,BoxMi.y,BoxMi.z);//小Z四条棱
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMa.x,BoxMi.y,BoxMi.z); glVertex3d(BoxMa.x,BoxMa.y,BoxMi.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMa.x,BoxMa.y,BoxMi.z); glVertex3d(BoxMi.x,BoxMa.y,BoxMi.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMi.x,BoxMa.y,BoxMi.z); glVertex3d(BoxMi.x,BoxMi.y,BoxMi.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMi.x,BoxMi.y,BoxMa.z); glVertex3d(BoxMa.x,BoxMi.y,BoxMa.z);//大Z四条棱
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMa.x,BoxMi.y,BoxMa.z); glVertex3d(BoxMa.x,BoxMa.y,BoxMa.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMa.x,BoxMa.y,BoxMa.z); glVertex3d(BoxMi.x,BoxMa.y,BoxMa.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMi.x,BoxMa.y,BoxMa.z); glVertex3d(BoxMi.x,BoxMi.y,BoxMa.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMi.x,BoxMi.y,BoxMa.z); glVertex3d(BoxMi.x,BoxMi.y,BoxMi.z);//Z从小到大四条
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMa.x,BoxMi.y,BoxMa.z); glVertex3d(BoxMa.x,BoxMi.y,BoxMi.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMa.x,BoxMa.y,BoxMa.z); glVertex3d(BoxMa.x,BoxMa.y,BoxMi.z);
        glColor3f( 1.0, 1.0, 0.0 );
        glVertex3d(BoxMi.x,BoxMa.y,BoxMa.z); glVertex3d(BoxMi.x,BoxMa.y,BoxMi.z);

    }
}
void CallAttribute(Station& station)
{
    VertexPositionColor *PCloud = station.PointIO.PtCloud().PointCloud;
    int PointNum =station.PointIO.PtCloud().PointNum;
    VertexPositionColor minPoint;
    VertexPositionColor maxPoint;
    VertexPositionColor center;
    VertexPositionColor gravity;
    for(int i=0;i<PointNum;i++)
    {
        VertexPositionColor Tpoint =PCloud[i];
        if(i==0)
        {
            minPoint =Tpoint;
            maxPoint = Tpoint;
            center = Tpoint;
        }
        else
        {
            if(Tpoint.x<=minPoint.x)minPoint.x = Tpoint.x;
            if(Tpoint.y<=minPoint.y)minPoint.y = Tpoint.y;
            if(Tpoint.z<=minPoint.z)minPoint.z = Tpoint.z;
            if(Tpoint.x>=maxPoint.x)maxPoint.x = Tpoint.x;
            if(Tpoint.y>=maxPoint.y)maxPoint.y = Tpoint.y;
            if(Tpoint.z>=maxPoint.z)maxPoint.z = Tpoint.z;
            gravity.x+=Tpoint.x;
            gravity.y+=Tpoint.y;
            gravity.z+=Tpoint.z;
        }
    }
    gravity.x/=(double)PointNum;
    gravity.y/=(double)PointNum;
    gravity.z/=(double)PointNum;
    center.x =(minPoint.x+maxPoint.x)/2.0;
    center.y =(minPoint.y+maxPoint.y)/2.0;
    center.z =(minPoint.z+maxPoint.z)/2.0;
    cout<<"box min:"<<minPoint<<endl;
    cout<<"box max:"<<maxPoint<<endl;
    cout<<"Gravity:"<<center<<endl;
    station.m_box.MinPoint = minPoint;
    station.m_box.MaxPoint = maxPoint;
    station.m_box.BoxCenter =center;
    station.Gravity =gravity;
    station.ifshowCloud = true;
    station.ifshowBox = false;
}
void qScarletOpenglInterface::ReadAndShowCloud(QString Q_FileName)
{
    ifDrawTenRabbit = false;
    std::string SelectedCloudPath = Q_FileName.toStdString();
    std::cout<<SelectedCloudPath<<std::endl;
    ScarletCloudIO myScarletCloudIO(SelectedCloudPath);
    myScarletCloudIO.Read();
    myScarletCloudIO.PrintStationStatus();
    VertexPositionColor *PCloud = myScarletCloudIO.PtCloud().PointCloud;
    int PointNum =myScarletCloudIO.PtCloud().PointNum;
    cout<<PCloud[0]<<endl;//第一个
    cout<<PCloud[PointNum -1]<<endl;//最后一个

    Station station;
    station.PointIO =myScarletCloudIO;
    CallAttribute(station);//有了点云之后计算其它属性。。。
    m_Stations.push_back(station);
    ifDrawStation = true;
    emit(signal_Cloudloaded());

    //针对兔子数据
    //只要不加这句话,兔子就不会显示,兔子测试数据位置://D:\Ninja\NinjaResource\PointCloud\Bunny.xyz
    //ReadAndShowTenRabbit(SelectedCloudPath);
}
//控制点云显示状况
void qScarletOpenglInterface::SetIfShowCheckCloud(int Index,bool ifshow)
{
    qDebug()<<"Control "<<Index<<" "<<ifshow;
    if(Index<0||Index>=m_Stations.size())
        return;
    Station StationGet = m_Stations[Index];
    StationGet.ifshowCloud =ifshow;
    m_Stations[Index] = StationGet;//还得赋值回去
}
void qScarletOpenglInterface::SetSelectedCloud(int Index,bool ifshow)//是否绘制外包核
{

    qDebug()<<"Control "<<Index<<" "<<ifshow;
    if(Index<0||Index>=m_Stations.size())
        return;

    //关闭其它外包核的显示:
    for(int i=0;i<m_Stations.size();i++)
    {
        Station StationGet = m_Stations[i];
        if(i==Index)
            StationGet.ifshowBox =ifshow;
        else
            StationGet.ifshowBox = false;
        m_Stations[i] = StationGet;//还得赋值回去
    }

}
void qScarletOpenglInterface::paintGL_TextureAndLight()
{
    //loadGLTextures();
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    //DrawBackGround(m_camera, m_texturFrame);//绘制背景======
    glLoadIdentity();   
    glTranslatef(  0.0,  0.0, zoom );
    glRotatef( xRot,  1.0,  0.0,  0.0 );
    glRotatef( yRot,  0.0,  1.0,  0.0 );
    glBindTexture( GL_TEXTURE_2D, m_texture[filter] );

    glBegin( GL_QUADS );//绘制立方体===============
    //DrawCub();
    glEnd();

    if(ifDrawTenRabbit == true)//绘制十倍兔===============
    {
        glBegin( GL_POINTS );
        DrawRabbit(m_TenRabbit);
        glEnd();
    }
    if(ifDrawStation == true)//绘制每一站===============
    {
        glBegin( GL_POINTS );
        DrawStationPoint(m_Stations);
        glEnd();
        glBegin( GL_LINES );
        DrawStationBox(m_Stations);
        glEnd();
    }

    //这里绘制正方体的方法,上一章已经讲解过了。
    //将xRot和yRot的旋转值分别增加xSpeed和ySpeed个单位。xSpeed和ySpeed的值越大,立方体转得就越快。
    xRot += xSpeed;
    yRot += ySpeed;
    SetAirShutDown(0.025);
    glLoadIdentity();
    //你每次paint的时候都要调用
    if ( !ligtht )//是否光照
    {
      glDisable( GL_LIGHTING );
    }
    else
    {
      glEnable( GL_LIGHTING );
    }
    if ( blend )//是否融合
    {
      glEnable( GL_BLEND );
      glDisable( GL_DEPTH_TEST );
    }
    else
    {
      glDisable( GL_BLEND );
      glEnable( GL_DEPTH_TEST );
    }
}



光棍节到了,那么关于本人代码的免费分享

最近CSDN有点走歪路了。
    我发现随着我上传的资源的下载量增加,tmd竟然收取的积分也越来越多了。
    代码的魅力就在于原创与开源。靠着别人上传的资源去赚取利益是不对的。
    所以为了秉承分享的精神,以后我会将代码分享到百度网盘中,随着时间更新,我会将每一个版本都上传上去,供大家免费下载。
    第一波链接在这里了:

https://pan.baidu.com/s/1qYLro0c

在传送门中尽情地下载吧!
    在传送门中尽情地下载吧!
    在传送门中尽情地下载吧!
    我希望大家在下载后将体验效果即使反馈给我,我究竟还有什么做的不好的地方,或者我应该朝着什么样的方向进行学习,都请毫无保留地告诉我吧!
    之前代码由于没有免费,给大家造成学习上的阻碍,还请原谅! 
    在传送门中尽情地下载吧!

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值