欢迎光临散文网 会员登陆 & 注册

STL模型在单片机上3D旋转显示

2023-07-05 14:46 作者:村夫唐某  | 我要投稿

STL文/件说明:

  STL文/件是一种由三角形面组成3D模型的文/件,常用于3D打印机。 由于经常接触,就很好奇SLT文件到底怎么组成的?还可以怎么玩? 1:STL分为BIN格式和ASCLL格式。 BIN格式的构成大概就一堆二进制文/件,需要对应结构解码使用。

ASCLL格式则是文本格式,用记事本就可以直观看到数据说明。

这里我的代码是使用的BIN文/件格式解码。。。 2:BIN格式STL文件说明 可以看到图片中的数据,前80字节为文/件描述头,

紧接着就是4字节的关键数据:构成物体的三角面个数。 源码部分也是通过它来  【校验是否为BIN格式】  和  【显示(点/线/面)】。

紧接着的就是每个面的数据了,一个面的描述共50字节。 3*4字节float浮点的法向量数据(x,y,z), 3*4字节float浮点的点1坐标数据(x,y,z), 3*4字节float浮点的点2坐标数据(x,y,z), 3*4字节float浮点的点3坐标数据(x,y,z), 2字节的u16说明数据(可忽略)。 源码的编写:

1:结构体的定义 其实可以发现BIN格式的STL文/件就是面数量和面组成结构比较重要, 所以代码部分就省去了文/件的头结构体,你非得使用也没事。。。 //三角面结构体 typedef struct {   float Normalvector[3];//法线矢量   float Vertex1[3];//顶点坐标1   float Vertex2[3];//顶点坐标2   float Vertex3[3];//顶点坐标3   uint16_t attributebytexountend;//属性统计 } TRIAN; ////BIN格式STL文件结构体 不重要,可以不用。 //typedef struct { //  u8 header[80]; //80字节 “SOLID?”不重要 //  uint32_t Numberoftriangles;//三角面片数量 //  TRIAN trian; //} STL 2:验证是否是BIN格式STL文/件 由于文/件时存储在SD卡文/件夹内的,所以需要使用FAT文/件系统进行文件读取, 一般读取SD文/件时大多是即用即取,这里全部读取数据提高了数据获取数据,减少延时。 由于SLT-BIN格式 数据头描述固定为80+4字节,一个三角面的组成固定为50字节, 所以就可以直接通过 【总字节=80+4+面*50】 进行验证。 如上图的正方形bin.STL文件 总字节数(684)=80+4+(三角面)12*50  验证通过。 //读取文件全部一次读取方便快速计算     f_read(&stl_file,file_buff,stl_file.obj.objsize,(UINT*)&br);     LCD_ShowxNum(300,170,br,5,16,0);     f_close(&stl_file);//关闭文件 stl_file.obj.objsize被释放了 以br为主           //获取面个数     tmp = (u8*)&number;     reda=(file_buff+80);     for(x=0;x<4;x++) *tmp++ = *reda++;     Show_Str(30,190,200,16,"STL 三角面个数",16,0);     LCD_ShowxNum(210,190,number,5,16,0);           ///判断是否为BIN格式STL 总字节=面个数*58+84     if(br != (number*50+84))      {       Show_Str(30,210,400,24,"该STL文件不是BIN格式!",24,0);       while(1);     } 3:需要特/别注意RAM的存取BUG 在代码中,多次使用了最简单的 单字节指针进行数据传递。 for(x=0;x<4;x++) *tmp++ = *reda++; 理论上只要数据类型(强/制转换)一样就可以用等式进行传递, //trian2=*(TRIAN *)reda; 这是为什么呢?是因为前面我们将所有STL数据存储在了RAM里面, 将指针指向文/件时,在进行float类型数据储存时,部分数据没有4字节对齐, 然后就直接触发BUG了。。。。(调试了好久。。一把心酸泪啊。) reda=(file_buff+84+i*50); tmp = (u8*)&trian2; for(x=0;x<50;x++) *tmp++ = *reda++; //trian2=*(TRIAN *)reda;//直接取值会导致float 4字节不对齐 跑飞 4:3D物体的旋转及显示 旋转部分移植的网友开源的代码,也没问他具体哪里弄的(发现也是移植过的,OPENGL?)。自己也写过三维矩阵代码,但是没这个快。功能没这个多(后面不显示,面填充(应该是他写的),面颜色角度渲染)。。。 这里是通过按键进行点,线,面进行切换显示。         if(showmode==0)         {           //显示点           if(++color_nm > 9)color_nm=0;           POINT_COLOR=color[color_nm];            pBackBuffer[(((int)cube[0][1]+LOGO16_GLCD_HEIGHT)*480+((int)cube[0][0])+LOGO16_GLCD_WIDTH)] = POINT_COLOR;           if(++color_nm > 9)color_nm=0;           POINT_COLOR=color[color_nm];            pBackBuffer[(((int)cube[1][1]+LOGO16_GLCD_HEIGHT)*480+((int)cube[1][0])+LOGO16_GLCD_WIDTH)] = POINT_COLOR;           if(++color_nm > 9)color_nm=0;           POINT_COLOR=color[color_nm];            pBackBuffer[(((int)cube[2][1]+LOGO16_GLCD_HEIGHT)*480+((int)cube[2][0])+LOGO16_GLCD_WIDTH)] = POINT_COLOR;         }         else if(showmode==1)         {           //显示点连线 全显示           if(++color_nm > 9)color_nm=0;           POINT_COLOR=color[color_nm];            LCD_Buff_DrawLine(LOGO16_GLCD_WIDTH+cube[0][0],LOGO16_GLCD_HEIGHT+cube[0][1],LOGO16_GLCD_WIDTH+cube[1][0],LOGO16_GLCD_HEIGHT+cube[1][1],pBackBuffer);           if(++color_nm > 9)color_nm=0;           POINT_COLOR=color[color_nm];           LCD_Buff_DrawLine(LOGO16_GLCD_WIDTH+cube[0][0],LOGO16_GLCD_HEIGHT+cube[0][1],LOGO16_GLCD_WIDTH+cube[2][0],LOGO16_GLCD_HEIGHT+cube[2][1],pBackBuffer);           if(++color_nm > 9)color_nm=0;           POINT_COLOR=color[color_nm];           LCD_Buff_DrawLine(LOGO16_GLCD_WIDTH+cube[1][0],LOGO16_GLCD_HEIGHT+cube[1][1],LOGO16_GLCD_WIDTH+cube[2][0],LOGO16_GLCD_HEIGHT+cube[2][1],pBackBuffer);         }         else         {           //判断是否显示面            dx0=cube[1][0]-cube[0][0];           dx1=cube[2][0]-cube[0][0];           dy0=cube[1][1]-cube[0][1];           dy1=cube[2][1]-cube[0][1];           if(dx0*dy1 > dx1*dy0)           {             trian2.Normalvector[0]=((cube[1][1]-cube[0][1])*(cube[2][2]-cube[0][2]))-((cube[1][2]-cube[0][2])*(cube[2][1]-cube[0][1]));             trian2.Normalvector[1]=((cube[1][2]-cube[0][2])*(cube[2][0]-cube[0][0]))-((cube[1][0]-cube[0][0])*(cube[2][2]-cube[0][2]));             trian2.Normalvector[2]=((cube[1][0]-cube[0][0])*(cube[2][1]-cube[0][1]))-((cube[1][1]-cube[0][1])*(cube[2][0]-cube[0][0]));             lenSq = trian2.Normalvector[0]*trian2.Normalvector[0]+ trian2.Normalvector[1]*trian2.Normalvector[1]+ trian2.Normalvector[2]*trian2.Normalvector[2];             ilen = sqrt(lenSq);             if (fabs(ilen) > 0.001f) ilen = 1.0f/ilen;             else ilen = 0;             trian2.Normalvector[2] *= ilen;             POINT_COLOR = sqrt(trian2.Normalvector[2]) * 31.5f;             RotatePoly(cube,3);             renderPolygonSub(cube,3,POINT_COLOR);           }                   } 程序源码工程附近不支持上传,这里附上链接,或者在开源广场搜索此文章找到对应工程附件下载就行。 https:// oshwhub.com /article/dan-pian-ji-xuan-zhuai-xian-shi-3dmu-xing-stl

STL模型在单片机上3D旋转显示的评论 (共 条)

分享到微博请遵守国家法律