日々適当

hibitekitou

このやり方でいいのか?

cg |2014-07-16

マジ面倒くさい。
えーと、csvを読み込んで、その値を元にシーンにパーティクルを作成したかったのです。目的はcsvに書かれた位置にcvsに書かれた高さの棒を立てるという物なので、パーティクルじゃなくて単なるキューブをいっぱい並べるでもいいんですけど、いっぱい並べると重くなりそうなんでパーティクルにしました。

例えばcsvはこんな感じ。

A,0,0,0.5,0.6,0.7,0.8
B,1,1,0.1,0.3,0.6,1.2
C,2,0,0.2,0.3,0.4,0.6
D,3,-1,1.5,1.1,0.9,0.5
E,4,0,1.3,0.5,0.3,0.1
F,5,1,1.2,1.3,1.4,0.5
G,6,0,0.2,0.3,0.6,0.8
H,7,-1,1.2,1.1,1.05,0.9
I,8,0,0.2,0.6,0.8,0.9
J,9,1,1.2,1.4,1.5,1.1
K,10,0,0.2,0.3,0.2,0.1

各行の2つ目がx位置、3つ目がz位置、4つ目から7つ目が時間1から時間4の高さという具合です。つまり各地点の4つの時間の値を持ったcsvファイルというわけですな。これを読み込んでパーティクルを設定するのに、例えば以下のように書いてみました。

import maya.cmds as cmds

filePath = '/Users/username/Desktop/test.csv'
pName = 'TESTPTCL'

f = open(filePath, 'r')
fileCnt = f.readlines()
f.close

pos = []
h1 = []
h2 = []
h3 = []
h4 = []

for line in fileCnt:
    line.rstrip('\n')
    lineItems = line.split(',')
    pos.append( ( float(lineItems[1]) , 0.0, float(lineItems[2]) ) )
    h1.append( float(lineItems[3]) )
    h2.append( float(lineItems[4]) )
    h3.append( float(lineItems[5]) )
    h4.append( float(lineItems[6]) )

cmds.particle( position = pos , name = pName )

seledted = cmds.ls( selection = True )
pName = seledted[0]

sph = cmds.listRelatives(pName)
cmds.addAttr( pName + "|" + sph[0], longName="h1v", dataType='doubleArray' )
cmds.addAttr( pName + "|" + sph[0], longName="h2v", dataType='doubleArray' )
cmds.addAttr( pName + "|" + sph[0], longName="h3v", dataType='doubleArray' )
cmds.addAttr( pName + "|" + sph[0], longName="h4v", dataType='doubleArray' )

for i in range( len(h1) ):
    cmds.select( pName + '.pt[' + str(i) + ']' )
    cmds.setParticleAttr( attribute='h1v', floatValue=h1[i] )
    cmds.setParticleAttr( attribute='h2v', floatValue=h2[i] )
    cmds.setParticleAttr( attribute='h3v', floatValue=h3[i] )
    cmds.setParticleAttr( attribute='h4v', floatValue=h4[i] )

cmds.saveInitialState( pName )



位置情報の配列から一気にパーティクルを作成して、その後、パーティクルIDを元にカスタムアトリビュートを各時間分設定(h1v~h4v)し、その上で、各アトリビュートにcsvから読み込んだ値を入れてやるという流れです。
最後にsaveInitialStateを実行しています。これやらないと、スクリプトを走らせた直後はカスタムアトリビュートに値が保持されているものの、スクラブすると値がリセットされちゃうのです(ゼロになる)。これはこーいうものなんですかね?リセットされちゃうってのを回避する方法を知らないがためにすごく時間を無駄にした…

その上で、パーティクルシェイプにキューブは無いからポリゴンキューブを一個作成し、インスタンサーでパーティクルにキューブを適用してやる。でもって、インスタンスのキューブのスケール値が参照するカスタムアトリビュートをパーティクルに作成し(スケールなのでベクトル型のPer particleのもの)、各時間の値をミックスするために参照するスカラー値のカスタムアトリビュートも作成しやす。仮に前者をCubeScale、後者をMixとしときやしょう。



そいで、CubeScaleの Runtime before dynamics にエクスプレッションを設定です。あ、このエクスプレッションが設定されたパーティクルのお名前はTESTPTCLとなってます。

float $h1v = TESTPTCLShape.h1v;
float $h2v = TESTPTCLShape.h2v;
float $h3v = TESTPTCLShape.h3v;
float $h4v = TESTPTCLShape.h4v;

float $mix = TESTPTCLShape.Mix;
vector $pos;

float $scl;

if ($mix < 1)
$scl = $mix * $h2v + (1 - $mix) * $h1v; else if ($mix >= 1 && $mix < 2) $scl = ($mix - 1) * $h3v + (1 - ( $mix - 1) ) * $h2v; else if ($mix >= 2 && $mix < 3) $scl = ($mix - 2) * $h4v + (1 - ( $mix - 2) ) * $h3v; else $scl = $h4v; TESTPTCLShape.CubeScale = <<1.0, $scl, 1.0>>; $pos = TESTPTCLShape.position; TESTPTCLShape.position = <<$pos.x, $scl * 0.5 , $pos.z>>;

 



なんかもぉ、すごく面倒くさいんですけど(値をカスタムアトリビュートに設定するところまで、これはどのツールでも面倒さは変わらないだろうけど)、こんなもんなんですかね…

コメント ( 0 )|Trackback ( )
 
コメント
 
コメントはありません。
コメントを投稿する
ブログ作成者から承認されるまでコメントは反映されません
 
名前
タイトル
URL
コメント
コメント利用規約に同意の上コメント投稿を行ってください。

数字4桁を入力し、投稿ボタンを押してください。