This repository has been archived on 2023-03-25. You can view files and clone it, but cannot push or open issues or pull requests.
mightyscape-1.1-deprecated/extensions/fablabchemnitz/can_generator/can_generator.py

371 lines
16 KiB
Python

#! /usr/bin/env python3
'''
@author: mini@revollo.de
member of the erfindergarden
Inkscape Erweiterung - Dosen Generator
13.01.2019
Danke an neon22 https://github.com/Neon22/inkscape_extension_template
Nach seiner Anleitung konnte ich dieses Programm erstellen.
'''
import inkex
from lxml import etree
from math import *
__version__ = '0.2'
def points_to_svgd(p, close = True):
""" convert list of points (x,y) pairs
into a closed SVG path list
"""
f = p[0]
p = p[1:]
svgd = 'M %.2f,%.2f ' % f
for x in p:
svgd += ' %.4f,%.4f' % x
if close:
svgd += 'z'
return svgd
def punkte_erstellen(punkte, x, y):
###Schreibt die aktuellen Koordinaten in die Punkteliste
punkte.append((x, y))
class CanGenerator(inkex.EffectExtension):
def add_arguments(self, pars):
pars.add_argument("--height", type=int, default = 50, help="Höhe der Dose")
pars.add_argument("--overhang", type=int, default = 40, help="Überstand des Deckels")
pars.add_argument("--diameter", type=int, default = 40, help="diameter der Dose")
pars.add_argument("--angle", type=float, default = 22.5, help="angle der segments")
pars.add_argument("--material", type=float, default = 3.6, help="Materialstärke")
pars.add_argument("--bottom", type=inkex.Boolean, default = False, help="Deckel und bottom?")
pars.add_argument("--active-tab", default='title', help="Active tab.")
self.deckel_punkte = []
self.deckel_pfad = []
self.seite_punkte = []
self.seite_pfad = []
self.ausschnitt_punkte = []
self.ausschnitt_pfad = []
self.ausschnitt_nummer = 0
self.einschnitt_punkte = []
self.einschnitt_pfad = []
self.einschnitt_nummer = 0
self.einschnitt_breite = 0.2 #Abstand zwischen den beiden Einschnittlinien
def pfad_erstellen(self, pfad, punkte):
# Die gesammelten x und y Koordinaten der Punkte werden in Pfade (d) umgewandelt.
pfad.append(points_to_svgd(punkte))
del punkte[:]
def pfade_schreiben(self):
###Schreibt alle Pfade nacheinander in die Szene
path_stroke = '#101010' # Farbe für die Dose
path_fill = 'none' # keine Füllung, nur eine Linie
path_stroke_width = '0.4' # can also be in form '0.6mm'
for nummer in range(len(self.pfade)):
# define style using basic dictionary
pfad_attribute = {'id': "pfad%d"%nummer, 'stroke': path_stroke,
'fill': path_fill, 'stroke-width': path_stroke_width,
'd': self.pfade[nummer]}
# add path to scene
pfad = etree.SubElement(self.topgroup, inkex.addNS('path','svg'), pfad_attribute )
def deckel_erstellen(self):
###Erstellt alle Punkte für den Aussenkreis des Deckels.
angle = self.angle
segments = int(360 / angle)
for segment_nr in range(segments + 1):
#y berechnen = Gegenkathete
y = sin(radians(angle)) * self.radius_mit_overhang * -1
#Innenangle berechnen
beta = 180 - 90 - angle
#Ankathete berechnen
b = sin(radians(beta)) * self.radius_mit_overhang
#x berechnen
x = self.radius_mit_overhang - b - self.overhang
punkte_erstellen(self.deckel_punkte, x, y)
angle += self.angle
self.deckel_schreiben()
def deckel_schreiben(self):
###Schreibt den Deckel ohne Ausschnitte in die Szene
path_stroke = '#0000ff' # Farbe für den Rand
path_fill = 'none' # keine Füllung, nur eine Linie
path_stroke_width = '0.6' # can also be in form '0.6mm'
#Punkte zu Pfad umwandeln
self.deckel_pfad = points_to_svgd(self.deckel_punkte, False)
# define style using basic dictionary
deckel_attribute = {'id': "rand", 'stroke': path_stroke, 'fill': path_fill,
'stroke-width': path_stroke_width , 'x': '0', 'y': '0', 'd': self.deckel_pfad}
# add path to scene
deckel = etree.SubElement(self.topgroup, inkex.addNS('path','svg'), deckel_attribute )
def ausschnitt_erstellen(self):
###Erstellt alle Punkte für den Aussenkreis des Deckels.
angle = self.angle
for segment_nr in range(self.segments):
###Punkt 1 wird berechnet
#y berechnen = Gegenkathete
y = sin(radians(angle)) * self.radius * -1
#Innenangle berechnen
beta = 180 - 90 - angle
#Ankathete berechnen
b = sin(radians(beta)) * self.radius
#x berechnen
x = self.radius - b
punkte_erstellen(self.ausschnitt_punkte, x, y)
angle += self.angle
###Punkt 2 wird berechnet
#y berechnen = Gegenkathete
y = sin(radians(angle)) * self.radius * -1
#Innenangle berechnen
beta = 180 - 90 - angle
#Ankathete berechnen
b = sin(radians(beta)) * self.radius
#x berechnen
x = self.radius - b
punkte_erstellen(self.ausschnitt_punkte, x, y)
###Punkt 3 wird berechnet
alpha = angle - (self.angle / 2)
beta = 180 - 90 - alpha
y += sin(radians(alpha)) * self.material
x += sin(radians(beta)) * self.material
angle += self.angle
punkte_erstellen(self.ausschnitt_punkte, x, y)
### Punkt 4 wird berechnet
alpha = 180 - alpha
beta = 180 - 90 - alpha
x -= sin(radians(alpha)) * self.ausschnitt_breite
y -= sin(radians(beta)) * self.ausschnitt_breite
punkte_erstellen(self.ausschnitt_punkte, x, y)
#
self.ausschnitt_schreiben()
del self.ausschnitt_punkte[:]
def ausschnitt_schreiben(self):
###Schreibt den Ausschnitte in die Szene
path_stroke = '#ff0000' # Farbe für den Rand
path_fill = 'none' # keine Füllung, nur eine Linie
path_stroke_width = '0.6' # can also be in form '0.6mm'
#Punkte zu Pfad umwandeln
self.ausschnitt_pfad = points_to_svgd(self.ausschnitt_punkte, True)
# define style using basic dictionary
ausschnitt_attribute = {'id': "ausschnitt_%s"%self.ausschnitt_nummer, 'stroke': path_stroke, 'fill': path_fill,
'stroke-width': path_stroke_width , 'x': '0', 'y': '0', 'd': self.ausschnitt_pfad}
self.ausschnitt_nummer += 1
# add path to scene
ausschnitt = etree.SubElement(self.topgroup, inkex.addNS('path','svg'), ausschnitt_attribute )
def seite_erstellen(self):
###Erstellt die Seite der Dose mit den Zinken und den Einschnitten###
x = 0
y = self.radius_mit_overhang + 10
punkte_erstellen(self.seite_punkte, x, y)
for item in range(int(self.segments / 2)):
y -= self.material
punkte_erstellen(self.seite_punkte, x, y)
x += self.ausschnitt_breite
punkte_erstellen(self.seite_punkte, x, y)
y += self.material
punkte_erstellen(self.seite_punkte, x, y)
x += self.ausschnitt_breite
punkte_erstellen(self.seite_punkte, x, y)
if self.bottom == False:
y += self.height - self.material
punkte_erstellen(self.seite_punkte, x, y)
x -= self.segments * self.ausschnitt_breite
punkte_erstellen(self.seite_punkte, x, y)
y -= self.height - self.material
punkte_erstellen(self.seite_punkte, x, y)
else:
y += self.height - self.material - self.material
punkte_erstellen(self.seite_punkte, x, y)
for item in range(int(self.segments / 2)):
x -= self.ausschnitt_breite
punkte_erstellen(self.seite_punkte, x, y)
y += self.material
punkte_erstellen(self.seite_punkte, x, y)
x -= self.ausschnitt_breite
punkte_erstellen(self.seite_punkte, x, y)
y -= self.material
punkte_erstellen(self.seite_punkte, x, y)
y -= self.height
punkte_erstellen(self.seite_punkte, x, y)
self.seite_schreiben()
def seite_schreiben(self):
###Schreibt die Seite in die Szene
path_stroke = '#0000ff' # Farbe für den Rand
path_fill = 'none' # keine Füllung, nur eine Linie
path_stroke_width = '0.6' # can also be in form '0.6mm'
#Punkte zu Pfad umwandeln
self.seite_pfad = points_to_svgd(self.seite_punkte, True)
# define style using basic dictionary
seite_attribute = {'id': "seite", 'stroke': path_stroke, 'fill': path_fill,
'stroke-width': path_stroke_width , 'x': '0', 'y': '0', 'd': self.seite_pfad}
# add path to scene
seite = etree.SubElement(self.topgroup, inkex.addNS('path','svg'), seite_attribute )
def einschnitte_erstellen(self):
###Erstellt die Einschnitte in die Seite
x = self.einschnitt_breite / -2
y = self.radius_mit_overhang + 10 - self.material
for segment_nr in range(self.segments - 1):
###Punkt 1 wird berechnet
x += self.ausschnitt_breite
punkte_erstellen(self.einschnitt_punkte, x, y)
###Punkt 2 wird berechnet
x += self.einschnitt_breite
punkte_erstellen(self.einschnitt_punkte, x, y)
###Punkt 3 wird berechnet
y += self.height
punkte_erstellen(self.einschnitt_punkte, x, y)
### Punkt 4 wird berechnet
x -= self.einschnitt_breite
punkte_erstellen(self.einschnitt_punkte, x, y)
y -= self.height
self.einschnitte_schreiben()
del self.einschnitt_punkte[:]
def einschnitte_schreiben(self):
###Schreibt die Einschnitte in die Seite
path_stroke = '#00ff00' # Farbe für die Einschnitte
path_fill = 'none' # keine Füllung, nur eine Linie
path_stroke_width = '0.6' # can also be in form '0.6mm'
#Punkte zu Pfad umwandeln
self.einschnitt_pfad = points_to_svgd(self.einschnitt_punkte, True)
# define style using basic dictionary
einschnitt_attribute = {'id': "einschnitt_%s"%self.einschnitt_nummer, 'stroke': path_stroke, 'fill': path_fill,
'stroke-width': path_stroke_width , 'x': '0', 'y': '0', 'd': self.einschnitt_pfad}
self.einschnitt_nummer += 1
# add path to scene
einschnitt = etree.SubElement(self.undergroup, inkex.addNS('path','svg'), einschnitt_attribute )
### -------------------------------------------------------------------
### This is your main function and is called when the extension is run.
def effect(self):
###Hauptprogramm
# holt die Parameter aus Inkscape
self.height = self.options.height
self.diameter = self.options.diameter
self.overhang = self.options.overhang
self.radius = self.diameter / 2
self.radius_mit_overhang = self.radius + self.overhang
self.angle = self.options.angle
self.bottom = self.options.bottom
self.material = self.options.material
self.segments = int(360 / self.angle)
#Ausschnittbreite errechnen
y = sin(radians(self.angle)) * self.radius
beta = 180 - 90 - self.angle
b = sin(radians(beta)) * self.radius
x = self.radius - b
self.ausschnitt_breite = sqrt((x * x) + (y * y))
# what page are we on
page_id = self.options.active_tab # sometimes wrong the very first time
#Eigenschaften der SVG auslesen und die Größe der Dose anpassen
svg = self.document.getroot()
#viewbox_size = '0 0 ' + str(self.breite) + ' ' + str(self.height)
#svg.set('viewBox', viewbox_size)
#svg.set('height', str(self.height))
#svg.set('width', str(self.breite))
# Embed the path in a group to make animation easier:
# Be sure to examine the internal structure by looking in the xml editor inside inkscape
# Make a nice useful name
g_attribs = { inkex.addNS('label','inkscape'): 'dosen-gruppe', 'id': "dose",}
# add the group to the document's current layer
self.topgroup = etree.SubElement(self.svg.get_current_layer(), 'g', g_attribs )
# Create SVG Path under this top level group
# Make a nice useful name
g_attribs = { inkex.addNS('label','inkscape'): 'einschnitt-gruppe', 'id': "einschnitte",}
# add the group to the document's current layer
self.undergroup = etree.SubElement(self.svg.get_current_layer(), 'g', g_attribs )
# Create SVG Path under this top level group
self.deckel_erstellen()
self.ausschnitt_erstellen()
self.seite_erstellen()
self.einschnitte_erstellen()
# Make a nice useful name
text_g_attribs = { inkex.addNS('label','inkscape'): 'dosen-gruppe', 'id': "Branding",}
# add the group to the document's current layer
textgroup = etree.SubElement(self.svg.get_current_layer(), 'g', text_g_attribs )
line_style = {'font-size': '10px', 'font-style':'normal', 'font-weight': 'normal',
'fill': '#ff0000', 'font-family': 'Consolas',
'text-anchor': 'start'}
branding_line_attribs = {inkex.addNS('label','inkscape'): 'branding-text',
'id': 'front text',
'style': str(inkex.Style(line_style)),
'x': str(0),
'y': str(0)
}
branding_line = etree.SubElement(textgroup, inkex.addNS('text','svg'), branding_line_attribs)
branding_line.text = 'dosen-generator by mini revollo member of the erfindergarden'
# Make a nice useful name
einschnitt_text_g_attribs = { inkex.addNS('label','inkscape'): 'einschnitt-gruppe', 'id': "Einschnitte_Text",}
# add the group to the document's current layer
textgroup = etree.SubElement(self.svg.get_current_layer(), 'g', einschnitt_text_g_attribs )
line_style = {'font-size': '5px', 'font-style':'normal', 'font-weight': 'normal',
'fill': '#00ff00', 'font-family': 'Consolas',
'text-anchor': 'start'}
einschnitt_line_attribs = {inkex.addNS('label','inkscape'): 'Einschnitte_text',
'id': 'front text',
'style': str(inkex.Style(line_style)),
'x': str(0),
'y': str(self.radius_mit_overhang + self.height / 2)
}
branding_line = etree.SubElement(textgroup, inkex.addNS('text','svg'), einschnitt_line_attribs)
branding_line.text = 'Die Einschnitte nur zu 70 Prozent in das Material lasern'
if __name__ == '__main__':
CanGenerator().run()