Added option to specify custom length to scale up a path to desired
length
This commit is contained in:
parent
a9adc3d322
commit
6b687774c7
@ -2,23 +2,27 @@
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Scale To Path Length</name>
|
||||
<id>fablabchemnitz.de.paste_length</id>
|
||||
<param name="tab" type="notebook">
|
||||
<page name="pasteLength" gui-text="Paste Length">
|
||||
<param name="scaleFrom" type="optiongroup" appearance="combo" gui-text="Scale From:">
|
||||
<option value="center">Center</option>
|
||||
<option value="topLeft">Top Left</option>
|
||||
<option value="topRight">Top Right</option>
|
||||
<option value="bottomLeft">Bottom Left</option>
|
||||
<option value="bottomRight">Bottom Right</option>
|
||||
</param>
|
||||
<param name="scale" type="float" gui-text="Scale Factor:">1</param>
|
||||
<param name="precision" type="int" default="5" min="0" max="10" gui-text="Precision:">5</param>
|
||||
</page>
|
||||
<page name="desc" gui-text="Help">
|
||||
<param name="pasteLengthhelp" type="description" xml:space="preserve">This effect makes the length of all the destination paths the same as that of the source path, while maintaining their shapes. The source is the topmost path in the selection. Precision field denotes the number of significant digits, to which the length is rounded.
|
||||
</param>
|
||||
</page>
|
||||
<param name="scaleFrom" type="optiongroup" appearance="combo" gui-text="Scale From:">
|
||||
<option value="center">Center</option>
|
||||
<option value="topLeft">Top Left</option>
|
||||
<option value="topRight">Top Right</option>
|
||||
<option value="bottomLeft">Bottom Left</option>
|
||||
<option value="bottomRight">Bottom Right</option>
|
||||
</param>
|
||||
<param name="scale" type="float" precision="3" gui-text="Scale Factor:">1</param>
|
||||
<param name="precision" type="int" default="5" min="0" max="10" gui-text="Precision:">5</param>
|
||||
<param name="override_selection" type="bool" gui-text="Use entered length" gui-description="Use a custom length instead using the length of the first object in selection">false</param>
|
||||
<param name="custom_length" type="float" min="0.001" max="99999.000" precision="3" gui-text="Custom length">100.000</param>
|
||||
<param name="unit" type="optiongroup" appearance="combo" gui-text="Units">
|
||||
<option value="mm">mm</option>
|
||||
<option value="cm">cm</option>
|
||||
<option value="in">in</option>
|
||||
<option value="pt">pt</option>
|
||||
<option value="px">px</option>
|
||||
<option value="pc">pc</option>
|
||||
</param>
|
||||
<spacer/>
|
||||
<label>This effect makes the length of all the destination paths the same as that of the source path (or your custom desired input length), while maintaining their shapes. The source is the topmost path in the selection. Precision field denotes the number of significant digits, to which the length is rounded. </label>
|
||||
<effect>
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
|
@ -22,8 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
'''
|
||||
|
||||
import inkex
|
||||
from inkex import bezier
|
||||
from inkex.paths import Path, CubicSuperPath
|
||||
|
||||
from inkex import bezier, Path, CubicSuperPath, PathElement
|
||||
|
||||
class PasteLengthEffect(inkex.Effect):
|
||||
|
||||
@ -32,7 +32,9 @@ class PasteLengthEffect(inkex.Effect):
|
||||
self.arg_parser.add_argument('--scale', type = float, default = '1', help = 'Additionally scale the length by')
|
||||
self.arg_parser.add_argument('--scaleFrom', default = 'center', help = 'Scale Path From')
|
||||
self.arg_parser.add_argument('--precision', type = int, default = '5', help = 'Number of significant digits')
|
||||
self.arg_parser.add_argument("--tab", default="sampling", help="Tab")
|
||||
self.arg_parser.add_argument("--override_selection", type = inkex.Boolean, default = False, help = "Use a custom length instead using the length of the first object in selection")
|
||||
self.arg_parser.add_argument("--custom_length", type = float, default = 100.000, help = "Custom length")
|
||||
self.arg_parser.add_argument("--unit", default = "mm", help = "Units")
|
||||
|
||||
def scaleCubicSuper(self, cspath, scaleFactor, scaleFrom):
|
||||
bbox = Path(cspath).bounding_box()
|
||||
@ -86,27 +88,39 @@ class PasteLengthEffect(inkex.Effect):
|
||||
scaleFrom = self.options.scaleFrom
|
||||
tolerance = 10 ** (-1 * self.options.precision)
|
||||
selections = self.svg.selected
|
||||
pathNodes = self.document.xpath('//svg:path',namespaces=inkex.NSS)
|
||||
outStrs = [str(len(pathNodes))]
|
||||
pathNodes = self.svg.selection.filter(PathElement).values()
|
||||
|
||||
paths = [(pathNode.get('id'), CubicSuperPath(pathNode.get('d'))) for pathNode in pathNodes]
|
||||
|
||||
if(len(paths) > 1):
|
||||
srcPath = paths[-1][1]
|
||||
srclen = self.getLength(srcPath, tolerance)
|
||||
paths = paths[:len(paths)-1]
|
||||
for key, cspath in paths:
|
||||
curveLen = self.getLength(cspath, tolerance)
|
||||
if self.options.override_selection is False:
|
||||
if(len(paths) > 1):
|
||||
srcPath = paths[-1][1]
|
||||
srclen = self.getLength(srcPath, tolerance)
|
||||
paths = paths[:len(paths)-1]
|
||||
for key, cspath in paths:
|
||||
curveLen = self.getLength(cspath, tolerance)
|
||||
|
||||
self.scaleCubicSuper(cspath, scaleFactor = scale * (srclen / curveLen), scaleFrom = scaleFrom)
|
||||
try: #we wrap this in try-except because if the elements are within groups it will cause errors
|
||||
selections[key].set('d', CubicSuperPath(cspath))
|
||||
except:
|
||||
pass
|
||||
self.scaleCubicSuper(cspath, scaleFactor = scale * (srclen / curveLen), scaleFrom = scaleFrom)
|
||||
try: #we wrap this in try-except because if the elements are within groups it will cause errors
|
||||
selections[key].set('d', CubicSuperPath(cspath))
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
inkex.errormsg("Please select at least two paths, with the path whose \
|
||||
length is to be copied at the top. You may have to convert the shape \
|
||||
to path with path->Object to Path.")
|
||||
else:
|
||||
inkex.errormsg("Please select at least two paths, with the path whose \
|
||||
length is to be copied at the top. You may have to convert the shape \
|
||||
to path with path->Object to Path.")
|
||||
if(len(paths) > 0):
|
||||
srclen = self.svg.unittouu(str(self.options.custom_length) + self.options.unit)
|
||||
for key, cspath in paths:
|
||||
curveLen = self.getLength(cspath, tolerance)
|
||||
|
||||
self.scaleCubicSuper(cspath, scaleFactor = scale * (srclen / curveLen), scaleFrom = scaleFrom)
|
||||
try: #we wrap this in try-except because if the elements are within groups it will cause errors
|
||||
selections[key].set('d', CubicSuperPath(cspath))
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
inkex.errormsg("Please select at least one path. You may have to convert the shape to path with path->Object to Path.")
|
||||
if __name__ == '__main__':
|
||||
PasteLengthEffect().run()
|
||||
|
Reference in New Issue
Block a user