Created
June 7, 2016 02:32
-
-
Save yamahigashi/392620e0b2ed6cdbab7d579450d1f8d8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# in maya | |
# -*- coding: utf-8 -*- | |
import re | |
import json | |
import maya.mel as mel | |
from maya.api import OpenMaya as OpenMaya2 | |
import FabricEngine.Core as fe | |
import FabricEngine.CAPI as capi | |
def convert_safe_json(string): | |
def _maketrans(m): | |
try: | |
return { | |
"\\'": '', | |
'\\"': '', | |
'\t': ' ', | |
'\n': '', | |
'\r': '', | |
'\\n': '', | |
'\\r': '' | |
}[m.group(1)] | |
except KeyError: | |
return '' | |
string = re.sub(r'''(\n|\r|\t)''', _maketrans, string) | |
string = re.sub(r'''[^\\](\\"|\\')''', _maketrans, string) | |
string = re.sub(r'''[^\\](\\"|\\')''', _maketrans, string) | |
string = re.sub(r'''(\\n|\\r)''', _maketrans, string) | |
# j = json.loads(string) | |
return string | |
def json_from_dfgexec(dfgexec): | |
j = dfgexec.exportJSON() | |
j = convert_safe_json(j) | |
return json.loads(j) | |
class CanvasPortInfo(object): | |
''' | |
type: 0 DFGPortType_In | |
type: 1 DFGPortType_IO | |
type: 2 DFGPortType_Out | |
''' | |
def __init__(self, container, index): | |
self.container = container | |
self.name = container.getExecPortName(index) | |
self.portType = container.getExecPortType(index) | |
self.hasSrc | |
def __str__(self): | |
return " " * (self.container.depth + 1) + self.name | |
@property | |
def isConnected(self): | |
if "exec" in self.name: | |
return False | |
def _inner(x, t, c=0): | |
try: | |
if t in [0, 1]: # In and IO | |
return x.hasSrcPorts(self.path) | |
else: | |
return x.hasDstPorts(self.path) | |
except Exception as e: | |
print e | |
if c > 10: | |
raise | |
print "fallback" * c, x.isPreset() | |
if x.parent: | |
_inner(x.parent, t, c + 1) | |
else: | |
print "gave up", self.path | |
return False | |
_inner(self.container, self.portType) | |
@property | |
def hasSrc(self): | |
if (self.container.parent and self.container.parent.isPreset): | |
return True | |
if self.portType == 2: | |
return True | |
return self.isConnected | |
@property | |
def path(self): | |
if self.container.path: | |
return "{}.{}".format(self.container.path, self.name) | |
else: | |
return self.name | |
class CanvasDFGExe(capi.DFGExec): | |
def __init__(self, dfg, parent=None, name=None): | |
super(CanvasDFGExe, self).__init__(dfg) | |
if name: | |
self.name = name | |
else: | |
self.name = self.getTitle() | |
self.parent = parent | |
self.depth = self.parent.depth + 1 if self.parent else 0 | |
self.subNodes = self._searchSubNodes() or [] | |
self.ports = self._searchPorts() or [] | |
@property | |
def execType(self): | |
''' return Exec type | |
0: graph | |
1: func | |
''' | |
return self.getType() | |
@property | |
def nodeType(self): | |
''' | |
DFGNodeType_Inst | |
DFGNodeType_Get | |
DFGNodeType_Set | |
DFGNodeType_Var | |
DFGNodeType_User | |
''' | |
if not self.parent: | |
return 0 | |
return self.parent.getNodeType(self.name) | |
@property | |
def presetName(self): | |
return self.getPresetName() | |
@property | |
def presetPath(self): | |
if not self.parent: | |
return "" | |
# FIXME: | |
ppath = self.parent.dfgexec.getNodeDesc(self.name) | |
ppath = json.loads(ppath).get('presetPath', self.presetName) | |
return ppath | |
@property | |
def path(self): | |
if self.parent and len(self.parent.name) > 0: | |
res = "{}.{}".format(self.parent.path, self.name) | |
else: | |
# node in top level graph | |
res = self.name | |
return res | |
@property | |
def isGraph(self): | |
return self.execType == 0 | |
def _searchSubNodes(self): | |
if not self.isGraph: | |
return [] | |
kids = [] | |
for i in xrange(self.getNodeCount()): | |
sub_name = self.getNodeName(i) | |
sub_type = self.getNodeType(sub_name) | |
if _ignoreNodeType(sub_type): | |
continue | |
sub_exec = CanvasDFGExe(self.getSubExec(sub_name), parent=self, name=sub_name) | |
kids.append(sub_exec) | |
return kids | |
def _searchPorts(self): | |
if _ignoreNodeType(self.nodeType): | |
return [] | |
ports = [] | |
for i in xrange(self.getExecPortCount()): | |
port = CanvasPortInfo(self, i) | |
# print port | |
ports.append(port) | |
return ports | |
def _ignoreNodeType(t): | |
return t not in [0, 4] | |
# -------------------------------------------------------------------------- # | |
def get_dfgexe(maya_node_name): | |
ctxt_id = mel.eval('FabricCanvasGetContextID;') | |
bind_id = mel.eval('FabricCanvasGetBindingID -node "{}";'.format(maya_node_name)) | |
# capi_client = capi.FEC_ClientBind(None, None, ctxt_id) # dones not use | |
core_client = fe.createClient({'contextID': ctxt_id}) | |
host = core_client.DFG.host | |
dfgbinding = host.getBindingForID(bind_id) | |
dfgexec = dfgbinding.getExec() | |
return dfgexec | |
def dump(node): | |
for kid in node.subNodes: | |
print " " * kid.depth, ">", kid.name | |
for p in node.ports: | |
print " " * (kid.depth + 1), p.name, p.hasSrc | |
dump(kid) | |
def collapse(node): | |
all_nodes = [node] | |
def __inner__(node): | |
for kid in node.subNodes: | |
all_nodes.append(kid) | |
__inner__(kid) | |
__inner__(node) | |
return all_nodes | |
def extract_by_preset_name(top_node, preset_name): | |
all = collapse(top_node) | |
return [x for x in all if preset_name == x.presetName] | |
# ********* prepare ********************** | |
# access canvas dfgexec object | |
# :ref: http://docs.fabric-engine.com/FabricEngine/2.2.0/HTML/CAPIProgrammingGuide/canvas.html | |
# canvas_node_name = "canvasNode1" | |
canvas_node_name = cmds.ls(sl=True)[0] | |
dfgexec = get_dfgexe(canvas_node_name) | |
# ********* A ******************** | |
# loaded_json = json_from_dfgexec(dfgexec) | |
# todo: parse this json | |
# ********* B ******************** | |
# object oriented way for parse node hierarchy down | |
p = CanvasDFGExe(dfgexec) | |
# dump(p) | |
x = extract_by_preset_name(p, 'Cache') | |
for y in x: | |
print y.path | |
print 'done!! ----------------------------' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment