Autodesk Forge上でのBucket上のファイル変換

Forgeのビューワはいろいろな機能があるだけれど、選択したオブジェクトをOBJ, SVFなどに出力する機能を備えている。そんなに難しわけではないのですが、アクセストークンやURN取得の流れなどを理解していないととっつきにくいので、その辺は[前回の記事](https://qiita.com/Takashi_Kasuya/items/409997752b47b038abe4)を参照してほしい。
基本的には以下のサイトを参考にした。
https://developer.autodesk.com/en/docs/model-derivative/v2/tutorials/translate-source-file-to-obj/
ちなみに、どんなフォーマットにも変換できるわけではない。IFCだと、SVFだけですね。
https://developer.autodesk.com/en/docs/model-derivative/v2/overview/supported-translations/


# URNへの変換
Bucket上にアップされたファイルを参照するためのURN（urn:adsk.objects:os.object:mybucket_xxxxxxx/HelloWall.ifc）は、ファイルをアップロードするときにレスポンスコードに記載されている。それをURL-safe Base64(No padding)に変換する必要がある。

この[サイト](https://www.freeformatter.com/base64-encoder.html#ad-output)でURNを変換するとURNは以下のようになるので、URL-safeにするために、最後にある=を削除するということらしい。「dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM=」

# OBJへの変換
変換のためには、以下のAPIを利用すればよい。
https://developer.autodesk.com/en/docs/model-derivative/v2/reference/http/job-POST/

具体的には、以下のようなトークン、URNと出力するフォーマットを指定する。

```
curl -X 'POST' -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxx' -H 'Content-Type: application/json' -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/job' -d
'{
  "input": {
    "urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM"
  },
  "output": {
    "formats": [
      {
        "type": "svf",
        "views": ["2d","3d"]
      }
    ]
  }
}'
```

うまくいくと、以下のようなレスポンスがある。

```
{
"result":"created",
"urn":"dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM",
"registerKeys":["6614afbe-1af2-4fc0-8e56-6c9a4a223b9a"],
"acceptedJobs":{"output":{"formats":[{"type":"svf","views":["2d","3d"]}]}}
}
```

変換が終わるまで少し時間がかかるので、以下のように問い合わせを行う。

```
curl -X 'GET' 
  -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxx' 
  -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM/manifest'
```

変換が終わっていると、SVFのURNが入ったレスポンスが返ってくる。そのURNを今度はURLエンコードする（Base64ではない！）。結果を先ほどと同じURLの最後に加えてリクエストする。すると変換後のバイナリが送られてくる。

```
curl -X 'GET' 
  -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxx' 
  -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM/manifest/urn%3Aadsk.viewing%3Afs.file%3AdXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM%2Foutput%2F0%2F0.svf'
```

ちなみに、以下のように問い合わせるとファイルのメタデータを取得することもできる。

```
curl -X 'GET' 
  -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxx' 
  -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM/metadata
```

レスポンスでは、リクエストしたデータのGUIDなどを取得することができる。上記のmetadataのあとにつけてリクエストすると、オブジェクトの構造を教えてくれる。要するにIFCの場合は、その階層とプロパティのデータということになる。

```
curl -X 'GET' 
  -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxx' 
  -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bXlidWNrZXRfa2FzdXlhL0hlbGxvV2FsbC5pZmM/metadata/26af68b6-8952-4a43-89b4-f771aa807d8a
```

ここでレスポンスとして帰ってきたobjectidを使って、変換のリクエストをすることができる。この方法を使うと、IFCからでもOBJに変換することは可能であることが確認できた。
https://developer.autodesk.com/en/docs/model-derivative/v2/tutorials/extract-geometry-from-source-file/


具体的には、以下のようなOBJとなった。

```
WaveFront *.obj file (generated by Autodesk ATF)

mtllib 6f9d3481-728b-3363-af95-42adb0a4a9ea.mtl

g Obj.7

v -240.000000 -14.999986 240.000000
v -240.000000 -14.999986 0.000000
v 159.999988 -15.000011 240.000000
v 159.999988 -15.000011 0.000000
v -240.000000 15.000011 240.000000
v -240.000000 15.000011 0.000000
v 159.999988 14.999986 240.000000
v 159.999988 14.999986 0.000000
vn -0.000001 -10.000000 0.000000
vn -10.000000 0.000001 0.000000
vn 0.000001 10.000000 0.000000
vn 10.000000 -0.000001 0.000000
vn 0.000000 0.000000 10.000000
vn 0.000000 0.000000 -10.000000
usemtl Obj.7
f 1//1 2//1 3//1
f 3//1 2//1 4//1
f 5//2 6//2 1//2
f 1//2 6//2 2//2
f 7//3 8//3 5//3
f 5//3 8//3 6//3
f 3//4 4//4 7//4
f 7//4 4//4 8//4
f 3//5 7//5 1//5
f 1//5 7//5 5//5
f 8//6 4//6 6//6
f 6//6 4//6 2//6

# 8 vertices
# 0 texture params
# 6 normals
# 12 facets

# 1 groups
```