added funshapes extension, fixed some bug in incadiff inx
This commit is contained in:
parent
b0b3026b6d
commit
7f29d3eefc
16
extensions/fablabchemnitz/funshapes/funshapes.inx
Executable file
16
extensions/fablabchemnitz/funshapes/funshapes.inx
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||||
|
<name>Fun Shapes</name>
|
||||||
|
<id>fablabchemnitz.de.funshapes</id>
|
||||||
|
<effect implements-custom-gui="true">
|
||||||
|
<object-type>path</object-type>
|
||||||
|
<effects-menu>
|
||||||
|
<submenu name="FabLab Chemnitz">
|
||||||
|
<submenu name="Shape/Pattern from Generator"/>
|
||||||
|
</submenu>
|
||||||
|
</effects-menu>
|
||||||
|
</effect>
|
||||||
|
<script>
|
||||||
|
<command location="inx" interpreter="python">funshapes.py</command>
|
||||||
|
</script>
|
||||||
|
</inkscape-extension>
|
199
extensions/fablabchemnitz/funshapes/funshapes.py
Normal file
199
extensions/fablabchemnitz/funshapes/funshapes.py
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# coding=utf-8
|
||||||
|
#
|
||||||
|
# Copyright (C) [2021] [Matt Cottam], [mpcottam@raincloud.co.uk]
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
"""
|
||||||
|
A simple Extension to test if a Gtk3 Gui will work on most Inkscape 1.1+ Systems.
|
||||||
|
Inkscape 1.1 is the minimum verion.
|
||||||
|
Draws a simple set of randomly coloured circles and outputs them to the canvas.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import inkex
|
||||||
|
from inkex.elements import Group, PathElement
|
||||||
|
from inkex import transforms, styles
|
||||||
|
|
||||||
|
import random
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
from gi.repository import Gtk, GdkPixbuf, Gdk
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
# Could not find simplestyle, found this instead in extensions repo
|
||||||
|
def formatStyle(a):
|
||||||
|
"""Format an inline style attribute from a dictionary"""
|
||||||
|
return ";".join([att + ":" + str(val) for att, val in a.items()])
|
||||||
|
|
||||||
|
|
||||||
|
def random_rgb(self):
|
||||||
|
random_red = random.randrange(0, 255)
|
||||||
|
random_green = random.randrange(0, 255)
|
||||||
|
random_blue = random.randrange(0, 255)
|
||||||
|
|
||||||
|
return f'rgb({random_red}, {random_green}, {random_blue})'
|
||||||
|
|
||||||
|
|
||||||
|
# Generate a circle or circle path
|
||||||
|
def draw_svg_circle(self, r, cx, cy, parent, is_path):
|
||||||
|
style = {'stroke': 'black',
|
||||||
|
# 'stroke-opacity': (r/200),
|
||||||
|
'stroke-width': '0.1',
|
||||||
|
# 'fill': 'none'
|
||||||
|
'fill': random_rgb(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs = {
|
||||||
|
'style': formatStyle(style),
|
||||||
|
'r': str(r),
|
||||||
|
'cx': str(cx),
|
||||||
|
'cy': str(cy)
|
||||||
|
}
|
||||||
|
|
||||||
|
my_circle = etree.SubElement(Funshapes.output_group, inkex.addNS('circle', 'svg'), attribs)
|
||||||
|
|
||||||
|
|
||||||
|
def draw_svg_circle_series(self, r, cx, cy, parent, is_path):
|
||||||
|
|
||||||
|
my_list = range(1, 100)
|
||||||
|
for item in reversed(my_list):
|
||||||
|
draw_svg_circle(self, item, cx, cy, parent, is_path)
|
||||||
|
|
||||||
|
gtk3_add_svg_image(self, Funshapes.output_group)
|
||||||
|
|
||||||
|
|
||||||
|
def draw_svg_circle_series_scale(self, r, cx, cy, parent, is_path):
|
||||||
|
Funshapes.output_group.clear()
|
||||||
|
|
||||||
|
upper_range = int(Funshapes.main_window.h_scale.get_value())
|
||||||
|
|
||||||
|
my_list = range(1, upper_range)
|
||||||
|
for item in reversed(my_list):
|
||||||
|
draw_svg_circle(self, item, cx, cy, parent, is_path)
|
||||||
|
|
||||||
|
gtk3_add_svg_image(self, Funshapes.output_group)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def group_wrapper(self, my_objects, to_layer):
|
||||||
|
group_id = 'g' + str(random.randrange(100000, 1000000))
|
||||||
|
|
||||||
|
new_group = self.svg.add(Group.new('#' + group_id))
|
||||||
|
# inkex set, takes account of NS attribs etc
|
||||||
|
new_group.set('inkscape:groupmode', 'layer')
|
||||||
|
new_group.set('inkscape:label', 'My_Layer_' + group_id)
|
||||||
|
|
||||||
|
# When plucking an object from an svg, will only have its own transforms
|
||||||
|
# Composed transforms must be applied instead.
|
||||||
|
|
||||||
|
for my_object in my_objects:
|
||||||
|
my_object_transforms = my_object.composed_transform()
|
||||||
|
my_object.attrib['transform'] = ''
|
||||||
|
my_object.transform.add_matrix(my_object_transforms)
|
||||||
|
new_group.append(my_object)
|
||||||
|
|
||||||
|
new_group.attrib['id'] = group_id
|
||||||
|
return new_group
|
||||||
|
|
||||||
|
|
||||||
|
def object_to_xml_tag(self):
|
||||||
|
my_tag = str(self.tostring().decode("utf-8"))
|
||||||
|
return my_tag
|
||||||
|
|
||||||
|
##########################
|
||||||
|
# GTK3 GUI SECTION BELOW
|
||||||
|
##########################
|
||||||
|
|
||||||
|
|
||||||
|
def gtk3_gui(self):
|
||||||
|
|
||||||
|
Funshapes.main_window = Gtk.Window()
|
||||||
|
Funshapes.main_window.root_grid = Gtk.Grid()
|
||||||
|
Funshapes.main_window.add(Funshapes.main_window.root_grid)
|
||||||
|
|
||||||
|
root_grid = Funshapes.main_window.root_grid
|
||||||
|
main_window = Funshapes.main_window
|
||||||
|
|
||||||
|
gtk3_scales(root_grid, Funshapes.main_window)
|
||||||
|
|
||||||
|
main_window.connect("destroy", Gtk.main_quit)
|
||||||
|
main_window.show_all()
|
||||||
|
|
||||||
|
draw_svg_circle_series(self, 200, 100, 100, Funshapes.self.svg, 'yes')
|
||||||
|
|
||||||
|
Gtk.main()
|
||||||
|
|
||||||
|
return main_window
|
||||||
|
|
||||||
|
|
||||||
|
def gtk3_scales(grid, inkex_self):
|
||||||
|
ad1 = Gtk.Adjustment(value=20, lower=0, upper=100, step_increment=5, page_increment=10, page_size=0)
|
||||||
|
|
||||||
|
inkex_self.h_scale = Gtk.Scale(
|
||||||
|
orientation=Gtk.Orientation.HORIZONTAL, adjustment=ad1)
|
||||||
|
|
||||||
|
inkex_self.h_scale.set_digits(0)
|
||||||
|
inkex_self.h_scale.set_valign(Gtk.Align.START)
|
||||||
|
|
||||||
|
inkex_self.h_scale.connect("value-changed", draw_svg_circle_series_scale, 50, 100, 100, None, None)
|
||||||
|
|
||||||
|
grid.attach(inkex_self.h_scale, 1, 0, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def gtk3_add_svg_image(self, svg_object):
|
||||||
|
|
||||||
|
Funshapes.base_image = Gtk.Image()
|
||||||
|
Funshapes.base_image.set_from_file('white.png')
|
||||||
|
|
||||||
|
random_number = random.randrange(10000, 1000000, 1)
|
||||||
|
|
||||||
|
# convert svg object to svg xml
|
||||||
|
svg = object_to_xml_tag(svg_object)
|
||||||
|
|
||||||
|
svg = f'<svg width="200" viewBox="0 0 200 ' \
|
||||||
|
f'200" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">{svg}</svg> '
|
||||||
|
|
||||||
|
loader = GdkPixbuf.PixbufLoader()
|
||||||
|
loader.write(svg.encode())
|
||||||
|
loader.close()
|
||||||
|
pixbuf = loader.get_pixbuf()
|
||||||
|
|
||||||
|
Funshapes.preview_image = Gtk.Image.new_from_pixbuf(pixbuf)
|
||||||
|
Funshapes.preview_image.show_all()
|
||||||
|
|
||||||
|
if Funshapes.main_window.root_grid.get_child_at(1, 1) is None:
|
||||||
|
Funshapes.main_window.root_grid.attach(Funshapes.preview_image, 1, 1, 1, 1)
|
||||||
|
else:
|
||||||
|
Funshapes.main_window.root_grid.get_child_at(1, 1).destroy()
|
||||||
|
Funshapes.main_window.root_grid.attach(Funshapes.preview_image, 1, 1, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class Funshapes(inkex.EffectExtension):
|
||||||
|
|
||||||
|
def effect(self):
|
||||||
|
Funshapes.self = self
|
||||||
|
output_group_id = f'Funshapes_{random.randrange(10000, 1000000, 1)}'
|
||||||
|
Funshapes.output_group = Group.new('#' + output_group_id)
|
||||||
|
# create new gtk3 window and attach to effect self
|
||||||
|
self.win = gtk3_gui(self)
|
||||||
|
|
||||||
|
# When GTK is exited
|
||||||
|
Funshapes.self.svg.append(Funshapes.output_group)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
Funshapes().run()
|
@ -3,13 +3,13 @@
|
|||||||
<name>Incadiff</name>
|
<name>Incadiff</name>
|
||||||
<id>fablabchemnitz.de.incadiff</id>
|
<id>fablabchemnitz.de.incadiff</id>
|
||||||
<effect needs-document="true" needs-live-preview="false">
|
<effect needs-document="true" needs-live-preview="false">
|
||||||
<effects-menu hidden="false">
|
<object-type>all</object-type>
|
||||||
|
<effects-menu>
|
||||||
<submenu name="FabLab Chemnitz">
|
<submenu name="FabLab Chemnitz">
|
||||||
<submenu name="Modify existing Path(s)"/>
|
<submenu name="Modify existing Path(s)"/>
|
||||||
</submenu>
|
</submenu>
|
||||||
</effects-menu>
|
</effects-menu>
|
||||||
<menu-tip>Apply successive difference operations on superimposed paths. Useful for plotter addicts.</menu-tip>
|
<menu-tip>Apply successive difference operations on superimposed paths. Useful for plotter addicts.</menu-tip>
|
||||||
<object-type>all</object-type>
|
|
||||||
</effect>
|
</effect>
|
||||||
<script>
|
<script>
|
||||||
<command location="inx" interpreter="python">incadiff.py</command>
|
<command location="inx" interpreter="python">incadiff.py</command>
|
||||||
|
@ -14,13 +14,15 @@ ls -d */ | wc -l
|
|||||||
echo "Removing unrequired pyc cache files"
|
echo "Removing unrequired pyc cache files"
|
||||||
find . -type d -name "__pycache__" -exec rm -rf {} \;
|
find . -type d -name "__pycache__" -exec rm -rf {} \;
|
||||||
|
|
||||||
|
read -p "Build local gallery extension zip files?" -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Building Inkscape gallery extension zip files"
|
||||||
|
TARGETDIR="../000_Inkscape_Gallery"
|
||||||
|
mkdir -p $TARGETDIR > /dev/null
|
||||||
|
|
||||||
echo "Building Inkscape gallery extension zip files"
|
#list of extensions which are uploaded at Inkscape gallery by us at the moment
|
||||||
TARGETDIR="../000_Inkscape_Gallery"
|
for EXTENSION in \
|
||||||
mkdir -p $TARGETDIR > /dev/null
|
|
||||||
|
|
||||||
#list of extensions which are uploaded at Inkscape gallery by us at the moment
|
|
||||||
for EXTENSION in \
|
|
||||||
"animate_order" \
|
"animate_order" \
|
||||||
"cleanup_styles" \
|
"cleanup_styles" \
|
||||||
"contour_scanner_and_trimmer" \
|
"contour_scanner_and_trimmer" \
|
||||||
@ -42,7 +44,7 @@ for EXTENSION in \
|
|||||||
"ungrouper_and_element_migrator_filter" \
|
"ungrouper_and_element_migrator_filter" \
|
||||||
"unwind_paths" \
|
"unwind_paths" \
|
||||||
"vpypetools"
|
"vpypetools"
|
||||||
do
|
do
|
||||||
EXTRA=""
|
EXTRA=""
|
||||||
if [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
if [[ $EXTENSION == "styles_to_layers" ]] || [[ $EXTENSION == "ungrouper_and_element_migrator_filter" ]]; then
|
||||||
EXTRA="${EXTRA} apply_transformations/"
|
EXTRA="${EXTRA} apply_transformations/"
|
||||||
@ -52,4 +54,5 @@ do
|
|||||||
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
ZIPFILE=$TARGETDIR/$EXTENSION.zip
|
||||||
rm $ZIPFILE > /dev/null
|
rm $ZIPFILE > /dev/null
|
||||||
zip -r $ZIPFILE $EXTENSION/ 000_about_fablabchemnitz.svg $EXTRA
|
zip -r $ZIPFILE $EXTENSION/ 000_about_fablabchemnitz.svg $EXTRA
|
||||||
done
|
done
|
||||||
|
fi
|
||||||
|
Reference in New Issue
Block a user