STL三维模型切片(一)——文件导入

STL格式的三维模型由大量三角形面片构成,文件中只记录了每个三角形的基本信息,包括三个顶点及其法向量(表示内外)。在对该模型进行处理之前,首先必须将其导入进来。STL格式的有两种记录形式:二进制及文本方式,二者没有本质区别,都只是记录了三角形的信息。先放代码,再逐个功能进行分析。

private MeshGeometry3D GetMeshModelFromSTLFile(string path)
{

    StreamReader srFirstLine = new StreamReader(path);
    string fileType = srFirstLine.ReadLine().Substring(0, 5);
    string secondLine = srFirstLine.ReadLine().Trim().Substring(0, 5);
    srFirstLine.Close();

    MeshGeometry3D mesh3D = new MeshGeometry3D();
    int indexOfTriangles = 0;
    if (fileType == "solid" && secondLine == "facet") //ASCII type
    {
        StreamReader sr = new StreamReader(path);
        sr.ReadLine();//remove first line
        while (sr.ReadLine() != null) //remove facet normal line
        {
            if (sr.ReadLine() == null)
            {
                break;
            }//remove outer loop line

            mesh3D.Positions.Add(StringToPoint3D(sr.ReadLine()));
            mesh3D.TriangleIndices.Add(indexOfTriangles++);

            mesh3D.Positions.Add(StringToPoint3D(sr.ReadLine()));
            mesh3D.TriangleIndices.Add(indexOfTriangles++);

            mesh3D.Positions.Add(StringToPoint3D(sr.ReadLine()));
            mesh3D.TriangleIndices.Add(indexOfTriangles++);

            sr.ReadLine(); //remove endloop
            sr.ReadLine(); //remove endfacet

        }
        sr.Close();
        return mesh3D;

        Point3D StringToPoint3D(string vertexStr)
        {
            var tt = vertexStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            return new Point3D
            {
                X = Convert.ToDouble(tt[1]),
                Y = Convert.ToDouble(tt[2]),
                Z = Convert.ToDouble(tt[3])
            };
        }
    }
    else //Binary type
    {
        BinaryReader br = new BinaryReader(File.OpenRead(path));
        br.ReadBytes(80);//去掉80字节
        var count = (int)br.ReadUInt32();//三角形数目
        for (int i = 0; i < count; i++)
        {
            br.ReadBytes(12);//三个4字节表示三角形法向量,不需要
            mesh3D.Positions.Add(new Point3D { X = br.ReadSingle(), Y = br.ReadSingle(), Z = br.ReadSingle() });
            mesh3D.TriangleIndices.Add(indexOfTriangles++);

            mesh3D.Positions.Add(new Point3D { X = br.ReadSingle(), Y = br.ReadSingle(), Z = br.ReadSingle() });
            mesh3D.TriangleIndices.Add(indexOfTriangles++);

            mesh3D.Positions.Add(new Point3D { X = br.ReadSingle(), Y = br.ReadSingle(), Z = br.ReadSingle() });
            mesh3D.TriangleIndices.Add(indexOfTriangles++);

            br.ReadBytes(2);//去掉最后两个字节
        }
        br.Close();
        return mesh3D;
    }

}

首先,我们需要判断STL文件是二进制还是文本格式。一般来说,文本格式第一行以solid开头,即当第一行前5个字符为solid时,可以认为该文件为文本格式。经过大量检验,发现该方法是可行的。直到有一次发现某个二进制格式的STL文件开头5个字符也是solid,说明该方法不能百分之百保证判断准确。于是,添加第二行判断,文本格式的STL文件第二行以facet开头,两者都满足的情况下,基本可以确定该文件为文本格式,否则为二进制格式。

随后,确定格式后,分别按其格式字义逐行(字)读取,并添加到Mesh对象中,这样就将STL文件读取进来了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值