Vuforia Studio 3D活用備忘録：3D内のプロパティ(メタデータ)値を利用 その４

#はじめに

Vuforia Studioでは、3DCADで作成した3DをARとして表示できるが、さらに、3Dデータ内のプロパティ値（メタデータ）を扱う事ができる。プロパティ値を利用する例を備忘録としておく。
今回は、3DCADで追加したカスタムプロパティの一覧表示について。

#前提

Vuforia Studio バージョン 8.5.13 以降。
この備忘録は、Vuforia Studioで、3DデータをAR表示させ、同時に2D画面上に2Dウィジェットを表示させ、さらにホームJSにJavaScriptコードを追加するARの作成経験がある人が対象。
また、以下の備忘録**その１**と**その３**を試し済みの人が対象。
・[Vuforia Studio 3D活用備忘録：3D内のプロパティ(メタデータ)値を利用 その１](
https://qiita.com/tm181001/items/a70b1ec243d1ab559a5c)
・[Vuforia Studio 3D活用備忘録：3D内のプロパティ(メタデータ)値を利用 その３](
https://qiita.com/tm181001/items/18cdeecba87088646d5d)

#3Dデータについて

今回は、3DCADで追加したカスタムプロパティのデータを扱う。Creoの3Dデータで試してみる。Vuforia Studioは様々な3DCADデータに対応しているので、他の3DCADデータでも本例と同様の事が出来る。カスタムプロパティのデータを取り出すのに使うカテゴリ名が、3DCADごとに異なるので、Creo以外の3Dデータの場合のカテゴリ名は、確認したら追記していきたい。

#3D内のプロパティ(メタデータ)値を一覧表示する例（システムプロパティとカスタムプロパティ）

**その１**では、パーツとアセンブリのデータを取得して、一覧表示を試した。
**その３**では、一覧表示でパーツを選択したら、ARの3Dの該当箇所の色を変更した。下図は、「選択したパーツが内部にあっても見えるようにする（常に手前に表示する）」までの実施結果である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/e541f275-c4dc-53a0-0fdf-7e0d0109a87f.png)
今回は、**その３**の上図の実施結果に対して、3Dデータを変更後、一覧表示でパーツを選択したら、そのパーツのシステムプロパティ一覧と、カスタムプロパティ一覧を表示してみる。

###3Dデータを変更する

Creoにてカスタムプロパティを追加した3Dデータを用意する。
ARプロジェクトの3Dキャンパスにて、3Dデータの表示に使用しているモデルウィジェットを選択して、「リソース＋」をクリックし、用意したCreoデータを選択しなおす。「エクスペリエンスのCADメタデータへのアクセスを許可」をチェックした状態で「追加」でアップロードする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/49868705-10b4-2e39-d431-2ccf72d61a79.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/8ec143f7-5332-c8f9-4f27-6b8f2d825427.png)
すると、3Dデータの表示が、新しい3Dデータに変わる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/69c77247-e1b6-6840-9cee-0d14fdf3aa76.png)
プレビューで、新しい3Dデータのパーツ一覧表示と選択ができるかを確認してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/7e000df0-8d9c-3cf0-acbf-3294e2f071f0.png)
3Dデータを変更しても、パーツの一覧表示と選択はちゃんと使えている。それでは、カスタムプロパティ取得へと進もう。

###カスタムプロパティデータの取得を追加する

これまではシステムプロパティのカテゴリになっているプロパティデータを、getCategory('__PV_SystemProperties') で取得していた。Creoのカスタムプロパティの場合は、getCategory('PROE Parameters') で取得できる。そこで、ホームJS のJavaScriptの内容に、以下のように追加をしていく。

```javaScript:
var modelName = 'model-1'; // ウィジェット名が異なる場合は変更
var selectName = 'select-1'; // ウィジェット名が異なる場合は変更

var customCategory = 'PROE Parameters'; // カテゴリ名（Creo:'PROE Parameters', ）

//--------------------------------------------------

// 取り出したアセンブリやパーツデータを格納する変数（JSON形式）
var parts = [];
parts.push({'IndentName':' ','PartIDPath':' '});
// 取り出したアセンブリやパーツデータ（カスタムプロパティ）を格納する変数（JSON形式）
var parts2 = [];
```
カスタムプロパティ用のカテゴリ名の変数 customCategory を追加しておく。また、取得したカスタムプロパティのデータを格納する変数 parts2 を追加しておく。

```javaScript:
    // IDパスを、「PartIDPath」の値として追加する
    partsysprop['PartIDPath'] = idpath;
    parts.push(partsysprop);

    // 3DCADで追加されたカスタムプロパティデータのカテゴリのデータを取り出す
    var customprop = partdata.getCategory(customCategory);
    if(customprop==undefined){
      customprop = {};
    }
    // IDパスを、「PartIDPath」の値として追加する
    customprop['PartIDPath'] = idpath;
    parts2.push(customprop);
  }
```
システムプロパティデータを parts.push() で格納する処理の下に、カスタムプロパティデータを getCategory(customCategory) で取得し、データ識別用の IDパスデータを追加して、parts2.push() で格納する。
カスタムプロパティが含まれていないデータも存在するので、customprop が undefined の場合の処理も追加している。

###カスタムプロパティデータを表示するUIを追加する（タブウィジェットを利用）

プロパティデータ一覧を表示するにあたり、システムプロパティの表示とカスタムプロパティの表示との切替ができるように、タブを使い表示してみる。2Dキャンパスにて、タブウィジェットを下部パネルにドラッグ＆ドロップで追加する。追加したタブウィジェットにて、右下にある「＋タブを追加」を実行し、2つ目のタブを追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/88ed7743-9527-c854-eced-141263428518.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/2e0245ed-57d4-39d6-1a09-7f3dcdc4cce1.png)
タブ名は、各タブごとに選択して「タイトル」のテキストを入力して変更できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/37205c9d-3c1e-d05f-e9fc-701134b9e78f.png)
プロパティデータ一覧は、今回はテキスト領域に表示してみる。そこで、各タブごとにテキスト領域ウィジェットをドラッグ＆ドロップで追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/d6d3910f-b0d4-1437-578b-b210d7533501.png)
各テキスト領域ウィジェットは、忘れずに「読み取り専用」をチェックしておく。チェックしておかないと、AR実行時にタッチすると編集入力がはじまってしまう。

表示用画面の用意をしたので、次に、JavaScriptに表示処理を追加していく。

###カスタムプロパティデータを表示する処理を追加する

```javaScript:
// JSONデータの中からIDが一致するデータを取出し、データの内容をテキストに書き出す
$scope.showProperties = function(jsonData, id, textAreaName){
  // IDが一致するデータを取り出す
  var props = $scope.getMatchData(jsonData, id);
  // データの内容をテキスト化する
  var propText = '';
  if(props.length>0){
    var keys = Object.keys(props[0]);
    for(var k=0; k<keys.length; k++){
      propText = propText + keys[k] + '=' + props[0][keys[k]] +',\n';
    }
  }
  // 2Dテキスト領域ウィジェットに、作成したテキストを書き出す
  $scope.setWidgetProp(textAreaName, 'text', propText);
}

// JSONデータの中からIDが一致するデータを取り出す
$scope.getMatchData = function(jsonData, id){
  var matchData = jsonData.filter(
    function(item, index){
      if(item['PartIDPath'] === id) return true;
    }
  );
  return matchData;
}
```

パーツ一覧から選択したときに、選択したパーツのプロパティを取出して表示するには、$scope.selectPart = function(data)　の処理の最後に、以下の処理を追加する。partsのシステムプロパティをタブ１のテキスト領域に、parts2のシステムプロパティをタブ２のテキスト領域に書き出す。

```javaScript:
  // 2Dテキスト領域ウィジェットに、プロパティ内容を書き出す
  $scope.showProperties(parts, data, textAreaName1); //　タブ「プロパティ１」
  $scope.showProperties(parts2, data, textAreaName2); //　タブ「プロパティ２」
```
上記では、テキスト領域ウィジェットの IDを変数 textAreaName1、textAreaName2 で指定している。そこで、JavaScriptの最初の箇所に、以下の変数定義を追加する。

```javaScript:
var textAreaName1 = 'textArea-1'; // ウィジェット名が異なる場合は変更
var textAreaName2 = 'textArea-2'; // ウィジェット名が異なる場合は変更
```

保存して、プレビューにて、パーツを選択してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/f1e4cea4-2f6d-13d4-73fb-1ac4db69da85.png)
画面下に追加したタブに、プロパティデータが表示されるようになった！　が、表示が小さすぎる。。

###プロパティ一覧表示数を増やす

テキスト領域は、デフォルトの「行」指定が 3 になっている。これを 15 に変更する。保存してプレビューを確認する。パーツを選択して、プロパティ２を選択すると、おぉ、カスタムプロパティ一覧を表示している！　出来た！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/40e499cc-c608-b9e1-2c53-608f2ea00bf0.png)

####タブ未選択時の表示が狭いのを改良する

尚、カスタムプロパティ一覧表示とは直接関係ないが、タブウィジェットにテキスト領域ウィジェットを直接配置して使うと、２つ前の図のように、タブ未選択時のデフォルト表示の横幅が狭くておかしい。テキスト領域の幅をCSSで指定してみたが、px値の指定は反映されるが、%値の指定は反映されない。１つ何とかする方法はあった。デフォルトで表示される最初のタブだけ、テキスト領域ウィジェットを直接配置ぜずに、先にグリッドレイアウトウィジェットを配置して、グリッドレイアウトの column にテキスト領域を配置すると、横幅の狭い表示はされなくなる。Vuforia Studioは配置の変更を簡単にできる。タブ１のテキスト領域ウィジェットをカット＆ペーストで、一旦タブ２に移動し、タブ１にグリッドレイアウトウィジェットを追加後、移動していたテキスト領域ウィジェットをカット＆ペーストでグリッドレイアウトの column に移動させれば、簡単に画面配置を変更できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297270/c79586c8-1e9b-8a67-b77d-5003185f8162.png)


#おわりに

3DCADデータには、製造に必要なデータ、保守に必要なデータなどを、プロパティ値（メタデータ）として含める事も多い。そのデータをARでも利用すれば、製造、保守に簡単に活用できる。積極利用すべきだと思う。
本備忘録では、**その４**として、3DCADで追加されたカスタムプロパティのデータ一覧を表示することを試した。積極利用すべきデータのほとんどは、このカスタムプロパティに保存されている。今回の方法でカスタムプロパティにどのようなプロパティ名のデータが含まれているかを確認できる。プロパティ名がわかれば、個別にデータを取出して活用することも容易に実現できる。

#注意

3DCADデータのアセンブリやパーツ名（構造名）に日本語を使っている場合、jsonファイルでは日本語部分が文字化けするようなので注意。同様に、カスタムプロパティに日本語を使っている場合も文字化けする。日本語に限らず、マルチバイト文字は文字化けするようである。

#参考

・[Vuforia Studio 3D活用備忘録：3D内のプロパティ(メタデータ)値を利用 その１　パーツとアセンブリを一覧表示する](
https://qiita.com/tm181001/items/a70b1ec243d1ab559a5c)

・[Vuforia Studio 3D活用備忘録：3D内のプロパティ(メタデータ)値を利用 その３　色などを変更する](
https://qiita.com/tm181001/items/18cdeecba87088646d5d)

・[Vuforia Studio 3D活用備忘録：3D内のプロパティ(メタデータ)値を利用 その５　3D ARをタップしてパーツを選択する](https://qiita.com/tm181001/items/28143dd1a53b668cfb93)
2021/6/17 追加

・[エクスペリエンスへの CAD メタデータの組み込み @ Vuforia Studioヘルプ](
http://support.ptc.com/help/vuforia/studio/ja/#page/Studio_Help_Center%2Fcad_metadata_api.html)

・[Incorporate CAD Metadata Into an Experience ( version 8.5.13 and later) @ ptc community](https://community.ptc.com/t5/Vuforia-Studio-and-Chalk-Tech/Incorporate-CAD-Metadata-Into-an-Experience-version-8-5-13-and/ta-p/693341)

・[Vuforia Studio - introduction to MetaData Video @ ptc community](https://community.ptc.com/t5/Vuforia-Studio/Vuforia-Studio-introduction-to-MetaData-Video/td-p/695630?posno=6&q=Metadata%20Vuforia&source=search)