From 14f078c8217450317b4824cb450b336ba6590011 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Wed, 5 Aug 2015 13:57:53 +0200 Subject: Inkscape export: Renamed module to inkscape. This module will later be used for other export types than just DXF. --- support/dxf_export/effect.py | 201 ------------------------------------------- 1 file changed, 201 deletions(-) delete mode 100644 support/dxf_export/effect.py (limited to 'support/dxf_export/effect.py') diff --git a/support/dxf_export/effect.py b/support/dxf_export/effect.py deleted file mode 100644 index c72037c..0000000 --- a/support/dxf_export/effect.py +++ /dev/null @@ -1,201 +0,0 @@ -""" -Based on code from Aaron Spike. See http://www.bobcookdev.com/inkscape/inkscape-dxf.html -""" - -import pkgutil, os, re -from . import inkex, simpletransform, cubicsuperpath, cspsubdiv - - -def _get_unit_factors_map(): - # Fluctuates somewhat between Inkscape releases. - pixels_per_inch = 96. - pixels_per_mm = pixels_per_inch / 25.4 - - return { - 'px': 1.0, - 'mm': pixels_per_mm, - 'cm': pixels_per_mm * 10, - 'm' : pixels_per_mm * 1e3, - 'km': pixels_per_mm * 1e6, - 'pt': pixels_per_inch / 72, - 'pc': pixels_per_inch / 6, - 'in': pixels_per_inch, - 'ft': pixels_per_inch * 12, - 'yd': pixels_per_inch * 36 } - - -class Layer(object): - def __init__(self, inkscape_name, export_name, use_paths): - self.inkscape_name = inkscape_name - self.export_name = export_name - self.use_paths = use_paths - - -class ExportEffect(inkex.Effect): - _unit_factors = _get_unit_factors_map() - - def __init__(self, layers): - inkex.Effect.__init__(self) - - self._layers_by_inkscape_name = { i.inkscape_name: i for i in layers } - self._lines = [] - self._handle = 255 - self._layer_indices = { } - self._flatness = float(os.environ['DXF_FLATNESS']) - - def _get_user_unit(self): - """ - Return the size in pixels of the unit used for measures without an explicit unit. - """ - - document_height = self._measure_to_pixels(self._get_document_height_attr()) - view_box_attr = self.document.getroot().get('viewBox') - - if view_box_attr: - _, _, _, view_box_height = map(float, view_box_attr.split()) - else: - view_box_height = document_height - - return document_height / view_box_height - - def _get_document_unit(self): - """ - Return the size in pixels that the user is working with in Inkscape. - """ - - inkscape_unit_attrs = self.document.getroot().xpath('./sodipodi:namedview/@inkscape:document-units', namespaces = inkex.NSS) - - if inkscape_unit_attrs: - unit = inkscape_unit_attrs[0] - else: - _, unit = self._parse_measure(self._get_document_height_attr()) - - return self._get_unit_factor(unit) - - def _get_document_height_attr(self): - return self.document.getroot().xpath('@height', namespaces = inkex.NSS)[0] - - def _get_layer_index(self, layer_name): - index = self._layer_indices.get(layer_name) - - if index is None: - index = len(self._layer_indices) - self._layer_indices[layer_name] = index - - return index - - def _add_line(self, layer_name, csp): - (x1, y1), (x2, y2) = csp - line = layer_name, x1, y1, x2, y2 - - self._lines.append(line) - - def _add_path(self, layer_name, path): - cspsubdiv.cspsubdiv(path, self._flatness) - - for sub in path: - for i in range(len(sub) - 1): - self._handle += 1 - s = sub[i] - e = sub[i + 1] - self._add_line(layer_name, [s[1], e[1]]) - - def _add_shape(self, node, document_transform, element_transform): - path = cubicsuperpath.parsePath(node.get('d')) - layer = self._layers_by_inkscape_name.get(self._get_inkscape_layer_name(node)) - - if layer is None: - layer_name = '' - else: - layer_name = layer.export_name - - transform = simpletransform.composeTransform( - document_transform, - simpletransform.composeParents(node, element_transform)) - - simpletransform.applyTransformToPath(transform, path) - - self._add_path(layer_name, path) - - def effect(self): - user_unit = self._get_user_unit() - document_unit = self._get_document_unit() - height = self._measure_to_pixels(self._get_document_height_attr()) - - document_transform = simpletransform.composeTransform( - [[1 / document_unit, 0, 0], [0, 1 / document_unit, 0]], - [[1, 0, 0], [0, -1, height]]) - - element_transform = [[user_unit, 0, 0], [0, user_unit, 0]] - - for node in self.document.getroot().xpath('//svg:path', namespaces = inkex.NSS): - self._add_shape(node, document_transform, element_transform) - - def write_dxf(self, file): - file.write(pkgutil.get_data(__name__, 'dxf_header.txt')) - - def _write_instruction(code, value): - print >> file, code - print >> file, value - - for layer_name, x1, y1, x2, y2 in self._lines: - _write_instruction(0, 'LINE') - _write_instruction(8, layer_name) - _write_instruction(62, self._get_layer_index(layer_name)) - _write_instruction(5, '{:x}'.format(self._handle)) - _write_instruction(100, 'AcDbEntity') - _write_instruction(100, 'AcDbLine') - _write_instruction(10, repr(x1)) - _write_instruction(20, repr(y1)) - _write_instruction(30, 0.0) - _write_instruction(11, repr(x2)) - _write_instruction(21, repr(y2)) - _write_instruction(31, 0.0) - - file.write(pkgutil.get_data(__name__, 'dxf_footer.txt')) - - @classmethod - def _parse_measure(cls, string): - value_match = re.match(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)', string) - unit_match = re.search('(%s)$' % '|'.join(cls._unit_factors.keys()), string) - - value = float(string[value_match.start():value_match.end()]) - - if unit_match: - unit = string[unit_match.start():unit_match.end()] - else: - unit = None - - return value, unit - - @classmethod - def _measure_to_pixels(cls, string, default_unit_factor = None): - """ - Parse a string containing a measure and return it's value converted to pixels. If the measure has no unit, it will be assumed that the unit has the size of the specified number of pixels. - """ - - value, unit = cls._parse_measure(string) - - return value * cls._get_unit_factor(unit, default_unit_factor) - - @classmethod - def _get_inkscape_layer_name(cls, node): - while node is not None: - layer = node.get(inkex.addNS('label', 'inkscape')) - - if layer is not None: - return layer - - node = node.getparent() - - return None - - @classmethod - def _get_unit_factor(cls, unit, default = None): - if unit is None: - if default is None: - default = 1 - - return default - else: - return cls._unit_factors[unit] -- cgit