#!/usr/bin/env python # These two lines are only needed if you don't put the script directly into # the installation directory import sys sys.path.append('/usr/share/inkscape/extensions') import math import subprocess #We will call Inkscape to compute the bounding box import inkex from simplestyle import * import simpletransform class clonesPerspectiveEffect(inkex.Effect): """ Creates a series of clones shrinking to a vanishing point. The vanishing point is the center of rotation, which must be dragged out to the side before invocation. """ def __init__(self): """ Constructor. Defines the parms option of a script. """ # Call the base class constructor. inkex.Effect.__init__(self) # Define string option "--what" with "-w" shortcut and default value "World". self.OptionParser.add_option('-n', '--num', action = 'store', type = 'int', dest = 'num', default = 5, help = 'Drag out center of rotation before calling') self.OptionParser.add_option('-r', '--ratio', action = 'store', type = 'float', dest = 'ratio', default = 0.9, help = 'Ratio of size of nearest neighbor to first. Must be < 1') def effect(self): """ Effect behaviour. Overrides base class' method. """ global boxstring global seld svg = self.document.getroot() num = int( self.options.num ) ratio = float( self.options.ratio ) seld = self.selected if 1 != len(seld) : inkex.errormsg("Select exactly 1 thing. Group if necessary") sys.exit (1) id = seld.keys()[0] sel = seld[id] dic = sel.attrib try : tx = dic[inkex.addNS('transform-center-x','inkscape') ] except KeyError : tx = '0.' try : ty = dic[inkex.addNS('transform-center-y','inkscape') ] except KeyError : ty = '0.' if float(tx) == 0. and float(ty) == 0. : inkex.errormsg("Center of rotation at center of object") sys.exit (1) thebox = simpletransform.computeBBox([sel]) width = thebox[1] - thebox[0] height = thebox[3] - thebox[2] cx = float(thebox[0]) + 0.5 * width #Find center of selected object cy = float(thebox[2]) + 0.5 * height #Find center of selected object tx = float(tx) ty = float(ty) crat = 1.0 otx = tx oty = ty parent = self.getParentNode(sel) j = parent.index(sel) for i in range(num) : crat *= ratio tx *= ratio ty *= ratio att = { "id" : self.uniqueId("clone" + id), inkex.addNS('href','xlink') : "#" + id, inkex.addNS('transform-center-x','inkscape') : str(tx), inkex.addNS('transform-center-y','inkscape') : str(ty), # "x" : "0", # "y" : "0", 'transform' : ("matrix(%f,0,0,%f,%f,%f)" % (crat, crat,(1. - crat)*(cx + otx), (1. - crat)*(cy - oty))), #WHY Inkscape and SVG run +y in OPPOSITE directions is BEYOND me. "width" : "100%", "height" : "100%", } parent.insert(j, inkex.etree.Element('use', att) ) # Create effect instance and apply it. effect = clonesPerspectiveEffect() effect.affect() sys.exit( 0 )