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): ...@@ -344,20 +344,33 @@ class ContourModel(BaseModel):
break break
# merge 'other_polygon' with all other connectable polygons # merge 'other_polygon' with all other connectable polygons
for polygon in connectables: 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]: if other_polygon.get_points()[-1] == polygon.get_points()[0]:
for line in polygon.get_lines(): for line in polygon.get_lines():
if other_polygon.is_closed:
return
other_polygon.append(line) other_polygon.append(line)
self._line_groups.remove(polygon) self._line_groups.remove(polygon)
elif other_polygon.get_points()[0] == polygon.get_points()[-1]: elif other_polygon.get_points()[0] == polygon.get_points()[-1]:
lines = polygon.get_lines() lines = polygon.get_lines()
lines.reverse() lines.reverse()
for line in lines: for line in lines:
if other_polygon.is_closed:
return
other_polygon.append(line) other_polygon.append(line)
self._line_groups.remove(polygon) self._line_groups.remove(polygon)
elif allow_reverse: elif allow_reverse:
if other_polygon.get_points()[-1] == polygon.get_points()[-1]: if other_polygon.get_points()[-1] == polygon.get_points()[-1]:
polygon.reverse_direction() polygon.reverse_direction()
for line in polygon.get_lines(): for line in polygon.get_lines():
if other_polygon.is_closed:
return
other_polygon.append(line) other_polygon.append(line)
self._line_groups.remove(polygon) self._line_groups.remove(polygon)
elif other_polygon.get_points()[0] == polygon.get_points()[0]: elif other_polygon.get_points()[0] == polygon.get_points()[0]:
...@@ -365,12 +378,17 @@ class ContourModel(BaseModel): ...@@ -365,12 +378,17 @@ class ContourModel(BaseModel):
lines = polygon.get_lines() lines = polygon.get_lines()
lines.reverse() lines.reverse()
for line in lines: for line in lines:
if other_polygon.is_closed:
return
other_polygon.append(line) other_polygon.append(line)
self._line_groups.remove(polygon) self._line_groups.remove(polygon)
else: else:
pass pass
else: else:
pass pass
if other_polygon.is_closed:
# we are finished
return
def append(self, item, unify_overlaps=False, allow_reverse=False): def append(self, item, unify_overlaps=False, allow_reverse=False):
super(ContourModel, self).append(item) super(ContourModel, self).append(item)
...@@ -379,7 +397,11 @@ class ContourModel(BaseModel): ...@@ -379,7 +397,11 @@ class ContourModel(BaseModel):
if allow_reverse: if allow_reverse:
item_list.append(Line(item.p2, item.p1)) item_list.append(Line(item.p2, item.p1))
found = False 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: for candidate in item_list:
if line_group.is_connectable(candidate): if line_group.is_connectable(candidate):
line_group.append(candidate) line_group.append(candidate)
...@@ -470,15 +492,25 @@ class ContourModel(BaseModel): ...@@ -470,15 +492,25 @@ class ContourModel(BaseModel):
Beware: never use this function if the direction of lines may not Beware: never use this function if the direction of lines may not
change. 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() open_polygons = [poly for poly in self.get_polygons()
if not poly.is_closed] 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: for poly in open_polygons:
self._line_groups.remove(poly) self._line_groups.remove(poly)
poly_open_before = len(open_polygons) poly_open_before = len(open_polygons)
for poly in open_polygons: for poly in open_polygons:
for line in poly.get_lines(): for line in poly.get_lines():
self.append(line, allow_reverse=True) self.append(line, allow_reverse=True)
if progress_callback and progress_callback():
return
poly_open_after = len([poly for poly in self.get_polygons() poly_open_after = len([poly for poly in self.get_polygons()
if not poly.is_closed]) if not poly.is_closed])
if poly_open_before != poly_open_after: if poly_open_before != poly_open_after:
...@@ -490,11 +522,10 @@ class ContourModel(BaseModel): ...@@ -490,11 +522,10 @@ class ContourModel(BaseModel):
finished = [] finished = []
remaining_polys = [poly for poly in self.get_polygons() remaining_polys = [poly for poly in self.get_polygons()
if poly.is_closed] if poly.is_closed]
if callback: if progress_callback:
progress_callback = pycam.Utils.ProgressCounter( # shift the counter back by the number of new closed polygons
2 * len(remaining_polys), callback).increment progress_callback(2 * (number_of_initial_closed_polygons - \
else: len(remaining_polys)))
progress_callback = None
remaining_polys.sort(key=lambda poly: abs(poly.get_area())) remaining_polys.sort(key=lambda poly: abs(poly.get_area()))
while remaining_polys: while remaining_polys:
# pick the largest polygon # pick the largest polygon
......
...@@ -62,7 +62,7 @@ class Polygon(TransformableContainer): ...@@ -62,7 +62,7 @@ class Polygon(TransformableContainer):
def append(self, line): def append(self, line):
if not self.is_connectable(line): if not self.is_connectable(line):
raise ValueError("This line does not fit to the polygon") 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 " \ raise ValueError("A line with zero length may not be part of a " \
+ "polygon") + "polygon")
else: else:
...@@ -365,7 +365,6 @@ class Polygon(TransformableContainer): ...@@ -365,7 +365,6 @@ class Polygon(TransformableContainer):
for line in self.get_lines(): for line in self.get_lines():
line.to_OpenGL(**kwords) line.to_OpenGL(**kwords)
def _update_limits(self, point): def _update_limits(self, point):
if self.minx is None: if self.minx is None:
self.minx = point.x self.minx = point.x
......
...@@ -85,7 +85,7 @@ class DXFParser(object): ...@@ -85,7 +85,7 @@ class DXFParser(object):
IGNORE_KEYS = ("DICTIONARY", "VPORT", "LTYPE", "STYLE", "APPID", "DIMSTYLE", IGNORE_KEYS = ("DICTIONARY", "VPORT", "LTYPE", "STYLE", "APPID", "DIMSTYLE",
"BLOCK_RECORD", "BLOCK", "ENDBLK", "ACDBDICTIONARYWDFLT", "POINT", "BLOCK_RECORD", "BLOCK", "ENDBLK", "ACDBDICTIONARYWDFLT", "POINT",
"ACDBPLACEHOLDER", "LAYOUT", "MLINESTYLE", "DICTIONARYVAR", "CLASS", "ACDBPLACEHOLDER", "LAYOUT", "MLINESTYLE", "DICTIONARYVAR", "CLASS",
"HATCH") "HATCH", "VIEW", "VIEWPORT")
def __init__(self, inputstream, color_as_height=False, fonts_cache=None, def __init__(self, inputstream, color_as_height=False, fonts_cache=None,
callback=None): callback=None):
...@@ -203,7 +203,20 @@ class DXFParser(object): ...@@ -203,7 +203,20 @@ class DXFParser(object):
line1 = None line1 = None
line2 = None line2 = None
elif line1 in [self.KEYS[key] for key in ("DEFAULT", "TEXT_MORE")]: 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: else:
line2 = line2.upper() line2 = line2.upper()
self.line_number += 2 self.line_number += 2
...@@ -253,7 +266,7 @@ class DXFParser(object): ...@@ -253,7 +266,7 @@ class DXFParser(object):
if self._open_sequence == "POLYLINE": if self._open_sequence == "POLYLINE":
self.parse_polyline(False) self.parse_polyline(False)
else: else:
log.warn("DXFImporter: unexpected SEQEND found at line %d" + \ log.warn("DXFImporter: unexpected SEQEND found at line %d" % \
start_line) start_line)
def parse_vertex(self): def parse_vertex(self):
...@@ -556,7 +569,7 @@ class DXFParser(object): ...@@ -556,7 +569,7 @@ class DXFParser(object):
# item. # item.
if not key is None: if not key is None:
self._push_on_stack(key, value) 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 # just a warning - continue as usual
log.warn("DXFImporter: Second alignment point is not " + \ log.warn("DXFImporter: Second alignment point is not " + \
"implemented for TEXT items - the text specified " + \ "implemented for TEXT items - the text specified " + \
...@@ -755,7 +768,7 @@ class DXFParser(object): ...@@ -755,7 +768,7 @@ class DXFParser(object):
p1[2] = float(color) / 255 p1[2] = float(color) / 255
p2[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])) 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) self.lines.append(line)
else: else:
log.warn("DXFImporter: Ignoring zero-length LINE (between " \ log.warn("DXFImporter: Ignoring zero-length LINE (between " \
...@@ -817,6 +830,7 @@ class DXFParser(object): ...@@ -817,6 +830,7 @@ class DXFParser(object):
p1 = Point(p1[0], p1[1], center.z) p1 = Point(p1[0], p1[1], center.z)
p2 = xy_point_coords[index + 1] p2 = xy_point_coords[index + 1]
p2 = Point(p2[0], p2[1], center.z) p2 = Point(p2[0], p2[1], center.z)
if p1 != p2:
self.lines.append(Line(p1, p2)) self.lines.append(Line(p1, p2))
else: else:
log.warn("DXFImporter: Ignoring tiny ARC (between input " + \ log.warn("DXFImporter: Ignoring tiny ARC (between input " + \
......
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