zoukankan      html  css  js  c++  java
  • C#读取Adams的Shell文件(*.shl)

    Shell文件(*.shl)是Adams的一种几何形状文件,外形全是由多边形(直线连接的节点组成)表示的。本文介绍一下Shell文件的读取方法,以及在OpenGL中的显示方法。

    1. Shell文件格式

    Shell文件现在有两个版本。

    1.1 版本1的范例:

    8 6 1.0
    -1.0 -1.0 1.0
    -1.0 1.0 1.0
    1.0 1.0 1.0
    1.0 -1.0 1.0
    -1.0 -1.0 -1.0
    -1.0 1.0 -1.0
    1.0 1.0 -1.0
    1.0 -1.0 -1.0
    4 1 2 3 4
    4 5 6 2 1
    3 2 6 7
    4 3 7 8 4
    4 1 4 8 5
    4 8 7 6 5

    蓝色行中的第一个数字表示节点的个数,第二个是多边形的数量,第三个是缩放系数(一般情况下为1)。

    红色行为每个节点的坐标。绿色行第一个数字为多边形节点的数目,剩下的为每个节点的编号,与红色部分节点的顺序相对应,节点编号是从1开始。

    1.2 版本2的范例:

    Version: 2
    3559 1362 3559 1.000000
    -0.020500 0.005692 -0.001418
    -0.020500 0.006541 -0.002266
    -0.020500 0.005692 -0.000797
    -0.020500 0.005692 -0.000797
    -0.020500 0.005692 -0.001418
    13 14 18 22 27 28 24 20 15 10 6 4 8 12
    3 236 71 1
    3 33 1 71
    5 121 118 110 112 116
    15 70 74 76 83 101 104 106 98 95 91 93 88 86 81 79
    -0.022787 -0.041839 0.998864
    1.000000 -0.000000 0.000000
    0.018219 0.496961 0.867581
    0.000000 0.923962 0.382485
    1.000000 -0.000000 0.000000

    蓝色行中的第一个数字表示节点的个数,第二个是多边形的数量,第三个对应紫色行的数目,第四个是缩放系数(一般情况下为1)。

    红色和绿色行与版本1的含义一致。紫色行的用处不清楚,Adams帮助文档中只介绍了版本1的格式。

    2. 读取Shell文件

    C#读取shell文件代码如下,输入变量path是shell文件的路径。

    public static void DrawShell(string path)
    {
        List<Vector3> points = new List<Vector3>(); //points
        List<List<int>> seqs = new List<List<int>>(); //sequency
        List<Vector3> normals = new List<Vector3>(); 
        int lineNumber = 0;
    
        //read shl file
        if (!File.Exists(path))
        {
            MessageBox.Show("Cannot find the shell file");
        }
        string content = File.ReadAllText(path);
        string[] lines = content.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
        bool version2 = false;
    
        while (lines[lineNumber].Contains(":"))
        {
            lineNumber++;
            version2 = true;
        }
    
        string[] numbers = lines[lineNumber].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        int ptNum = Convert.ToInt32(numbers[0]);
        int seqNum = Convert.ToInt32(numbers[1]);
        int normalNum;
        float scale;
    
        if (version2)
        {
            normalNum = Convert.ToInt32(numbers[2]);
            scale = Convert.ToSingle(numbers[3]);
        }
        else
        {
            normalNum = 0;
            scale = Convert.ToSingle(numbers[2]);
        }
        
        
        
        for (int i = 0; i < ptNum; i++)
        {
            string[] pt = lines[lineNumber + 1 + i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            if (pt.Count() == 3)
            {
                points.Add(new Vector3(
                    Convert.ToSingle(pt[0].Trim()) * scale,
                    Convert.ToSingle(pt[1].Trim()) * scale,
                    Convert.ToSingle(pt[2].Trim()) * scale)
                    );
    
            }
            else
            {
                points.Add(new Vector3(0f, 0f, 0f));
            }
        }
        
        for (int i = 0; i < seqNum; i++)
        {
            string[] seq = lines[lineNumber + 1 + ptNum + i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            if (seq.Count() > 1)
            {
                seqs.Add(seq.ToList().ConvertAll<int>(x => Convert.ToInt32(x)));
            }
        }
    
        /*
        if (normalNum > 0)
        {
            for (int i = 0; i < normalNum; i++)
            {
                string[] pt = lines[lineNumber + 1 + i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                if (pt.Count() == 3)
                {
                    normals.Add(new Vector3(
                        Convert.ToDouble(pt[0].Trim()),
                        Convert.ToDouble(pt[1].Trim()),
                        Convert.ToDouble(pt[2].Trim()))
                        );
    
                }
                else
                {
                    normals.Add(new Vector3d(0d, 0d, 0d));
                }
            }
        }
        */
    
        foreach(List<int> seq in seqs)
        {
            if (seq[0] > 2)
            {
                List<Vector3> vertices = new List<Vector3>();
                
                seq.RemoveAt(0);
                foreach (int index in seq)
                {
                    vertices.Add(points[index - 1]);
                }
    
                //使用OpenGL显示每个多边形
                Tessellation.Triangulate(vertices);
            }
        }
       
    }

    上面代码中的Tessellation.Triangulate(vertices),是使用Glu的网格化(Tessellation)显示形状。该Tessellation类的具体内容,见我的另一篇文章:OPENGL: 多边形网格化(tessellation) 。

    下面是读取某个齿轮shell文件的显示结果:

  • 相关阅读:
    web前端开发最佳实践--(笔记之JavaScript最佳实践)
    web前端开发最佳实践--(笔记一)
    HTML5及CSS3--freeCodeCamp(笔记一)
    javascript系列--函数(一)
    HTML5本地存储
    分享一些好用的设计网站
    .net面试问题总结
    ife_task10--弹性盒子
    WPF--搭建一个简单的demo
    信息技术文集
  • 原文地址:https://www.cnblogs.com/xpvincent/p/2940484.html
Copyright © 2011-2022 走看看