geometry + Python > 四面体結合体 > 隠面以外の三角形インデックスを得る > freeBoundary_171112 > v0.1, v0.2

```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)
```

### 背景

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

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

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

### 処理概要

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

### テストデータ

[MATLAB > 四面体メッシュプロット > tetramesh() | view(30,30) | サブセット表示 tetramesh(tet(2:3,:),X)](https://qiita.com/7of9/items/40c40b2c789c7e845bbb#%E3%82%B5%E3%83%96%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E8%A1%A8%E7%A4%BA)


## v0.1 > ２つの四面体

### code

Matplotlibで動作確認しているが、Numpy環境でも動くだろう。

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

'''
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)

if __name__ == '__main__':
    Test_get_shown_triangles()

```

```txt:run
hidden: [[1092, 856, 1095]]
---except for hidden---
[1092  856 1094]
[1092 1094 1095]
[ 856 1094 1095]
[1092 1095  896]
[1092  896  856]
[1095  896  856]
```

2つの四面体でのテストはできた。


## v0.2 > 3つの四面体

### データ

MATLABコード。
以下のインデックスで３つの四面体結合になっていた。

```matlab
>> load tetmesh
>> tetramesh(tet(106:108,:),X)
>> view(60,0)
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/82fa6ec1-e74c-ddc0-6e52-4a090d3f2941.png)

```matlab
>> tet(106:108,:)

ans =

        1098        1175        1170        1204
        1098        1170        1175        1172
        1098        1170        1203        1204
```

### code 

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

'''
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)

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

```

```txt:run
hidden: [[1098, 1175, 1170], [1098, 1170, 1204], [1098, 1170, 1175]]
---except for hidden---
[1098 1175 1204]
[1175 1170 1204]
[1098 1170 1172]
[1098 1175 1172]
[1170 1175 1172]
[1098 1170 1203]
[1098 1203 1204]
[1170 1203 1204]
```

4 x 3 - 4 = 8

期待通りになっている。