C#でSTLデータを扱うライブラリ

# 概要
　C#で3D形状の解析を行う際、頂点や面などのデータを分析する必要があるかと思います。ここでは、私が作成中のSTLデータを扱うライブラリ[SurfaceAnalyzer](https://www.nuget.org/packages/SurfaceAnalyzer)を紹介します。同ライブラリを用いることで、3D形状を簡単に分析することが出来ます。また、サブディビジョンサーフェスと呼ばれる形状の平滑化手法も実装しています。形状の分析だけでなく表示を行いたい場合は、OpenGLのC#ラッパーであるOpenTKと組み合わせることをお勧めします。
　※研究用に速度よりも使いやすさやデータの整合性を優先しているので高速な処理や大規模データにはあまりお勧めできません。

# できること
　実装されている代表的な機能は以下になります。

- STLデータ（バイナリまたはASCII）の読み込み(LoadData.LoadSTL())
- STLデータ（ASCII）の保存(SaveData.SaveSTL())
- 形状(PolygonModel)
    - ガウス曲率の絶対積分値(GaussCurvatureIntegration() 形状の複雑さを表現)
    - ガウス曲率の積分値(GaussCurvatureIntegration_noABS() 形状の位相を表現)
    - 平均曲率の積分値(AverageCurvatureIntegration())
    - 重心点(GravityPoint())
    - 重心点からの最大距離（形状の大きさ）(MaxDiameter())
- 面(Face)
    - 各頂点の角度(GetAngle())
    - 法線ベクトル(Normal())
    - 面積(Area())
    - 重心(FacePoint())
- 頂点(Vertex)
    - ガウス曲率(GaussCurvature)
    - 平均曲率(AverageCurvature)
- その他の機能
    - Catmull-Clarkサブディビジョンサーフェス(ShapeTransform.SubdivisionSurface())
　

# 使い方
　nugetからダウンロード・インストールすることが出来ます。

## nugetからインストール
　nugetで「SurfaceAnalyzer」を検索し、インストールします。
![スクリーンショット 2020-05-03 19.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628237/24051861-380e-29d2-3d72-931dda080470.png)

## 形状の読み込み
　形状を読み込んで、頂点数を算出するサンプルプログラムを示します。
　LoadData.LoadSTL(string filePath, bool analyze)メソッドを使います。
　filePathは、STLファイルのパス、analyzeは形状の分析を行うかのbool値を示します。

```C#:Load_Shape
using System;
using SurfaceAnalyzer;

namespace Program
{
    class Program1
    {
        static void Main(string[] args)
        {
            LoadShape();
        }

        public void LoadShape()
        {
            string filePath = @"C:\Users\Desktop\ball_ascii.STL";
            PolygonModel surface = LoadData.LoadSTL(filePath, true); //STLデータの読み込み

            int count = surface.Vertices.Count; //頂点数
            System.Console.WriteLine("number of vertex:{0}", count);
        }
     }
}

```

## 表面積の算出
　表面積を算出するサンプルプログラムを示します。

```C#:Surface_Area
using System;
using SurfaceAnalyzer;

namespace Program
{
    class Program1
    {
        static void Main(string[] args)
        {
            CalcSurfaceArea();
        }

        public void CalcSurfaceArea()
        {
            string filePath = @"C:\Users\Desktop\ball_ascii.STL";
            PolygonModel surface = LoadData.LoadSTL(filePath, true);

            double area = 0;
            foreach (var face in surface.Faces)
            {
                area += face.Area();
            }
            System.Console.WriteLine("surface area:{0}", area);
        }
     }
}

```

## サブディビジョンサーフェスによる変形＆保存
　形状を読み込み、サブディビジョンサーフェス変形をし、保存するサンプルプログラムを以下に示します。ファイルの書き出しは、STLバイナリ方式のみ対応しています。

```C#:Surface_Area
using System;
using SurfaceAnalyzer;

namespace Program
{
    class Program1
    {
        static void Main(string[] args)
        {
            SubdivisionSurface();
        }

        public void SubdivisionSurface()
        {
            //読み込み
            string loadFilePath = @"C:\Users\Desktop\ball_ascii.STL";
            PolygonModel surface = LoadData.LoadSTL(loadFilePath, true);

            //サブディビジョンサーフェス
            PolygonModel subSurface = ShapeTransform.SubdivisionSurface(surface);

            //保存
            string saveFilePath = @"C:\Users\Desktop\ball_ascii2.STL";
            SaveData.SaveSTL(surface, saveFilePath, "subSurface");
        }
     }
}

```

読み込んだ形状
![スクリーンショット 2020-05-03 20.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628237/3fcba186-5bc5-e316-59a6-e06b8a924bc3.png)

保存した形状
![スクリーンショット 2020-05-03 20.07.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628237/23798424-9978-a794-f5c6-96b3049f4bd9.png)

# まとめ
　STLデータを簡単に分析することが出来るSurfaceAnalyzerを紹介しました。ここに書いた以外にも様々な機能が実装されていますが、それらは今後紹介していきます。