- h1: 簡易な3Dプロット - p: - お仕事でROSのRVizを使い、点群地図を表示させる事があります。 - p: - RVizのマウス操作に慣れてくると、 - 表示アングル調整が素早く出来るようになり - 「うまく出来てるなぁ〜」と感心させられます。 - p: - まぁそれも、お仕事で使わせてもらえる「パワフルなマシン」の恩恵も多々あるのかと。 - p: - CPUはIntel Core i7。 - GPUはNVIDIA GeForce GTX 1070。 - p: - 非力なマシンでは、ROSを入れてRVizを動かす事自体の敷居が高いです。 - p: - とは言え、膨大なデータ量の点群地図を扱わなければ、、、 - 簡単なデータならば、非力なマシンでもこの操作感を再現できるのでは? - p: - という事で、 - RVizの右側のTypeがXYOrbit(rviz)の時のマウスドラッグの動作を、 - wxPythonを使って試してみました。 - p: - グラフィックの表示は、負荷の軽いワイヤーフレームで。 - p: - a href="http://kondoh2.html.xdomain.jp/rt/index.html": レイトレーシング 2018春 - の - a href="http://kondoh2.html.xdomain.jp/rt/v1.html#wf": まずはワイヤーフレームから - で使ってた部品 - (ut, mt, v, line, vecs, ax, fcx, lstx) - を流用してみました。 - p: - これらの部品を使ってワイヤーフレーム用のエンジンwfrm.pyを作り、 - wxPythonのアプリ本体p3d.pyから呼び出してます。 - p: - hr: / - ul: - li /: - a href="#wx": wxPythonインストール - li /: - a href="#v1": バージョン1 - ul: - li /: a href="#v1_boot": 起動 - li /: a href="#v1_op": 操作 - li /: a href="#v1_data": データ - li /: - a href="#v2": バージョン2 - ul: - li /: a href="#v2_view_top": 上からのビューを追加 - li /: a href="#v2_stdin": 標準入力からロード - li /: - a href="#v3": バージョン3 - ul: - li /: a href="#v3_chgs": バージョン3の変更内容 - li /: a href="#v3_srv": サーバの指定 - li /: a href="#v3_import": pythonのモジュールのインポート - li /: - a href="#v4": バージョン4 - p: - hr: / - p: - a href="index.yaml": index.yaml (JIS) - '/' - a href="body.yaml": body.yaml (JIS) - p: - hr: / - a name="wx": - h2: wxPythonインストール - p: - 以前に - a href="http://kondoh.html.xdomain.jp/py3.html": python3対応のメモ - でも、 - a href="http://kondoh2.html.xdomain.jp/rt/index.html": レイトレーシング 2018春 - の - a href="http://kondoh2.html.xdomain.jp/rt/v15.html#i_did_it": えらいこっちゃ - で、自宅のpython環境のデフォルトがpython2からpython3に上がってしまった事を書いてましたが、、、 - p: - wxPythonはpython2に入れたままで、python3には入れてませんでした。 - p: - さて'wxPython mac install'などとググってみると、、、 - なにやら、python3でなかなかうまくいかない気配? - p: - wxPythonのサイトのDwonloadを見てみると、macやwindowsは'pip install -U wxPython'とだけ書いてる感じです。 - p: - ならばとpip3で試してみると、とりあえず入ってくれました(^_^v - pre: | $ pip3 install -U wxPython : $ python Python 3.6.5 (default, Mar 30 2018, 06:41:49) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import wx >>> wx.VERSION (4, 0, 3, '') >>> - p: - hr: / - a name="v1": - h2: バージョン1 - p: - a href="p3d_v1.tgz": p3d_v1.tgz - pre: | $ tar xzf p3d_v1.tgz $ cd p3d - a name="v1_boot": - h3: 起動 - pre: | $ ./p3d.py -fn xxx.yaml ( -fn xxx.yaml を省略すると cube.yaml ) - a name="v1_op": - h3: 操作 - h4: 左ボタンによるドラッグ - p: - 視点が目標点の回りを回転します。 - p: - 視点からの目線の表示なので、表示されてる対象が回転してるように見えます。 - h4: 右ボタンによるドラッグ - p: - マウスを動かすと、視点が目標点に向かって接近したり遠ざかったりします。 - p: - ズーム的な表示の変化になります。 - h4: 中ボタンによるドラッグ - p: - (今時はマウスのホイール押下か左右同時押しかな?) - p: - ドラッグの移動量に応じて、目標点が移動します。 - p: - 目標点の移動は、視点を中心とした回転移動にしてみました。 - (RVizの動きとはちょっと違うかも...) - h4: その他 - p: - RVizではGUIのZeroボタンによるアングルのリセットがありますが、 - 左ボタンによるダブルクリックで、そのようにしてみました。 - a name="v1_data": - h3: データ - p: - ワイヤーフレームのデータは、yamlファイルに書いてロードします。 - p: - p3d.py の起動時に -fn xxx.yaml で指定します。 - 省略するとデフォルトはとりあえず cube.yaml - p: - yamlファイルのデータ形式は、ベタな感じで次の通り。 - pre: | $ cat cube.yaml ps: - [-1,-1,-1] - [ 1,-1,-1] - [ 1, 1,-1] - [-1, 1,-1] - [-1,-1, 1] - [ 1,-1, 1] - [ 1, 1, 1] - [-1, 1, 1] idxs: - [0,1,2,3,0,4,5,6,7,4,1,5,0] - [2,6] - [3,7] eye_p: [0,-20,0] eye_t: [0,0,0] - ul: - li \: 全体は辞書の形式で、 - li \: キー ps は3次元座標の点のリスト - li \: キー idxs は「折れ線」のリスト - li \: 「折れ線」はpsのインデックスを並べたリスト - li \: キー eye_p は視点の座標 - li \: キー eye_t は視点から眺める目標点の座標 - img src="v1.gif": / - p: - hr: / - a name="v2": - h2: バージョン2 - a name="v2_view_top": - h3: 上からのビューを追加 - p: - RVizのでもそうなのですが、 - ビューのタイプがXYOrbitのときの中ボタンドラッグでの調整が難しいです。 - p: - 上から見降ろしたビューのタイプ、TopDownOrthoを追加してみました。 - p: - ビュー切替えは、右ボタンのダブルクリックで行ないます。 - p: - RVizのようにポップアップメニューにしても良かったのですが、、、 - リセットを左ボタンのダブルクリックにしてたので、その習わしで。 - p: - a href="v2.patch": v2.patch - pre: | $ cat v2.patch | patch -p1 - p: - ビューをTopDownOrthoに切替えたり、XYOrbitに戻したりするとき、 - 内部で保持してる視点の位置は変化させてません。 - p: - 描画時の座標に変換の直前で、 - 視点座標系とグローバル座標系の変換行列に細工して、 - 真上からの視点になるように変更してます。 - p: - なので、中ボタンドラッグ以外の、左ボタンドラッグと右ボタンドラッグでは、 - ビューのタイプに関わらず同じ処理です。 - p: - TopDownOrthoで中ボタンドラッグすると、 - 視点と目標点ともにXY平面に沿って平行移動します。 - p: - 本当に上からのアングルになっているのか確認するため、 - cube.yamlの立方体の上面に斜線を1つ追加しました。 - p: - 上からのビューで中ボタンドラッグで移動させてみると、 - 視点の近く側にある面の方が少しだけ大きく表示されるので、 - 斜線のある面が上にきてる事が判ります。;-p) - img src="v2.gif": / - a name="v2_stdin": - h3: 標準入力からロード - p: - YAMLファイル名の指定 -fn xxx.yaml で、 - ファイル名'-'を指定すると標準入力からロードするようにしてみました。 - p: - 合わせて「いわゆる伝統的な図」のYAMLデータを出力するsinc.pyを追加しました。 - pre: | $ chmod +x sinc.py $ ./sinc.py | ./p3d.py -fn - - p: - などと実行すると、生成したデータをファイルに落すことなく表示を試せます。 - img src="v2_2.gif": / - p: - hr: / - a name="v3": - h2: バージョン3 - p: - sinc.pyの図を表示すると、処理が重く反応が鈍いです。 - p: - a href="http://kondoh2.html.xdomain.jp/rt/index.html": レイトレーシング 2018春 - の方式そのままに、C言語で実装したサーバにしてみました。 - p: - a href="v3.tgz": v3.tgz - pre: | $ rm -rf p3d $ tar xzf v3.tgz $ cd p3d $ make - a name="v3_chgs": - h3: バージョン3の変更内容 - ul: - li /: まず主要な処理を別プロセスのサーバで実行するように切り出し - li /: pythonで書いたサーバでお試し - li /: サーバ側をC言語で実装して置き換え - p: - これまでのバージョンの構成は一旦捨てて、v3.tgz でまとめなおしてます。 - 流用するソースはmakeでサイトから引っ張ってきます。 - ul: - li /: - a href="http://kondoh2.html.xdomain.jp/rt/index.html": レイトレーシング 2018春 - から rt/ - li /: - a href="http://kondoh.html.xdomain.jp/ezyaml/index.html": 簡易なYAMLパーサ 2018夏 - から ezyaml/ - li /: - a href="http://kondoh.html.xdomain.jp/argmnt/index.html": テキスト配置ツール - から argmnt/ - p: - (argmnt/ は 中の opt.py しか使ってません ;-p) - table: - tr: - th: Makefile - td: メイクファイル - tr: - th: p3d.py - td: 本体 - tr: - th: wfrm.py - td: ワイヤーフレーム処理とpython版のサーバ - tr: - th: wfrm.c - td: ワイヤーフレーム処理とC言語版のサーバ - tr: - th: dl_rt.sh - td: - a href="http://kondoh2.html.xdomain.jp/rt/index.html": レイトレーシング 2018春 - からダウンロードして rt/ を生成するスクリプト - tr: - th: dl_ezyaml.sh - td: - a href="http://kondoh.html.xdomain.jp/ezyaml/index.html": 簡易なYAMLパーサ 2018夏 - からダウンロードして ezyaml/ を生成するスクリプト - tr: - th: dl_argmnt.sh - td: - a href="http://kondoh.html.xdomain.jp/argmnt/index.html": テキスト配置ツール - からダウンロードして argmnt/ を生成するスクリプト - tr: - th: import.sh - td: 自前のpythonパッケージ内の暗黙の相対パスimportを明示的な相対パスimportに書き換えるスクリプト - tr: - th: librt.patch - td: ダウンロードした rt/ に変更を加えるためのパッチ - tr: - th: cube.yaml - td: 立方体のサンプルデータ - tr: - th: sinc.py - td: 伝統の図のデータを生成するプログラム - p: - a href="http://kondoh2.html.xdomain.jp/rt/index.html": レイトレーシング 2018春 - からの rt/ には librt.patch をあてて修正するようになってます。 - p: - rt/Makeile がライブラリを作るようになってなかったのと、 - rt/vecs.c に地雷のようにバグが残ってたので修正。 - p: - (春の間、よくこの地雷を踏まずにCGをレンダリングしてたものだ...) - img src="v3.gif": / - a name="v3_srv": - h3: サーバの指定 - h4: サーバを使わない場合 - pre: | $ ./p3d.py -fn cube.yaml $ ./sinc.py | ./p3d.py -fn - - h4: pythonのサーバを起動して使う場合 - p: - "-srv オプションを付けます" - pre: | $ ./p3d.py -fn cube.yaml -srv -ka $ ./sinc.py | ./p3d.py -fn - -srv -ka - h4: C言語で実装したサーバを起動して使う場合 - p: - "-srv c オプションを付けます" - pre: | $ cat cube.yaml | ezyaml/blk.py | ./p3d.py -fn - -srv c -ka $ ./sinc.py | ./p3d.py -fn - -srv c -ka - p: - C言語のサーバからYAMLデータのロードでは、 - a href="http://kondoh.html.xdomain.jp/ezyaml/index.html": 簡易なYAMLパーサ 2018夏 - のライブラリを使っているので、YAMLのブロックスタイルしかロードできません。 - p: - YAMLデータを ezyaml/blk.py を使ってブロックスタイルに変換してからロードします。 - p: - "-ka オプションを追加すると、クローズボックスをクリックして終了するときに、" - rt/val.py の値サーバも含めて、起動した全てのサーバを終了させます。 - p: - "-ka オプションを指定しない場合は、終了時にwfrmサーバだけ終了させます。" - img src="v3_2.gif": / - p: - 手持ちのMacの環境では、 - sinc.pyの図の表示がキビキビと動いてくれるようになりました。v^_^) - a name="v3_import": - h3: pythonのモジュールのインポート - p: - これまでpython2で普通に自前のモジュールをインポートしてました。 - いわゆる「暗黙の相対パスのインポート」です。 - pre: | $ ls foo.py bar.py $ cat foo.py import bar : - p: - カレントディレクトリで実行する分にはええのですが、 - 例えば今回のように、過去のソース流用するためにパッケージディレクトリを作って置いた場合... - pre: | $ find . -type f ./pkg1/foo.py ./pkg1/bar.py ./pkg1/__init__.py ./hoge.py $ cat hoge.py from pkg1 import foo : $ cat pkg1/foo.py import bar : $ python2 hoge.py : $ - p: - python2ではこれでOK。 - p: - これがpython3では - pre: | $ python3 hoge.py Traceback (most recent call last): File "hoge.py", line 1, in from pkg1 import foo File "pkg1/foo.py", line 1, in import bar - p: - python3では、明示的に相対パスのimportにせねばならんとな。 - pre: | $ cat pkg1/foo.py from . import bar : $ python3 hoge.py : $ $ python2 hoge.py : $ - p: - などと pkg1/foo.py を書き換えると、python3でもOK。 - p: - import.sh を作って rt/ の下の自前モジュールの import を書き換えるようにしてみました。 - p: - しかしながら、この明示的な相対パスのimportを使ってしまうと、 - pkg1/foo.py が "__main__" をもってて実行したい場合... - pre: | $ cat pk1/foo.py from . import bar : if __name__ == "__main__": print('foo') # EOF $ python2 pkg1/foo.py Traceback (most recent call last): File "pkg1/foo.py", line 1, in from . import bar ValueError: Attempted relative import in non-package $ python3 pkg1/foo.py Traceback (most recent call last): File "pkg1/foo.py", line 1, in from . import bar SystemError: Parent module '' not loaded, cannot perform relative import - p: - python2 でも python3 でもエラー。 - p: - pythonコマンドの -m オプションでモジュールを指定して実行すればOK。 - pre: | $ python2 -m pkg1.foo foo $ python3 -m pkg1.foo foo - p: - rt/srvs.py から val.py サーバを起動して、他のサーバの起動コマンドを登録したりしとります。 - p: - wfrm.py の 関数 new()から srvs.py の infs[] を変更、追加して対応してみました。 - p: - (pythonは何でもpublicなので可能ですね ;-p) - h3: TODO - ul: - li /: - C言語で実装したサーバのとき上からのViewで中ボタンdragの動きが怪しい? - li /: - make cleanしてmakeしなおすとimport.shが何度もあたるのでダメ - li /: - 座標変換行列の合成最適化がrt/lstx.pyにあるがrt/lstx.cに実装してなかった - li /: - 背景色は黒の方がしっくりこないか? - li /: - 線の色を変えて表示したい - p: - hr: / - a name="v4": - h2: バージョン4 - p: - a href="v4.patch": v4.patch - pre: | $ make clean $ cat v4.patch | patch -p1 $ make - p: - TODOの項目対策、対応してみました。 - h4: C言語で実装したサーバのとき上からのViewで中ボタンdragの動きが怪しい? - p: - 単純なバグでした。 - Viewによる中ボタンdragの動作が、pythonのときとは逆になってました。 - h4: make cleanしてmakeしなおすとimport.shが何度もあたるのでダメ - p: - import.shの中で org/ ディレクトリの有無で実施済が判定するようにしてみました。 - h4: 座標変換行列の合成最適化がrt/lstx.pyにあるがrt/lstx.cに実装してなかった - p: - rt/lst.[ch] への lstx_opt() 追加を、librt.patch に含めてみました。 - さほど速度の効果がないかも知れませんが、 - wfrm.c の get_lst() から lstx_opt() を呼び出すようにしてみました。 - h4: 背景色は黒の方がしっくりこないか? - p: - 背景色のデフォルトを黒くしました。 - p3d.py の起動オプション -bg xxx で変更可能です。 - pre: | $ ./p3d.py -bg wx.WHITE $ ./p3d.py -bg '(0,128,128)' - p: - などと指定できます。 - (括弧の中の数値は r, g, b 順です) - h4: 線の色を変えて表示したい - p: - cube.yaml のキー'idxs'の箇所に指定を追加してみました。 - pre: | $ cat cube.yaml ps: - [-1,-1,-1] - [ 1,-1,-1] - [ 1, 1,-1] - [-1, 1,-1] - [-1,-1, 1] - [ 1,-1, 1] - [ 1, 1, 1] - [-1, 1, 1] idxs: - [0,1,2,3,0,4,5,6,7,4,1,5,0] - col: [200,0,0] - [2,6] - [3,7] - col: [50,200,0] - [4,6] eye_p: [0,-20,0] eye_t: [0,0,0] - p: - idxs のリストの要素として、 - キー'col'で、値が [r, g, b] の順のリストを指定します。 - (残念ながら 'wx.BLACK' などの文字列は指定できません) - p: - 以降、その指定色で線が描画されます。 - p: - 初めのデフォルト色は白です。 - p: - 初めのデフォルト色は p3d.py の起動オプション -fg xxx で変更可能です。 - pre: | $ ./p3d.py -fg wx.RED $ ./p3d.py -fg '(0,128,128)' - p: - などと指定できます。 - (括弧の中の数値は r, g, b 順です) - p: - sinc.pyも無意味に色つきデータを出力するよう変更してみました。;-p) - p: - img src="v4.gif": / - p: - img src="v4_2.gif": / - h3: TODO - ul: - li /: s: C言語で実装したサーバのとき上からのViewで中ボタンdragの動きが怪しい? - li /: s: make cleanしてmakeしなおすとimport.shが何度もあたるのでダメ - li /: s: 座標変換行列の合成最適化がrt/lstx.pyにあるがrt/lstx.cに実装してなかった - li /: s: 背景色は黒の方がしっくりこないか? - li /: s: 線の色を変えて表示したい - p: - hr: / # EOF