1 from __future__ import print_function 2 3 import inspect 4 import os 5 import re 6 import sys 7 import traceback 8 from collections import namedtuple 9 10 try: 11 import poser 12 except ImportError: 13 poser = None 14 15 if sys.version_info.major > 2: 16 basestring = str 17 xrange = range 18 else: 19 range = xrange 20 21 PARMS = namedtuple("PARMS", "Name args doc") 22 classnames = set() 23 24 sc = poser.Scene() 25 26 27 DONT_CALL_FILE = None 28 DONT_CALL = set() 29 30 def debug(*args): 31 print(*args, file=sys.stderr) 32 33 34 #def dont_call(funcstr): 35 # if DONT_CALL_FILE: 36 # print(funcstr, file=DONT_CALL_FILE) 37 38 39 def analyze(obj2analyze): 40 container = dict( 41 classes=list(), 42 builtins=list(), 43 consts=list() 44 ) 45 46 members = inspect.getmembers(obj2analyze) 47 if members: 48 for name, obj in members: 49 if name.startswith("_"): 50 continue 51 doc = obj.__doc__.replace(" ", "\n").split("\n") if obj.__doc__ else None 52 if name.startswith("k"): 53 #if isinstance(obj, basestring): 54 # obj = "'{}'".format(obj) 55 container["consts"].append(PARMS(name, obj, "")) 56 elif inspect.isclass(obj): 57 container["classes"].append(PARMS(name, None, doc)) 58 classnames.add(name.strip().lower()) 59 elif inspect.isbuiltin(obj): 60 container["builtins"].append(PARMS(name, None, doc)) 61 else: 62 t = getattr(poser, obj2analyze.__class__.__name__ + "Type") 63 if t: 64 for name in dir(t): 65 if name.startswith("_"): 66 continue 67 obj = getattr(obj2analyze, name) 68 doc = obj.__doc__.replace(" ", "\n").split("\n") if obj.__doc__ else None 69 container["builtins"].append(PARMS(name, None, doc)) 70 71 return container 72 73 74 def print_obj(container, tabs=0): 75 if not container: 76 debug(">>>>>>>>>EMPTY") 77 return 78 t = "\t" * tabs 79 for _entry in sorted(container["consts"]): 80 if _entry.doc: 81 print(t + "# ".join(_entry.doc)) 82 frmt = "{}{} = '{}'" if isinstance(_entry.args, basestring) \ 83 else "{}{} = {}" 84 print(frmt.format(t, _entry.Name, _entry.args)) 85 if tabs == 0: 86 print("#", "-" * 70) 87 88 for _entry in sorted(container["classes"]): 89 print("\n{}class {}:".format(t, _entry.Name)) 90 if _entry.doc: 91 doc = ("\n" + t + "\t").join(_entry.doc) 92 print('{}"""\n{}\n{}"""'.format(t, doc, t)) 93 if _entry.args is not None: 94 print("{}\tdef __init__({}):".format(t, _entry.args)) 95 print("{}\t\tpass".format(t)) 96 97 try: 98 if _entry.Name == "SceneType": 99 print_obj(analyze(poser.Scene()), tabs + 1) 100 elif _entry.Name == "CredManagerType": 101 print_obj(analyze(CredManager), tabs + 1) 102 elif _entry.Name == "ClothSimulatorType" and cloth_simulator: 103 print_obj(analyze(cloth_simulator), tabs + 1) 104 elif _entry.Name == "ActorType" and Actor: 105 print_obj(analyze(Actor), tabs + 1) 106 elif _entry.Name == "ParmType" and Parameter: 107 print_obj(analyze(Parameter), tabs + 1) 108 elif _entry.Name == "GeomType" and Geometry: 109 print_obj(analyze(Geometry), tabs + 1) 110 elif _entry.Name == "PolygonType" and Geometry: 111 print_obj(analyze(Geometry.Polygons()[0]), tabs + 1) 112 elif _entry.Name == "TexPolygonType" and Geometry: 113 print_obj(analyze(Geometry.TexPolygons()[0]), tabs + 1) 114 elif _entry.Name == "VertType" and Geometry: 115 print_obj(analyze(Geometry.Vertices()[0]), tabs + 1) 116 elif _entry.Name == "TexVertType" and Geometry: 117 print_obj(analyze(Geometry.TexVertices()[0]), tabs + 1) 118 elif _entry.Name == "FigureType" and Figure: 119 print_obj(analyze(Figure), tabs + 1) 120 elif _entry.Name == "MaterialType" and Material: 121 print_obj(analyze(Material), tabs + 1) 122 elif _entry.Name == "ShaderTreeType" and Shadertree: 123 print_obj(analyze(Shadertree), tabs + 1) 124 elif _entry.Name == "ShaderNodeType" and Node: 125 print_obj(analyze(Node), tabs + 1) 126 elif _entry.Name == "ShaderNodeInputType" and Node: 127 print_obj(analyze(Node.Inputs()[0]), tabs + 1) 128 elif _entry.Name == "ImExporterType" and Imexporter: 129 print_obj(analyze(Imexporter), tabs + 1) 130 elif _entry.Name == "MovieMakerType" and Moviemaker: 131 print_obj(analyze(Moviemaker), tabs + 1) 132 elif _entry.Name == "MotionNodeType" and Motionrig: 133 print_obj(analyze(Motionrig), tabs + 1) 134 elif _entry.Name == "SuperFlyOptionsType" and Superfly: 135 print_obj(analyze(Superfly), tabs + 1) 136 elif _entry.Name == "FireFlyOptionsType" and Firefly: 137 print_obj(analyze(Firefly), tabs + 1) 138 elif _entry.Name == "Dialog": 139 dlg = poser.Dialog() 140 print_obj(analyze(dlg), tabs + 1) 141 del dlg 142 elif _entry.Name == "DialogDirChooser": 143 dlg = poser.DialogDirChooser() 144 print_obj(analyze(dlg), tabs + 1) 145 del dlg 146 elif _entry.Name == "DialogFileChooser": 147 dlg = poser.DialogFileChooser(2) 148 print_obj(analyze(dlg), tabs + 1) 149 del dlg 150 elif _entry.Name == "DialogTextEntry": 151 dlg = poser.DialogTextEntry() 152 print_obj(analyze(dlg), tabs + 1) 153 del dlg 154 else: 155 print("{}\tpass".format(t)) 156 except poser.error as err: 157 debug(err) 158 print("{}\tpass".format(t)) 159 160 print() 161 162 for _entry in sorted(container["builtins"]): 163 args = _entry.args or "*args" 164 if tabs > 0: 165 args = "self, {}".format(_entry.args or "*args") 166 print("\n{}def {}({}):".format(t, _entry.Name, args)) 167 if _entry.doc: 168 doc = ("\n" + t + "\t").join(_entry.doc) 169 print('{}\t"""\n{}\t{}\n{}\t"""'.format(t, t, doc, t)) 170 171 is_list = False 172 return_str = None 173 last_line = _entry.doc[-1].strip() 174 res = re.match(r"[\(\[]\s*[\(\[].*?[\)\]]\s*[\]\)]", last_line) 175 if res: 176 # return type is tuple or list of tuples 177 res_str = res.string[res.regs[0][0] + 1:res.regs[0][1] - 1].strip() 178 res_str = [s for s in re.split(r"([\(\[][^\)]*[\)\[]),", res_str) if s.strip()] 179 for idx, _subentry in enumerate(res_str): 180 for _r in re.findall(r"<((\w+)\s*type)>", _subentry, flags=re.IGNORECASE): 181 if _r[1].lower() in "int float list tuple": 182 _subentry = re.sub("<"+_r[0]+">", _r[1].lower()+"(0)", _subentry, flags=re.IGNORECASE) 183 else: 184 _subentry = re.sub("<"+_r[0]+">", _r[0]+"()", _subentry, flags=re.IGNORECASE) 185 res_str[idx] = _subentry.strip() 186 187 return_str = "list({})" if last_line.startswith("[") else "tuple({})" 188 return_str = return_str.format(", ".join(res_str)) 189 190 if return_str is None: 191 res = re.match(r"\(?<([^>]+)>", last_line) 192 if res: 193 return_type = res.groups(1)[0].strip() 194 is_list = False 195 if return_type.endswith("List") or return_type.endswith("list"): 196 return_type = return_type.split()[0] 197 is_list = True 198 199 if return_type.lower() in classnames: 200 return_str = return_type + "()" 201 elif return_str == "NoneType": 202 return_str = "" 203 elif return_type == "IntType": 204 return_str = "int(1)" 205 elif return_type == "FloatType": 206 return_str = "float(1.0)" 207 elif return_type == "StringType": 208 return_str = "str('{}()')".format(_entry.Name) 209 elif return_type == "DictType": 210 return_str = 'dict()' 211 elif return_type == "HairType": 212 return_str = "HairType()" 213 214 if not return_str.strip(): 215 DONT_CALL.add(_entry.Name) 216 217 if return_str is None: 218 if "FloatType 4x4 Tuple" in last_line: 219 return_str = "(float(0), float(0), float(0), float(0))" 220 221 if _entry.Name == "WxAuiManager": 222 return_str = "wx.AuiManager()" 223 224 elif _entry.Name == "WxApp": 225 return_str = "poser.WxApp()" 226 227 if is_list: 228 return_str = "list({})".format(return_str) 229 230 if return_str is not None: 231 print("{}\treturn {}".format(t, return_str)) 232 else: 233 print("{}\treturn".format(t)) 234 else: 235 print("{}\tpass".format(t)) 236 DONT_CALL.add(_entry.Name) 237 238 # temp_dir = poser.TempLocation() 239 temp_dir = os.path.dirname(sys.argv[0]) 240 fname = os.path.join(temp_dir, "POSER_FAKE.py") 241 242 _stdout = sys.stdout 243 errmsg = None 244 245 Actor = poser.Scene().CurrentActor() 246 Figure = poser.Scene().CurrentFigure() 247 if Figure and Actor: 248 Geometry = Actor.Geometry() 249 Parameter = Actor.Parameters()[0] 250 Material = Actor.Materials()[0] 251 if Material: 252 Shadertree = Material.ShaderTree() 253 if Shadertree: 254 Node = Shadertree.Nodes()[0] 255 256 if sc.NumClothSimulators() == 0: 257 cloth_simulator = sc.CreateClothSimulator() 258 else: 259 cloth_simulator = sc.ClothSimulator(0) 260 261 Imexporter = sc.ImExporter() 262 Moviemaker = sc.MovieMaker() 263 CredManager = poser.CredManager() 264 Motionrig = poser.NewMotionRig() 265 Superfly = sc.CurrentSuperFlyOptions() 266 Firefly = sc.CurrentFireFlyOptions() 267 268 try: 269 Hair = Actor.HairGroup(0) 270 except: 271 Hair = None 272 273 try: 274 with open(fname, "w") as fh: 275 sys.stdout = fh 276 print_obj(analyze(poser)) 277 if Hair: 278 print("\nclass HairType:") 279 print_obj(analyze(Hair), 1) 280 281 except Exception: 282 exc_type, exc_value, exc_traceback = sys.exc_info() 283 print(traceback.format_exception(exc_type, exc_value, exc_traceback), file=_stdout) 284 finally: 285 sys.stdout = _stdout 286 287 with open(os.path.join(temp_dir, "DONT_CALL.txt"), "w") as fh: 288 for entry in DONT_CALL: 289 print(entry, file=fh) 290 291 print(errmsg or "Written to: {}".format(fname)) 292 293 else: 294 print("Can not work with an empty scene.") 295