Fake_poser3a.py
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