Commit 266b86cf authored by sumpfralle's avatar sumpfralle

added basic DXF importer (supports only lines)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@352 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent fe9b4980
# -*- coding: utf-8 -*-
"""
$ID$
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM 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 3 of the License, or
(at your option) any later version.
PyCAM 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 PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
from pycam.Geometry import Point, Line
import pycam.Geometry.Model
import sys
class DXFParser:
# see http://www.autodesk.com/techpubs/autocad/acad2000/dxf/group_code_value_types_dxf_01.htm
MAX_CHARS_PER_LINE = 2049
KEYS = {
"MARKER": 0,
"START_X": 10,
"START_Y": 20,
"START_Z": 30,
"END_X": 11,
"END_Y": 21,
"END_Z": 31,
"COLOR": 62,
}
def __init__(self, inputstream):
self.inputstream = inputstream
self.line_number = 0
self.lines = []
self.parse_content()
def get_model(self):
return {"lines": self.lines}
def _read_key_value(self):
try:
line1 = self.inputstream.readline(self.MAX_CHARS_PER_LINE).strip()
line2 = self.inputstream.readline(self.MAX_CHARS_PER_LINE).strip()
except IOError:
return None, None
if not line1 and not line2:
return None, None
try:
line1 = int(line1)
except ValueError:
print >>sys.stderr, "Invalid key in line " \
+ "%d (int expected): %s" % (self.line_number, line1)
return None, None
if line1 in (self.KEYS["START_X"], self.KEYS["START_Y"],
self.KEYS["START_Z"], self.KEYS["END_X"], self.KEYS["END_Y"],
self.KEYS["END_Z"]):
try:
line2 = float(line2)
except ValueError:
print >>sys.stderr, "Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2)
line1 = None
line2 = None
elif line1 in (self.KEYS["COLOR"],):
try:
line2 = int(line2)
except ValueError:
print >>sys.stderr, "Invalid input in line " \
+ "%d (float expected): %s" % (self.line_number, line2)
line1 = None
line2 = None
else:
line2 = line2.upper()
pass
self.line_number += 2
return line1, line2
def parse_content(self):
key, value = self._read_key_value()
while (not key is None) and not ((key == self.KEYS["MARKER"]) and (value == "EOF")):
if key == self.KEYS["MARKER"]:
if value in ("SECTION", "TABLE", "LAYER", "ENDTAB", "ENDSEC"):
# we don't handle these meta-information
pass
elif value == "LINE":
self.parse_line()
else:
# not supported
print "Ignored unsupported element in line %d: %s" \
% (self.line_number, value)
key, value = self._read_key_value()
def parse_line(self):
start_line = self.line_number
p1 = [None, None, None]
p2 = [None, None, None]
key, value = self._read_key_value()
while (not key is None) and (key != self.KEYS["MARKER"]):
if key == self.KEYS["START_X"]:
p1[0] = value
elif key == self.KEYS["START_Y"]:
p1[1] = value
elif key == self.KEYS["START_Z"]:
p1[2] = value
elif key == self.KEYS["END_X"]:
p2[0] = value
elif key == self.KEYS["END_Y"]:
p2[1] = value
elif key == self.KEYS["END_Z"]:
p2[2] = value
else:
pass
key, value = self._read_key_value()
end_line = self.line_number
if (None in p1) or (None in p2):
print >>sys.stderr, "Incomplete LINE definition between line " \
+ "%d and %d" % (start_line, end_line)
else:
self.lines.append(Line(Point(p1[0], p1[1], p1[2]), Point(p2[0], p2[1], p2[2])))
def check_header(self):
# we expect "0" in the first line and "SECTION" in the second one
key, value = self._read_key_value()
if (key != KEYS["MARKER"]) or (value and (value != "SECTION")):
print >>sys.stderr, "DXF file header not recognized"
return None
def import_model(filename):
try:
f = open(filename,"rb")
except IOError, err_msg:
print >>sys.stderr, "Failed to read file (%s): %s" % (filename, err_msg)
return None
result = DXFParser(f)
lines = result.get_model()["lines"]
model = pycam.Geometry.Model.ContourModel()
for l in lines:
model.append(l)
print "Imported DXF model: %d lines" % len(lines)
return model
if __name__ == "__main__":
filename = sys.argv[1]
import_model(filename)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment