[Python] dgExplorerモジュール作りました。

まだブログには書いてないんですけど、この間RenderSanミーティング#3行ってきました。
で、その時に、ブログ読んでますよ、Pythonネタだったら突っ込みいれますよ、とコメント頂いたので、
とりあえず、取りとめも無く突然スクリプト貼っつけてみますwww

簡単に説明すると、DGネットワークの中から指定したタイプのノードを探しに行くスクリプトです。
再帰処理ってすごく好きなんですが、イマイチちゃんと使えてる自身がないので、
世のMayaPythonistaの方々から突っ込みいれて頂きたくUPしてみます。

おれだったらこうする!
お前レベル低すぎ!
余計な処理してんじゃねぇ!
再帰のさの字も知らねぇ小童が!

などなど、なんでも宜しくお願いします。

せっかくなのでいろんな方からコメント頂きたいです。

あ!そうだ、コメント英語で書いてるんですが、練習かねてノリで書いてるので、
絶対支離滅裂な英語だとおもいます。
そこに関しても突っ込み頂ければ、自分で思いっきり笑いますので、是非wwwwwww

あとコメントの書き方が若干アレなのは、doxygen仕様です。
引数と戻り値ぐらいを軽く書いてるだけですが。一応。

ということで以下にソースコード↓。


######################################################################
import maya.cmds as mc

# fixed number
DST = 0
SRC = 1

## Explore node in spacified node’s dependency graph
class DgExplorer:
    ## Initialize
    def __init__(self, nodename, maxdepth = 10):
        self.rootnode = nodename
        self.maxdepth = maxdepth
        self.iterdepth = 0
        self.connectedNodes = []
        self.throughNodes = []

    ## A simple wrapper function for self.find
    # \n search type specified nodes in distination network
    # \param nodetype search node type
    def findDistinations(self, nodetype=None):
        self.find(DST, nodetype)

    ## A simple wrapper function for self.find
    # \n search type specified nodes in source network
    # \param nodetype search node type
    def findSource(self, nodetype=None):
        self.find(SRC, nodetype)

    ## Find connected nodes (recrusive function)
    # \param direction iterate direction(DST or SRC preffered)
    # \param nodetype search node type
    # \return connected nodes list
    def find(self, direction=SRC, nodetype=None):
        # iterate in dg network
        _connectedNodes = self._iter_find(self.rootnode, 0, direction)
        if len(_connectedNodes) > 0:
            if nodetype != None:
                self.connectedNodes = [node for node in _connectedNodes if mc.objectType(node) == nodetype]
            else:
                self.connectedNodes = list(set(_connectedNodes))
        if len(self.connectedNodes) > 0:
            self.connectedNodes = list(set(self.connectedNodes))
        return self.connectedNodes

    ## Find connected nodes (recrusive function)
    # \param nodename name of refer connection node
    # \param direction iterate direction(DST or SRC preffered)
    # \return list of found nodes
    def _iter_find(self, node, depth, direction):
        depth += 1
        if depth > self.maxdepth:
            return []
        elif depth > self.iterdepth:
            self.iterdepth = depth
        dgnode = DgNode(node)
        connected = dgnode.getDestination() if direction == DST else dgnode.getSource()
        for conn in connected:
            if conn in self.throughNodes:
                continue
            else:
                self.throughNodes.append(conn)
                connected += self._iter_find(conn, depth, direction)
        return connected

    ## Return connected nodes list
    # \return list of connected nodes
    def getConnected(self):
        return self.connectedNodes

    ## Get iterated depth
    # \return depth
    def getDepth(self):
        return self.iterdepth

class DgNode:
    ## Initialize
    def __init__(self, nodename):
        self.name = nodename
        self.srcNodes = []
        self.dstNodes = []
        #self.repeatNodes = []
        self._referConnected()

    ## Inquiry all connection
    def _referConnected(self):
        self.referSource()
        self.referDestination()
        #self.checkRepeat()

    ## Inquiry source side node
    # \n found nodes are seted to member variable
    def referSource(self):
        _src = mc.listConnections(self.name, s=1, d=0, p=0, sh=1)
        if _src != None:
            self.srcNodes = _src
    
    ## Inquiry destination side node
    # \n found nodes are seted to member variable
    def referDestination(self):
        _dst = mc.listConnections(self.name, s=0, d=1, p=0, sh=1)
        if _dst != None:
            self.dstNodes = _dst
    
    ## Get connected nodes only source side
    # \return nodename list
    def getSource(self):
        return self.srcNodes

    ## Get connected nodes only destination side
    # \return nodename list
    def getDestination(self):
        return self.dstNodes

    ## Get all connected nodes (Source, Destination)
    # \return tuple of all connection info list (src, dst)
    def getAllConnected(self):
        return (self.srcNodes, self.dstNodes)

if __name__ == ‘__main__’:
    items = mc.ls(sl=True)
    depth = 100            # recrusion depth
    type = ‘joint’        # search type
    dge = DgExplorer(items[0], depth)
    nodes = dge.find(DST, type)        # start search
    print ‘—–‘ * 10
    print dge.getDepth()
    print ‘—–‘ * 10
    for node in nodes:
        print ‘%s : %s’ % (node, mc.objectType(node))
    print ‘—–‘ * 10
    print ”

######################################################################

ちなみにこれ、僕にしてはスクリプトとして良く出来てる方。
もっともっと勉強せねばなーとおもいます。

「[Python] dgExplorerモジュール作りました。」への2件のフィードバック

  1. 好みの問題もあるので無難な所で2点ほど。

    # fixed number
    DST = 0
    SRC = 1

    一般に自明なコメントは良くない物とされています。よく見かける例では
    const int hoge = 1; //Constant variable.
    とか。
    # DST and SRC are indicators meaning destination and source connection(s) of a node respectively
    (文法間違ってるかも)とかならいいと思いますが。あとPythonでは文字列使ってる人が多いようです。

    DST or SRC preffered
    preferredは「推奨する」なんで他にもあるのかと勘違いされそうです。

  2. >hohehohe2さん
    あざーーす!!

    > 一般に自明なコメントは良くない物とされています。
    あー、、、確かに。。
    これは言い訳させてもらうと、MELから入った自分としては定数という文化が無かったため、自分用メモというところで書いちゃいました。
    そろそろ慣れてきたので、はずします:)

    全然意識せずにやってた、、、危ない、、、

    > コメント
    > preferred
    な、なるほど。
    知ってる単語&しっくり来るのがこれぐらいだったので、無意識に使ってました。

    うーん、良く分からずに英語コメント使うのも危ないですね。
    英語の勉強せねば、とおもいます。

    ご指摘ありがとうございますーーー!!

コメントを残す

メールアドレスが公開されることはありません。