0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

USDの実践メモ 02 : メッシュの作成

Posted at

前回に続き,今回はメッシュを作成します。

メッシュの作成

次のようなメッシュの作成に取り組みます。Vertex が 6 点,Face が 2 面あります。

meshgrid_480x360.png

これを 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!

color_mesh_400x205.png

面単位でデータアサイン

上の例では 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,あんどうめぐみさん による以下のサイトが理解の助けになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?