Visual検索の方法 後編

皆さんこんにちは、Emulate3Dの技術担当の大竹です。

今回は、前回に引き続きEmulate3D で利用頻度の高いVisual検索についてご紹介します。
前編・後編に分かれているため、よろしければこちらもご一緒にご覧ください。

目次

■ 対象Visualの子供から検索

  □「名前」で1個の子Visualを取得する方法

  □「名前」で複数の子Visualを取得する方法

  □「タイプ」で複数の子Visualを取得する方法

  □「指定した条件」に一致する全ての子Visualを取得する方法

■ まとめ

対象Visualの子供から検索

対象Visualの子供から検索する方法での特徴は、
シーン上に存在する他のVisualを気にせず、対象Visualから特定のVisualを検索出来る点です。

以下のモデルをサンプルとして、動作を確認します。

Visual 子供 検索 サンプル


こちらのサンプルモデルでは、対象Visualはコンベヤに流れる「Pallet」です。
「Pallet」の子供に「Tote」があり、「Tote」の子供に「Box」があります。

対象Visualの子供からVisualを検索する方法は、
大きく分けて以下の4種類あります。

●「名前」で1個の子Visualを取得する方法

●「名前」で複数の子Visualを取得する方法

●「タイプ」で複数の子Visualを取得する方法

●「指定した条件」に一致する全ての子Visualを取得する方法

「名前」で1個の子Visualを取得する方法

1つ目は対象Visualから「名前」で1個の子Visualを取得する方法です。
対象Visual内で一意に存在する子Visualを取得したい時に便利です。

C#の場合

var yellowBox = load.FindChild("YellowBox");

var yellowBox = load.FindImmediateChild("YellowBox");

JScriptの場合

var yellowBox : Visual = load.FindChild("YellowBox");

var yellowBox : Visual = load.FindImmediateChild("YellowBox");


各2つの処理では、検索したいVisual名を渡して一致するVisualを取得出来ます。

もし、同じ名前のVisualが複数対象Visualの子供として存在する場合は、どれか1個のみを取得します。
また、FindChild関数とFindImmediateChild関数は、同じように対象Visualの子供を取得しますが、大きな違いが1つあります。

それは「全ての子供から検索」するか「直下の子供から検索」するかの違いです。
図に表すとこんな感じですね。

親子関係 図


対象Visualの構成は上図のようになっています。
FindChild関数の場合、対象Visualの「Pallet」の全ての子供は「Tote」と「Box」が検索対象であるのに対し、
FindImmediateChild関数の場合は直下の「Tote」のみ検索対象です。

先ほどの図に加えると、こんな感じです。

処理 検索 範囲


今回のサンプルコードの場合、検索する名前が「YellowBox」だったため、
FindImmediateChild関数での取得は無し、
FindChild関数では以下の4個のうち1個を取得します。

名前 1つ Visual 検索

「名前」で複数の子Visualを取得する方法

2つ目は対象Visualから「名前」で複数の子Visualを取得する方法です。
対象Visual内で複数の同じ名前の子Visualに対して何か実行したい時に便利です。

C#の場合

var tobox-03-blue = load.FindImmediateChildren("BlueTote");

JScriptの場合

var tobox-03-blue : IEnumerable<Visual> = load.FindImmediateChildren("BlueTote");


FindImmediateChildren関数では、直下に存在する子供から指定された名前のVisualを全て取得出来ます。

サンプルモデルで搬送されているPallet上のToteの名前を全て一緒の「BlueTote」にした場合、「BlueTote」の以下の4個のVisualが取得出来ます。

名前 直下 Visual 1つ 検索

「タイプ」で複数の子Visualを取得する方法

3つ目は対象Visualの「タイプ」で複数の子Visualを取得する方法です。
対象Visual内で複数の同じTypeの子Visualに対して何か実行したい時に便利です。

C#の場合

var boxs = load.FindType(typeof(BoxVisual));

var importedMeshes = load.FindImmediateType(typeof(ImportedMeshVisual));

JScriptの場合

var boxs : ArrayList = load.FindType(BoxVisual);

var importedMeshes : ArrayList = load.FindImmediateType(ImportedMeshVisual);


各2つの処理では、検索したいTypeを渡して一致するVisualを全て取得出来ます。

FindType関数とFindImmediateType関数の違いは、1つ目で紹介した関数同様
「全ての子供から検索」するか、「直下の子供から検索」するかの違いです。

また、2つの処理は今まで紹介した関数と異なり、対象Visualも検索対象になります。

サンプルコードのFindType関数の場合、16個のBoxVisualを取得出来ます。

Type 複数 Visual 検索


サンプルコードのFindImmediateType関数の場合、直下の「Tote」そして「Pallet」の5個を取得出来ます。

Type 直下 Visual 複数 検索

「指定した条件」に一致する全ての子Visualを取得する方法

4つ目は対象Visualから「指定した条件」に一致する全ての子Visualを取得する方法です。
「名前」や「Type」以外に詳細な条件を指定してVisualを取得したい時に便利です。

C#の場合

var loads = load.FilteredDescendants(
                vis => (vis as PhysicsObject) is null ? 
                false : (vis as PhysicsObject).BodyType == PhysicsBodyType.Load
                );

var loads = load.FilteredChildren(
                vis => (vis as PhysicsObject) is null ? 
                false : (vis as PhysicsObject).BodyType == PhysicsBodyType.Load
                );

JScriptの場合

var loads : IEnumerable<Visual> = load.FilteredDescendants(
                                      vis -> defined(vis.BodyType) &&
                                      vis.BodyType == PhysicsBodyType.Load
                                  );

var loads : IEnumerable<Visual> = load.FilteredChildren(
                                      vis -> defined(vis.BodyType) &&
                                      vis.BodyType == PhysicsBodyType.Load
                                  );

各2つの処理では、検索したい条件式を渡して一致する全てのVisualを取得出来ます。

サンプルコードでの条件は対象の子Visualが「物理オブジェクトである」かつ「BodyTypeがLoadである」の2点です。
また、今回の書き方はラムダ式三項演算子を組み合わせています。

ラムダ式って?
 関数定義を呼び出し元に書く方式です。 要は使い捨て・その場限りの処理のことです。

三項演算子って?
 条件を指定し、真偽の分岐処理を簡単に書く方式です。if文を簡略化したものです。


FilteredDescendants関数とFilteredChildren関数の違いは、1つ目で紹介した関数同様「全ての子供から検索」するか、「直下の子供から検索」するかの違いです。

サンプルモデルで搬送されているPallet上のLoadの中で灰色のVisualのBodyTypeを「Visual Only」にして2つの処理を実行してみます。

条件 Visual 複数 検索


サンプルコードのFilteredDescendants関数の場合、「Box」 8個、「Tote」2個の合計10個を取得出来ます。

条件 Visual 複数 検索 FilteredDescendants


サンプルコードのFilteredChildren関数の場合、「Tote」2個を取得出来ます。

条件 Visual 複数 検索 FilteredChildren


対象のVisualの子供から検索が可能なため、
一部のVisualに対して固有の操作を行いたい場合に4つの検索方法を利用してはいかがでしょうか。

まとめ

いかがでしたでしょうか。
Emulate3D で数多くのVisual検索方法があることが分かったと思いますが、
状況によっての使い分けが難しいと感じたと思います。


最後に前編・後編でご紹介した各検索方法をまとめます。

★「シーン上に置かれたVisualから検索」は、全てのVisualから検索する。
★「対象Visualの子供から検索」は、検索範囲を子供に絞って検索する。
★「プロパティから検索」は、名前や親子関係が変わっても同じVisualを検索する。

今回ご紹介した内容が、少しでも皆様のお役に立てれば幸いです。
今後もブログによりEmulate3D の操作や技術をご紹介していきますので、ご活用ください。