UV_2_SVG.py
1    from __future__ import print_function, division, absolute_import
2    import sys
3    import os
4    from random import randint
5    
6    if sys.version_info.major > 2:
7        basestring = str
8    else:
9        range = xrange
10   
11   try:
12       import poser
13   except ImportError:
14       from PoserLibs import POSER_FAKE as poser
15   
16   SCENE = poser.Scene()
17   
18   fig = SCENE.CurrentFigure()
19   
20   
21   ### --------------------------------------------------------------------------
22   ### collect tex vertices based on materials
23   def acceptableActor(ac):
24       assert isinstance(ac, poser.ActorType)
25       return (ac.IsBodyPart() and
26               hasattr(ac, "Geometry") and
27               ac.Geometry() is not None and
28               ac.Geometry().NumVertices() > 0)
29   
30   
31   def get_texVertices(figure, scale=100):
32       assert isinstance(figure, poser.FigureType)
33       tvertex_dict = dict()
34   
35       for ac in [_ac for _ac in figure.Actors() if acceptableActor(_ac)]:  # type: poser.ActorType
36           geom = ac.Geometry()
37           tsets = geom.TexSets()
38           tverts = geom.TexVertices()
39           matidx = -1
40           tvertlist = []
41           for poly, tpoly in zip(geom.Polygons(), geom.TexPolygons()):  # type: poser.PolygonType,poser.TexPolygonType
42               if matidx != poly.MaterialIndex():
43                   matidx = poly.MaterialIndex()
44                   d = tvertex_dict.setdefault(poly.MaterialName(), dict())
45                   d.setdefault("actors", set()).add(ac.Name())
46                   tvertlist = d.setdefault("tverts", list())
47               numv = tpoly.NumTexVertices()
48               this_verts = [(tverts[_i].U() * scale, tverts[_i].V() * scale) for _i in
49                             tsets[tpoly.Start():tpoly.Start() + numv]]
50               tvertlist.append(this_verts)
51   
52       return tvertex_dict
53   
54   
55   def svg_polyline(tvertex_dict, materialname, color, height):
56       assert isinstance(tvertex_dict, dict)
57       assert isinstance(materialname, basestring)
58       # vertex_dict[] == dicts; keys = materialnames
59       # vertex_dict[matname]["actors"] == list of actornames
60       # vertex_dict[matname]["tverts"] == list of vertices for this material
61       for line in tvertex_dict.get(materialname).get("tverts"):
62           points = " ".join(["{},{}".format(v[0], height - v[1]) for v in line])
63           yield '<polygon points="%s" style="fill:rgb(%s, %s, %s);stroke:black;stroke-width:1" />' \
64                 % (points, color[0], color[1], color[2])
65   
66   
67   def minmax(figure, scale):
68       assert isinstance(figure, poser.FigureType)
69       minv = [100000, 100000]
70       maxv = [-100000, -100000]
71       for geom in [_ac.Geometry() for _ac in figure.Actors() if acceptableActor(_ac)]:
72           for tv in geom.TexVertices():
73               if tv.U() < minv[0]:
74                   minv[0] = tv.U()
75               elif tv.U() > maxv[0]:
76                   maxv[0] = tv.U()
77               if tv.V() < minv[1]:
78                   minv[1] = tv.V()
79               elif tv.V() > maxv[1]:
80                   maxv[1] = tv.V()
81       return [minv[0] * scale, minv[1] * scale], [maxv[0] * scale, maxv[1] * scale]
82   
83   
84   def FigureUV_2_SVG(figure, scale=100, stream=None):
85       """stream == filehandle. Must have a write function."""
86       assert isinstance(figure, poser.FigureType)
87       assert hasattr(stream, "write")
88   
89       vertex_dict = get_texVertices(figure, scale=scale)
90       _, maxv = minmax(figure, scale)
91       maxv[0] += 220
92       materials = []
93       stream.write('<svg width="%s" height="%s" xmlns="http://www.w3.org/2000/svg">\n' % tuple(maxv))
94       for idx, mat in enumerate(vertex_dict.keys()):
95           r = randint(128, 255)
96           g = randint(128, 255)
97           b = randint(128, 255)
98           materials.append(((r, g, b), mat))
99           for line in svg_polyline(vertex_dict, mat, (r, g, b), maxv[1]):
100              stream.write(line + "\n")
101  
102      style = "<style>\n" \
103             ".mat {font: bold 30px; background: #a0a0a0}\n" \
104             "</style>\n"
105      stream.write(style)
106      ofs = 30
107      xpos = maxv[0] -180
108      ypos = 100
109      while ypos < maxv[1]:
110          for idx, mat in enumerate(materials):
111              c = ",".join(map(str, mat[0]))
112              stream.write('<rect x="%s" y="%s" width="200" height="25" style="fill: rgb(%s)"/>\n' % (xpos - 20, ypos, c))
113              stream.write('<text x="%s" y="%s" class="mat" fill="black">%s</text>\n' % (xpos, ypos+20,  mat[1]))
114              ypos += ofs
115          ypos += ofs * 2
116  
117      stream.write("</svg>\n")
118  
119  svg_file = os.path.join(poser.TempLocation(), "temp.svg")
120  with open(svg_file, "w") as fh:
121      FigureUV_2_SVG(SCENE.CurrentFigure(), scale=1000, stream=fh)
122  
123  if os.path.exists(svg_file):
124      import webbrowser
125      webbrowser.open(svg_file, new=2)
126  
127