トップ | puarts.com
ロゴ
「Python」に関連する記事一覧
0  

毎回自作プログラムに.objのジオメトリアニメーションをロードするために、Mayaから1フレームずつモデルをエクスポートするのが面倒だったので、.obj形式の連番ファイルをエクスポートする Python スクリプトを書きました。

誰かの役に立つかもしれないので貼っておきます。

選択中のモデルを現在のタイムスライダーの区間内すべての整数フレームでobjエクスポートします。 オプションは全部オフにしてあるので、必要であれば、export_optionsの文字列を編集して下さい。


import maya.cmds as mc;
import maya.mel as mel;

def ExportSelectionAsObjFileForAllFrames(export_dir, file_name_without_ext):
	min_time = mc.playbackOptions(minTime=True, q=True);
	max_time = mc.playbackOptions(maxTime=True, q=True);
	export_options = "groups=0;ptgroups=0;materials=0;smoothing=0;normals=0";
	for frame in range(min_time, max_time + 1):
		mc.currentTime(frame);
		file_path = "%s/%s-%04d.obj"%(export_dir, file_name_without_ext, frame);
		mc.file(file_path, force=True, options=export_options, typ="OBJexport", pr=True, es=True);

export_dir = "D:/Oputputs";
file_name = "object";
ExportSelectionAsObjFileForAllFrames(export_dir, file_name);
FFmpegから動画のフレームレートやら時間, 解像度などの情報を取得するにはどうしたらいいかなんですが, 調べても入力動画だけを指定して実行したときのエラー出力にある情報を切り出してくるような方法しか見つかりませんでした。

仕方なくその方法で取得しようと思ったんですがFFmpegの吐き出している動画情報はエラー出力の方に吐き出されているようでPythonでエラー出力どうやるのか知らなかったのでメモしておきます。

popen2をimportして, 下記のようにpopen2.popen3を使うと標準エラー出力の文字列を取得できるようです。

stdout, stdin, stderr = popen2.popen3('ffmpeg -i video.avi')

stderrにエラー出力がfileオブジェクトとして格納されます。

FFmpegの動画情報を取得して表示する例は次のようになります。


import popen2



stdout, stdin, stderr = popen2.popen3('ffmpeg -i video.avi');

for line in stderr:

    print(line);


あとはここから必要な文字列を頑張って切り出せば情報が取得できます。

なんかもっと簡単な方法ないのでしょうか。
PythonでDOM(Document Object Model)を使ってXMLファイルからデータを読み込む例です。この例ではJava, C++, Pythonのそれぞれのprint関数をリストアップします。

This is example code for reading XML by DOM(Document Object Model) in Python. In this example, it list up print function in Java, C++ and Python for each rule.
 
Reading XML in Python is very easy!
 
 
sample.xml

<?xml version="1.0" encoding="UTF-8"?>


<CommandList>
  <cmd type="Java">System.out.print("test")</cmd>
  <cmd type="C++">printf("test")</cmd>
  <cmd type="Python">print("test")</cmd>
</CommandList>


source code.

from xml.dom.minidom import parse



def printCommandList(xmlPath):
  dom = parse(xmlPath);
  root = dom.documentElement
  print(root.nodeName);
   
  cmdNodeList = root.childNodes;
  for cmdNode in cmdNodeList:
    if cmdNode.nodeName == "cmd":
      typeName = cmdNode.getAttributeNode("type");
      command = "";
      cmdText = cmdNode.childNodes[0];
      if cmdText.nodeType == cmdText.TEXT_NODE:
        command = cmdText.data;
      print(str(typeName.nodeValue)+":"+str(command));
       
  dom.unlink();
printCommandList("./sample.xml");


output
CommandList
Java: System.out.print("test")
C++: printf("test")
Python: print("test")
 

Reference
DOM(Python版)入門

Pythonではappend([])でリストに新しいリストの追加を行えば、リストの次元数を簡単に増やせるんですね。

こんなに簡単に次元数を動的に変えられるのはPythonの大きなメリットですね。

  example


objs=["obj0", "obj1", "obj2"];
list=[];
cnt=0;
for s1 in objs:
        list.append([]);
        list[cnt].append(s1);
        list[cnt].append(s1);
        cnt=cnt+1;

print(list);
# [['obj0','obj0'],['obj1','obj1'],['obj2','obj2']]
まだあまりPythonの扱いに慣れていませんが、とりあえずオブジェクト指向だ!ということで、pythonのclassに手をつけ始めました。Maya上で気軽にオブジェクト指向言語が使えるなんて、考えてみれば相当便利です。

とりあえず、極シンプルなクラスを書くとこんな感じになります。

class MyClass:
    i = 0;
    def increment(self):
        self.i=self.i+1;
 

使用例
c=MyClass();
print(c.i);
c.increment();
print(c.i);
 

他の言語と違ってインスタンス変数へのアクセスはメソッドにselfを引数にして与えて、そのメンバとしてアクセスする点は、インスタンス変数とメソッド内のローカル変数をはっきり区別できるという利点はありますが、変数名が長くなるので少し面倒です。

関係ないですが、しばらくPythonを使っていて変数の型を考えなくていいのがとても便利に感じてきました。初めてPythonを使ったときは変数の扱いが自由すぎて、なんて危ない言語なんだと思いましたが、使っていても型宣言がないせいでミスを犯すようなことは特になかったので、抵抗を感じなくなってきたんだと思います。

むしろ今は型宣言があるMELを使うのが面倒に感じます。
Python v2.7.1 documentation
http://docs.python.org/library/stdtypes.html


上記のページによるとPythonではsys.maxintで最大値、-sys.maxint-1が最小値となるようです。

sys.maxint is always set to the maximum plain integer value for the current platform, the minimum value is -sys.maxint - 1
 


example

import sys
print(-sys.maxint-1);
print(sys.maxint);

Pythonメモ モジュール名の取得

2010/11/02
(2018/11/12 最終更新)

MayaでPythonスクリプトを使ってGUIを作り、モジュールとしてインポートした場合、ボタンクリック時などでの実行関数は読み込んだモジュールの関数を実行しなければならないので、MayaのGUI側に引数として渡す関数にはモジュール名が必要になります。

以下のコードでモジュール名を取得できます。


import inspect

def getModuleName():
    frame=inspect.currentframe();
    code=frame.f_code;
    modname = inspect.getmodulename(code.co_filename);
    return modname;

moduleName = getModuleName();

何かもっと賢い方法がありそうな気がしますが、とりあえず、私はこの方法で何とかなっています。もっと良い方法を知っておられる方がいましたら、是非ともご教授下さい。

CG開発でPythonを使う機会が増えてきました。
zipというペアのデータをループするのに便利な関数があったのでメモしておきます。

zipを使うと長さが同じリスト同士をくっつけてひとつのタプルにできます。
ただし、タプルにすると値を代入できなくなるので注意が必要です。


list1=['a1', 'b1', 'c1'];

list2=['a2', 'b2', 'c2'];

for a1, a2 in zip(list1, list2):

    print("element of list1 is " + a1

        + ",element of list2 is "+ a2);



もしくは



list1=['a1', 'b1', 'c1'];

list2=['a2', 'b2', 'c2'];

for a in zip(list1, list2):

    print("element of list1 is " + a[0]

         + ",element of list2 is "+ a[1]);



のようにして使います。


使用例


nameList = ['Nakamura','Suzuki','Satou'];

idList = ['003','006','012'];



for name, id in zip(nameList, idList):

    msg = u"""%sさんのID: """ % name;

    print(msg+id);



# Result:

# NakamuraさんのID: 003

# SuzukiさんのID: 006

# SatouさんのID: 012

 


Pythonスクリプトを書いていて、他の言語と比べて便利だと思った仕様があったのでメモしておきます。

for a in b:

ではbの中にある要素をaに格納しながらループを行います。このinを次のようにifで使うと別の意味になります。

if a in b:

これはbの中にaという要素があるかどうかを判定して、あればTrueを返すという意味になります。

これを利用するとリスト同士の比較などが楽に行えます。
例えば、objGrp1とobjGrp2の両方にある文字列を調べてlistに書き出したいとき、次のように簡単に書くことができます。


objGrp1=['rice', 'tomato',

         'bread', 'banana'];

objGrp2=['meat', 'rice', 

         'banana', 'apple',

         'milk', 'orange']; 



list=[];



cnt = 0;

for obj in objGrp1:

 if obj in objGrp2:

  list.append(obj);

  cnt=cnt+1;



print(list);



# Result:

# ['rice', 'banana'] 



ちなみにMELで書くと、次のようにforループが2回出てくる。


string $objGrp1[]={"rice", "tomato",

                   "bread", "banana"};

string $objGrp2[]={"meat", "rice", 

                   "banana", "apple",

                   "milk", "orange"};



string $list[];



int $cnt=0;

for($obj1 in $objGrp1){

 for($obj2 in $objGrp2){

  if(gmatch($obj2, $obj1){

   $list[$cnt]=$obj1;

   $cnt++;

  }

 }

}

print($list);



// Result:

// rice

// banana



C言語などに精通した人間にはMELの構文の方がわかりやすいですが、Pythonのように簡単に書ける方法もわかってしまえば、一人でプログラムを作る分にはとても便利です。

ただし、開発をチームで行う場合、チーム内にPythonに精通していない人がいると、こういった書き方が逆に混乱を招いてしまいます。あえてPythonのような特殊な構文を使わない方がミスがなくなる可能性があるので、そういった場合はよく考えて使うことが必要になります。

0  

0.022 sec
にほんブログ村 ゲームブログ ファイアーエムブレムへ にほんブログ村 デザインブログ コンピュータグラフィックスへ

Copyright(C)2006-2018 wsp All Rights Reserved