(一)CGAL库应用:指定平面切割模型并用openGL显示该层面轮廓

1、先看效果图
(一)CGAL库应用:指定平面切割模型并用openGL显示该层面轮廓_第1张图片

(一)CGAL库应用:指定平面切割模型并用openGL显示该层面轮廓_第2张图片

图一是笔者使用solidworks随手画的,并没有特殊含义,只是特意拉伸几个形态各异的孔,以凸显截取模型层面的效果,长方体整体的尺寸是600600400;
图二是程序运行的效果图,C++控制台程序,模型处理使用的是cgal库,画图用的是openGL,截取的高度是z=200的位置。(csdn图片的大小安排不如之前那么方便了,布局莫名奇妙~)

2、整体思路
1)solidworks画出三维模型,然后另存为stl文件,stl文件是用三角形面片表示的三维网格,文件存储的是点和三角形面片信息,有ASCII和binary两种存储格式,其中ASCII格式可以用记事本打开,binary用记事本打开则会乱码,这里使用ASCII格式保存,这些都可以在solidworks中设置,不过,现在主流的三位模型软件都可以生成stl文件,如UG之类的(不得不说笔者更喜欢UG呀,但是也就那样吧,用电脑画图没意思,还是手画比较惬意~);

2)写一段python脚本,将stl转换成off文件,off文件同样是三维模型的存储文本文件,不过相对stl而言,off不再局限于三角形面片,四边形五边形都可以,因为cgal的mesh模型可以直接导入off文件,所以就把stl转为off,两种文件的转换,笔者懒得自己写了,就用了另一个博主的脚本,将stl转换成off,链接在此:“https://blog.csdn.net/renjiangui/article/details/76250736”,感谢这位博主哥,不过有一点小问题,让我焦头烂额了个把小时,因为生成的off文件一经代码input,计算机就会呼呼作响,怎么也载入不了模型,当时就觉得好奇怪,一个简单的长方体模型不至于这么久吧,于是用记事本打开off文件,找啊找啊,还是找到了原因,原来这段脚本生成的off文件,第二个参数面片数,赫然写着32.0,我当时心里真的是超级无语了,面片数怎么可能是浮点数呢?改成整数当然就OK啦,后面想学cgal库的童鞋可要注意啦,这个点非常坑~~~~~~(估计也没人看,因为cgal库使用的人确实不多,而且对初学者而言,可以说是相当不友好了,虽然笔者也是初学者,哈哈);
3)有了数据,然后是写代码,应用cgal库进行模型的切割,获得轮廓;
4)使用openGL将轮廓画出来,确实挺简单的哈。

3、程序代码

#include 
#include 
#include //以上是本文用到的cgal头文件
#include//openGL头文件
#include 
#include
#include< utility>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point;
typedef K::Segment_3 segment;
typedef std::vector My_Polyline;
typedef CGAL::Surface_mesh Mesh;
//cgal库里面定义了很多内核,每个内核代表特定的场景,相应的场景有相应的模型
//CGAL::Exact_predicates_inexact_constructions_kernel,这个内核代表使用笛卡尔坐标系,以及
//对应的齐次坐标系,然后是定义这样的坐标系下的模型,如三维点Point_3,三维线段Segment_3,
//My_Polyline、Mesh分别表示三维轮廓以及三维网格


void display() {
glClear(GL_COLOR_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 1, 0);
 for (auto K : temp_Polylines) {
  glBegin(GL_POLYGON);
  for (int i = 0; i < K.size(); ++i) {
   glVertex2d(K[i].x(), K[i].y());
  }
  glEnd();
  glFinish();
 }//openGL画图时用的回调函数,这里只是简单地画出轮廓;

int main(int argc, char* argv[]) {

 const char* filename = "3.off";
 std::ifstream input(filename);
 Mesh mesh;
 if (!input || !(input >> mesh) || mesh.is_empty()
  || !CGAL::is_triangle_mesh(mesh)) {
  std::cerr << "Not a valid input file." << std::endl;
  return 1;
 }//载入off模型

CGAL::Polygon_mesh_slicer slicer(mesh);
 slicer(K::Plane_3(0, 0,1, -200), std::back_inserter(temp_Polylines));//直接定义slicer进行模型界面获取,没错,就是
 //这么简单,一段代码实现切平面(平面定义是ax+by+cz+d=0,所以本例的切平面就是z=200)截取模型,轮廓
 //点的数据全部存储在temp_Polylines中,接下来就简单地用openGL将这条轮廓画出来吧。

//一些初始化操作
 glutInit(&argc, argv);   //初始化GLUT
 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
 glutInitWindowPosition(300, 300);
 glutInitWindowSize(800,800);
 glutCreateWindow("RT");
 glClearColor(0.0, 0.0, 0.0, 0);
 glClear(GL_COLOR_BUFFER_BIT);
 glPointSize(1);
 glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
 gluOrtho2D(-100, 700,-100, 700);
glutDisplayFunc(&display);//初始化操作到这里都是定义窗口的属性,这里调用回调函数,进行轮廓的绘画
 glutMainLoop();    //持续显示,当窗口改变会重新绘制图形

system("pause");
 return 0;
 }
 

4 结语
中间隔了差不多五个月没有在CSDN上写博客了,虽然本想继续写数值分析的博客的,但是无奈数值分析期末考试考得太差了,所以,哈哈,虽然学得认真,但考试真的不能强求啊,安慰安慰自己;
中间做过目标检测的课程设计,虚拟机安装过Linux,学习数据结构和算法等等都可以写博客,但是觉得这些东西大家都写的很好,我也没必要再多费笔墨,所以就暂时隔了这么久没有在这上面写过东西了,这次是因为课题研究的关系,用到了cgal库,觉得很有意思,于是就写了这么一小段博客,其实,我还是觉得,这些文字更多是写给自己看的吧!

友情提示:安装并编译cgal库有些复杂,需要耐心!安装openGL倒是很简单,加油哦~

你可能感兴趣的:(cgal库应用,C++,cgal,泛型编程,OpenGL)