前回に続き,今回はメッシュを作成します。
メッシュの作成
次のようなメッシュの作成に取り組みます。Vertex が 6 点,Face が 2 面あります。
これを Points(頂点座標),FaceVertexCounts(面の頂点数),FaceVertexIndices(面の頂点ID) の各アトリビュートに落とし込みます。DoubleSided(両面表示)はオフとしました。
from pxr import Usd, UsdGeom, Sdf
def create_mesh(stage, path):
mesh = UsdGeom.Mesh.Define(stage, path)
# Points
vList = []
vList.append((-1, 0, 0))
vList.append(( 0, 0, 0))
vList.append(( 1, 0, 0))
vList.append((-1, 1, 0))
vList.append(( 0, 1, 0))
vList.append(( 1, 1, 0))
mesh.CreatePointsAttr(vList)
# FaceVertexCounts
fList = []
fList.append(4)
fList.append(4)
mesh.CreateFaceVertexCountsAttr(fList)
# FaceVertexIndices
fList = []
fList.extend((0, 1, 4, 3))
fList.extend((1, 2, 5, 4))
mesh.CreateFaceVertexIndicesAttr(fList)
# DoubleSided
mesh.CreateDoubleSidedAttr(False)
return mesh
ここで,頂点に色情報(RGB)を与えてみます。
色は指定の頂点以外の空間(たとえば面全体)にも現れてほしいので,補間が可能な Primvar として盛り込みます。補間方法は varying(Bilinear補間)を指定しています。
# DisplayColor
vList = []
vList.append((1, 0, 0)) # Red
vList.append((0, 1, 0)) # Green
vList.append((0, 0, 1)) # Blue
vList.append((1, 1, 0)) # Yellow
vList.append((1, 1, 1)) # White
vList.append((1, 0, 1)) # Magenta
primvar_api = UsdGeom.PrimvarsAPI(mesh)
primvar = primvar_api.CreatePrimvar('displayColor', Sdf.ValueTypeNames.Color3f, interpolation=UsdGeom.Tokens.varying)
primvar.GetAttr().Set(vList)
メインプログラムです。
if __name__ == '__main__':
# ステージ作成
stage = create_stage()
# ルートノード作成
rootNode = create_node(stage, '/World', is_defaultPrim=True)
# メッシュ作成
mesh = create_mesh(stage, rootNode.GetPath().AppendChild('Mesh'))
# USDファイルにエクスポート
stage.GetRootLayer().Export('./Mesh.usda')
出力は次のとおり。usdchecker もパスしました。
#usda 1.0
(
defaultPrim = "World"
metersPerUnit = 0.01
upAxis = "Y"
)
def Xform "World"
{
def Mesh "Mesh"
{
int[] faceVertexCounts = [4, 4]
int[] faceVertexIndices = [0, 1, 4, 3, 1, 2, 5, 4]
point3f[] points = [(-1, 0, 0), (0, 0, 0), (1, 0, 0), (-1, 1, 0), (0, 1, 0), (1, 1, 0)]
color3f[] primvars:displayColor = [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0), (1, 1, 1), (1, 0, 1)] (
interpolation = "varying"
)
}
}
$ usdchecker Mesh.usda
Success!
面単位でデータアサイン
上の例では 6 個の頂点に色情報を割り当てましたが,面単位で区切って割り当てることもできます。はじめにひとつ目の面の 4 頂点,次にふたつ目の面の 4 頂点,… といった具合です。そのような指定は,Primvar の interpolation を faceVarying にすることで可能になります。
# displayColor
fvList = []
fvList.append((1, 0, 0)) # Red
fvList.append((0, 1, 0)) # Green
fvList.append((1, 1, 1)) # White
fvList.append((1, 1, 0)) # Yellow
fvList.append((0, 1, 0)) # Green
fvList.append((0, 0, 1)) # Blue
fvList.append((1, 0, 1)) # Magenta
fvList.append((1, 1, 1)) # White
primvar_api = UsdGeom.PrimvarsAPI(mesh)
primvar = primvar_api.CreatePrimvar('displayColor', Sdf.ValueTypeNames.Color3f, interpolation=UsdGeom.Tokens.faceVarying)
primvar.GetAttr().Set(fvList)
このようにしても上と同じ結果が得られます。
この「面単位」でのアサインは,次の記事に書く予定のマテリアルの作成においてテクスチャマッピングで使用されることになります。
参考資料
ft-lab (Yutaka Yoshisaka) さん,USD-WG,あんどうめぐみさん による以下のサイトが理解の助けになりました。