<?xml version="1.0" encoding="UTF-8" ?>
<feed xml:lang="ja" xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0">
  <title type="text">MOCHI-MOCHI</title>
  <subtitle type="html"></subtitle>
  <link rel="self" type="application/atom+xml" href="https://mochio326.blog.shinobi.jp/atom"/>
  <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/"/>
  <updated>2013-12-07T03:51:47+09:00</updated>
  <author><name>モチオ</name></author>
  <generator uri="//www.ninja.co.jp/blog/" version="0.9">忍者ブログ</generator>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" />
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/15</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/maya/%E6%8C%87%E5%AE%9A%E3%83%8E%E3%83%BC%E3%83%88%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%82%8B%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%AB%E3%83%BC%E3%83%96%E3%81%8B%E3%82%89%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E7%AF%84%E5%9B%B2%E5%8F%96%E5%BE%97" />
    <published>2016-10-22T14:06:26+09:00</published> 
    <updated>2016-10-22T14:06:26+09:00</updated> 
    <category term="MAYA" label="MAYA" />
    <title>指定ノートに接続されてるアニメーションカーブからフレーム範囲取得</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[リグログさんにmayaでフレーム範囲を取得するコードがあったのでそれをちょっと改造させてもらいました。<br />

<blockquote><a href="http://rigglog.sakura.ne.jp/db/2016/06/21/%E3%80%90maya%E3%80%91%E3%82%AD%E3%83%BC%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%81%AE%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88-%E3%82%A8%E3%83%B3%E3%83%89%E3%81%AE%E5%8F%96%E5%BE%97/" title="" target="_blank">【Maya】キーフレームのスタート / エンドの取得 | リグログ！<br />
</a></blockquote>
<p>ノード単体からの取得する関数です。<br />
元の関数と同じようにTranslate / Rotate /&nbsp; Scale から対象選べるようにしてみました。<br />
（もうちょいスマートな方法ある気がしますが。。。）<br />
<br />
</p>
<pre class="brush: python;">import maya.cmds as cmds

def get_time_range_from_node(node=None, t=True, r=True, s=True):
    '''
    ノードからアニメカーブの範囲を取得する
    t : Translate
    r : Rotate
    s : Scale
    '''
    anim_curves = []
    if t is True:
        anim_curves += cmds.listConnections(node, t='animCurveTL', et=True)
    if r is True:
        anim_curves += cmds.listConnections(node, t='animCurveTA', et=True)
    if s is True:
        anim_curves += cmds.listConnections(node, t='animCurveTU', et=True)
    min_time = None
    max_time = None
    for anim_curve in anim_curves:
        indices = cmds.getAttr('%s.ktv' %anim_curve, mi=True)
        for i in indices:
            t,v = cmds.getAttr('%s.ktv[%i]' %(anim_curve,i))[0]
            if min_time is None or t &lt; min_time:
                min_time = t
            elif max_time is None or max_time &lt; t:
                max_time = t
    return min_time,max_time
</pre>
<script type="text/javascript">     
SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/14</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/maya/multiprogresswin" />
    <published>2016-08-14T05:13:03+09:00</published> 
    <updated>2016-08-14T05:13:03+09:00</updated> 
    <category term="MAYA" label="MAYA" />
    <title>マルチプログレスバー</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<img src="//mochio326.blog.shinobi.jp/File/6ea4fa8c.jpeg" alt="" /> <br />
処理系統が複雑になってくると、プログレスバーを複数表示したい場面が多くなってきます。<br />
そういうときに、何も考えずに使っても追加したプログレスバーがメインウインドウにドッキングされるものが欲しかったので作りました。<br />

<pre class="brush: python;">multi_prog_win = None
class MultiProgressWin(object):
    WIDTH = 300
    def __init__(self, title="MultiProgressWin", max=100, display_text=""):
        self.showwin = False
        if multi_prog_win is None:
            global multi_prog_win
            multi_prog_win = cmds.window(t=title, w=self.WIDTH, s=False)
            cmds.showWindow(multi_prog_win)
            self.showwin = True
        self.__add_bar(display_text, max)
        cmds.refresh()

    def __add_bar(self, display_text, max):
        self.layout = cmds.columnLayout(p=multi_prog_win)
        self.text = cmds.text(display_text, p=self.layout)
        self.bar = cmds.progressBar(maxValue=max, w=self.WIDTH, p=self.layout, progress=0)

        # デフォルトの高さが39ずつ増えていたのでキリが良いように40増やしてみる
        preHeight = cmds.window(multi_prog_win, q=True, height=True)
        global multi_prog_win
        cmds.window(multi_prog_win, edit=True, h=preHeight + 40)

    def update(self, display_text=None, step=1):
        '''
        プログレスバーを動かす。
        通常は１ずつ増加
        '''
        cmds.progressBar(self.bar, e=True, step=step)
        if display_text is not None:
            cmds.text(self.text, e=True, l=display_text)
            cmds.refresh()

        progress = cmds.progressBar(self.bar, q=True, progress=True)
        max      = cmds.progressBar(self.bar, q=True, maxValue=True)

        global multi_prog_win
        preHeight = cmds.window(multi_prog_win, q=True, height=True)

        if progress == max and preHeight - 40 &gt; 0: # 0以下になったときのエラー回避
            cmds.window(multi_prog_win, edit=True, h=preHeight - 40)

    def reset(self, display_text=None):
        '''
        プログレスバーのリセット
        '''
        cmds.progressBar(self.bar, e=True, progress=0)
        if display_text is not None:
            cmds.text(self.text, e=True, l=display_text)
            cmds.refresh()

    def kill(self):
        '''
        作ったものを削除。
        Windowを生成していたらWindowが消えるが、
        追加プログレスバーの場合だったらプログレスバーだけ消える
        '''
        if self.showwin is False:
            cmds.deleteUI(self.layout, control=True)
            return
        global multi_prog_win
        cmds.deleteUI(multi_prog_win)
        del multi_prog_win
</pre>
<img src="//mochio326.blog.shinobi.jp/File/h.gif" alt="" /><br />
&uarr;動くとこんな感じです。<br />
雑なコードですが&hellip;上の様に動かすコードはこのようになります。
<pre class="brush: python;">def test(text=u"一つ追加"):
    pw = MultiProgressWin(display_text=text, max=100)
    for i in range(100):
        pw.update(text)
        time.sleep(0.02)
    pw.kill()


def test2():
    text=u"追加一つ目"
    pw = MultiProgressWin(display_text=text, max=100)
    for i in range(100):
        pw.update(text)
        time.sleep(0.02)
        if i == 50:
            test(u"二つ目追加！！")
            text=u"２つ目が終わったので再開"
    pw.kill()

pw = MultiProgressWin(display_text="ベースのプログレスバー" ,max=5)

time.sleep(1)

pw.update()
time.sleep(1)

pw.update("プログレスバー１つ追加するよ")
time.sleep(1)

test()

pw.update("ベースのプログレスバー")
time.sleep(1)


pw.update("プログレスバー2つ追加するよ")
time.sleep(1)

test2()

pw.update()
time.sleep(1)

pw.reset("リセットもできる")
time.sleep(2)

pw.kill()
</pre>
<br />
test関数が外部モジュールに存在していた場合も問題ないことは一応確認しました。<br />
global変数を使っていたり、中々に強引なのでちょっと心配ですが自分の用件は満たせそうなのでひとまずこれで良しとします。<br />
ウインドウやバーの幅、位置の調整機能はついてないので必要であれば改造くださいまし。<br />
<br />
<span style="text-decoration: line-through;">あと、追加のプログレスバーが消えた場合にウインドウが自動的に最適なサイズになってくれれば気持ちいいんですが、どうやればいいんでしょう？<br />
<br />
</span><strong><span style="color: #ff0000;">2016/08/16　<a href="https://twitter.com/redglasses67" title="" target="_blank"><span style="color: #ff0000;">赤めがね@redglasses67</span></a>さんがバーの増減に応じてウインドウが適切なサイズになるように追記してくださいました。<span style="text-decoration: line-through;"><br />
</span>&darr;修正したコードで実行したらこんな感じ。完璧です！</span></strong><br />
<img src="//mochio326.blog.shinobi.jp/File/9f10fbd5.gif" alt="" />　
<script type="text/javascript">     
SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/13</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/pyside/pyside%E3%81%AE%E5%8B%89%E5%BC%B7%E6%96%B9%E6%B3%95" />
    <published>2016-07-10T04:40:45+09:00</published> 
    <updated>2016-07-10T04:40:45+09:00</updated> 
    <category term="PySide" label="PySide" />
    <title>PySideの勉強方法</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<p>PySideでGUI作りたいけど、PySideというキーワードでググっても情報出てこない&hellip;<br />
これ、どうやって勉強すればいいの&hellip;？？<br />
<br />
と思っていたんですが、「PyQtのコード観ればいいだったわ(｀・&omega;・&acute;)」という事に今更ながら気づいたので、メモ。<br />
<br />
<br />
<a href="http://myenigma.hatenablog.com/entry/2016/01/24/113413" title="" target="_blank">PythonのPyQtによるクロスプラットフォームGUIアプリ作成入門 - MyEnigma</a><br />
<a href="http://w3log.hatenablog.com/entry/2012/03/13/162805" title="" target="_blank">PyQt QTreeWidget サンプル - T&amp;T simple<br />
</a><a href="http://hareoff.blogspot.jp/2013/03/pyqtqtreeviewwidget.html" title="" target="_blank">Datの如く: [PyQt]QTreeView内にWidgetを配置</a></p>
<p>コノあたりのサンプルコードはちょっと変更するだけでMayaでも動作させられます。</p>
<pre class="brush: python;">from PyQt4 import QtGui, QtCore,Qt
</pre>
<p>となっている部分を以下の様に書き換えます（元の内容によって変わりますが。）</p>
<pre class="brush: python;">from PySide import QtCore, QtGui
</pre>
<hr />
<p><br />
次にクラスの定義部分。</p>
<pre class="brush: python;">class Example(QtGui.QWidget):
</pre>
<p>Mayaで表示させるために以下の様にします。</p>
<pre class="brush: python;">from maya.app.general.mayaMixin import MayaQWidgetBaseMixin
class Example(MayaQWidgetBaseMixin, QtGui.QWidget):
</pre>
<hr />
<p>GUIの表示部分</p>
<pre class="brush: python;">app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
</pre>
<p>こんな感じに。</p>
<pre class="brush: python;">app = QtGui.QApplication.instance()
Example()
sys.exit()
app.exec_()
</pre>
<p>後ろ二つについては以前の記事とおなじですね。<br />
<br />
<a href="http://mochio326.blog.shinobi.jp/pyside/%E3%80%90maya%E3%80%91maya2015%E3%81%8B%E3%82%89%E3%81%AFshiboken%E4%BD%BF" title="" target="_blank">MOCHI-MOCHI 【MAYA】Maya2015からはshiboken使わなくてもいいらしい</a></p>
<p><br />
ただし、PyQtとPySideの差異もあるので考慮しなければならない部分もあるようです。<br />
<br />
<a href="http://doloopwhile.hatenablog.com/entry/20110207/1297075318" title="" target="_blank">PySideとPyQtの差異 - None is None is None</a></p>
<p>しかし、これで色々と情報を入手できそうです！</p>
<script type="text/javascript">     
SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/12</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/maya/%E6%8C%87%E5%AE%9A%E3%83%8E%E3%83%BC%E3%83%89%E4%BB%A5%E4%B8%8B%E3%81%AE%E3%83%86%E3%82%AF%E3%82%B9%E3%83%81%E3%83%A3%E3%82%92%E3%83%AA%E3%82%B5%E3%82%A4%E3%82%BA" />
    <published>2016-07-04T03:08:00+09:00</published> 
    <updated>2016-07-04T03:08:00+09:00</updated> 
    <category term="MAYA" label="MAYA" />
    <title>指定ノード以下のテクスチャをリサイズ</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[MAYAでモデルに貼られているテクスチャがでかすぎる！<br />
アニメーション作業だったらこんな高解像度のテクスチャはいらん！<br />
という、そんなアナタ！！ピッタリなの作りましたよ！！！<br />
<br />
指定ノード以下のテクスチャをリサイズして貼り直します。<br />
<br />

<pre class="brush: python;"># -*- coding: utf-8 -*-
from maya import cmds
from PIL import Image
import pymel.core as pm
import os
import stat


def get_shading_engines(root_node=None):
    '''
    指定ノード以下のshading_engineの重複しないリストを取得
    '''
    en_list = []
    if root_node is None:
        shapes = pm.ls(type="mesh")
    else:
        if isinstance(root_node, (str, unicode)): root_node = pm.PyNode(root_node)
        shapes = root_node.listRelatives(ad=True, type="mesh")
    file_nodes = []
    for i in shapes:
        shading_engines = i.shadingGroups()
        en_list+=shading_engines
    #重複をなくしてから戻す
    return list(set(en_list))

def get_all_texture_node(root_node=None):
    '''
    指定ノード以下に接続されている全テクスチャノードを取得
    '''
    file_nodes = []
    en_list = get_shading_engines(root_node)
    for en in en_list:
        file_nodes.extend(cmds.ls(cmds.listHistory(en.name()),type='file'))
    return list(set(file_nodes))

def get_truth_file_path(filepath, dir):
    '''
    パスの存在をしらべる。なければセットプロジェクトされているフォルダ以下にないか探しにいく。
    '''
    if os.path.exists(filepath):
        return filepath
    workpath =  pm.workspace( q=True, rootDirectory=True )
    if dir is not None:
        workpath = workpath + dir
    filename =  os.path.basename(filepath)

    for root, dirs, files in os.walk(workpath):
        for file in files:
            if filename == file:
                return root + r"/" +file

    return filepath

def get_use_texture_path_list(root_node=None):
    '''
    指定ノード以下に接続されているテクスチャパスのリスト
    '''
    file_nodes = get_all_texture_node(root_node)
    files = []
    for tex in file_nodes:
        path = cmds.getAttr(tex + '.fileTextureName')
        truth_path= get_truth_file_path(path, "sourceimages")
        if truth_path is None:continue;
        files.append(truth_path)
    files = list(set(files))
    return files
    
def set_texture_to_specified_dir(root_node=None, dir=""):
    '''
    指定ノード以下に接続されているテクスチャを指定のディレクトリに接続し直す
    '''
    file_nodes = get_all_texture_node(root_node)
    for tex in file_nodes:
        def_path = cmds.getAttr(tex + '.fileTextureName')
        base_name = os.path.basename(def_path)
        new_path = os.path.join(dir, base_name)
        if os.path.isfile(new_path):
            cmds.setAttr(tex + '.fileTextureName', new_path, type='string')

def resize_texture(root_node=None, dir="", magnification=1, width=None, height=None):
    '''
    指定ノード以下のテクスチャをリサイズ（別フォルダに出力）
    画像幅と高さが両方していされてればそっち優先
    
    root_node : テクスチャ書き出すルートノード
    export_dir : 書き出すフォルダ
    magnification : テクスチャの倍率
    width : 画像幅
    height: 画像高さ
    '''
    files = get_use_texture_path_list(root_node)
    if os.path.exists(dir) == False:
        os.makedirs(dir)

    # ペースト先のファイルが読み取り専用だった場合エラーになるので対処しとく
    for f in files:
        dir_path, file_name = os.path.split(f)
        save_file_path = dir+'\\'+file_name
        if os.path.exists(save_file_path):
            os.chmod(save_file_path, stat.S_IWRITE)
        im = Image.open(f)
        w = int(im.size[0]) * magnification
        h = int(im.size[1]) * magnification
        if width is not None and height is not None:
            w = width
            h = height
        im.resize((int(w),int(h))).save(save_file_path)
        
    set_texture_to_specified_dir(root_node=root_node, dir=dir)
</pre>
<br />
使い方はこんな感じ。<br />

<pre class="brush: python;">resize_texture(root_node='root', dir=r'C:\temp\test', magnification=0.1)
</pre>
<br />
magnificationで元画像からの倍率を指定します。<br />
引数のwidthとheightで全て統一したサイズにもできます。（こっちのが優先される）<br />
テクスチャは上書きはしたくなかったので、必ず別フォルダに書き出すようになってます。<br />
<br />
また、pythonの画像処理ライブラリのPILを利用しています。<br />
<a href="http://www.lifewithpython.com/2013/09/pil.html" title="" target="_blank">http://www.lifewithpython.com/2013/09/pil.html</a><br />
<br />
が、MAYAだと普通にそこら辺から落としてきたものだとエラーで使えないので、mayaに合わせてビルドしたモジュールが必要ということです。<br />
GitHubにて2014～2016用の各種モジュールを配布してくださっている方がいると教えていただきましたので、以下にリンク貼っておきます。ダウンロードしてパスを通しておきましょう。<br />
<br />
<a href="https://github.com/zclongpop123/maya_python_packages" title="" target="_blank">https://github.com/zclongpop123/maya_python_packages</a><br />
<br />
<br />
<a href="http://3dnchu.com/archives/cg-test-models/" title="" target="_blank">3D人さんの記事</a>から手に入れたテストモデルに実行するとこんな感じです。<br />
<br />
<img src="//mochio326.blog.shinobi.jp/File/7a984b30.jpeg" alt="" /> <br />
コードの中にはテクスチャパスを取得したりゴニョゴニョしたり、色々なパーツがあるので分解して利用してもそれなりに使えるところもあるかもしれません。<br />
<br />
ちなみに、なにやらjpgをリサイズしようとすると「IOError: decoder jpeg not available」と出てエラーになるようでした。<br />
libjpegってのが無いようですね。<br />
自分はtgaさえ処理できれば良かったので、対処してませんが他の形式でも何かあるかもしれません。<br />

<script type="text/javascript">     
SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/11</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/maya/maya%20ascii%E3%81%8B%E3%82%89%E7%9B%B4%E6%8E%A5%E6%83%85%E5%A0%B1%E5%8F%96%E5%BE%97" />
    <published>2016-06-28T03:22:19+09:00</published> 
    <updated>2016-06-28T03:22:19+09:00</updated> 
    <category term="MAYA" label="MAYA" />
    <title>Maya Asciiから直接情報取得</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<p>Mayaのシーンファイル（Maya Ascii）をMayaに読み込まずに直接情報を取得します。</p>
<pre class="brush: python;">## -*- coding: utf-8 -*-
import os
import re

class Node(object):
    
    def __init__(self, path, nodetype):
        self.path = path
        self.nodetype = nodetype

    def _get_value(self, param, stg):
        '''
        -n "hogehoge" のhogehoge部分を取得
        '''
        pattern = param + ' "(.+?)"'
        matchedList = re.findall(pattern, stg)
        if len(matchedList) is 0:
            return ''
        pattern = '^' + param + ' "|"$'
        return re.sub(pattern, '', matchedList[0])
        
    def _get_node_name(self, stg):
        return self._get_value('-n', stg)

    def _get_parent(self, stg):
        return self._get_value('-p', stg)
    
    def search(self):
        list = []
        fil = "createNode " + self.nodetype
        f = open(self.path)
        line = self._read(f)
        
        while line:
            if fil not in line:
                line = self._read(f)
                continue
            #目的のタイプのノードを発見
            nd = NodeData()
            nd.name = self._get_node_name(line)
            nd.parent = self._get_parent(line)
            #attr
            line = self._read(f)
            while re.match('setAttr' , line) is not None:
                at = self._disassembly_setattr_data(line)
                nd.attr[at.name] = at
                line = self._read(f)
                
            list.append(nd)
        f.close()
        return list

    def _disassembly_setattr_data(self, stg):
        '''
        setAttrの文字列を分解する
        '''
        attr = AttrData()
        #アトリビュート名
        attr.name = re.findall('"\..+?"', stg)
        if len(attr.name) &gt; 0:
            attr.name = re.sub('"\.|"', '', attr.name[0])
        #タイプ
        attr.type = re.findall('-type ".+?"', stg)
        if len(attr.type) &gt; 0:
            attr.type = re.sub('-type "|"', '', attr.type[0])
        else:
            attr.type = ''
        #値(多分末尾に書かれてる)
        attr.value = re.sub('^.+ |"|;', '', stg)
        attr.value = attr.value.strip()
        return attr

    def _read(self, file):
        '''
        ;までを1行として読み込む
        strip()で先頭と末尾の空白文字（改行・タブなどなど）が簡単に取り除けるらしいよ。
        '''
        line = file.readline().strip()
        while line[-1:] != ';':
            l = file.readline().strip()
            #EOF
            if l == '':
                break
            line =  line + l
        return line

class NodeData(object):
    '''
    ノードデータ
    '''
    def __init__(self):
        self.name = ''
        self.parent = ''
        self.attr = {}

class AttrData(object):
    '''
    アトリビュートデータ
    '''
    def __init__(self):
        self.value = ''
        self.name = ''
        self.type = ''
</pre>
<p>とりあえず新規シーンをMaya Asciiで保存します。<br />
今回のコードは自分の必要な部分だけなので、取得できるのはノードの情報のみです。<br />
使い方は以下のような感じ。</p>
<pre class="brush: python;">nodes = Node(r'c:\test.ma', 'camera').search()
</pre>
<p>これでシーン内のカメラの情報を取得します。<br />
情報をprint文で書き出してみましょ。</p>
<pre class="brush: python;">4
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
[node name]perspShape 	[parent node]persp
[attr name]ncp 	[value]10 	[type]
[attr name]imn 	[value]persp 	[type]string
[attr name]den 	[value]persp_depth 	[type]string
[attr name]v 	[value]no 	[type]
[attr name]coi 	[value]180.75837217595105 	[type]
[attr name]hc 	[value]%camera 	[type]string
[attr name]fl 	[value]128.07659939244272 	[type]
[attr name]man 	[value]persp_mask 	[type]string
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
[node name]topShape 	[parent node]top
[attr name]ncp 	[value]10 	[type]
[attr name]o 	[value]yes 	[type]
[attr name]rnd 	[value]no 	[type]
[attr name]ow 	[value]30 	[type]
[attr name]den 	[value]top_depth 	[type]string
[attr name]v 	[value]no 	[type]
[attr name]coi 	[value]100.1 	[type]
[attr name]hc 	[value]%camera 	[type]string
[attr name]imn 	[value]top 	[type]string
[attr name]man 	[value]top_mask 	[type]string
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
[node name]frontShape 	[parent node]front
[attr name]ncp 	[value]10 	[type]
[attr name]o 	[value]yes 	[type]
[attr name]rnd 	[value]no 	[type]
[attr name]ow 	[value]30 	[type]
[attr name]den 	[value]front_depth 	[type]string
[attr name]v 	[value]no 	[type]
[attr name]coi 	[value]100.1 	[type]
[attr name]hc 	[value]%camera 	[type]string
[attr name]imn 	[value]front 	[type]string
[attr name]man 	[value]front_mask 	[type]string
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
[node name]sideShape 	[parent node]side
[attr name]ncp 	[value]10 	[type]
[attr name]o 	[value]yes 	[type]
[attr name]rnd 	[value]no 	[type]
[attr name]ow 	[value]30 	[type]
[attr name]den 	[value]side_depth 	[type]string
[attr name]v 	[value]no 	[type]
[attr name]coi 	[value]100.1 	[type]
[attr name]hc 	[value]%camera 	[type]string
[attr name]imn 	[value]side 	[type]string
[attr name]man 	[value]side_mask 	[type]string
</pre>
<br />
なにやら怪しげな部分もありますが、シーンに最初から存在してるカメラの情報がなんとなく取得できてます。<br />
取得するノード名を変えれば他の種類のノードの情報も取得できます。<br />
ただし、未対応なフラグや情報は多いですし、setAttrしか処理してませんから追加されたアトリビュートなどの情報は取得できておりませんのでご注意を＾＾；<br />
<br />

<script type="text/javascript">     
SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/10</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/python/python%E3%81%8B%E3%82%89excel%E3%82%92%E6%93%8D%E4%BD%9C%E3%81%99%E3%82%8B" />
    <published>2016-06-05T21:41:14+09:00</published> 
    <updated>2016-06-05T21:41:14+09:00</updated> 
    <category term="python" label="python" />
    <title>pythonからExcelを操作するクラス</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[MayaからExcelを操作しないといけない場面がありそうだったので、<br />
pythonとclassの勉強の為にExcel操作クラスを作ってみました。<br />

<pre class="brush: python;">## -*- coding: utf-8 -*-
import site
import os
import re
site.addsitedir(os.path.dirname(os.path.abspath(__file__)) + r'\win32maya2015')
import win32com.client as com

# ------------------------------------------------
# 数字をアルファベットに変換 1  -&gt; A  27 -&gt; AA
def num2char(num):
    quotient, remainder = divmod(num, 26)
    chars = ''
    if quotient &gt; 0:
        chars = chr(quotient + 64)
    if remainder &gt; 0:
        chars = chars + chr(remainder + 64)
    return chars

# ------------------------------------------------
# アルファベットを数字に変換  A  -&gt; 1  AA -&gt; 27
def char2num(chars):
    num = 0
    for c in chars:
        num = num * 26 + (ord(c) - 64)
    return num


'''--------------------------------------------------------------------------------'''
class App(object):

    XLMAXIMIZED = -4137

    def __init__(self, visible=False):
        self.__excel_app = com.Dispatch("Excel.Application")
        #警告メッセージを表示しない。
        self.__excel_app.DisplayAlerts = False
        self.__excel_app.Visible = visible
        if(visible==True):
            self.__excel_app.WindowState = self.XLMAXIMIZED
            self.__excel_app.Visible = True

    # ------------------------------------------------
    # Excelブックを新規作成
    def add(self):
        book = self.__excel_app.Workbooks.Add()
        return Workbook(book)

    # ------------------------------------------------
    # エクセルファイルを開く
    def open(self, path, sheet=None, readonly=False):
        book = self.__excel_app.Workbooks.Open(path, 2, readonly)
        return Workbook(book)

    # ------------------------------------------------
    # エクセルプロセスを終了
    # (閉めにこれをやらないとプロセスに__excel_appがいっぱい残るので注意)
    def quit(self):
        self.__excel_app.Application.Quit()


'''--------------------------------------------------------------------------------'''
class Workbook(object):

    def __init__(self, book):
        self.__book = book

    # ------------------------------------------------
    # nameをアクセサ付きのプロパティとして登録
    sheets = property(doc='sheets property')

    @sheets.setter
    def sheets(self):
        pass

    @sheets.getter
    def sheets(self):
        return self._get_sheet_list()

    @sheets.deleter
    def sheets(self):
        pass

    # ------------------------------------------------
    # ブックを閉じる
    def close(self):
        self.__book.Close()
        self.__book = None

    # ------------------------------------------------
    # 上書き保存
    def save(self):
        self.__book.Save()

    # ------------------------------------------------
    # 名前をつけて保存
    def save_as(self, path):
        self.__book.SaveAs(path)

    # ------------------------------------------------
    # ブック内のシート一覧を取得する
    def _get_sheet_list(self):
        list = []
        for value in self.__book.Worksheets:
            list.append(Sheet(value))
        return list

    # ------------------------------------------------
    #  名前でシートを検索
    def find_sheet(self, name):
        if isinstance(name, str):
            name = name.decode('ShiftJIS')
        for value in self.sheets:
            if value.name == name:
                return value
        return None

    # ------------------------------------------------
    # シート削除(シート名、もしくは番号で指定)
    def delete_sheet(self, target):
        if type(target) is str:
            if not self.find_sheet(target):
                print u"[error]Designation of the sheet does not exist"
                return None
        if type(target) is int:
            if target &lt; 1 or target &gt; len(self.sheets):
                print u"[error]Designation of the sheet does not exist"
                return None
        self.__book.Worksheets(target).Delete()

    # ------------------------------------------------
    # シート作成
    def add_sheet(self, name):
        ws = self.__book.Worksheets.Add()
        ws.Name = name
        return Sheet(ws)


'''--------------------------------------------------------------------------------'''
class Sheet(object):

    XLDOWN = -4121
    XLUP = -4162
    XLTOLEFT = -4159
    XLTORIGHT = -4161

    def __init__(self, sheet):
        self.__sheet = sheet
        self._name = sheet.Name
        self._index = sheet.Index

    # ------------------------------------------------
    # nameをアクセサ付きのプロパティとして登録
    name = property(doc='name property')

    @name.setter
    def name(self, value):
        self._name = value
        self.__sheet.Name = value

    @name.getter
    def name(self):
        return self._name

    @name.deleter
    def name(self):
        pass

    # ------------------------------------------------
    # indexをアクセサ付きのプロパティとして登録
    index = property(doc='index property')

    @index.setter
    def index(self):
        pass

    @index.getter
    def index(self):
        return self._index

    @index.deleter
    def index(self):
        pass

    # ------------------------------------------------
    # セルを取得
    def get_cell(self, x, y):
        return Cell(self.__sheet, x, y)

    # ------------------------------------------------
    # 指定列(x)の最終行を取得する
    def max_row(self, x):
        if type(x) is str:
            x = char2num(x)
        return self.__sheet.Cells(65536, x).End(self.XLUP).Row

    # ------------------------------------------------
    # 指定行(y)の最終列を取得する
    def max_colum(self, y):
        return self.__sheet.Cells(y, 256).End(self.XLTOLEFT).Column

    # ------------------------------------------------
    # 行から指定の値のセルを取得する(横方向に調べる）
    def find_cell_from_rows(self, y, search_value, start_x=1):
        cells = []
        if isinstance(start_x, str):
            start_x = char2num(start_x)
        max_x = self.max_colum(y)
        for x in range(start_x, max_x):
            c = self.__comparison_detail(x, y, search_value)
            if c is not None:
                cells.append(c)
        return cells

    # ------------------------------------------------
    # 列から指定の値のセルを取得する(縦方向に調べる）
    def find_cell_from_columns(self, x, search_value, start_y=1):
        cells = []
        max_y = self.max_row(x)
        for y in range(start_y, max_y):
            c = self.__comparison_detail(x, y, search_value)
            if c is not None:
                cells.append(c)
        return cells

    # ------------------------------------------------
    # セルの内容比較
    def __comparison_detail(self, x, y, search_value):
        #cell_value = self.__sheet.Cells(y, x).Value
        cell = Cell(self.__sheet, x, y)
        cell_value = cell.text
        if isinstance(search_value, str):
            search_value = search_value.decode('ShiftJIS')

        if cell_value is None:
            return None

        f = re.search(search_value, cell_value)
        if f is None:
            return None

        return cell


'''--------------------------------------------------------------------------------'''
class Cell(object):

    def __init__(self, sheet, x, y):
        self.__sheet = sheet
        self.__cell = sheet.Cells(y, x)
        self.__range = sheet.Range(num2char(self.x) + str(self.y))

    # ------------------------------------------------
    # xをアクセサ付きのプロパティとして登録
    x = property(doc='x property')

    @x.setter
    def x(self):
        pass

    @x.getter
    def x(self):
        return self.__cell.Column

    @x.deleter
    def x(self):
        pass

    # ------------------------------------------------
    # yをアクセサ付きのプロパティとして登録
    y = property(doc='y property')

    @y.setter
    def y(self):
        pass

    @y.getter
    def y(self):
        return self.__cell.Row

    @y.deleter
    def y(self):
        pass

    # ------------------------------------------------
    # valueをアクセサ付きのプロパティとして登録
    value = property(doc='value property')

    @value.setter
    def value(self, value):
        self.__cell.Value = value

    @value.getter
    def value(self):
        return self.__cell.Value

    @value.deleter
    def value(self):
        pass

    # ------------------------------------------------
    # textをアクセサ付きのプロパティとして登録
    text = property(doc='text property')

    @text.setter
    def text(self):
        pass

    #表示そのままの文字列を取得するため、RangeオブジェクトにあるTextプロパティを戻す
    @text.getter
    def text(self):
        return self.__range.Text

    @text.deleter
    def text(self):
        pass

    # ------------------------------------------------
    # heightをアクセサ付きのプロパティとして登録
    height = property(doc='height property')

    @height.setter
    def height(self, value):
        self.__cell.RowHeight = value

    @height.getter
    def height(self):
        return self.__cell.RowHeight

    @height.deleter
    def height(self):
        pass

    # ------------------------------------------------
    # widthをアクセサ付きのプロパティとして登録
    width = property(doc='width property')

    @width.setter
    def width(self, value):
        self.__cell.ColumnWidth  = value

    @width.getter
    def width(self):
        return self.__cell.ColumnWidth

    @width.deleter
    def width(self):
        pass

    # ------------------------------------------------
    # colorをアクセサ付きのプロパティとして登録
    bg_color = property(doc='bg_color property')

    @bg_color.setter
    def bg_color(self, value):
        #とりあえずcolorインデックスでの指定のみ対応
        self.__cell.Interior.ColorIndex = value

    @bg_color.getter
    def bg_color(self):
        pass

    @bg_color.deleter
    def bg_color(self):
        pass
</pre>
<span class="st"><br />
</span>使い方としては以下のような感じですね。<br />
<br />
<br />

<pre class="brush: python;">## -*- coding: utf-8 -*-
#まずはインポート
import Excel

#------------------------------------------------------------------------------
#◆Appクラス

#これでエクセルを立ち上げる
excel = Excel.App()

#既存のエクセルファイルを開く&rarr;Workbookクラスが戻ってくる
book = excel.open(r"エクセルファイルのパス")

#新しいブックを開く場合はこう&rarr;Workbookクラスが戻ってくる
book = excel.add()

#すべてが終わったらエクセルを終了しましょう
excel.quit()

#------------------------------------------------------------------------------
#◆Workbookクラス

#これでシートのリストが取得できる
book.sheets

#ワークブック自身を閉じる
book.close()

#上書き保存
book.save()

#名前を付けて保存
book.save_as(r"セーブするパス")

#シートを名前で検索&rarr;存在していた場合シートクラスのインスタンスが戻される
sheet = book.find_sheet("Sheet1")

#シートを削除
book.delete_sheet(名前もしくは番号を指定)

#シートを作成&rarr;シートクラスのインスタンスが戻される
sheet = book.add_sheet()

#------------------------------------------------------------------------------
#◆Sheetクラス

#シート名
sheet.name

#シート名変更
sheet.name = "ほげほげ"

#シートのインデックス（番号）
sheet.index

#セルの取得&rarr;Cellクラスが戻る
#x : 列（横方向）　A〜Zもしくは数字を指定
#y : 行（縦方向）　数字を指定
sheet.get_cell(x ,y)

#指定列(x)の最終行を取得する
sheet.max_row(x)

#指定行(y)の最終列を取得する
sheet.max_colum(y)

#行から指定の値のセルを取得する(横方向に調べる）&rarr;Cellクラスが戻る
#y : 縦方向　数字を指定
#search_value : 対象の値（調べるのは表示されている文字列。内部の式などは見ない）
#start_x : 何列目からサーチを開始するか。でふぉは1から
#現時点ではsearch_valueが含まれていれば検出対象となる。完全一致などのしては出来ない
sheet.find_cell_from_rows(y, search_value, start_x)

#列から指定の値のセルを取得する(縦方向に調べる）
#上記とほとんど一緒
sheet.find_cell_from_columns(x, search_value, start_y)

#------------------------------------------------------------------------------
#◆Cellクラス
#メソッドはなし。

#セルの列番号（横方向）
#読み取り専用
cell.x

#セルの行番号（縦方向）
#読み取り専用
cell.y

#セルの内容
#セルの内容によって戻ってくる型が違う。場合によってはちょっと扱いづらいかも？
#1と表示されているセルでも1.0として戻ってきたりする
cell.value

#セルのテキスト
#表示されている値を文字列として取得
#1と表示されているセルは1が戻ってくる。
#読み取り専用
cell.text

#セルの縦幅
cell.height

#セルの横幅
cell.width

#セルの背景色
#設定する場合は番号を指定。そのうち色直指定できるように拡張したい。
cell.bg_color
</pre>
<br />
<br />
<span class="st">pywin32経由でのExcel操作のコードです。<br />
冒頭の</span><span class="st">pywin32をインポートする部分は書き換えてくださいね。</span><span class="st"><span class="st"></span><br />
<br />
コードの中身は基本的にはこんなかんじ&darr;（流石わかりやすい！）<br />
<br />
<a href="http://flame-blaze.net/archives/4887" title="">http://flame-blaze.net/archives/4887</a><br />
<br />
<br />
ただし、今回の自分の目的の様にMayaから標準のpywin32モジュールを利用しようとしてもできません。。。<br />
オー トデスク帝国によると「Maya2013以降のPythonは、通常配布されているPythonとは違うバージョンのVisual Studioでコンパルされているため外部モジュールが利用できません。 」とのことで、Mayaが使っている同じバージョンのVisual Studioで再コンパイルする必要があるそうです（メンドクサイ&hellip;）<br />
<br />
<a href="https://knowledge.autodesk.com/ja/support/maya/troubleshooting/caas/sfdcarticles/sfdcarticles/kA230000000tsRX.html" title="">https://knowledge.autodesk.com/ja/support/maya/troubleshooting/caas/sfdcarticles/sfdcarticles/kA230000000tsRX.html<br />
</a><br />
少し前まで、ネットでMaya各バージョンのpywin32モジュールを配ってくれていた方がいたのですが、今はなにやらページが消えております&hellip;。<br />
メンドクサイですが、それぞれご用意を&hellip;。<span class="st"> (;&acute;A｀)<br />
</span></span><span class="st"><span class="st"><br />
pythonでのExcel操作モジュールは<a href="http://www.python-izm.com/contents/external/excel.shtml" title="">「python-excel」</a></span></span><span class="st"><span class="st"><span class="st"><span class="st">や</span></span><span class="st"><span class="st"><a href="http://pepper.is.sci.toho-u.ac.jp/index.php?%A5%CE%A1%BC%A5%C8%2FPython%A4%AB%A4%E9Excel%A5%D5%A5%A1%A5%A4%A5%EB%A4%F2%A4%A4%A4%B8%A4%EBopenpyxl" title=""><span class="st"><span class="st">「</span></span><span class="st"><span class="st">openpyxl」</span></span></a>があるのですが、<br />
python-excelは書き込みと読込モジュールに分かれていて、かつ2007以降の*.xlsxは非対応ですし<br />
もう一つのopenpyxlは逆に</span></span></span></span><span class="st"><span class="st"><span class="st"><span class="st"><span class="st"><span class="st"><span class="st"><span class="st">*.xlsx</span></span></span></span>にしか対応してない&hellip;</span></span></span></span><span class="st"><span class="st"><span class="st"><span class="st"><span class="st">(&acute;・&omega;・`)<br />
新旧のフォーマットが混在した状態の環境だとどちらも使えなさそう&hellip;ってことに。<br />
<br />
書いたはいいけど、自分でもまだ使ってないので機能不足状態ですが<br />
もし何かのお役にたてれば幸いですー</span></span></span></span></span><span class="st"><span class="st"><span class="st"><span class="st"><span class="st"><span class="st">ヾ(*&acute;&forall;｀*)ﾉ゛</span></span></span></span></span><wbr /></span>
<script type="text/javascript">     
SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/9</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/pyside/%E3%80%90maya%E3%80%91maya2015%E3%81%8B%E3%82%89%E3%81%AFshiboken%E4%BD%BF" />
    <published>2015-08-18T01:07:34+09:00</published> 
    <updated>2015-08-18T01:07:34+09:00</updated> 
    <category term="PySide" label="PySide" />
    <title>【MAYA】Maya2015からはshiboken使わなくてもいいらしい</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<a href="http://bonbonbe.hatenablog.com/entry/2015/04/19/181755" title="" target="_blank">Maya PySide まとめ - 水深1mm</a><br />
<br />
&uarr;このブログの記事を発見して、どうやらMAYA2015からはshibokenを使わなくてもMAYAのウインドウの後ろにPySideウインドウが行かないように出来るらしいぞ、という事が判明。<br />
<br />
ふむふむ。<br />
なにやらMayaQWidgetBaseMixinってものを読み込んでますね。。<br />
ただ、試してみたところサンプルコードではうまく動作しませんでした。<br />
更にちょこっとググってみると、以下のページにヒット。<br />
<br />
<a href="http://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__files_GUID_66ADA1FF_3E0F_469C_84C7_74CEB36D42EC_htm" title="" target="_blank">http://help.autodesk.com/view/MAYAUL/2016/ENU/?guid=__files_GUID_66ADA1FF_3E0F_469C_84C7_74CEB36D42EC_htm</a><br />
<br />
どうやら、GUIのクラスを作る際にMayaQWidgetBaseMixinも継承しないといけないようです。<br />
それを反映したコードが以下。<br />

<pre class="brush: python;"># -*- coding: utf-8 -*-
from PySide import QtCore, QtGui
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

#OKってボタンが表示されるだけのUI
class GUI(MayaQWidgetBaseMixin, QtGui.QWidget):
    def __init__(self, parent=None):
        super(GUI, self).__init__(parent=parent)
        self.layout = QtGui.QVBoxLayout()
        self.setLayout(self.layout)
        self.okButton = QtGui.QPushButton('OK')
        self.layout.addWidget(self.okButton)

if __name__ == '__main__':
    app = QtGui.QApplication.instance()
    ui = GUI()
    ui.show()
    sys.exit()
    app.exec_()
</pre>
<script type="text/javascript">SyntaxHighlighter.all(</script>
<br />
MAYA2014以前のshibokenを利用した方法は色々な方が書かれてます<br />
（いつもながらホントお世話になっております）<br />
<br />
<a href="http://d.hatena.ne.jp/hiromu4/20120212/1329031446" title="" target="_blank">Maya2012でPyside-ウィンドウを後ろにいかせない - hiros-log<br />
</a><a href="http://flame-blaze.net/archives/2991" title="" target="_blank">[Maya] Designerで作った.uiをMayaで使用する [PySide] | Reincarnation+<br />
<br />
</a>ちなみに、MAYA2015ではshibokenをインポートする際、<br />

<pre class="brush: python;">
from Shiboken.shiboken import wrapInstance
</pre>
<br />
ではエラーが出てしまうので、<br />

<pre class="brush: python;">
from shiboken import wrapInstance
</pre>
<br />
としないといけないらしい。 <br />
後は、UIを描画する際に良く見るサンプルコードで<br />

<pre class="brush: python;">
app = QtGui.QApplication(sys.argv)
ui = GUI()
ui.show()
sys.exit(app.exec_())
</pre>
<br />
という風に書かれてるんだけど、以下のようにしないと動かないらしい。<br />

<pre class="brush: python;">
app = QtGui.QApplication.instance()
ui = GUI()
ui.show()
sys.exit()
app.exec_()
</pre>
<br />
シンプルなコードなのに動かないなーって時間かけてググってたらたどり着いた答え。<br />
なぜかはよく分かりません。<br />
<br />
MAYA2014までだったら正常に動くんだろうか、、、、<br />
うむむ、、、まだまだ分からないことが多いっすねorz]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/8</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/pymel/%E3%80%90maya%E3%80%91%E3%82%B7%E3%82%A7%E3%82%A4%E3%83%97%E3%83%8E%E3%83%BC%E3%83%89%E3%81%AE%E3%83%90%E3%82%A6%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AB" />
    <published>2015-03-24T02:15:42+09:00</published> 
    <updated>2015-03-24T02:15:42+09:00</updated> 
    <category term="pymel" label="pymel" />
    <title>【MAYA】シェイプノードのバウンディングボックスにロケータを配置（指定フレーム範囲内）</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[指定ノード以下のシェイプノード全体のバウンディングボックスとして取得。<br />
バウンディングボックスの座標にロケータ作成。 <br />
これをフレーム数分繰り返す<br />
<br />
pymel pm.currentTime(fr)でアップデートをFalseにして画面描画を行わないと、 バウンディングボックスの情報も更新されなかった。
<pre class="brush: python;">import pymel.core as pm
import maya.cmds as cmds

#指定ノード以下のシェイプノードのバウンディングボックスを取得
def get_boundingbox(root):
 
    if isinstance(root,str) == True:
        root = pm.PyNode(root)
         
    transforms = root.listRelatives(ad=True,type="transform")
    pm.select(transforms)
    bbox = cmds.polyEvaluate(b=True, ae=True)
    return bbox
        
#バウンディングボックスの位置にロケータ作成
def make_bbox_locator(bbox ,root):
    for x in bbox[0]:
        for y in bbox[1]:
            for z in bbox[2]:
                l = pm.spaceLocator(p=(x, y, z))
                pm.parent(l ,root)



min = int(pm.Env().minTime)
max = int(pm.Env().maxTime)
step = 5　#フレームステップ数

obj = pm.selected()[0]
root = pm.group(em=True, name='bbox_root')


for fr in range(min ,max ,step):
    pm.currentTime(fr)
    bbox = get_boundingbox(obj)
    make_bbox_locator(bbox ,root)
</pre>
<script type="text/javascript">SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/7</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/pymel/%E3%80%90maya%E3%80%91%E5%B0%8F%E7%B2%92%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%80%80%E3%81%9D%E3%81%AE%EF%BC%92" />
    <published>2015-03-18T02:28:06+09:00</published> 
    <updated>2015-03-18T02:28:06+09:00</updated> 
    <category term="pymel" label="pymel" />
    <title>【MAYA】小粒スクリプト　その２</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[<h4>選択以下のシェイプノードのバウンディングボックスを取得</h4>
<pre class="brush: python;">import pymel.core as pm

import pymel.core as pm
import maya.cmds as cmds

def get_boundingbox(root):
 
    if isinstance(root,str) == True:
        root = pm.PyNode(root)
         
    transforms = root.listRelatives(ad=True,type="transform")

    pm.select(transforms)
    bbox = cmds.polyEvaluate(b=True, ae=True)
    print bbox
        
                    

files = get_boundingbox(pm.selected()[0])


</pre>
<script type="text/javascript">SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
  <entry>
    <id>mochio326.blog.shinobi.jp://entry/6</id>
    <link rel="alternate" type="text/html" href="https://mochio326.blog.shinobi.jp/pymel/%E3%80%90maya%E3%80%91%E3%83%8E%E3%83%BC%E3%83%89%E4%BB%A5%E4%B8%8B%E3%81%AE%E3%83%86%E3%82%AF%E3%82%B9%E3%83%81%E3%83%A3%E3%82%92%E6%8C%87%E5%AE%9A%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%AB%E3%82%B3" />
    <published>2015-03-14T16:12:26+09:00</published> 
    <updated>2015-03-14T16:12:26+09:00</updated> 
    <category term="pymel" label="pymel" />
    <title>【MAYA】ノード以下のテクスチャを指定フォルダにコピー→パスの切り替え</title>
    <content mode="escaped" type="text/html" xml:lang="utf-8"> 
      <![CDATA[ノード以下のテクスチャファイルを外部のフォルダにコピー、コピー後にテクスチャパスを書き換えるpymelです。<br />
テクスチャファイルの一覧を取得する関数はいつもお世話になっている<br />
<br />
<a href="http://flame-blaze.net/script%E6%96%87%E6%B3%95%E3%83%BB%E9%80%86%E5%BC%95%E3%81%8D%E8%BE%9E%E5%85%B8/%E9%80%86%E5%BC%95%E3%81%8D%E8%BE%9E%E5%85%B8/715-2" title="" target="_blank">逆引きmayaCommand辞典 | Reincarnation+</a><br />
<br />
さんから拝借しました～。<br />
<span class="st">((&ldquo;(人&omega;・)</span><span class="st">ありがたや～(・&omega;人)&rdquo;))</span><br />
<br />

<pre class="brush: python;">#!/usr/bin/env python<br />


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pymel.core as pm
import os
import shutil


#指定ノード以下に接続されている全テクスチャノードを取得
def get_all_texture_node(root_node):
 
    if isinstance(root_node, str) == True:
        root_node = pm.PyNode(root_node)
         
    shapes = root_node.listRelatives(ad=True, type="mesh")
    file_nodes = []
    for i in shapes:
        shading_engines = i.connections(type="shadingEngine")
        for s in shading_engines:
            shader_list = s.surfaceShader.connections()
            for shader in shader_list:
                file_node = shader.connections(type="file")
                file_nodes += file_node
                    
    return file_nodes
    


#指定ノード以下に接続されているテクスチャパスのリスト
def get_use_texture_list(root_node):
    
    file_nodes = get_all_texture_node(root_node)
    
    files = []
    for tex in file_nodes:
        files.append(tex.fileTextureName.get())
                    
    files = list(set(files))
    return files 

#指定ノード以下に接続されているテクスチャを指定のディレクトリに接続し直し
def set_texture_to_specified_dir(root_node, dir):

    file_nodes = get_all_texture_node(root_node)

    for tex in file_nodes:
        def_path = tex.fileTextureName.get()
        base_name = os.path.basename(def_path)
        new_path = os.path.join(dir, base_name)
        if os.path.isfile(new_path):
            tex.fileTextureName.set(new_path)


#ファイルリストを指定のディレクトリにコピーする
def copy_filelist(list ,copy_dir):
    os.makedirs(copy_dir)
    for e in files:
        shutil.copy(e, copy_dir)



dir = r"c:\temp\test\test2"
node = pm.selected()[0]
files = get_use_texture_list(node)
copy_filelist(files ,dir)
set_texture_to_specified_dir(node ,dir)




</pre>
<script type="text/javascript">SyntaxHighlighter.all()</script>]]> 
    </content>
    <author>
            <name>モチオ</name>
        </author>
  </entry>
</feed>