Commit 7caa67c6 authored by sumpfralle's avatar sumpfralle

fixed encoding problems of DXFImporter

some more small fixes for polygon handling


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1022 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 4598f46f
......@@ -344,20 +344,33 @@ class ContourModel(BaseModel):
break
# merge 'other_polygon' with all other connectable polygons
for polygon in connectables:
# check again, if the polygon is still connectable
for connector in connectors:
if polygon.is_connectable(connector):
break
else:
# skip this polygon
continue
if other_polygon.get_points()[-1] == polygon.get_points()[0]:
for line in polygon.get_lines():
if other_polygon.is_closed:
return
other_polygon.append(line)
self._line_groups.remove(polygon)
elif other_polygon.get_points()[0] == polygon.get_points()[-1]:
lines = polygon.get_lines()
lines.reverse()
for line in lines:
if other_polygon.is_closed:
return
other_polygon.append(line)
self._line_groups.remove(polygon)
elif allow_reverse:
if other_polygon.get_points()[-1] == polygon.get_points()[-1]:
polygon.reverse_direction()
for line in polygon.get_lines():
if other_polygon.is_closed:
return
other_polygon.append(line)
self._line_groups.remove(polygon)
elif other_polygon.get_points()[0] == polygon.get_points()[0]:
......@@ -365,12 +378,17 @@ class ContourModel(BaseModel):
lines = polygon.get_lines()
lines.reverse()
for line in lines:
if other_polygon.is_closed:
return
other_polygon.append(line)
self._line_groups.remove(polygon)
else:
pass
else:
pass
if other_polygon.is_closed:
# we are finished
return
def append(self, item, unify_overlaps=False, allow_reverse=False):
super(ContourModel, self).append(item)
......@@ -379,7 +397,11 @@ class ContourModel(BaseModel):
if allow_reverse:
item_list.append(Line(item.p2, item.p1))
found = False
for line_group in self._line_groups:
# Going back from the end to start. The last line_group always has
# the highest chance of being suitable for the next line.
line_group_indexes = xrange(len(self._line_groups) - 1, -1, -1)
for line_group_index in line_group_indexes:
line_group = self._line_groups[line_group_index]
for candidate in item_list:
if line_group.is_connectable(candidate):
line_group.append(candidate)
......@@ -470,15 +492,25 @@ class ContourModel(BaseModel):
Beware: never use this function if the direction of lines may not
change.
"""
# try to connect all open polygons
number_of_initial_closed_polygons = len([poly
for poly in self.get_polygons() if poly.is_closed])
open_polygons = [poly for poly in self.get_polygons()
if not poly.is_closed]
if callback:
progress_callback = pycam.Utils.ProgressCounter(
2 * number_of_initial_closed_polygons + len(open_polygons),
callback).increment
else:
progress_callback = None
# try to connect all open polygons
for poly in open_polygons:
self._line_groups.remove(poly)
poly_open_before = len(open_polygons)
for poly in open_polygons:
for line in poly.get_lines():
self.append(line, allow_reverse=True)
if progress_callback and progress_callback():
return
poly_open_after = len([poly for poly in self.get_polygons()
if not poly.is_closed])
if poly_open_before != poly_open_after:
......@@ -490,11 +522,10 @@ class ContourModel(BaseModel):
finished = []
remaining_polys = [poly for poly in self.get_polygons()
if poly.is_closed]
if callback:
progress_callback = pycam.Utils.ProgressCounter(
2 * len(remaining_polys), callback).increment
else:
progress_callback = None
if progress_callback:
# shift the counter back by the number of new closed polygons
progress_callback(2 * (number_of_initial_closed_polygons - \
len(remaining_polys)))
remaining_polys.sort(key=lambda poly: abs(poly.get_area()))
while remaining_polys:
# pick the largest polygon
......
......@@ -62,7 +62,7 @@ class Polygon(TransformableContainer):
def append(self, line):
if not self.is_connectable(line):
raise ValueError("This line does not fit to the polygon")
elif line.len == 0:
elif line.len < epsilon:
raise ValueError("A line with zero length may not be part of a " \
+ "polygon")
else:
......@@ -365,7 +365,6 @@ class Polygon(TransformableContainer):
for line in self.get_lines():
line.to_OpenGL(**kwords)
def _update_limits(self, point):
if self.minx is None:
self.minx = point.x
......
......@@ -85,7 +85,7 @@ class DXFParser(object):
IGNORE_KEYS = ("DICTIONARY", "VPORT", "LTYPE", "STYLE", "APPID", "DIMSTYLE",
"BLOCK_RECORD", "BLOCK", "ENDBLK", "ACDBDICTIONARYWDFLT", "POINT",
"ACDBPLACEHOLDER", "LAYOUT", "MLINESTYLE", "DICTIONARYVAR", "CLASS",
"HATCH")
"HATCH", "VIEW", "VIEWPORT")
def __init__(self, inputstream, color_as_height=False, fonts_cache=None,
callback=None):
......@@ -203,7 +203,20 @@ class DXFParser(object):
line1 = None
line2 = None
elif line1 in [self.KEYS[key] for key in ("DEFAULT", "TEXT_MORE")]:
line2 = _unescape_control_characters(line2)
# check the string for invalid characters
try:
text = unicode(line2)
except UnicodeDecodeError:
log.warn("DXFImporter: Invalid character in string in " + \
"line %d" % self.line_number)
text_chars = []
for char in line2:
try:
text_chars.append(unicode(char))
except:
pass
text = u"".join(text_chars)
line2 = _unescape_control_characters(text)
else:
line2 = line2.upper()
self.line_number += 2
......@@ -253,7 +266,7 @@ class DXFParser(object):
if self._open_sequence == "POLYLINE":
self.parse_polyline(False)
else:
log.warn("DXFImporter: unexpected SEQEND found at line %d" + \
log.warn("DXFImporter: unexpected SEQEND found at line %d" % \
start_line)
def parse_vertex(self):
......@@ -556,7 +569,7 @@ class DXFParser(object):
# item.
if not key is None:
self._push_on_stack(key, value)
if (None in ref_point2) and (ref_point != ref_point2):
if (not None in ref_point2) and (ref_point != ref_point2):
# just a warning - continue as usual
log.warn("DXFImporter: Second alignment point is not " + \
"implemented for TEXT items - the text specified " + \
......@@ -755,7 +768,7 @@ class DXFParser(object):
p1[2] = float(color) / 255
p2[2] = float(color) / 255
line = Line(Point(p1[0], p1[1], p1[2]), Point(p2[0], p2[1], p2[2]))
if line.len > 0:
if line.p1 != line.p2:
self.lines.append(line)
else:
log.warn("DXFImporter: Ignoring zero-length LINE (between " \
......@@ -817,7 +830,8 @@ class DXFParser(object):
p1 = Point(p1[0], p1[1], center.z)
p2 = xy_point_coords[index + 1]
p2 = Point(p2[0], p2[1], center.z)
self.lines.append(Line(p1, p2))
if p1 != p2:
self.lines.append(Line(p1, p2))
else:
log.warn("DXFImporter: Ignoring tiny ARC (between input " + \
"line %d and %d): %s / %s (%s - %s)" % (start_line,
......
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