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文件的显示结果:

C#读取Adams的Shell文件(*.shl)

 

 

你可能感兴趣的:(shell)