ファクトリーセッティング

このシステムは、コンストラクタとファクトリーモジュールを管理、運用するためのものです。この章ではコマンドによってファクトリーセッティングを操作し、どのような挙動を行うものなのかを解説していきます。

運用に使用するクラス

ファクトリーセッティングを運用するにあたって、主に以下のクラスを使用します。

factory.FactoryData

このクラスはファクトリーセッティングそのものであり、このクラスでプロジェクトディレクトリ単位のファクトリーの設定を作成、編集する事ができます。

FactoryDataクラスではスクリプトベースのリギングを行う上で必用な情報を設定します。

setRootPath(str)

このメソッドはファクトリーセッティングを行う上で最も重要なメソッドです。このメソッドの引数にはディレクトリパスを指定します。

1
2
3
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')

指定されたディレクトリパスは、ファクトリーセッティングのプロジェクトディレクトリとして認識されます。ファクトリーの操作は、全てこのプロジェクトディレクトリとして認識されたデータに対して行われます。

その他の編集・参照用メソッド

ルートディレクトリを設定したら、以下のメソッドも使用する事ができます。この設定により、ファクトリーセッティングとして操作する対象のアセット情報を登録する事ができます。

メソッド一覧

setAssetName(str)

アセット名を設定する。

setAssetType(str)

アセットの種類を設定する

setProject(str)

プロジェクト名を設定する。

setConstructorName(str)

使用するコンストラクタ名を設定する。使用できるコンストラクタ名については使用可能コンストラクタの一覧を取得するを参照。

1
2
3
4
5
6
7
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.setAssetName('grico')
settings.setAssetType('CH')
settings.setProject('RigTraining')
settings.setConstructorName('standardConstructor')

情報をプロジェクトディレクトリに保存する。

これらの情報を設定した後に、saveFileメソッドを使用するとsetRootPathで指定したディレクトリの直下に、設定された情報に基づいたgrisFactoryWorkspace.xmlが作成されます。

1
2
3
4
5
6
7
8
9
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.setAssetName('grico')
settings.setAssetType('CH')
settings.setProject('RigTraining')
settings.setConstructorName('standardConstructor')

settings.saveFile()

既存のプロジェクトディレクトリの情報を取得する。

すでに設定用xmlファイルが保存されているプロジェクトディレクトリに対してsetRootPathを行った場合、設定ファイルが自動的に読み込まれ、アセット情報が設定されている状態になります。

設定されている情報を取得するには以下のメソッドを使用することで可能です。

メソッド一覧

assetName

アセット名を取得する。

assetType

アセットの種類を取得する。

project

プロジェクト名を取得する。

constructorName

使用するコンストラクタ名を取得する。

1
2
3
4
5
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.assetName()
# Result: grico #

constructors.ConstructorManager

このクラスはコンストラクタを管理するためのクラスです。カレントのコンストラクタを設定したり、使用できるコンストラクタのリストの情報などを管理しています。

また、コンストラクタにはデフォルトで取り扱うファクトリーモジュールの情報も持っています。ファクトリーセッティングを運用する上で、このファクトリーモジュールの情報が必用になるため、これらクラスを使用して必用な情報を集めてきます。

コンストラクタ自体の詳細な説明についてはコンストラクタをご覧下さい。

使用可能コンストラクタの一覧を取得する

ファクトリーセッティングに渡す、使用可能なコンストラクター名の一覧を取得するには以下の方法で行います。

1
2
3
4
from gris3 import constructors
cst_mngr = constructors.ConstructorManager()
cst_mngr.names()
# Result: ['standardConstructor', 'unityConstructor'] #

コンストラクタのインスタンスを取得する

各コンストラクタは、pythonのモジュールとして記述されています。このモジュール自体を取得するにはmoduleメソッドを使用します。

このメソッドの引数にはnamesメソッドによって取得できるリストのいずれかの文字列になります。

1
2
3
4
from gris3 import constructors
cst_mngr = constructors.ConstructorManager()
cst_mod = cst_mngr.module('standardConstructor')
# Result: <module 'gris3.constructors.standardConstructor' from ~>

コンストラクタ用モジュールには必ずConstructorクラスが存在します。コンストラクタークラスの引数には上記のFactoryDataのインスタンスを渡します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from gris3 import factory, constructors
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.setAssetName('grico')
settings.setAssetType('CH')
settings.setProject('RigTraining')
settings.setConstructorName('standardConstructor')

cst_mngr = constructors.ConstructorManager()
cst_mod = cst_mngr.module('standardConstructor')
cst = cst_mod.Constructor(settings)
# Result: <gris3.constructors.standardConstructor.Constructor object at ~> #

デフォルトのファクトリーモジュール一覧を取得する

前述のように、コンストラクタには取り扱うファクトリーモジュールのデフォルトセットが登録されています。この一覧を取得し、FactoryDataに反映させます。

デフォルトのファクトリーモジュールセットはFactoryModules変数内に格納されています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from gris3 import constructors
cst_mngr = constructors.ConstructorManager()
cst = cst_mngr.module('standardConstructor').Constructor()
cst.FactoryModules
# Result: (
#  <gris3.factory.ModuleInfo : "jointBuilder" / "None" / "None" / "">,
#  <gris3.factory.ModuleInfo : "cageManager" / "None" / "None" / "">,
#  <gris3.factory.ModuleInfo : "drivenManager" / "None" / "None" / "">,
#  <gris3.factory.ModuleInfo : "weightManager" / "None" / "None" / "">,
#  <gris3.factory.ModuleInfo : "facial" / "None" / "None" / "">,
#  <gris3.factory.ModuleInfo : "extraJointManager" / "None" / "None" / "">,
#  <gris3.factory.ModuleInfo : "controllerExporter" / "None" / "None" / "">
#)

この変数に格納されているのはModuleInfoクラスを複数持つリストです。

ModuleInfoは

  • モジュール名

  • このモジュールが操作対象とするディレクトリ名

  • エイリアス名(別名)

  • 内部操作する際にキーワードとなるタグ

の4つの情報を持つクラスで、ファクトリーセッティングやコンストラクタはこの情報を元にファクトリーモジュールの管理を行います。

参考

ModuleInfoの詳細についてはModuleInfoクラスをご覧下さい。

ユーザーはアセットごとにこの情報をカスタマイズする事が出来ますが、基本的にコンストラクタが要求するデフォルトのファクトリーモジュールセットは必ず作るようにして下さい。

このファクトリーモジュールセットをFactoryDataオブジェクトに追加します。

FactoryDataにモジュールセットを登録し、保存する。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from gris3 import factory, constructors
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')

cst_mngr = constructors.ConstructorManager()
cst = cst_mngr.module('standardConstructor').Constructor()
for info in cst.FactoryModules:
    settings.addModule(info.moduleName(), info)

settings.saveFile()

この操作により、このアセットが取り扱うコンストラクタと、ファクトリーモジュールのセットに関する設定が完了しました。

完了するとgrisFactoryWorkspace.xml内には各種情報とファクトリーモジュールセットに関する情報が追記されます。

factoryModules.FactoryModuleManager

このクラスはgrisが管理するファクトリーモジュールの管理や、情報取得機能を提供するクラスです。

このクラスのインスタンスを作成すると、grisが管理するファクトリーモジュールを一度全てインポートします。この処理は時間がかかるため、このクラスはシングルトンになっており余計な処理を挟まないようになっています。

ファクトリーモジュールは要素の書き出し機能と、書き出し先がペアとなる事で成立します。モジュールと書き出し先のペアリングは、ファクトリーセッティングによりプロジェクトディレクトリ単位で設定する事ができます。しかし、毎回ペアリングを設定しなくてもいいように、各ファクトリーモジュールはデフォルトの書き出し先名を持っています。

FactoryModuleManagerクラスはこのペアリング情報を提供します。

モジュールと書き出し先のデフォルトのペア情報を取得する

FactoryModuleManagerのmoduleNameListメソッドを使用すると、現在使用可能なファクトリーモジュールの一覧が取得できます。この一覧は辞書型式になっており、モジュール名とそのモジュールを管理するクラスにアクセスできるようになります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from gris3 import factoryModules
fmm = factoryModules.FactoryModuleManager()
fmm.moduleNameList()
# Result: {
#    'extraJointManager': <class 'gris3.factoryModules.extraJointManager.Department'>,
#    'facial': <class 'gris3.factoryModules.facial.Department'>,
#    'cageManager': <class 'gris3.factoryModules.cageManager.Department'>,
#    'controllerExporter': <class 'gris3.factoryModules.controllerExporter.Department'>,
#    'workspace': <class 'gris3.factoryModules.workspace.Department'>,
#    'weightManager': <class 'gris3.factoryModules.weightManager.Department'>,
#    'model': <class 'gris3.factoryModules.model.Department'>,
#    'drivenManager': <class 'gris3.factoryModules.drivenManager.Department'>,
#    'jointBuilder': <class 'gris3.factoryModules.jointBuilder.Department'>
#}

各モジュールには必ずDepartmentクラスを持っており、このクラスが各モジュールの動作を定義しています。

モジュールのデフォルトで設定されている書き出し先ディレクトリ名もこのクラスが管理しています。

jointBuilderモジュールのデフォルト書き出し先名を取得する。
1
2
3
4
5
from gris3 import factoryModules
fmm = factoryModules.FactoryModuleManager()
cls = fmm.moduleNameList().get('jointBuilder')
cls().directoryName()
# Result: joints #

factoryModules.FactorySettings

このクラスはファクトリーウィンドウと紐付けられた非常に重要なクラスですが、実態はfactory.FactoryDataクラスを親クラスとしたサブクラスです。

従ってプロジェクトディレクトリをコマンドで作成する内で記述されている

settings = factory.FactoryData()

settings = factoryModules.FactorySettings()

に置き換えても動作するようになっています。

FactoryDataクラスとの違い

前述の説明だけ見るとほぼFactoryDataクラスと同じ内容ですが、こちらはQtCore.QObjectからも多重継承しており、設定変更を行う度にGUIへシグナルを送出するようになっています。

blockdiag QtCore.QObject factory.FactoryData factoryModules.Factor ySettings

そのため、このクラスはシングルトンで作られており、存在するファクトリーウィンドウや実行するConstructorなど、すべてに対して影響を与えます。

警告

このクラスはGUIへの影響が大きいため取り扱いには注意が必用です。

ファクトリーセッティングというシステムにおいては、起動中のアプリ内で復数のアセットを同時進行で扱う事はないという前提があります。そのためファクトリーセッティングでは常に現在作業中のアセットの情報のみが提供され、Constructorに関する機能はこの一つのアセットの情報のみを取り扱うように設計されています。

blockdiag FactorySettings ConstructorManager Constructor FactoryWindow(GUI) data data data

代表的なのはconstructorモジュールのcurrentConstructorメソッドです。このメソッドは現在FactorySettingsクラスのsetRootPathされているプロジェクトディレクトリが設定されているコンストラクタを返すようになっています。

これはcurrentConstructor内でFactorySettingsクラスを呼び出し、このクラスがセットしているプロジェクトディレクトリの設定を読み取るようになっているためです。

blockdiag ConstructorManager FactorySettings access data

FactorySettingsを任意のFactoryDataに置き換える

通常はFactorySettingsを使用する事によって問題なく運用する事ができますが、このクラスはファクトリーウィンドウなどのGUIにも影響を及ぼすため、スクリプトを裏で実行したい場合などには向かないケースもあります。

このようにGUI起動中に別の設定でConstructorを実行したいなどの場合は

factoryModulues.startManualy

を使用します。このクラスはインスタンス作成時にFactoryDataオブジェクトを渡して使用する、with文用のコンテキストです。

このクラスをwith文で使用すると、with内で呼ばれるFactorySettingsは全てインスタンス時に渡したFactoryDataオブジェクトに置き換わります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from gris3 import factoryModules, constructors, factory
# GUIに連動した設定オブジェクトを作成。
fs = factoryModules.FactorySettings()
fs.setRootPath('D:/assets/testRig')
fs.setConstructorName('standardConstructor')

# currentConstructorメソッドは常にFactorySettingsの内容を反映する。========
constructors.currentConstructor()
# Result: <class 'gris3.constructors.standardConstructor.Constructor'> #

fs.setConstructorName('unityConstructor')
constructors.currentConstructor()
# Result: <class 'gris3.constructors.unityConstructor.Constructor'> #

fd = factory.FactoryData()
fd.setRootPath('D:/assets/testRig')
fd.setConstructorName('standardConstructor')
constructors.currentConstructor()
# Result: <class 'gris3.constructors.unityConstructor.Constructor'> #
# =========================================================================

# startManualy内だけcurrentConstructorメソッドの挙動が変わる。=============
with factoryModules.startManualy(fd):
    constructors.currentConstructor()
    # Result: <class 'gris3.constructors.standardConstructor.Constructor'> #
cm.currentConstructor()
# Result: <class 'gris3.constructors.unityConstructor.Constructor'> #
# =========================================================================

constructorモジュール内の機能にはFactorySettingsにアクセスしているものが多いため、このモジュールにまつわる何かを呼ぶ際にはstartManualyを使用すると良いでしょう。

プロジェクトディレクトリをコマンドで作成する

このセクションでは前述した仕組みを使用して、スクリプトでファクトリーが取り扱うプロジェクトディレクトリを作成してみましょう。

以下のコードでは任意のディレクトリにstandardConstructorのデフォルトセットを設定し、プロジェクトディレクトリを作成しています。

尚、FactoryDataにセットするディレクトリパスは、予め作成しておく必用があります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from gris3 import factory, constructors, factoryModules
# 使用するコンストラクタ名を定義しておく。
constructor_name = 'standardConstructor'

# アセットの設定を行う。
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.setAssetName('grico')
settings.setAssetType('CH')
settings.setProject('RigTraining')
settings.setConstructorName(constructor_name)

# 各モジュールのデフォルトの書き出し先のテーブルを作成する。
fmm = factoryModules.FactoryModuleManager()
dir_table = {
    name : f_cls().directoryName()
    for name, f_cls in fmm.moduleNameList().items()
}

# 使用するコンストラクタクラスのインスタンスを作成し、
# 要求されるデフォルトのファクトリーモジュールセットのリストを取得。
cm = constructors.ConstructorManager()
m = cm.module(constructor_name) #コンストラクタを格納しているpyモジュール
c = m.Constructor(settings)     #コンストラクタのインスタンス
modulelist = c.FactoryModules

for info in modulelist:
    module_name = info.moduleName()
    dirname = dir_table.get(module_name)
    if not dirname:
        raise RuntimeError(
            'A module {} was not found in default factory modules.'.format(
                module_name
            )
        )
    # 新規でModuleInfoを作成し、その中にデフォルトの書き出し先の名前も格納しておく。
    new_mod = factory.ModuleInfo(module_name, dirname, info.alias(), info.tag())
    # FactoryDataにモジュール情報を追加する。
    settings.addModule(module_name,  new_mod)

# モデル保存用と作業データ保存用ディレクトリを追加する。
for module_name, dirname in c.SpecialModules.items():
    new_mod = factory.ModuleInfo(module_name, dirname, '', '')
    settings.addModule(module_name,  new_mod)

# プロジェクト設定を書き出す。
settings.saveFile()

# プロジェクト設定に基づいて、プロジェクトディレクトリ内にファクトリーモジュールが
# 必用とする書き出し先ディレクトリを作成する。
factory.createFactoryDirectory(settings)

# コンストラクタに用意されているスクリプトのテンプレートを作成する。
cmd, module = cm.getConstructionScriptCmd(constructor_name, True)
cmd(settings, module)

プロジェクトディレクトリのビルドスクリプトを実行する

このセクションではアセットのリギングが完了したプロジェクトディレクトリのスクリプトを、コマンドから実行してみましょう。

まずは定番の、FactoryDataクラスを作成してプロジェクトディレクトリのパスを設定から初めます。

1
2
3
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')

続いて、実行可能なモジュールの一覧を取得してみましょう。

1
2
3
4
5
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.listScripts()
# Result: ['setup_high', 'setup_low', '__init__'] #

FactoryData.listScriptsメソッドは、Constructorとして実行可能なPythonモジュールがリストとして返ってきます。

Constructorとして実行可能とは、単純にモジュール内にConstructorという名前の機能が存在するかどうかで判定しています。また原則として__init__は実行しても無効です。(対応する読み込みモデルが存在しないため)

最後にこのリストの中の一つを実行してみましょう。尚リストの中身がわかっているのであれば、listScriptsは行う必要はありません。

1
2
3
4
from gris3 import factory
settings = factory.FactoryData()
settings.setRootPath('D:/assets/testRig')
settings.execScript('setup_high')

これで目的のアセットのビルドが開始されます。