geometry + Numpy > 四面体結合体 > 隠面以外の三角形インデックスを得る > freeBoundary_171112 > v0.3 > 同じインデックスセットが得られた

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

[v0.1](https://qiita.com/7of9/items/ff6ca65cdf9973fb6a16)


### 背景

[MATLAB > freeBoundary()を試してみた > tetmeshを処理してみた > 疑問点](https://qiita.com/7of9/items/2c0d30a618efcdeabb0f)

MATLABにはfreeBoundary()というAPIがある。Numpyのビルトインにはない。

freeBoundaryの処理は以下なのだろう。
[MATLAB > freeBoundary() > 四面体結合物への適用 > 隠面以外の三角形の情報を取得する](https://qiita.com/7of9/items/9d09ea84094309151f38)

### 処理概要

- 四面体結合体から三角形のインデックス組合せを取得する
    - 隠面を除く

### テストデータ (入力)

MATLAB実装のコード
https://github.com/gradywright/spherepts/blob/master/code/getIcosNodes.m
においてgetIcosNodes(4,0)で実行した時の`tri = freeBoundary(TriRep(tri,x));`の処理前のデータを入力データとする。

```tri_bef_1711118.txt
   3.0000000e+00   2.0000000e+00   7.0000000e+00   1.0000000e+00
   2.0000000e+00   3.0000000e+00   6.0000000e+00   1.0000000e+00
   4.0000000e+00   3.0000000e+00   6.0000000e+00   2.0000000e+00
   3.0000000e+00   1.0000000e+01   6.0000000e+00   1.0000000e+00
   1.1000000e+01   7.0000000e+00   2.0000000e+00   5.0000000e+00
   7.0000000e+00   2.0000000e+00   5.0000000e+00   1.0000000e+00
   8.0000000e+00   1.2000000e+01   6.0000000e+00   1.0000000e+01
   4.0000000e+00   1.2000000e+01   6.0000000e+00   8.0000000e+00
   4.0000000e+00   8.0000000e+00   6.0000000e+00   3.0000000e+00
   8.0000000e+00   1.0000000e+01   6.0000000e+00   3.0000000e+00
   5.0000000e+00   2.0000000e+00   6.0000000e+00   1.0000000e+00
   3.0000000e+00   1.1000000e+01   9.0000000e+00   1.0000000e+00
   3.0000000e+00   7.0000000e+00   1.1000000e+01   1.0000000e+00
   7.0000000e+00   5.0000000e+00   1.1000000e+01   1.0000000e+00
   1.1000000e+01   5.0000000e+00   9.0000000e+00   1.0000000e+00
   6.0000000e+00   1.2000000e+01   4.0000000e+00   2.0000000e+00
   3.0000000e+00   4.0000000e+00   7.0000000e+00   2.0000000e+00
   8.0000000e+00   4.0000000e+00   7.0000000e+00   3.0000000e+00
   1.1000000e+01   4.0000000e+00   2.0000000e+00   7.0000000e+00
   3.0000000e+00   7.0000000e+00   9.0000000e+00   1.1000000e+01
```

### code v0.3

上記のデータファイルを読込みテストする関数Test_get_shown_triangles_fromfile()を追加した。

Jupyterコード。

```py:freeBoundary_171112.ipynb
import numpy as np

'''
v0.3 Nov. 18, 2017 test reading from file
  - add Test_get_shown_triangles_fromfile()
v0.2 Nov. 12, 2017 test with 3 tetrahedra
  - add Test_get_shown_triangles_3tetrahedra()
v0.1 Nov. 12, 2017
  - Test_get_shown_triangles()
  - is_same_list()
  - add get_shown_triangles()
  - add get_triangle_sets()
  - add find_hidden_triangleIndex()
'''

# on Python 3.5.2
# coding rule:PEP8


def find_hidden_triangleIndex(tris):
    overlap = []
    for lidx in range(len(tris) - 1):
        for ridx in range(len(tris)):
            if lidx == ridx:
                continue
            wrk = []
            for elem in tris[lidx]:
                if elem in tris[ridx]:
                    wrk += [elem]
            if (len(wrk) == 3):
                overlap += [wrk]
    return overlap


def get_triangle_sets(tris):
    idx1 = [0, 1, 2]
    idx2 = [0, 1, 3]
    idx3 = [0, 2, 3]
    idx4 = [1, 2, 3]
    wrk = []
    for lidx in range(len(tris)):
        wrk += [tris[lidx][idx1]]
        wrk += [tris[lidx][idx2]]
        wrk += [tris[lidx][idx3]]
        wrk += [tris[lidx][idx4]]
    return wrk


def is_same_list(lhs, rhs):
    cnt = 0
    for lelem in lhs:
        if lelem in rhs:
            cnt += 1
    return (cnt == 3)


def get_shown_triangles(trihdns, triall):
    wrk = []
    for atri in triall:
        ishidden = False
        for ahidden in trihdns:
            if is_same_list(ahidden, atri):
                ishidden = True
        if not ishidden:
            wrk += [atri]
    return wrk


def Test_get_shown_triangles():
    tri1 = [1092, 856, 1094, 1095]  # index of triangles for tetrahedra
    tri2 = [1092, 1095, 896, 856]  # index of triangles for tetrahedra
    tris = [np.array(tri1), np.array(tri2)]

    trihdn = find_hidden_triangleIndex(tris)
    print('hidden:', trihdn)
    triall = get_triangle_sets(tris)
    #
    trishown = get_shown_triangles(trihdn, triall)
    print('---except for hidden---')
    for elem in trishown:
        print(elem)


def Test_get_shown_triangles_3tetrahedra():
    tri1 = [1098, 1175, 1170, 1204]  # index of triangles for tetrahedra
    tri2 = [1098, 1170, 1175, 1172]  # index of triangles for tetrahedra
    tri3 = [1098, 1170, 1203, 1204]  # index of triangles for tetrahedra
    tris = [np.array(tri1), np.array(tri2), np.array(tri3)]

    trihdn = find_hidden_triangleIndex(tris)
    print('hidden:', trihdn)
    triall = get_triangle_sets(tris)
    #
    trishown = get_shown_triangles(trihdn, triall)
    print('---except for hidden---')
    for elem in trishown:
        print(elem)


def Test_get_shown_triangles_fromfile():
    tris = np.genfromtxt('tri_bef_171118.txt', delimiter='   ')

    trihdn = find_hidden_triangleIndex(tris)
    print('hidden:', trihdn)
    triall = get_triangle_sets(tris)
    #
    trishown = get_shown_triangles(trihdn, triall)
    print('---except for hidden---')
    for elem in trishown:
        print(elem)

if __name__ == '__main__':
    # Test_get_shown_triangles()
    # Test_get_shown_triangles_3tetrahedra()
    Test_get_shown_triangles_fromfile()

```

```txt:run
hidden: [[3.0, 2.0, 1.0], [2.0, 7.0, 1.0], [3.0, 7.0, 1.0], [3.0, 2.0, 7.0], [2.0, 3.0, 1.0], [2.0, 3.0, 6.0], [3.0, 6.0, 1.0], [2.0, 6.0, 1.0], [3.0, 6.0, 2.0], [4.0, 3.0, 6.0], [4.0, 6.0, 2.0], [4.0, 3.0, 2.0], [3.0, 6.0, 1.0], [3.0, 10.0, 6.0], [7.0, 2.0, 5.0], [11.0, 7.0, 5.0], [11.0, 7.0, 2.0], [7.0, 2.0, 1.0], [7.0, 2.0, 5.0], [2.0, 5.0, 1.0], [7.0, 5.0, 1.0], [8.0, 12.0, 6.0], [8.0, 6.0, 10.0], [12.0, 6.0, 8.0], [4.0, 6.0, 8.0], [4.0, 12.0, 6.0], [4.0, 6.0, 3.0], [4.0, 8.0, 6.0], [8.0, 6.0, 3.0], [4.0, 8.0, 3.0], [10.0, 6.0, 3.0], [8.0, 10.0, 6.0], [8.0, 6.0, 3.0], [2.0, 6.0, 1.0], [5.0, 2.0, 1.0], [3.0, 11.0, 1.0], [11.0, 9.0, 1.0], [3.0, 11.0, 9.0], [3.0, 7.0, 1.0], [3.0, 11.0, 1.0], [7.0, 11.0, 1.0], [3.0, 7.0, 11.0], [7.0, 5.0, 11.0], [7.0, 5.0, 1.0], [7.0, 11.0, 1.0], [5.0, 11.0, 1.0], [11.0, 9.0, 1.0], [11.0, 5.0, 1.0], [6.0, 4.0, 2.0], [6.0, 12.0, 4.0], [3.0, 7.0, 2.0], [3.0, 4.0, 2.0], [3.0, 4.0, 7.0], [4.0, 7.0, 2.0], [8.0, 4.0, 3.0], [4.0, 7.0, 3.0], [11.0, 2.0, 7.0], [4.0, 2.0, 7.0]]
---except for hidden---
[  3.  10.   1.]
[ 10.   6.   1.]
[ 11.   2.   5.]
[  8.  12.  10.]
[ 12.   6.  10.]
[  4.  12.   8.]
[  8.  10.   3.]
[ 5.  2.  6.]
[ 5.  6.  1.]
[ 3.  9.  1.]
[ 11.   5.   9.]
[ 5.  9.  1.]
[  6.  12.   2.]
[ 12.   4.   2.]
[ 8.  4.  7.]
[ 8.  7.  3.]
[ 11.   4.   2.]
[ 11.   4.   7.]
[ 3.  7.  9.]
[  7.   9.  11.]
```

### sphereptsの処理結果

MATLABコードsphereptsの処理結果はこちら。
下記の結果と同じインデックスセットが上記の処理にて得られていることが確認できた。
ただし、上記:(3 9 1)、下記:(3 1 9)のように要素の順番が入れ替わっている例はある。
最終結果に影響があるかは最終結果を得るコードを実装するまで分からない。

```tri_aft_171118.txt
   1.0000000e+01   6.0000000e+00   1.0000000e+00
   3.0000000e+00   1.0000000e+01   1.0000000e+00
   1.1000000e+01   5.0000000e+00   2.0000000e+00
   1.2000000e+01   6.0000000e+00   1.0000000e+01
   8.0000000e+00   1.2000000e+01   1.0000000e+01
   4.0000000e+00   1.2000000e+01   8.0000000e+00
   8.0000000e+00   1.0000000e+01   3.0000000e+00
   5.0000000e+00   1.0000000e+00   6.0000000e+00
   5.0000000e+00   6.0000000e+00   2.0000000e+00
   3.0000000e+00   1.0000000e+00   9.0000000e+00
   5.0000000e+00   9.0000000e+00   1.0000000e+00
   1.1000000e+01   9.0000000e+00   5.0000000e+00
   1.2000000e+01   4.0000000e+00   2.0000000e+00
   6.0000000e+00   1.2000000e+01   2.0000000e+00
   8.0000000e+00   3.0000000e+00   7.0000000e+00
   8.0000000e+00   7.0000000e+00   4.0000000e+00
   1.1000000e+01   4.0000000e+00   7.0000000e+00
   1.1000000e+01   2.0000000e+00   4.0000000e+00
   7.0000000e+00   9.0000000e+00   1.1000000e+01
   3.0000000e+00   9.0000000e+00   7.0000000e+00
```