Skip to content

Instantly share code, notes, and snippets.

@JFlynnXYZ
Last active March 20, 2024 11:25
Show Gist options
  • Save JFlynnXYZ/98d6c6b4a7fd43dcd77e33229ff1cb9c to your computer and use it in GitHub Desktop.
Save JFlynnXYZ/98d6c6b4a7fd43dcd77e33229ff1cb9c to your computer and use it in GitHub Desktop.
Code to convert a Maya Polygon object's UV's to an SVG render vector uvs
import maya.api.OpenMaya as om
import maya.cmds as cmds
import os.path
import svgwrite
STROKE_LINECAP = ("butt", "round", "square")
def check_reverse_line_drawn(newLineCoords, drawnLines):
reverseLineCoords = (newLineCoords[1], newLineCoords[0])
if reverseLineCoords in drawnLines:
return True
else:
return False
def convertLsToOpenMayaSelLs(ls):
"""
Converts a normal Python list (one that is commonly recieved
from maya.cmds.ls) to an OpenMaya selection list.
:param ls: list
The python list containing all selected items
:return OpenMaya.MSelectionList for the python list:
"""
if not hasattr(ls, "__iter__"):
ls = [ls]
selLs = om.MSelectionList()
for o in ls:
print o
selLs.add(o)
return selLs
defaultLineAtts = {"stroke_linecap": STROKE_LINECAP[0]}
def renderVectorUVs(objs=None, res=4096, strokeWidth=8, lineAtts=defaultLineAtts, lineColor=(0, 0, 0), drawText=False,
fontsize=1, drawCircles=False, circleRad=0.3):
if objs is None:
selection = om.MGlobal.getActiveSelectionList()
else:
selection = convertLsToOpenMayaSelLs(objs)
startDir = cmds.file(q=True, loc=True)
if startDir == "unknown":
startDir = os.path.expanduser("~")
else:
startDir = os.path.dirname(startDir)
for x in xrange(selection.length()):
dagPath = selection.getDagPath(x)
shapePath = selection.getDagPath(x).extendToShape()
mesh = om.MFnMesh(shapePath.node())
fileDir = os.path.join(startDir, str(dagPath))
fileOut = cmds.fileDialog2(fm=0, fileFilter="SVG File (*.svg)", dir=fileDir,
cap="Save UV SVG for model: {}".format(dagPath))
if fileOut != None:
fileOut = fileOut[0]
dwg = svgwrite.Drawing(fileOut, profile='full', size=(str(res) + 'px', str(res) + 'px'))
for uv in mesh.getUVSetNames():
texCoordListU, texCoordListV = mesh.getUVs(uv)
numUvsAssignedPerFace, uvIdsForFaceVertices = mesh.getAssignedUVs(uv)
if drawText or drawCircles:
for i in range(len(texCoordListU)):
coords = (texCoordListU[i] * res, ((1 - texCoordListV[i])) * res)
txtCoords = (coords[0] + circleRad / 2, coords[1] - circleRad / 2)
if drawCircles:
dwg.add(dwg.circle(coords, r=circleRad))
if drawText:
dwg.add(dwg.text(str(i), insert=txtCoords, fill="black", font_size=fontsize))
count = 0
drawnLines = []
for numUvIds in numUvsAssignedPerFace:
for i in range(numUvIds):
if i + count + 1 <= len(uvIdsForFaceVertices):
sId = uvIdsForFaceVertices[i + count]
if i == numUvIds - 1:
eId = uvIdsForFaceVertices[0 + count]
else:
eId = uvIdsForFaceVertices[i + count + 1]
if not check_reverse_line_drawn((eId, sId), drawnLines):
startCoords = (texCoordListU[sId] * res, ((1 - texCoordListV[sId])) * res)
endCoords = (texCoordListU[eId] * res, ((1 - texCoordListV[eId])) * res)
dwg.add(dwg.line(startCoords, endCoords, stroke=svgwrite.rgb(*list(lineColor) + ['%']),
stroke_width=strokeWidth, **lineAtts))
drawnLines.append((eId, sId))
count += numUvIds
dwg.save()
del dwg
renderVectorUVs()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment