graphics.hatenablog.com

技術系テクニカルアーティストのあれこれ

.Net Framework から .Net Core 3.1 への Assembly Loading/Unloading 移植メモ。

自作のツールを .Net 4.6 から .Net Core 3.1 に移植したので、メモがてら記事化しておく。


GitHub - hal1932/csi: CSharp pseudo Interpreter
C# をランタイムコンパイルしてPythonとかRubyの代わりに使う - graphics.hatenablog.com
GitHub - hal1932/Csi3

  • AppDomain → AssemblyLoadContext
  • Assembly.ReflectionOnlyLoad → MetadataLoadContext.Load
    • 型情報だけをロードする仕組み
    • .Net Standard 2.0 以降でのコアライブラリ参照
  • Visual Studio デバッガ(Version 16.4.2 時点)との相性問題?
続きを読む

今度こそ from import を reload する。

この記事は Maya Advent Calendar 2019 - Qiita の 22 日目の記事になります。
前日の記事は @lie_871221 さんの mayaコマンドを使ったGUIの書き方 - Qiita でした。


Python API 2.0 についてなにか書こうと思ってたんだけど、ネタに詰まったので、過去に書いた Python コードをリファインしたときの話を書いてみる。
Python で from import を reload する。 - graphics.hatenablog.com

Maya というよりほぼ 100% Python の話なんだけど、まぁなんていうか、reload 自体おおよそ Maya Python 固有の話なので。。

  • 以前の方法の問題点
    • reload 済みモジュールの考慮が甘かった
    • 相対 import への対応が不十分だった
  • 改善策
    • コード解析処理の変更
    • ast.alias の考慮
続きを読む

Maya負荷テスト用シーン作成メモ

テクスチャ用画像作成

@echo off
setlocal enabledelayedexpansion

set PATH=%PATH%;C:\Program Files\ImageMagick-7.0.9-Q16
for /l %%i in (0, 1, 9999) do (
    set N=0000%%i
    set N=!N:~-4!
    magick convert -background lightblue -fill blue -size 100x100 -pointsize 32 -gravity center label:!N! indices\index_!N!.png
)

キューブ生成

import maya.cmds as cmds

cmds.file(new=True, force=True)

def test(count):
    index = 0

    z_root = cmds.createNode('transform')

    for z in xrange(count):
        y_root = cmds.createNode('transform')

        for y in xrange(count):
            x_root = cmds.createNode('transform')

            for x in xrange(count):
                cube, _ = cmds.polyCube()
                cmds.setAttr('{}.t'.format(cube), -count/2+x, -count/2+y, -count/2+z, type='double3')
                cmds.setAttr('{}.s'.format(cube), 0.5, 0.5, 0.5, type='double3')

                material = cmds.shadingNode('lambert', asShader=True)
                sg = cmds.sets(renderable=True, noSurfaceShader=True, empty=True)
                cmds.sets(cube, forceElement=sg)
                cmds.connectAttr('{}.outColor'.format(material), '{}.surfaceShader'.format(sg))

                file = cmds.createNode('file')
                cmds.setAttr('{}.fileTextureName'.format(file), 'indices/index_{:04}.png'.format(index), type='string')
                cmds.connectAttr('{}.outColor'.format(file), '{}.color'.format(material))
                
                cmds.select('{}.f[*]'.format(cube), replace=True)
                cmds.polyEditUV(pu=0.5, pv=0.5, su=2.3, sv=2.3)
                cmds.polyEditUV(u=0, v=0.3);
                
                cmds.parent(cube, x_root)
                
                index += 1
            
            cmds.parent(x_root, y_root)
            
        cmds.parent(y_root, z_root)

test(20)

Reading PyMEL: ex01. ノード周り書いてみた

いくら趣味とはいえずっと読んでるのも大変だから、試しに自分でも書いてみた。
まずは PyNode に相当する部分から。

github.com

QyMEL って名前に特に意味はなくて、まぁとりあえず "P" の隣で "Q" にしとこうかな*1ってくらい。

  • 基本設計
    • __new__ を使わない
    • プロパティを明確に露出する
    • maya.cmds との併用を前提とする
    • __repr__()
  • コード生成
  • 型判定
  • クラス設計
    • MayaObject
    • Plug
    • Component
    • Iterator
    • DependNode

*1:宗教は同じだけど宗派が違うイメージ。

続きを読む

Reading PyMEL: 02. createFunctions

前回の記事で "import pymel.core as pm" はなぜ遅いのか? を書いたので、ここをもうちょっと深堀りしてみる。
pm.polyCube() みたいに、PyMEL はなぜ MEL コマンドを直接呼ぶことができて、しかも返り値を PyNode で受けとれるのか?

  • PyMEL 経由でコマンドを叩くと何が起きるのか?
  • newFuncWithReturnFunc
  • createFunctions
  • CmdCache
  • コマンド名と maya.cmds 内の関数との紐付け
    • MEL コマンドの実体
    • DLL 遅延ロード
    • stubFunc
    • コマンドの引数と返り値の PyMEL-friendly にする
    • wrappedCmd
続きを読む

Reading PyMEL: 01. PyNode

ふと思い立ってコードを読んでみることにした。
github.com

まずは pymel.core.PyNode から。
意外と複雑だし、ちゃんと読んだことのある人ってそんなに多くはないんじゃなかろうか。

  • PyNode の機能
  • シーン内オブジェクトへのアクセス
    • PyNode インスタンスの作成
    • __init__ と __new__
    • 作成すべきインスタンス型の特定
    • 余談1: "import pymel.core as pm" はなぜ遅いのか?
    • 余談2: ProxyUnicode
  • ノードの作成
続きを読む

C#とPythonからC++を叩いてみる。

たとえば Unity と Maya の両方で同じロジックを使いたい場合、C#Python で同じものを実装するのはとてもだるいので、C++ で書いてから共有できるようにしてみた。
GitHub - hal1932/DllExportTest

この手のことをやるときは基本的には SWIG で全然問題ないんだけど、あれはあれで面倒*1なので手動でやる方法を整理しておくのも悪くないとは思う。

  • 仕組み
  • C++
    • DLLエクスポート宣言
    • 関数の呼び出し規約
    • クラス定義
  • C#
    • DLL のロードとアンロード
    • 関数呼び出し
    • 引数と戻り値
    • コールバック関数
    • メモリ領域のやりとり
  • Python
    • DLL のロードとアンロード
    • 関数呼び出し
    • 引数と戻り値
    • コールバック関数の定義
    • メモリ領域のやりとり
    • スレッド周りの扱い

*1:例えば生成した Python モジュールを Maya で使いたい場合、mayapy を使って pyd を作ってやる必要があったりして無駄に汎用性を落とすことになる。ctypes 直叩きだと依存先に Maya が含まれないはずだからちょっとだけ嬉しい。

続きを読む