Skip to content

Instantly share code, notes, and snippets.

@rafaelperez
Created September 18, 2018 20:07
Show Gist options
  • Save rafaelperez/f3fb3fc48688ac48cab702ba96970426 to your computer and use it in GitHub Desktop.
Save rafaelperez/f3fb3fc48688ac48cab702ba96970426 to your computer and use it in GitHub Desktop.
import xml.etree.ElementTree as ET
import threading, re, struct, time
#Create the svg to roto class
class SvgRoto(threading.Thread):
def __init__(self, file, maxShapes=300, renderHidden=False):
threading.Thread.__init__(self)
#the file name
self.file = file
#list of all of the shapes
self.shapes = []
#maximum number of shapes
self.maxShapes = maxShapes
#render hidden SVG groups
self.renderHidden = renderHidden
#load the SVG file
self._loadSVG()
#parse the SVG file
self._parseSVG(self.svg)
#update nuke progress and kill it if the bar is at 100%
def _updateProgress(self, progress, message=None):
if message:
self.progressBar.setMessage(message)
self.progressBar.setProgress(progress)
if progress == 100:
del(self.progressBar)
#execute in main thread
def execute(self, func, *kwargs):
nuke.executeInMainThread(func, kwargs)
#execute in main thread with results
def rexecute(self, func, *kwargs):
return nuke.executeInMainThreadWithResult(func, kwargs)
#apparently not needed as Nuke seems to accept float values for vertex positions, but will keep it here just in case something changes in the future
def float2Hex(self, val):
#return hex(struct.unpack('<I', struct.pack('f', val))[0]).replace('0x','x')
return str(val)
#draw the vector shapes
def draw(self):
#width and height of the SVG canvas
h = self.format.height()
w = self.format.width()
#create the RotoPaint node
self._createRotoNode()
#strings containing parts of the nodes for version 6 and for version 7 and above
if nuke.NUKE_VERSION_MAJOR > 6:
curvesStringTemplate = 'AddMode 0 0 0 0 {{v x3f99999a}\n {f 0}\n {n\n {layer Root\n {f 0}\n {t ROOT_POS_X ROOT_POS_Y}\n {a}\n SHAPE_STRINGS}}}}'
shapeStringTemplate = '{curvegroup SHAPE_NAME 512 bezier\n {{cc\n {f 8192}\n {px x41880000\nSHAPE_POINTS}} idem}\n {tx 0 SHAPE_POS_X SHAPE_POS_Y}\n {a vis 1 r RED g GREEN b BLUE a ALPHA str 1 ss 0}}'
else:
curvesStringTemplate = 'AddMode 0 1 0 7 Bezier1 AnimTree: "" {\n Version: 1.2\n Flag: 0\n RootNode: 1\n Node: {\n NodeName: "Root" {\n Flag: 512\n NodeType: 1\n Transform: 0 0 S 0 0 S 0 0 S 0 0 S 0 1 S 0 1 S 0 0 S 0 ROOT_POS_X S 0 ROOT_POS_Y \n NumOfAttributes: 11\n "vis" S 0 1 "opc" S 0 1 "mbo" S 0 1 "mb" S 0 1 "mbs" S 0 0.5 "fo" S 0 1 "fx" S 0 0 "fy" S 0 0 "ff" S 0 1 "ft" S 0 0 "pt" S 0 0 \n }\n NumOfChildren: NUM_SHAPES\n SHAPE_STRINGS\n }\n}'
shapeStringTemplate = 'Node: {\n NodeName: "SHAPE_NAME" {\n Flag: 576\n NodeType: 3\n CurveGroup: "" {\n Transform: 0 0 S 1 1 0 S 1 1 0 S 1 1 0 S 1 1 1 S 1 1 1 S 1 1 0 S 1 1 SHAPE_POS_X S 1 1 SHAPE_POS_Y \n Flag: 0\n NumOfCubicCurves: 2\n CubicCurve: "" {\n Type: 0 Flag: 8192 Dim: 2\n NumOfPoints: SHAPE_NUM_POINTS\n SHAPE_POINTS \n }\n CubicCurve: "" {\n Type: 0 Flag: 8192 Dim: 2\n NumOfPoints: SHAPE_NUM_POINTS\n FSHAPE_POINTS \n }\n NumOfAttributes: 44\n "vis" S 0 1 "r" S 0 RED "g" S 0 GREEN "b" S 0 BLUE "a" S 0 ALPHA "ro" S 0 0 "go" S 0 0 "bo" S 0 0 "ao" S 0 0 "opc" S 0 1 "bm" S 0 0 "inv" S 0 0 "mbo" S 0 0 "mb" S 0 1 "mbs" S 0 0.5 "mbsot" S 0 0 "mbso" S 0 0 "fo" S 0 1 "fx" S 0 0 "fy" S 0 0 "ff" S 0 1 "ft" S 0 0 "src" S 0 0 "stx" S 0 0 "sty" S 0 0 "str" S 0 0 "sr" S 0 0 "ssx" S 0 1 "ssy" S 0 1 "ss" S 0 0 "spx" S 0 1024 "spy" S 0 778 "stot" S 0 0 "sto" S 0 0 "sv" S 0 0 "sf" S 0 1 "sb" S 0 1 "nv" S 0 1 "view1" S 0 1 "ltn" S 0 1 "ltm" S 0 1 "ltt" S 0 0 "tt" S 0 4 "pt" S 0 0 \n }\n }\n NumOfChildren: 0\n }'
shapeStrings = ''
curvesString = curvesStringTemplate
cnt=0
#iterate through the shapes and create the node
for shapeData in self.shapes:
shapeString = shapeStringTemplate
shapePoints = ''
fshapePoints = ''
#calculate the bounding box to get the center for the pivot
maxX = max(t[0] for t in shapeData['path'][0])
minX = min(t[0] for t in shapeData['path'][0])
centerX = minX+(maxX - minX)/2
maxY = max(t[1] for t in shapeData['path'][0])
minY = min(t[1] for t in shapeData['path'][0])
centerY = h-(minY+(maxY - minY)/2)
#iterate through all the positions (points and tangents) and create the shape part of the node
for i in range(len(shapeData['path'][0])):
shapeData['path'][0][i] = (self.float2Hex(shapeData['path'][0][i][0]), self.float2Hex(h-shapeData['path'][0][i][1]))
shapeData['path'][1][i] = (self.float2Hex(shapeData['path'][1][i][0]), self.float2Hex(-shapeData['path'][1][i][1]))
shapeData['path'][2][i] = (self.float2Hex(shapeData['path'][2][i][0]), self.float2Hex(-shapeData['path'][2][i][1]))
if nuke.NUKE_VERSION_MAJOR > 6:
shapePoints += '\n {' + shapeData['path'][1][i][0] +' '+ shapeData['path'][1][i][1] + '}\n {' + shapeData['path'][0][i][0] +' '+ shapeData['path'][0][i][1] + '}\n {' + shapeData['path'][2][i][0] +' '+ shapeData['path'][2][i][1] + '}'
else:
shapePoints += '0 S 1 1 ' + shapeData['path'][1][i][0] +' S 1 1 '+ shapeData['path'][1][i][1] + ' 0 0 S 1 1 ' + shapeData['path'][0][i][0] +' S 1 1 '+ shapeData['path'][0][i][1] + ' 0 0 S 1 1 ' + shapeData['path'][2][i][0] +' S 1 1 '+ shapeData['path'][2][i][1] + ' 0 '
fshapePoints += '0 S 1 1 ' + shapeData['path'][1][i][0] +' S 1 1 '+ shapeData['path'][1][i][1] + ' 0 0 S 1 1 0 S 1 1 0 0 0 S 1 1 ' + shapeData['path'][2][i][0] +' S 1 1 '+ shapeData['path'][2][i][1] + ' 0 '
#replace all the strings (this could be replaced to use format instead of replace)
shapeString = shapeString.replace('SHAPE_NUM_POINTS', str(len(shapeData['path'][0])*3))
shapeString = shapeString.replace('FSHAPE_POINTS', fshapePoints)
shapeString = shapeString.replace('SHAPE_POINTS', shapePoints)
shapeString = shapeString.replace('RED', self.float2Hex(shapeData['color'][0]))
shapeString = shapeString.replace('GREEN', self.float2Hex(shapeData['color'][1]))
shapeString = shapeString.replace('BLUE', self.float2Hex(shapeData['color'][2]))
shapeString = shapeString.replace('ALPHA', self.float2Hex(shapeData['color'][3]))
shapeString = shapeString.replace('SHAPE_NAME', 'Shape'+str(cnt))
shapeString = shapeString.replace('SHAPE_POS_X', str(centerX))
shapeString = shapeString.replace('SHAPE_POS_Y', str(centerY))
shapeStrings = shapeString + shapeStrings
cnt += 1
#replace the root node position and append the shapes
curvesString = curvesString.replace('ROOT_POS_X', str(w/2.0)).replace('ROOT_POS_Y', str(h/2.0))
curvesString = curvesString.replace('SHAPE_STRINGS', shapeStrings)
curvesString = curvesString.replace('NUM_SHAPES', str(len(self.shapes)))
#update the progress bar
self._updateProgress(99, 'Creating Shapes')
#create the node
self.curves.fromScript(curvesString)
#set the svg format (will take into account only pixel dimensions not relative ones like pt or em)
def _setFormat(self):
format = None
#first try finding the width/height attributes
try:
w, h = [int(round(float(self.svg.attrib['width'].replace('px', '')))), int(round(float(self.svg.attrib['height'].replace('px', ''))))]
except Exception, err:
#if that fails, try with the viewBox
try:
view = [float(dimm) for dimm in self.svg.attrib['viewBox'].replace('px', '').split(' ')]
w, h = [int(round(view[2]-view[0])), int(round(view[3]-view[1]))]
#if that fails, put the nuke root format as format dimensions
except:
w, h = [nuke.Root().format().width(), nuke.Root().format().height()]
#create the format if it doesn't exist
for f in nuke.formats():
if f.width() == w and f.height() == h:
format = f
break
if not format:
format = nuke.addFormat( str(w)+' '+str(h)+' 1.0 '+ str(w) + 'x' + str(h) )
self.format = format
#load the SVG xml file
def _loadSVG(self):
xml = ET.parse(self.file)
root = xml.getroot()
self.xml = xml
self.svg = root
#set the svg format
self._setFormat()
#create the roto node
def _createRotoNode(self):
self.node = nuke.createNode('RotoPaint')
self.curves = self.node['curves']
self.node['format'].setValue(self.format)
#convert hex color values to rgb
def _hex2rgb(self, value):
try:
value = value.lstrip('#')
lv = len(value)
if lv == 3:
value = ''.join([c*2 for c in list(value)])
lv = len(value)
return tuple(int(value[i:i + lv // 3], 16)/255.0 for i in range(0, lv, lv // 3))
except:
return (1,1,1)
#parse the SVG square shape
def _parseSVGSquare(self, node):
w = float(node.attrib['width'])
h = float(node.attrib['height'])
x = float(node.attrib['x']) if 'x' in node.keys() else 0
y = float(node.attrib['y']) if 'y' in node.keys() else x
rx = float(node.attrib['rx']) if 'rx' in node.keys() else None
ry = float(node.attrib['ry']) if 'ry' in node.keys() else rx
if not rx:
rx = ry
#draw the SVG square shape
shape = self.squareShape(w, h, x, y, rx, ry)
#append results to the shapes list
self.shapes.append({'path':shape, 'color':self._getSVGNodeColor(node)})
#parse the SVG circle shape
def _parseSVGCircle(self, node):
w = float(node.attrib['r'])
x = float(node.attrib['cx']) if 'cx' in node.keys() else 0
y = float(node.attrib['cy']) if 'cy' in node.keys() else x
#draw the SVG circle shape
shape = self.ellipseShape(w, w, x=x,y=y)
#append results to the shapes list
self.shapes.append({'path':shape, 'color':self._getSVGNodeColor(node)})
#parse the SVG ellipse shape
def _parseSVGEllipse(self, node):
w = float(node.attrib['rx'])
h = float(node.attrib['ry'])
x = float(node.attrib['cx']) if 'cx' in node.keys() else 0
y = float(node.attrib['cy']) if 'cy' in node.keys() else x
#draw the SVG ellipse shape
shape = self.ellipseShape(w, h, x=x,y=y)
#append results to the shapes list
self.shapes.append({'path':shape, 'color':self._getSVGNodeColor(node)})
#parse the SVG polygon shape
def _parseSVGPolygon(self, node):
path = self._tokenizeSVGCoords(node.attrib['points'])
pos = []
ltan = []
rtan = []
for i in range(len(path)):
if i%2 == 0:
pos.append((path[i], path[i+1]))
ltan.append((0,0))
rtan.append((0,0))
#append results to the shapes list
self.shapes.append({'path':[pos, ltan, rtan], 'color':self._getSVGNodeColor(node)})
#parse the path coordiantes and return a list of broken into commands and values
def _tokenizeSVGCoords(self, pathstring):
commands = 'MmZzLlHhVvCcSsQqTtAa'
commandsList = set(commands)
commandsRe = re.compile("(["+commands+"])")
valueRe = re.compile("[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?")
path = []
for item in commandsRe.split(pathstring):
if item in commandsList:
path.append(item)
for value in valueRe.findall(item):
path.append(float(value))
return path
#parse the SVG path shape
def _parseSVGPath(self, node):
#parse the path tokens, the arc token is not parsed, as it would take too much time to create the arc path command in nuke and it rarely used
#however if you want to do it feel free to write that piece of code :)
path = self._tokenizeSVGCoords(node.attrib['d'])
p0 = p1 = (0,0)
pos = []
ltan = []
rtan = []
startPath = True
for i in range(len(path)):
if isinstance('m', basestring):
if path[i] in ['M', 'm']:
#start a path
if startPath:
startPath = False
alpha = False
else:
alpha = True
if path[i].istitle():
p0 = (path[i+1], path[i+2])
else:
p0 = (p0[0]+path[i+1], p0[1]+path[i+2])
pos.append(p0)
ltan.append((0,0))
rtan.append((0,0))
elif path[i] in ['L', 'l']:
if path[i].istitle():
p2 = (path[i+1], path[i+2])
else:
p2 = (p0[0]+path[i+1], p0[1]+path[i+2])
pos.append(p2)
ltan.append((0,0))
rtan.append((0,0))
p0 = p2
elif path[i] in ['H', 'h']:
if path[i].istitle():
p2 = (path[i+1], p0[1])
else:
p2 = (p0[0]+path[i+1], p0[1])
pos.append(p2)
ltan.append((0,0))
rtan.append((0,0))
p0 = p2
elif path[i] in ['V', 'v']:
if path[i].istitle():
p2 = (p0[0], path[i+1])
else:
p2 = (p0[0], p0[1]+path[i+1])
pos.append(p2)
ltan.append((0,0))
rtan.append((0,0))
p0 = p2
elif path[i] in ['C', 'c']:
if path[i].istitle():
t1 = (path[i+1]-p0[0], path[i+2]-p0[1])
p2 = (path[i+5], path[i+6])
t2 = (path[i+3]-p2[0], path[i+4]-p2[1])
else:
t1 = (path[i+1], path[i+2])
p2 = (p0[0]+path[i+5], p0[1]+path[i+6])
t2 = (path[i+3]-path[i+5], path[i+4]-path[i+6])
pos.append(p2)
ltan.append(t2)
rtan[-1] = t1
rtan.append((0,0))
p0 = p2
elif path[i] in ['S', 's']:
if path[i].istitle():
t1 = (-t2[0], -t2[1])
p2 = (path[i+3], path[i+4])
t2 = (path[i+1]-p2[0], path[i+2]-p2[1])
else:
t1 = (-t2[0], -t2[1])
p2 = (p0[0]+path[i+3], p0[1]+path[i+4])
t2 = (path[i+1]-path[i+3], path[i+2]-path[i+4])
pos.append(p2)
ltan.append(t2)
rtan[-1] = t1
rtan.append((0,0))
p0 = p2
elif path[i] in ['Q', 'q']:
if path[i].istitle():
p1 = (path[i+1], path[i+2])
p2 = (path[i+3], path[i+4])
else:
p1 = (p0[0]+path[i+1], p0[1]+path[i+2])
p2 = (p0[0]+path[i+3], p0[1]+path[i+4])
t1x = p0[0] + 0.666 *(p1[0]-p0[0])
t1y = p0[1] + 0.666 *(p1[1]-p0[1])
t2x = p2[0] + 0.666 *(p1[0]-p2[0])
t2y = p2[1] + 0.666 *(p1[1]-p2[1])
t1 = (t1x-p0[0], t1y-p0[1])
t2 = (t2x-p2[0],t2y-p2[1])
pos.append(p2)
ltan.append(t2)
rtan[-1] = t1
rtan.append((0,0))
p0 = p2
elif path[i] in ['T', 't']:
if path[i].istitle():
p2 = (path[i+1], path[i+2])
else:
p2 = (p0[0]+path[i+1], p0[1]+path[i+2])
t1 = (-t2[0], -t2[1])
t2 = (-t2[1], t2[0])
pos.append(p2)
ltan.append(t2)
rtan[-1] = t1
rtan.append((0,0))
p0 = p2
elif path[i] in ['z','Z'] or i == len(path)-1:
self.shapes.append({'path':[pos,ltan,rtan], 'color':self._getSVGNodeColor(node, alpha=alpha)})
pos = []
ltan = []
rtan = []
if i == len(path)-1:
break
#get ellipse nuke coords
def ellipseShape(self, w,h, x=0,y=0):
pos = [(x,-h+y), (-w+x, y), (x,h+y), (w+x,y)]
ltan = [(w*0.55,0), (0,-h*0.55), (-w*0.55,0), (0,h*0.55)]
rtan = [(-w*0.55,0), (0,h*0.55), (w*0.55,0), (0,-h*0.55)]
return [pos, ltan, rtan]
#get square nuke coords
def squareShape(self, w,h, x=0,y=0, xr=0,yr=0):
if xr !=0 and yr ==0:
yr = xr
elif xr==0 and yr != 0:
xr = yr
if xr!=0 or yr!=0:
pos = [(x,y+yr), (x, y+h-yr), (x+xr,y+h),(x+w-xr,y+h), (x+w,y+h-yr), (x+w, y+yr), (x+w-xr, y), (x+xr, y)]
ltan = [(0, -yr/2), (0,0), (-xr/2, 0), (0,0), (0,yr/2), (0,0), (xr/2,0), (0,0)]
rtan = [(0,0), (0,yr/2), (0,0), (xr/2, 0), (0,0), (0,-yr/2), (0,0), (-xr/2,0)]
else:
pos = [(x,y), (x, y+h), (x+w,y+h), (x+w, y)]
ltan = [(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0)]
rtan = [(0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0), (0,0)]
return [pos, ltan, rtan]
#get svg node color, includes a list of web colors, alpha is defined based on the subpath, subpaths will have alpha to allow for holes, however the Nuke node will just make the whole through the alpha not just through the selected shape, so it will not work exactly like in the SVG file.
def _getSVGNodeColor(self, node, alpha = False):
webcolors = {'aliceblue':'#f0f8ff','antiquewhite':'#faebd7','aqua':'#00ffff','aquamarine':'#7fffd4','azure':'#f0ffff','beige':'#f5f5dc','bisque':'#ffe4c4','black':'#000000','blanchedalmond':'#ffebcd','blue':'#0000ff','blueviolet':'#8a2be2','brown':'#a52a2a','burlywood':'#deb887','cadetblue':'#5f9ea0','chartreuse':'#7fff00','chocolate':'#d2691e','coral':'#ff7f50','cornflowerblue':'#6495ed','cornsilk':'#fff8dc','crimson':'#dc143c','cyan':'#00ffff','darkblue':'#00008b','darkcyan':'#008b8b','darkgoldenrod':'#b8860b','darkgray':'#a9a9a9','darkgreen':'#006400','darkkhaki':'#bdb76b','darkmagenta':'#8b008b','darkolivegreen':'#556b2f','darkorange':'#ff8c00','darkorchid':'#9932cc','darkred':'#8b0000','darksalmon':'#e9967a','darkseagreen':'#8fbc8f','darkslateblue':'#483d8b','darkslategray':'#2f4f4f','darkturquoise':'#00ced1','darkviolet':'#9400d3','deeppink':'#ff1493','deepskyblue':'#00bfff','dimgray':'#696969','dodgerblue':'#1e90ff','firebrick':'#b22222','floralwhite':'#fffaf0','forestgreen':'#228b22','fuchsia':'#ff00ff','gainsboro':'#dcdcdc','ghostwhite':'#f8f8ff','gold':'#ffd700','goldenrod':'#daa520','gray':'#808080','green':'#008000','greenyellow':'#adff2f','honeydew':'#f0fff0','hotpink':'#ff69b4','indianred':'#cd5c5c','indigo':'#4b0082','ivory':'#fffff0','khaki':'#f0e68c','lavender':'#e6e6fa','lavenderblush':'#fff0f5','lawngreen':'#7cfc00','lemonchiffon':'#fffacd','lightblue':'#add8e6','lightcoral':'#f08080','lightcyan':'#e0ffff','lightgoldenrodyellow':'#fafad2','lightgray':'#d3d3d3','lightgreen':'#90ee90','lightpink':'#ffb6c1','lightsalmon':'#ffa07a','lightseagreen':'#20b2aa','lightskyblue':'#87cefa','lightslategray':'#778899','lightsteelblue':'#b0c4de','lightyellow':'#ffffe0','lime':'#00ff00','limegreen':'#32cd32','linen':'#faf0e6','magenta':'#ff00ff','maroon':'#800000','mediumaquamarine':'#66cdaa','mediumblue':'#0000cd','mediumorchid':'#ba55d3','mediumpurple':'#9370db','mediumseagreen':'#3cb371','mediumslateblue':'#7b68ee','mediumspringgreen':'#00fa9a','mediumturquoise':'#48d1cc','mediumvioletred':'#c71585','midnightblue':'#191970','mintcream':'#f5fffa','mistyrose':'#ffe4e1','moccasin':'#ffe4b5','navajowhite':'#ffdead','navy':'#000080','oldlace':'#fdf5e6','olive':'#808000','olivedrab':'#6b8e23','orange':'#ffa500','orangered':'#ff4500','orchid':'#da70d6','palegoldenrod':'#eee8aa','palegreen':'#98fb98','paleturquoise':'#afeeee','palevioletred':'#db7093','papayawhip':'#ffefd5','peachpuff':'#ffdab9','peru':'#cd853f','pink':'#ffc0cb','plum':'#dda0dd','powderblue':'#b0e0e6','purple':'#800080','red':'#ff0000','rosybrown':'#bc8f8f','royalblue':'#4169e1','saddlebrown':'#8b4513','salmon':'#fa8072','sandybrown':'#f4a460','seagreen':'#2e8b57','seashell':'#fff5ee','sienna':'#a0522d','silver':'#c0c0c0','skyblue':'#87ceeb','slateblue':'#6a5acd','slategray':'#708090','snow':'#fffafa','springgreen':'#00ff7f','steelblue':'#4682b4','tan':'#d2b48c','teal':'#008080','thistle':'#d8bfd8','tomato':'#ff6347','turquoise':'#40e0d0','violet':'#ee82ee','wheat':'#f5deb3','white':'#ffffff','whitesmoke':'#f5f5f5','yellow':'#ffff00','yellowgreen':'#9acd32','none':'#ffffff'}
val = '#000000'
if 'style' in node.keys():
styles = dict([(style.split(':')[0].strip(), style.split(':')[1].strip()) for style in filter(None, node.attrib['style'].split(';'))])
if 'fill' in styles.keys():
val = styles['fill']
elif 'fill' in node.keys():
val = node.attrib['fill']
if val.lower() in webcolors.keys():
val = webcolors[val.lower()]
r,g,b = self._hex2rgb(val)
if alpha:
a = 0.0
else:
a = 1.0
return [r, g, b, a]
#set the color on the node
def setColor(self, shape, color):
try:
red, green, blue, alpha = color
shape.getAttributes().set('r', red)
shape.getAttributes().set('g', green)
shape.getAttributes().set('b', blue)
shape.getAttributes().set('a', alpha)
except Exception, err:
print err
#start parsing the SVG file
def _parseSVG(self, root):
for node in root:
alpha = False
if node.tag.split('}')[1] == 'g':
if 'display' in node.keys():
if not node.attrib['display'] == 'none' or self.renderHidden:
self._parseSVG(node)
else:
self._parseSVG(node)
elif node.tag.split('}')[1] == 'rect':
self._parseSVGSquare(node)
elif node.tag.split('}')[1] == 'circle':
shape = self._parseSVGCircle(node)
elif node.tag.split('}')[1] == 'ellipse':
shape = self._parseSVGEllipse(node)
elif node.tag.split('}')[1] == 'polygon':
shape = self._parseSVGPolygon(node)
elif node.tag.split('}')[1] == 'path':
shape = self._parseSVGPath(node)
#run the script in a new thread
def run(self):
self.progressBar = nuke.ProgressTask('SVG RotoPaint')
self._updateProgress(1, 'SVG RotoPaint - Parsing the file')
self.rexecute( self.draw, )
self._updateProgress(100, 'Finished')
file = nuke.getFilename('Load Svg to RotoPaint', '*.svg')
if file:
SvgRoto(file).run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment