那么话不多说了啊,最近发现代码链接失效问题,那么没关系,全部源码已经分享到我置顶的文章上面了。
如果仍然发现失效问题(博主也是个白痴呢),请务必加我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
在传送门中尽情地下载吧!
在传送门中尽情地下载吧!
在传送门中尽情地下载吧!
我希望大家在下载后将体验效果即使反馈给我,我究竟还有什么做的不好的地方,或者我应该朝着什么样的方向进行学习,都请毫无保留地告诉我吧!
之前代码由于没有免费,给大家造成学习上的阻碍,还请原谅!
在传送门中尽情地下载吧!