Re: pythonでの無限遠光源の設定について ( No.1 ) |
- 日時: 2005/12/11 16:40
- 名前: 宮田
- 無限遠光源をカメラに追従したいということでしょうか?
カメラを動かさず、形状を動かせば目的の結果になりますよね。
パイソンでの書式は判りませんけど、考え方としては、
カメラの視点・注視点および無限遠光源の座標を取得。 視点・注視点のベクトルを計算 注視点・無限遠光源のベクトルを計算 視点を動かしたときの視点・注視点のベクトルを計算し、元ベクトルから の回転角を計算。 上記の答えから注視点・無限遠光源のベクトルを補正計算。
で良いように思いますけど‥
ただ、この方法だと注視点のほうを動かした場合(視点との平行移動以外) ベクトルが変わるのでうまく計算されないと思います。 また、ズームを使った場合もうまくかないかもしれません。
|
Re: pythonでの無限遠光源の設定について ( No.2 ) |
- 日時: 2005/12/13 07:38
- 名前: 加藤俊明
- こんばんわ、
以下、apple script で書いてみました。 python でも基本的な構文は同じなので、何をやっているかは解って頂けるのではないかと思います。
script は二種類あります。
script - 1 で現在の視線方向と無限遠光源方向との関係を線形状で記憶します。
カメラの方向を変える度に script - 2 を実行します。
そうすると、無限遠光源の方向がお望みの状態に保たれるようになります。
エラーメッセージは最低限のものしか書いてませんので、そのあたりは適宜判断して下さい。 また script - 1 によって、視線方向と無限遠光源方向 との関係を記憶するための線形状がルートパート直下に "distant light direction" と言う名前で作成されます。
もし、必要ならこの名前は変更して下さい。
このような線形状が勝手に作られてしまうのがイヤなら、同様の情報をファイル出力するという方法もありますね。
----- script - 1 --------
tell application "Shade 8 professional" inhibit update -- 無限遠光源の方向ベクトルを取得 set v to distant light direction -- 注視点座標を取得 set p1 to target -- 視点座標を取得 set p2 to eye -- 視線方向の単位ベクトルを求める set eV to {(item 1 of p2) - (item 1 of p1), (item 2 of p2) - (item 2 of p1), (item 3 of p2) - (item 3 of p1)} set L to sqrt ((item 1 of eV) ^ 2 + (item 2 of eV) ^ 2 + (item 3 of eV) ^ 2) set eV to {(item 1 of eV) / L, (item 2 of eV) / L, (item 3 of eV) / L} -- v, eV 座標をルートパート直下に線形状として出力する -- 現在の選択状態を保存 set hList to handle list -- 既に "distant light direction" という名前の線形状オブジェクトがあればそれを削除する if select by name "distant light direction" then if object type = line object then set deletedH to handle -- 削除される線形状のハンドルを記憶しておく cut else set handle list to hList beep allow update return -- "distant light direction" という名前の線形状以外のオブジェクトがあれば警告音を出して終了 end if end if -- 形状編集モード状態を記憶 set modifyMode to modify mode set modify mode to false -- ルートパートに移動 repeat while (select parent 1000) end repeat -- 線形状として出力(名称を "distant light direction" としておく) start polygon without closed append point at eV append point at {0, 0, 0} append point at v finish polygon set object name to "distant light direction" -- 選択状態を元に戻す -- hList の中に削除された線形状 "distant light direction" が含まれているなら、 -- それをリストの中から除外した新たなリスト handleList を作成する set handleList to {} -- handleList の初期化 repeat with h in hList if h ≠ deletedH then -- hList の中の h が deletedH と等しくなければ、handleList に追加する set handleList to handleList & h end if end repeat set handle list to handleList -- 選択状態を元に戻す -- 形状編集モードを元に戻す set modify mode to modifyMode allow update end tell
----- script - 2 --------
tell application "Shade 8 professional" inhibit update -- 現在の選択状態を保存 set hList to handle list -- "distantlight direction" という名前のオブジェクトを選択する select by name "distant light direction" -- もし見つからなかったなら、警告音を出して終了 if not result then beep allow update return end if -- 形状編集モード状態を記憶 set modifyMode to modify mode set modify mode to false -- 保存してあった視線方向単位ベクトルを読み込む set prev_eV to anchor point 0 -- 注視点座標を取得 set p1 to target -- 視点座標を取得 set p2 to eye -- 視線方向の単位ベクトルを求める set eV to {(item 1 of p2) - (item 1 of p1), (item 2 of p2) - (item 2 of p1), (item 3 of p2) - (item 3 of p1)} set L to sqrt ((item 1 of eV) ^ 2 + (item 2 of eV) ^ 2 + (item 3 of eV) ^ 2) set eV to {(item 1 of eV) / L, (item 2 of eV) / L, (item 3 of eV) / L} -- prev_eV が eV に重なるようにオイラー回転する-------------------------------- -- eV の経度 longitude1 を求める set L to sqrt ((item 1 of eV) ^ 2 + (item 3 of eV) ^ 2) if L > 1.0E-6 then -- eV は単位ベクトル故、長さの絶対値で判定可 set longitude1 to acos ((item 3 of eV) / L) if (item 1 of eV) < 0 then set longitude1 to -longitude1 end if else set longitude1 to 0 end if -- eV の緯度 latitude1 を求める set latitude1 to asin (item 2 of eV) -- prev_eV の経度 longitude2 を求める set L to sqrt ((item 1 of prev_eV) ^ 2 + (item 3 of prev_eV) ^ 2) if L > 1.0E-6 then -- prev_eV は単位ベクトル故、長さの絶対値で判定可 set longitude2 to acos ((item 3 of prev_eV) / L) if (item 1 of prev_eV) < 0 then set longitude2 to -longitude2 end if else set longitude2 to 0 end if -- prev_eV の緯度 latitude2 を求める set latitude2 to asin (item 2 of prev_eV) -- 現在選択状態にあるのは "distantlight direction"。 これを回転する move object around {0, 0, 0} rotate {0, -longitude2 * 180 / pi, 0} move object around {0, 0, 0} rotate {-(latitude1 - latitude2) * 180 / pi, 0, 0} move object around {0, 0, 0} rotate {0, longitude1 * 180 / pi, 0} --------------------------------------------------------------------- -- 回転された "distantlight direction" の 無限遠光源ベクトル座標 v を読み取る set v to (anchor point 2) -- 無限遠光源をセット set distant light direction to v -- 選択状態を元に戻す set handle list to hList -- 形状編集モードを元に戻す set modify mode to modifyMode allow update end tell
----- おしまい -----
|
Re: pythonでの無限遠光源の設定について ( No.3 ) |
- 日時: 2005/12/12 02:07
- 名前: 管理人
- 結構難しそうな話だなと思っていたら、強力な助っ人が
やっぱりオイラー回転が必要なんですね。
操作性を考えると、視線を変更すると自動的に無限遠光源も更新されるというのが 望ましいのでしょうが、スクリプトでは難しいのでしょうね。 ShadeR5まではスクリプト実行中の画面層が可能だったので、 ループを使った疑似常駐風スクリプトというのも使えたのですが。
|
Re: pythonでの無限遠光源の設定について ( No.4 ) |
- 日時: 2005/12/12 09:30
- 名前: A2
- ご返事ありがとうございます。大変参考になりました。
そもそも特殊な用途なので返信はないだろうと思っておりました。
加藤さんのスクリプトをpythonで作ろうと思います(出来るかどうかわからんが・・・)。
以下私事ですが、この無限遠光源方向の設定というのはPhotoshopにおける輪郭線抽出の為に必要で、 その他の設定は自作のレンダリングスクリプト(VB)で自動化していたのですが光源の方向と 全オブジェの表面材質全削除だけは(これは今でもできない)手動でおこなっています。
shade8はダウンロード販売がアップデートより安かったので購入しました。 目当ては当然トーンシェーダです。これで半自動化しているとはいえ、同じ絵に計4回のレンダリングや その他特殊な色の設定など面倒なことから解放されると喜び勇んだのですが、 これが少なくとも自分の環境では全く使い物にならない。
体験版でブーリアンなどの制約は知っていたのですが、これほどのろく、使い物にならないとは・・・ まあその他よくなっている点は多々あるし、輪郭線抽出は今まで通りやればいいかと思ったら 今度はVBスクリプトの動きが変。スクリプトウインドやマニュアルからもなくなっている。
何しろプログラミングど素人なのでVBからpythonに書き換えるのは並の苦労ではございません。
以上私事というよりグチでした。
|
Re: pythonでの無限遠光源の設定について ( No.5 ) |
- 日時: 2005/12/12 11:13
- 名前: 加藤俊明
- >全オブジェの表面材質全削除だけは(これは今でもできない)手動でおこなっています。
え〜、これはですねえ、再帰関数( 自分で自分自身を呼び出す関数 )を使って簡単にできます。
またまた Apple Script で恐縮ですが、サンプルスクリプトを二つ書いておきますね。
最初のは、ファイル内の全オブジェクトの表面材質設定を削除するもの。 二番目は、選択オブジェクトとその全ての子オブジェクトの表面材質設定を削除するものです。
最初の部分が異なるだけで、再帰関数の中身は両者とも全く同じです。
どなたか Python での 関数の書き方をご存じの方がいたならアドバイスお願い致します。
-- ファイル内の全オブジェクトの表面材質設定削除 ------------------------------
tell application "Shade 8 professional" inhibit update -- 現在の選択状態を保存 set hList to handle list -- ルートパートを選択 repeat while (select parent 1000) end repeat my DeleteSurfaceAttributes() -- 再帰関数を呼ぶ -- 選択状態を元に戻す set handle list to hList allow update end tell
-- ここから再帰関数 on DeleteSurfaceAttributes() tell application "Shade 8 professional" set has surface attributes to false -- 表面材質設定削除 if select child then -- 子オブジェクトが選択できるなら my DeleteSurfaceAttributes() -- 再帰関数を呼ぶ select parent -- 親オブジェクトを選択 end if repeat while select brother -- 全ての弟オブジェクトについて my DeleteSurfaceAttributes() -- 再帰関数を呼ぶ end repeat end tell end DeleteSurfaceAttributes
-- おしまい --------------------------------------------------------------
-- 選択オブジェクトとその全ての子オブジェクトの表面材質設定削除 ------------------
tell application "Shade 8 professional" inhibit update -- 現在の選択状態を保存 set hList to handle list -- 選択されている各オブジェクトについて repeat with h in hList set handle to h -- 選択オブジェクトを一つずつ選択 set has surface attributes to false -- 表面材質設定削除 if select child then -- 子オブジェクトが選択できるなら my DeleteSurfaceAttributes() -- 再帰関数を呼ぶ end if end repeat -- 選択状態を元に戻す set handle list to hList allow update end tell
-- ここから再帰関数 on DeleteSurfaceAttributes() tell application "Shade 8 professional" set has surface attributes to false -- 表面材質設定削除 if select child then -- 子オブジェクトが選択できるなら my DeleteSurfaceAttributes() -- 再帰関数を呼ぶ select parent -- 親オブジェクトを選択 end if repeat while select brother -- 全ての弟オブジェクトについて my DeleteSurfaceAttributes() -- 再帰関数を呼ぶ end repeat end tell end DeleteSurfaceAttributes
-- おしまい --------------------------------------------------------------
|
Re: pythonでの無限遠光源の設定について ( No.6 ) |
- 日時: 2005/12/12 17:32
- 名前: 宮田
- すごいなぁ。加藤さんにはいつも本当に感服させられます。
美術系に理数の知識は必要ないと言う人もいらっしゃるんですが、 美術には整然と創られた美しさ(幾何文様とか加藤さんのModelingPackIIもそうですよね) とそれを崩した美しさ(アニメやデフォルメなど)があると思います。 3Dでは2Dに比べてこの差が大きいので、双方を取り扱える・歩み寄らせる技術・知識を 持っている方は強力なクリェータですね。
|
Re: pythonでの無限遠光源の設定について ( No.7 ) |
- 日時: 2005/12/13 07:41
- 名前: 加藤俊明
- おっとっと、Re No.2 の所で紹介した script - 1 の所で、エラーチェックが不十分で場合によっては Shade がクラッシュしてしまう場合があったので、既に書き込みは直接訂正しておきました。
訂正前
-- 既に "distant light direction" という名前の線形状オブジェクトがあればそれを削除する if select by name "distant light direction" then if object type = line object then cut
-- 中略
-- 選択状態を元に戻す set handle list to hList
訂正後
-- 既に "distant light direction" という名前の線形状オブジェクトがあればそれを削除する if select by name "distant light direction" then if object type = line object then set deletedH to handle -- 削除される線形状のハンドルを記憶しておく cut
-- 中略
-- 選択状態を元に戻す -- hList の中に削除された線形状 "distant light direction" が含まれているなら、 -- それをリストの中から除外した新たなリスト handleList を作成する set handleList to {} -- handleList の初期化 repeat with h in hList if h ≠ deletedH then -- hList の中の h が deletedH と等しくなければ、handleList に追加する set handleList to handleList & h end if end repeat set handle list to handleList -- 選択状態を元に戻す
>双方を取り扱える・歩み寄らせる技術・知識を持っている
いやあ、結局のところ単なる算数フェチだけなのかも、 Illustrator で絵を描くのは得意ですが、自由曲面を手でチマチマと編集するのは未だに苦手で、はっきり言って下手くそでありますです。
|