summaryrefslogtreecommitdiff
path: root/support/dxf_export/effect.py
diff options
context:
space:
mode:
Diffstat (limited to 'support/dxf_export/effect.py')
-rw-r--r--support/dxf_export/effect.py201
1 files changed, 0 insertions, 201 deletions
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]