以前、Forgeに関する記事の中で、3DモデルのファイルをPostmanを使ってアップロード・変換する手順を紹介した。

しかしこの手順、API通信をPostmanを使って手動で行うため、トークンを取得したり、ファイルをアップしたりと、特にファイルの数が多くなるとかなり面倒くさい。

そこで今回、PHPを使ってこれら一連の流れを自動化するプログラムを作ってみた。

ディレクトリ構成

今回作ったプログラムのディレクトリ構成は次のとおり。

|-/
 |-index.php
 |-Forge.php
 |-ApiClient.php
 |-/model
  |-test1.f3d
  |-test2.f3d
  |-test3.f3d

それではファイルを一つずつ見ていこう。

ベースとなるクラスファイル

まずはAPI通信を行うためのベースとなるクラスファイル「ApiClient.php」を用意する。

<?php
class ApiClient {
  protected function execute($curlOpt) {
    $curl = curl_init();
    curl_setopt_array($curl, $curlOpt);

    $response = curl_exec($curl);
    $result = json_decode($response, true);
    curl_close($curl);

    return $result;
  }
}

API通信はPHPのCURL関数を使う。

Forgeクラスファイルの作成

次にApiClient.phpを継承する、Forgeクラスを作成する。

<?php
include_once ('./ApiClient.php');

class Forge extends ApiClient {
  // トークン管理用メンバ変数
  private $accessToken;

  // インスタンス生成時にトークンを取得・保存
  function __construct() {
    $this->getToken();
  }

  // トークン取得用メソッド
  private function getToken() {
    $curlOpt = [
      CURLOPT_URL => "https://developer.api.autodesk.com/authentication/v1/authenticate",
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_HTTPHEADER => [
        "Content-Type: application/x-www-form-urlencoded",
      ],
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POSTFIELDS => http_build_query([
        'client_id' => CLIENT_ID,
        'client_secret' => CLIENT_SECRET,
        'grant_type' => 'client_credentials',
        'scope' => 'bucket:create bucket:read data:read data:write data:create',
      ]),
    ];

    $res = parent::execute($curlOpt);
    $this->accessToken = $res['access_token'];
  }

  // ファイルアップロード用メソッド
  public function uploadFile($fileName) {
    $filePath = FILE_DIR.$fileName;
    $file = fopen($filePath, 'rb');

    $curlOpt = [
      CURLOPT_UPLOAD => true,
      CURLOPT_URL => "https://developer.api.autodesk.com/oss/v2/buckets/".BUCKET."/objects/".$fileName,
      CURLOPT_CUSTOMREQUEST => "PUT",
      CURLOPT_HTTPHEADER => [
        "Authorization: Bearer ".$this->accessToken,
        "Content-Type: application/octet-stream",
      ],
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_BINARYTRANSFER => true,
      CURLOPT_INFILE => $file,
      CURLOPT_INFILESIZE => filesize($filePath),
    ];

    return parent::execute($curlOpt);
  }

  // Viewer用にファイル形式を変換するメソッド
  public function modelDerivative($urn) {
    $encodeUrn = base64_encode($urn);

    $postJson = <<< DOC
{
  "input": {
    "urn": "{$encodeUrn}"
  },
  "output": {
    "formats": [
      {
        "type": "svf",
        "views": [
          "2d",
          "3d"
        ]
      }
    ]
  }
}
DOC;

    $curlOpt = [
      CURLOPT_URL => "https://developer.api.autodesk.com/modelderivative/v2/designdata/job",
      CURLOPT_CUSTOMREQUEST => "POST",
      CURLOPT_HTTPHEADER => [
        "Authorization: Bearer ".$this->accessToken,
        "Content-Type: application/json",
      ],
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POSTFIELDS => $postJson,
    ];

    return parent::execute($curlOpt);
  }

}

メインファイルの作成

最後に、ここまで用意したクラスをインスタンス化し、アクセストークン取得・ファイルのアップロード・変換と、一連の流れを実行する処理をindex.phpファイルに書いていく。

<?php
include_once ('./Forge.php');

const CLIENT_ID = '##########################';
const CLIENT_SECRET = '##########################';
const BUCKET = '##########################';
const FILE_DIR = './model/';

$files = [
  'test1.f3d',
  'test2.f3d',
  'test3.f3d',
];

// インスタンス作成、アクセストークン取得
$forge = new Forge;

foreach ($files as $file) {
  echo $file."<br>";
  $res = $forge->uploadFile($file);

  $res = $forge->modelDerivative($res['objectId']);
  echo "ファイル変換結果: ".$res['result'];
  echo "<br><br>";
}

CLIENT_IDやCLIENT_SECRET、BUCKET(バケット名)は各自の環境に合わせて適宜変更する。

ここまでファイルの用意ができたら、index.phpを実行してみよう。

$filesに格納したファイルを一括して対象のバケットへアップロードし、Viewer用にファイル形式を変換してくれる。