2017年11月22日

プロシージャルモデリングについて調べてみた その11 modo11.0v3

引き続き「プロシージャルモデリング」について調べてみたい。

前回までの仕組みで「エフェクタ」の「Height」のY軸位置で螺旋の全長が、「Width」のX軸位置で螺旋の旋回半径が決まり、Y軸方向に螺旋が生成される仕組みになっている事がわかった。

fig10

これらのエフェクタと曲線を捩じる「Vortex Effector」は「Axis」ロケータにペアレントされていて、

fig01

螺旋の方向を「Axis」でコントロール出来るようになっている。

fig02

ただこの仕組みがちょっとややこしい。通常「Height」が「Axis」にペアレントしている場合、「Axis」が回転すると、「Height」も同じように回転するので「Height」に引っ張られる「カーブ」の端点も同じ位置に移動して下のように「Axis」の回転と同期する。

fig03

これだけなら問題無いんだけど、この「カーブ」全体をX軸方向に移動する「エフェクタ」の「Width」も「Axis」によって回転するので、「Height」と「Width」の両方の影響を受けた「カーブ」はより回転してしまう。

fig04

その結果、「Axis」によって回転した「Vortex Effector」の捩じる軸方向からずれてしまい、

fig05

螺旋の半径が一定ではなくなってしまう。

fig06

続きはまた次回。

modo10-11ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2017年11月21日

ビットマップペイントツールのチュートリアルをやってみた その102 3dsmax 2017

引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。

前回調べたファイルストリームの「seek」メソッドの1文字ズレ問題だけど、とても簡単な解決方法を思いついた。それはどうやらさすがの「seek」メソッドもファイルの先頭位置は間違えないって事だ。つまり本番の「seek」の前に1回ファイルポインタを先頭に戻しちゃえば問題ないって事だ。

下のプログラムは「seek」をバグフィックスした「myseek」を作って「seek」を置き換えたものだ。

fn myseek fp dest= (
  seek fp 0
  seek fp dest
)

(
  filename = (getDir #temp +"/particlePaint_temp.txt")
  tmp_file = openFile filename
  frames = #()
  while not (eof tmp_file) do 
  (
    frame = readvalue tmp_file
    frames[frame+1] = (filePos tmp_file)
    count = readvalue tmp_file
    for i =  1 to count do
    (
      id = readvalue tmp_file
      tm = readvalue tmp_file
      scl = readvalue tmp_file
    )
  )

  readFrame = 5
  myseek tmp_file (frames[readFrame+1])
  count = readvalue tmp_file
  format "frame = % , count = %\n" readFrame count
  readFrame = 3
  myseek tmp_file (frames[readFrame+1])
  count = readvalue tmp_file
  format "frame = % , count = %\n" readFrame count
  readFrame = 1
  myseek tmp_file (frames[readFrame+1])
  count = readvalue tmp_file
  format "frame = % , count = %\n" readFrame count
  readFrame = 2
  myseek tmp_file (frames[readFrame+1])
  count = readvalue tmp_file
  format "frame = % , count = %\n" readFrame count
  readFrame = 10
  myseek tmp_file (frames[readFrame+1])
  count = readvalue tmp_file
  format "frame = % , count = %\n" readFrame count
  readFrame = 5
  myseek tmp_file (frames[readFrame+1])
  count = readvalue tmp_file
  format "frame = % , count = %\n" readFrame count
  close tmp_file
)

これが結果。これでファイルポインタをどこにやってもズレないで済むようになった。

myseek()
frame = 5 , count = 10
frame = 3 , count = 6
frame = 1 , count = 2
frame = 2 , count = 4
frame = 10 , count = 10
frame = 5 , count = 10
OK

このプログラムのもう一ついいところは将来「seek」がバグフィクスされても影響が無いってところだな。

続きはまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)3ds Max | CG

2017年11月20日

プロシージャルモデリングについて調べてみた その10 modo11.0v3

引き続き「プロシージャルモデリング」について調べてみたい。

前回までの部分で長さ0の「カーブ」の片方の端の頂点を選択セットに登録して、それを「Transform」オペレータで「アセンブリ入力」の「Length」の値の距離だけ移動させて、長さ「Length」の「カーブ」に仕立てるところまで調べた。

fig13

この「カーブ」に対して「Curve Rebuild」オペレータを適用することで頂点の数を増やして螺旋の形状に仕立てる下準備をする。

「Curve Rebuild」オペレータの「モード」は「間隔距離」になっていて、

fig02

「ポイント間隔」チャンネルは「アセンブリ入力」の「Point Spacing」に接続されていて、

fig03

「Point Spacing」の値の間隔で「カーブ」上に頂点が生成される。

fig01

この「カーブ」は「トランスフォーム」オペレータによってさらに変換させられる。「タイプ」が「メッシュ全体」になっているので「カーブ」全体が変換の対象になる。

fig05

「トランスフォーム」の「エフェクタ」には「Widthロケータ」が接続されている。

fig04

そして「Withロケータ」の「位置X」が「アセンブリ入力」の「Radius」に接続されているので、

fig06

「Radius」の値のぶんだけX方向に「カーブ」全体が移動する事になる。

fig07

これを捩じるのが「Vortex Effector」オペレータで、位置が(0,0,0)で、回転もスケーリングもしていないので、原点を中心にY軸で捩じることになる。

fig08

「ツイスト」チャンネルは「アセンブリ入力」の「Twist Per Meter」に接続され、「テーパー」チャンネルは「Taper」を「Length」で割った値が入力されている。これによって単位長さ当りの旋回半径の変化量を指定するようになっているわけだ。

fig09

これで原点からY軸に沿って「Length」の高さで「Radius」の半径の螺旋が生成されるわけだ。

fig10

続きはまた次回。

modo10-11ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2017年11月16日

ビットマップペイントツールのチュートリアルをやってみた その101 3dsmax 2017

引き続きMAXScriptマニュアルに載っている「チュートリアル-ビットマップペイントツールを9つの簡単なステップで作成する」 の続きを考えて見たい。

前回「seek」メソッドでファイルポインタを戻すと位置がズレる事がわかった。

この1文字ズレにはちょっと思い当たる事がある。それは前回も1文字ズレるために取得した位置に1加えて位置出しをしてたって事だ。プログラムを見るとファイルを最後まで読み込んだ後で「seek」でポインタをファイルの先頭方向に1回戻している。実はこの1回戻しが1文字ズレの原因なんじゃないだろうか?

そこでファイルポインタの位置を調べたら一回ファイルを閉じてもう一度ファイルを開きなおして試してみた。

(
	filename = (getDir #temp +"/particlePaint_temp.txt")
	tmp_file = openFile filename
	frames = #()
	while not (eof tmp_file) do 
	(
		frame = readvalue tmp_file
		frames[frame+1] = (filePos tmp_file)+1
		count = readvalue tmp_file
		for i =  1 to count do
		(
			id = readvalue tmp_file
			tm = readvalue tmp_file
			scl = readvalue tmp_file
		)
	)

	close tmp_file
	
	tmp_file = openFile filename

	readFrame = 1
	seek tmp_file (frames[readFrame+1])
	print (readline tmp_file)
	--count = readvalue tmp_file
	--format "frame = % , count = %\n" readFrame count
	readFrame = 5
	seek tmp_file (frames[readFrame+1])
	print (readline tmp_file)
	--count = readvalue tmp_file
	--format "frame = % , count = %\n" readFrame count
	readFrame = 3
	seek tmp_file (frames[readFrame+1])
	print (readline tmp_file)
	--count = readvalue tmp_file
	--format "frame = % , count = %\n" readFrame count
	close tmp_file
)

これがその結果。前回の結果と1文字ズレた。やはり想像通りのようで「seek」は戻る時に1文字ズレるようだ。なんじゃこの仕様・・・。

""
"0"
"6"
OK

そこでファイルポインタの位置を調べる時に1文字追加をやめてみると、

(
	filename = (getDir #temp +"/particlePaint_temp.txt")
	tmp_file = openFile filename
	frames = #()
	while not (eof tmp_file) do 
	(
		frame = readvalue tmp_file
		frames[frame+1] = (filePos tmp_file)
		count = readvalue tmp_file
		for i =  1 to count do
		(
			id = readvalue tmp_file
			tm = readvalue tmp_file
			scl = readvalue tmp_file
		)
	)

	close tmp_file
	
	tmp_file = openFile filename

	readFrame = 1
	seek tmp_file (frames[readFrame+1])
	print (readline tmp_file)
	--count = readvalue tmp_file
	--format "frame = % , count = %\n" readFrame count
	readFrame = 5
	seek tmp_file (frames[readFrame+1])
	print (readline tmp_file)
	--count = readvalue tmp_file
	--format "frame = % , count = %\n" readFrame count
	readFrame = 3
	seek tmp_file (frames[readFrame+1])
	print (readline tmp_file)
	--count = readvalue tmp_file
	--format "frame = % , count = %\n" readFrame count
	close tmp_file
)

このようになった。どうも配列のインデックスの開始が1なのと関係ありそうな匂いがするな。

"2"
"10"
",6"
OK

とりあえず「seek」で戻る時には1文字ズラすようにして実験してみた。

(
	filename = (getDir #temp +"/particlePaint_temp.txt")
	tmp_file = openFile filename
	frames = #()
	while not (eof tmp_file) do 
	(
		frame = readvalue tmp_file
		frames[frame+1] = (filePos tmp_file)
		count = readvalue tmp_file
		for i =  1 to count do
		(
			id = readvalue tmp_file
			tm = readvalue tmp_file
			scl = readvalue tmp_file
		)
	)
	close tmp_file
	
	tmp_file = openFile filename
	readFrame = 5
	seek tmp_file (frames[readFrame+1])
	count = readvalue tmp_file
	format "frame = % , count = %\n" readFrame count
	readFrame = 3
	seek tmp_file (frames[readFrame+1]+1)
	count = readvalue tmp_file
	format "frame = % , count = %\n" readFrame count
	readFrame = 1
	seek tmp_file (frames[readFrame+1]+2)
	count = readvalue tmp_file
	format "frame = % , count = %\n" readFrame count
	readFrame = 2
	seek tmp_file (frames[readFrame+1]+2)
	count = readvalue tmp_file
	format "frame = % , count = %\n" readFrame count
	readFrame = 10
	seek tmp_file (frames[readFrame+1]+2)
	count = readvalue tmp_file
	format "frame = % , count = %\n" readFrame count
	readFrame = 5
	seek tmp_file (frames[readFrame+1]+3)
	count = readvalue tmp_file
	format "frame = % , count = %\n" readFrame count
	close tmp_file
)

するとちゃんと値が取得できた。どうやらバグは間違いなさそうだ。

frame = 5 , count = 10
frame = 3 , count = 6
frame = 1 , count = 2
frame = 2 , count = 4
frame = 10 , count = 10
frame = 5 , count = 10
OK

続きはまた次回。

maxまとめページ



take_z_ultima at 11:30|この記事のURLComments(0)3ds Max | CG

2017年11月15日

プロシージャルモデリングについて調べてみた その9 modo11.0v3

引き続き「プロシージャルモデリング」について調べてみたい。

前回は「Spiral Curve」のパラメータの機能を調べてみた。今回はそれがどう実現されているかについて調べて行きたい。

シーンに読み込んだ「Spiral Curve」を「スケマティック」ビューにドラッグして、右クリックでメニューを出して「アセンブリへ展開」で「アセンブリ」に変換する。

fig01

それをダブルクリックして開く。

fig02

これが「アセンブリ」の中身だ。この中にある「Mesh (2)」を選んで、「プロパティ」パネルの「表示」サブタブから「可視」プロパティを「デフォルト」に切り替えてビューポートにこのアセンブリが生成するメッシュオブジェクトを表示する。

fig03

アイテムリストを見ると、「Mesh (2)」アイテムと、「Axis」「Height」「Width」ロケータ、「Vortex Effector」エフェクタで構成されているのが見て取れる。そして「Height」「Width」「Vortex Effector」は「Axis」にペアレントしていて、「Axis」の動きに3つのアイテムが追従するようになっている。

fig04

まず「Mesh (2)」から見て行く。

「メッシュオペレータ」リストで「Deform Folder」を無効にして「Mesh (2)」への効果を全部無効にして「Mesh (2)」を調べてみたら、

fig05

2つの頂点から構成される1本の曲線が入っていて、

fig06

その両端の頂点はどちらも原点(0,0,0)に存在しているようだ。

fig07

この「Mesh (2)」に対して最初に行われるオペレーションは、「Assign Selection Set」だ。

選択セットの対象は「Vertex」で、名前は「TopVert」になる。

fig10

割り当てられる頂点は「Select By Index」で頂点番号で指定されて、

fig08

0番の頂点が選択されている。

fig09

これで曲線を構成する2つの頂点のうちの1つが「TopVert」という選択セットに割り当てられた。

次のオペレーションは「Transform」だ。オペレーションの対象にするのは「頂点選択セット:TopVert」に含まれる頂点になっている。つまり曲線の片方の頂点だ。

fig11

「Transform」オペレータは「エフェクタ」の変換を操作対象に適用するもので、このオペレータの「エフェクタ」は「Height」ロケータに接続され、「Height」ロケータの「位置 Y」が「Length」チャンネルに接続されている。

fig12

つまり「Mesh (2)」の曲線は原点から(0,Length,0)を繋ぐ線になるわけだ。

fig13

この「Transform」オペレータを使えば頂点レベルの変形もいろいろ出来るわけだね。「Transform」オペレータはシーンに追加すると「エフェクタ」に繋がる「ロケータ」アイテムも同時に追加される。この「Transform」オペレータのロケータ(Hight)は「変形モード」が「ローカル」に設定されている。

続きはまた次回。

modo10-11ブログ目次



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG
Archives