Initial commit. First part of extensions. More are coming back again
soon.
This commit is contained in:
21
extensions/fablabchemnitz/sheriff_star/meta.json
Normal file
21
extensions/fablabchemnitz/sheriff_star/meta.json
Normal file
@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"name": "Sheriff Star",
|
||||
"id": "fablabchemnitz.de.sheriff_star",
|
||||
"path": "sheriff_star",
|
||||
"dependent_extensions": null,
|
||||
"original_name": "Sheriff Star",
|
||||
"original_id": "com.kacmarcik.pathmonkey.sheriff-star",
|
||||
"license": "MIT License",
|
||||
"license_url": "https://github.com/garykac/pathmonkey/blob/master/LICENSE",
|
||||
"comment": "ported to Inkscape v1 manually by Mario Voigt",
|
||||
"source_url": "https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.2/src/branch/master/extensions/fablabchemnitz/sheriff_star",
|
||||
"fork_url": "https://github.com/garykac/pathmonkey",
|
||||
"documentation_url": "https://stadtfabrikanten.org/display/IFM/Sheriff+Star",
|
||||
"inkscape_gallery_url": null,
|
||||
"main_authors": [
|
||||
"github.com/garykac",
|
||||
"github.com/eridur-de"
|
||||
]
|
||||
}
|
||||
]
|
33
extensions/fablabchemnitz/sheriff_star/sheriff_star.inx
Normal file
33
extensions/fablabchemnitz/sheriff_star/sheriff_star.inx
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Sheriff Star</name>
|
||||
<id>fablabchemnitz.de.sheriff_star</id>
|
||||
<param name="tab" type="notebook">
|
||||
<page name="settings" gui-text="Settings">
|
||||
<param name="points" type="int" min="5" max="10" gui-text="Num Points">6</param>
|
||||
<param name="star_tip_ratio" type="int" min="1" max="100" gui-text="Star Tip Circle Percentage">10</param>
|
||||
<param name="inner_ratio" type="int" min="1" max="100" gui-text="Inner Circle Percentage">58</param>
|
||||
<param name="show_inner_circle" type="bool" gui-text="Show Inner Circle">false</param>
|
||||
</page>
|
||||
<page name="help" gui-text="Help">
|
||||
<label xml:space="preserve">This extension creates a sheriff star in the currently selected circle or ellipse.
|
||||
|
||||
The outer vertices (points of the star) are connected through a point on the (usually hidden) inner circle. This inner connection point is located at an angle halfway between the angles of the two outer vertices. The radius of this inner circle is expressed as a percentage of the radius of the selected circle or ellipse.
|
||||
|
||||
Small circles are placed at the tip of each point of the star. The radius of these small circles is expressed as a percentage of the selected circle's radius (for ellipses, the x-radius is used).
|
||||
|
||||
The components that make up the star are left as separate objects so that additional processing can be performed.</label>
|
||||
</page>
|
||||
</param>
|
||||
<effect>
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Shape/Pattern from existing Object(s)"/>
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command location="inx" interpreter="python">sheriff_star.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
148
extensions/fablabchemnitz/sheriff_star/sheriff_star.py
Normal file
148
extensions/fablabchemnitz/sheriff_star/sheriff_star.py
Normal file
@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Sheriff Star
|
||||
Create n-pointed sheriff star.
|
||||
"""
|
||||
import inkex
|
||||
from math import *
|
||||
from lxml import etree
|
||||
|
||||
def addPathCommand(a, cmd):
|
||||
for x in cmd:
|
||||
a.append(str(x))
|
||||
|
||||
class SheriffStar(inkex.EffectExtension):
|
||||
|
||||
def add_arguments(self, pars):
|
||||
pars.add_argument('--tab')
|
||||
pars.add_argument('--points', type=int, default=5, help='Number of points (or sides)')
|
||||
pars.add_argument('--star_tip_ratio', type=float, default=10, help='Star tip circle % (star tip circle radius as a percentage of the outer radius)')
|
||||
pars.add_argument('--inner_ratio', type=float, default=58, help='Inner circle % (inner radius as a percentage of the outer radius)')
|
||||
pars.add_argument('--show_inner_circle', type=inkex.Boolean, default=False, help='Show inner circle')
|
||||
|
||||
def effect(self):
|
||||
layer = self.svg.get_current_layer();
|
||||
|
||||
if len(self.svg.selected) == 0:
|
||||
inkex.errormsg('Please select a circle or ellipse.')
|
||||
exit()
|
||||
|
||||
numValid = 0
|
||||
for id, obj in self.svg.selected.items():
|
||||
cx,cy, rx,ry = 0,0, 0,0
|
||||
style = ''
|
||||
isValid = False
|
||||
if obj.tag == inkex.addNS('circle','svg'):
|
||||
isValid = True
|
||||
cx = float(obj.get('cx'))
|
||||
cy = float(obj.get('cy'))
|
||||
rx = float(obj.get('r'))
|
||||
ry = rx
|
||||
elif obj.tag == inkex.addNS('ellipse', 'svg'):
|
||||
isValid = True
|
||||
cx = float(obj.get('cx'))
|
||||
cy = float(obj.get('cy'))
|
||||
rx = float(obj.get('rx'))
|
||||
ry = float(obj.get('ry'))
|
||||
elif obj.tag == inkex.addNS('path', 'svg'):
|
||||
if obj.get(inkex.addNS('type', 'sodipodi')) == 'arc':
|
||||
isValid = True
|
||||
cx = float(obj.get(inkex.addNS('cx', 'sodipodi')))
|
||||
cy = float(obj.get(inkex.addNS('cy', 'sodipodi')))
|
||||
rx = float(obj.get(inkex.addNS('rx', 'sodipodi')))
|
||||
ry = float(obj.get(inkex.addNS('ry', 'sodipodi')))
|
||||
|
||||
if not isValid:
|
||||
continue;
|
||||
|
||||
numValid += 1
|
||||
style = obj.get('style')
|
||||
transform = obj.get('transform')
|
||||
isEllipse = False
|
||||
if rx != ry:
|
||||
isEllipse = True
|
||||
|
||||
skip = 1
|
||||
sides = self.options.points
|
||||
innerRatio = float(self.options.inner_ratio) / 100.0
|
||||
starTipRatio = float(self.options.star_tip_ratio) / 100.0
|
||||
showInnerCircle = self.options.show_inner_circle
|
||||
|
||||
if showInnerCircle:
|
||||
if not isEllipse:
|
||||
cin =etree.SubElement(layer, inkex.addNS('circle','svg'))
|
||||
cin.set('r', str(rx * innerRatio))
|
||||
else:
|
||||
cin =etree.SubElement(layer, inkex.addNS('ellipse','svg'))
|
||||
cin.set('rx', str(rx * innerRatio))
|
||||
cin.set('ry', str(ry * innerRatio))
|
||||
cin.set('cx', str(cx))
|
||||
cin.set('cy', str(cy))
|
||||
cin.set('style', style)
|
||||
if transform:
|
||||
cin.set('transform', transform)
|
||||
|
||||
tau = 2*pi
|
||||
origin = -(tau / 4)
|
||||
out_pts = []
|
||||
in_pts = []
|
||||
for i in range(sides):
|
||||
# Outer points (on outer circle)
|
||||
theta = (i * (tau / sides))
|
||||
px = cx + rx * cos(origin + theta)
|
||||
py = cy + ry * sin(origin + theta)
|
||||
out_pts.append([px, py])
|
||||
|
||||
# Inner points (on inner circle)
|
||||
theta = ((i + (skip / 2.0)) * (tau / sides))
|
||||
px = cx + rx * innerRatio * cos(origin + theta)
|
||||
py = cy + ry * innerRatio * sin(origin + theta)
|
||||
in_pts.append([px, py])
|
||||
|
||||
# Add circles at each star tip.
|
||||
for pt in out_pts:
|
||||
cin =etree.SubElement(layer, inkex.addNS('circle','svg'))
|
||||
cin.set('r', str(rx * starTipRatio))
|
||||
cin.set('cx', str(pt[0]))
|
||||
cin.set('cy', str(pt[1]))
|
||||
cin.set('style', style)
|
||||
if transform:
|
||||
cin.set('transform', transform)
|
||||
|
||||
pts = []
|
||||
pt_done = {}
|
||||
for i in range(sides):
|
||||
if i in pt_done:
|
||||
continue;
|
||||
|
||||
p1 = out_pts[i]
|
||||
addPathCommand(pts, ['M', p1[0], p1[1]])
|
||||
|
||||
pt_done[i] = True
|
||||
start_index = i
|
||||
curr = start_index
|
||||
next = (curr + skip) % sides
|
||||
while next != start_index:
|
||||
p = out_pts[next]
|
||||
pt_done[next] = True
|
||||
|
||||
addPathCommand(pts, ['L', in_pts[curr][0], in_pts[curr][1]])
|
||||
addPathCommand(pts, ['L', p[0], p[1]])
|
||||
|
||||
curr = next
|
||||
next = (curr + skip) % sides
|
||||
addPathCommand(pts, ['L', in_pts[curr][0], in_pts[curr][1]])
|
||||
addPathCommand(pts, ['z'])
|
||||
|
||||
# Create star polygon as a single path.
|
||||
l1 =etree.SubElement(layer, inkex.addNS('path','svg'))
|
||||
l1.set('style', style)
|
||||
if transform:
|
||||
l1.set('transform', transform)
|
||||
l1.set('d', ' '.join(pts))
|
||||
|
||||
if numValid == 0:
|
||||
inkex.errormsg('Selection must contain a circle or ellipse.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
SheriffStar().run()
|
Reference in New Issue
Block a user