Commit dfbffd2b authored by sumpfralle's avatar sumpfralle

more style fixes

disabled "namedtuple" for now (it was never in effect)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@975 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent f84adff7
......@@ -3,7 +3,7 @@
$Id$
Copyright 2008-2010 Lode Leroy
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
Copyright 2010-2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
......@@ -22,11 +22,10 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Utils.threading
from pycam.Geometry.Point import Point
from pycam.Geometry.utils import number, INFINITE, epsilon
from pycam.Geometry.intersection import intersect_circle_point, \
intersect_cylinder_point, intersect_cylinder_line
from pycam.Geometry.intersection import intersect_cylinder_point, \
intersect_cylinder_line
import uuid
......@@ -49,7 +48,8 @@ class BaseCutter(object):
self.distance_radius = self.radius
self.distance_radiussq = self.distance_radius ** 2
self.shape = {}
self.moveto(location)
self.location = location
self.moveto(self.location)
self.uuid = None
self.update_uuid()
......@@ -131,8 +131,7 @@ class BaseCutter(object):
* triangle.radius + triangle.radiussq) + epsilon:
return None
(cl, d, cp) = self.intersect(BaseCutter.vertical, triangle, start=start)
return cl
return self.intersect(BaseCutter.vertical, triangle, start=start)[0]
def intersect_circle_triangle(self, direction, triangle, start=None):
(cl, ccp, cp, d) = self.intersect_circle_plane(direction, triangle,
......
......@@ -131,7 +131,8 @@ class CylindricalCutter(BaseCutter):
def moveto(self, location, **kwargs):
BaseCutter.moveto(self, location, **kwargs)
self.center = Point(location.x, location.y, location.z - self.get_required_distance())
self.center = Point(location.x, location.y,
location.z - self.get_required_distance())
def intersect_circle_plane(self, direction, triangle, start=None):
if start is None:
......@@ -166,10 +167,6 @@ class CylindricalCutter(BaseCutter):
return (cl, ccp, cp, l)
return (None, None, None, INFINITE)
def intersect_plane(self, direction, triangle, start=None):
# TODO: are "intersect_plane" and "self.intersect_circle_plane" obsolete?
return self.intersect_circle_plane(direction, triangle, start=start)
def intersect(self, direction, triangle, start=None):
(cl_t, d_t, cp_t) = self.intersect_circle_triangle(direction, triangle,
start=start)
......
......@@ -128,7 +128,8 @@ class ToroidalCutter(BaseCutter):
return (None, None, None, INFINITE)
def intersect_torus_triangle(self, direction, triangle, start=None):
(cl, ccp, cp, d) = self.intersect_torus_plane(direction, triangle, start=start)
(cl, ccp, cp, d) = self.intersect_torus_plane(direction, triangle,
start=start)
if cp and triangle.is_point_inside(cp):
return (cl, d, cp)
return (None, INFINITE, None)
......
......@@ -27,11 +27,12 @@ import os
class STLExporter:
def __init__(self, model, name="model", created_by="pycam", linesep=None, comment=None):
def __init__(self, model, name="model", created_by="pycam", linesep=None,
comment=None):
# sadly STL does not seem to support comments
self.model = model
self.name = name
self.created_by = created_by
self.comment = comment
if linesep is None:
self.linesep = os.linesep
else:
......@@ -49,20 +50,14 @@ class STLExporter:
date = datetime.date.today().isoformat()
yield """solid "%s"; Produced by %s (v%s), %s""" \
% (self.name, self.created_by, VERSION, date)
# sadly STL does not seem to support comments
"""
if self.comment:
for line in self.comment.split(self.linesep):
yield(";%s" % line)
"""
for tr in self.model.triangles():
norm = tr.normal.normalized()
for triangle in self.model.triangles():
norm = triangle.normal.normalized()
yield "facet normal %f %f %f" % (norm.x, norm.y, norm.z)
yield " outer loop"
# Triangle vertices are stored in clockwise order - thus we need
# to reverse the order (STL expects counter-clockwise orientation).
for p in (tr.p3, tr.p2, tr.p1):
yield " vertex %f %f %f" % (p.x, p.y, p.z)
for point in (triangle.p3, triangle.p2, triangle.p1):
yield " vertex %f %f %f" % (point.x, point.y, point.z)
yield " endloop"
yield "endfacet"
yield "endsolid"
......
......@@ -29,7 +29,7 @@ class SVGExporter:
def __init__(self, output, unit="mm"):
if isinstance(output, basestring):
# a filename was given
self.output = file(filename,"w")
self.output = file(output,"w")
else:
# a stream was given
self.output = output
......
......@@ -44,15 +44,22 @@ class gcode:
"G04 P3 T%d M6" % self.tool_id,
"G00 Z%.4f" % self.safetyheight)
def end(self):
return "M2"
def exactpath(self):
return "G61"
def continuous(self):
return "G64"
def rapid(self, x = None, y = None, z = None, a = None, gcode = "G00",
feed=None):
gcodestring = feedstring = xstring = ystring = zstring = astring = ""
def rapid(self, x=None, y=None, z=None, a=None, code="G00", feed=None):
gcodestring = ""
feedstring = ""
xstring = ""
ystring = ""
zstring = ""
astring = ""
if x == None:
x = self.lastx
if y == None:
......@@ -61,9 +68,9 @@ class gcode:
z = self.lastz
if a == None:
a = self.lasta
if gcode != self.lastgcode:
gcodestring = gcode
self.lastgcode = gcode
if code != self.lastgcode:
gcodestring = code
self.lastgcode = code
if x != self.lastx:
xstring = " X%.4f" % (x)
self.lastx = x
......@@ -76,7 +83,7 @@ class gcode:
if a != self.lasta:
astring = " A%.4f" % (a)
self.lasta = a
if (gcode == "G01") and feed and (feed != self.lastfeed):
if (code == "G01") and feed and (feed != self.lastfeed):
feedstring = " F%.4f" % (feed)
self.lastfeed = feed
positionstring = xstring + ystring + zstring + astring
......@@ -90,7 +97,7 @@ class gcode:
if y == None: y = self.lasty
if z == None: z = self.lastz
if a == None: a = self.lasta
return self.rapid(x, y, z, a, gcode="G01", feed=feed)
return self.rapid(x, y, z, a, code="G01", feed=feed)
def safety(self):
return self.rapid(z=self.safetyheight)
......
......@@ -27,12 +27,10 @@ from pycam.Geometry.Plane import Plane
from pycam.Geometry.utils import epsilon, sqrt
# OpenGLTools will be imported later, if necessary
#import pycam.Gui.OpenGLTools
import math
try:
import OpenGL.GL as GL
import OpenGL.GLUT as GLUT
GL_enabled = True
except ImportError:
GL_enabled = False
......@@ -42,6 +40,7 @@ class Line(TransformableContainer):
id = 0
def __init__(self, p1, p2):
super(Line, self).__init__()
self.id = Line.id
Line.id += 1
self.p1 = p1
......
......@@ -27,7 +27,7 @@ from pycam.Geometry.Triangle import Triangle
from pycam.Geometry.Line import Line
from pycam.Geometry.Plane import Plane
from pycam.Geometry.Polygon import Polygon
from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Point import Point
from pycam.Geometry.TriangleKdtree import TriangleKdtree
from pycam.Geometry.Matrix import TRANSFORMATIONS
from pycam.Toolpath import Bounds
......@@ -110,7 +110,8 @@ class BaseModel(TransformableContainer):
+ "support the 'export' function.") % str(type(self)))
def _update_limits(self, item):
# ignore items without limit attributes (e.g. the normal of a ContourModel)
# Ignore items without limit attributes (e.g. the normal of a
# ContourModel).
if hasattr(item, "minx"):
if self.minx is None:
self.minx = item.minx
......@@ -313,7 +314,8 @@ class ContourModel(BaseModel):
self._plane_groups = [self._plane]
self._item_groups.append(self._plane_groups)
self._cached_offset_models = {}
self._export_function = pycam.Exporters.SVGExporter.SVGExporterContourModel
self._export_function = \
pycam.Exporters.SVGExporter.SVGExporterContourModel
def reset_cache(self):
super(ContourModel, self).reset_cache()
......@@ -409,8 +411,10 @@ class ContourModel(BaseModel):
new_queue = processed
while len(self._line_groups) > 0:
self._line_groups.pop()
print "Processed polygons: %s" % str([len(p.get_lines()) for p in processed_polygons])
print "New queue: %s" % str([len(p.get_lines()) for p in new_queue])
print "Processed polygons: %s" % str([len(p.get_lines())
for p in processed_polygons])
print "New queue: %s" % str([len(p.get_lines())
for p in new_queue])
for processed_polygon in processed_polygons + new_queue:
self._line_groups.append(processed_polygon)
# TODO: this is quite expensive - can we do it differently?
......
......@@ -29,8 +29,10 @@ This reduces the memory consumption of a toolpath down to 1/3.
try:
# this works for python 2.6 or above (saves memory)
import collections.namedtuple
tuple_point = collections.namedtuple("TuplePoint", "x y z")
# TODO: disabled for now - check if we could enable it later ...
import INVALID_IMPORT
from collections import namedtuple
tuple_point = namedtuple("TuplePoint", "x y z")
get_point_object = lambda point: tuple_point(point.x, point.y, point.z)
except ImportError:
# dummy for python < v2.6 (consumes more memory)
......@@ -48,22 +50,22 @@ class Path:
self.points = []
def __repr__(self):
s = ""
s += "path %d: " % self.id
text = ""
text += "path %d: " % self.id
first = True
for p in self.points:
for point in self.points:
if first:
first = False
else:
s += "-"
s += "%d(%g,%g,%g)" % (p.id, p.x, p.y, p.z)
return s
text += "-"
text += "%d(%g,%g,%g)" % (point.id, point.x, point.y, point.z)
return text
def insert(self, index, p):
self.points.insert(index, get_point_object(p))
def insert(self, index, point):
self.points.insert(index, get_point_object(point))
def append(self, p):
self.points.append(get_point_object(p))
def append(self, point):
self.points.append(get_point_object(point))
def reverse(self):
self.points.reverse()
......@@ -22,18 +22,19 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Geometry import TransformableContainer
from pycam.Geometry.utils import INFINITE, epsilon
from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Point import Vector
# "Line" is imported later to avoid circular imports
#from pycam.Geometry.Line import Line
class Plane(TransformableContainer):
id = 0
def __init__(self, p, n):
def __init__(self, point, normal):
super(Plane, self).__init__()
self.id = Plane.id
Plane.id += 1
self.p = p
self.n = n
self.p = point
self.n = normal
if not isinstance(self.n, Vector):
self.n = self.n.get_vector()
......@@ -123,8 +124,7 @@ class Plane(TransformableContainer):
return None
def get_point_projection(self, point):
p, dist = self.intersect_point(self.n, point)
return p
return self.intersect_point(self.n, point)[0]
def get_line_projection(self, line):
# don't import Line in the header -> circular import
......
......@@ -25,9 +25,7 @@ from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Plane import Plane
from pycam.Geometry import TransformableContainer, get_bisector
from pycam.Geometry.utils import number, epsilon
import pycam.Geometry.Matrix as Matrix
import pycam.Utils.log
import math
# import later to avoid circular imports
#from pycam.Geometry.Model import ContourModel
......@@ -69,7 +67,8 @@ class Polygon(TransformableContainer):
self._update_limits(line.p2)
elif self._points[-1] == line.p1:
# the new Line can be added to the end of the polygon
if line.dir == self._points[-1].sub(self._points[-2]).normalized():
if line.dir == self._points[-1].sub(
self._points[-2]).normalized():
# Remove the last point, if the previous point combination
# is in line with the new Line. This avoids unnecessary
# points on straight lines.
......@@ -84,7 +83,8 @@ class Polygon(TransformableContainer):
else:
# the new Line can be added to the beginning of the polygon
if (len(self._points) > 1) \
and (line.dir == self._points[1].sub(self._points[0]).normalized()):
and (line.dir == self._points[1].sub(
self._points[0]).normalized()):
# Avoid points on straight lines - see above.
self._points.pop(0)
if line.p1 != self._points[-1]:
......@@ -142,7 +142,6 @@ class Polygon(TransformableContainer):
Currently this works only for line groups in an xy-plane.
Returns zero for empty line groups or for open line groups.
Returns negative values for inner hole.
TODO: "get_area" is wrong by some factor - check the result!
"""
if not self._points:
return 0
......@@ -227,7 +226,8 @@ class Polygon(TransformableContainer):
or (not self.is_closed and index == len(self._points) - 1):
return None
else:
return self._points[index].add(self._points[(index + 1) % len(self._points)]).div(2)
return self._points[index].add(self._points[(index + 1) % \
len(self._points)]).div(2)
def get_lengths(self):
result = []
......@@ -324,7 +324,8 @@ class Polygon(TransformableContainer):
lines = []
for index in range(len(self._points) - 1):
lines.append(Line(self._points[index], self._points[index + 1]))
# connect the last point with the first only if the polygon is closed
# Connect the last point with the first only if the polygon is
# closed.
if self.is_closed:
lines.append(Line(self._points[-1], self._points[0]))
self._lines_cache = lines
......@@ -333,16 +334,6 @@ class Polygon(TransformableContainer):
def to_OpenGL(self, **kwords):
for line in self.get_lines():
line.to_OpenGL(**kwords)
return
offset_polygons = self.get_offset_polygons(0.2)
for polygon in offset_polygons:
for line in polygon.get_lines():
line.to_OpenGL(**kwords)
"""
for index, point in enumerate(self._points):
line = Line(point, point.add(self.get_bisector(index)))
line.get_length_line(1).to_OpenGL()
"""
def _update_limits(self, point):
if self.minx is None:
......@@ -452,9 +443,12 @@ class Polygon(TransformableContainer):
shifted_lines[prev_index] = (False, Line(prev_line.p1, cp))
shifted_lines[next_index] = (False, Line(cp, next_line.p2))
else:
cp, dist = prev_line.get_intersection(next_line, infinite_lines=True)
raise BaseException("Expected intersection not found: " \
+ "%s - %s - %s(%d) / %s(%d)" % (cp, shifted_lines[prev_index+1:next_index], prev_line, prev_index, next_line, next_index))
cp, dist = prev_line.get_intersection(next_line,
infinite_lines=True)
raise BaseException("Expected intersection not found: " + \
"%s - %s - %s(%d) / %s(%d)" % \
(cp, shifted_lines[prev_index+1:next_index],
prev_line, prev_index, next_line, next_index))
if index > next_index:
# we wrapped around the end of the list
break
......@@ -603,7 +597,8 @@ class Polygon(TransformableContainer):
for cached_offset in self._cached_offset_polygons:
if is_better_offset(best_offset, cached_offset):
best_offset = cached_offset
best_offset_polygons = self._cached_offset_polygons[cached_offset]
best_offset_polygons = \
self._cached_offset_polygons[cached_offset]
remaining_offset = offset - best_offset
result_polygons = []
for poly in best_offset_polygons:
......@@ -780,14 +775,16 @@ class Polygon(TransformableContainer):
# We ignore groups that changed the direction. These
# parts of the original group are flipped due to the
# offset.
log.debug("Ignoring reversed polygon: %s / %s" % (self.get_area(), group.get_area()))
log.debug("Ignoring reversed polygon: %s / %s" % \
(self.get_area(), group.get_area()))
continue
# Remove polygons that should be inside the original,
# but due to float inaccuracies they are not.
if ((self.is_outer() and (offset < 0)) \
or (not self.is_outer() and (offset > 0))) \
and (not self.is_polygon_inside(group)):
log.debug("Ignoring inaccurate polygon: %s / %s" % (self.get_area(), group.get_area()))
log.debug("Ignoring inaccurate polygon: %s / %s" \
% (self.get_area(), group.get_area()))
continue
groups.append(group)
if not groups:
......
......@@ -39,11 +39,14 @@ else:
ceil = lambda value: int(math.ceil(value))
# return "0" for "-epsilon < value < 0" (to work around floating inaccuracies)
# otherwise: return the sqrt function of the current type (could even raise exceptions)
# otherwise: return the sqrt function of the current type (could even raise
# exceptions)
if _use_precision:
sqrt = lambda value: (((value < -epsilon) or (value > 0)) and value.sqrt()) or 0
sqrt = lambda value: (((value < -epsilon) or (value > 0)) and \
value.sqrt()) or 0
else:
sqrt = lambda value: (((value < -epsilon) or (value > 0)) and math.sqrt(value)) or 0
sqrt = lambda value: (((value < -epsilon) or (value > 0)) and \
math.sqrt(value)) or 0
if _use_precision:
number = lambda value: decimal.Decimal(str(value))
......
......@@ -2,7 +2,7 @@
"""
$Id$
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
Copyright 2010-2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
......@@ -32,13 +32,11 @@ except (ImportError, RuntimeError):
from pycam.Geometry.Point import Point
import pycam.Geometry.Matrix as Matrix
from pycam.Geometry.utils import sqrt, number, epsilon
from pycam.Geometry.utils import sqrt, number
import pycam.Utils.log
import gtk
import gobject
import pango
import math
import time
# buttons for rotating, moving and zooming the model view window
BUTTON_ROTATE = gtk.gdk.BUTTON1_MASK
......@@ -237,12 +235,13 @@ class Camera:
# This distance calculation is completely based on trial-and-error.
distance = math.sqrt(sum([d ** 2 for d in v["distance"]]))
distance *= math.log(math.sqrt(width * height)) / math.log(10)
left = v["center"][0] - math.sin(v["fovy"] / 360.0 * math.pi) * distance
right = v["center"][0] + math.sin(v["fovy"] / 360.0 * math.pi) * distance
top = v["center"][1] + math.sin(v["fovy"] / 360.0 * math.pi) * distance
bottom = v["center"][1] - math.sin(v["fovy"] / 360.0 * math.pi) * distance
near = v["center"][2] - 2 * math.sin(v["fovy"] / 360.0 * math.pi) * distance
far = v["center"][2] + 2 * math.sin(v["fovy"] / 360.0 * math.pi) * distance
sin_factor = math.sin(v["fovy"] / 360.0 * math.pi) * distance
left = v["center"][0] - sin_factor
right = v["center"][0] + sin_factor
top = v["center"][1] + sin_factor
bottom = v["center"][1] - sin_factor
near = v["center"][2] - 2 * sin_factor
far = v["center"][2] + 2 * sin_factor
GL.glOrtho(left, right, bottom, top, near, far)
GLU.gluLookAt(camera_position[0], camera_position[1],
camera_position[2], v["center"][0], v["center"][1],
......@@ -383,9 +382,10 @@ class ModelViewWindowGL:
for action in context_menu_actions:
action_group.add_action(action)
uimanager = gtk.UIManager()
# the "pos" parameter is optional since 2.12 - we can remove it later
# The "pos" parameter is optional since gtk 2.12 - we can
# remove it later.
uimanager.insert_action_group(action_group, pos=-1)
uimanager_template = """<ui><popup name="context">%s</popup></ui>"""
uimanager_template = '<ui><popup name="context">%s</popup></ui>'
uimanager_item_template = """<menuitem action="%s" />"""
uimanager_text = uimanager_template % "".join(
[uimanager_item_template % action.get_name()
......@@ -442,12 +442,6 @@ class ModelViewWindowGL:
ord("K"): (0, 1),
ord("L"): (-1, 0),
}
def get_char(value):
# avoid exceptions
if 0 <= value <= 255:
return chr(value)
else:
return None
if key_string and (key_string in '1234567'):
names = ["reset", "front", "back", "left", "right", "top", "bottom"]
index = '1234567'.index(key_string)
......@@ -603,7 +597,8 @@ class ModelViewWindowGL:
and (abs(event.y - self.mouse["pressed_pos"][1]) < 3):
# A quick press/release cycle with the right mouse button
# -> open the context menu.
self.context_menu.popup(None, None, None, event.button, int(event.get_time()))
self.context_menu.popup(None, None, None, event.button,
int(event.get_time()))
@check_busy
@gtkgl_functionwrapper
......@@ -910,8 +905,8 @@ def draw_complete_model_view(settings):
and settings.get("simulation_toolpath_moves")):
GL.glColor4f(*settings.get("color_model"))
model = settings.get("model")
min_area = abs(model.maxx - model.minx) * abs(model.maxy - model.miny) / 100
"""
min_area = abs(model.maxx - model.minx) * abs(model.maxy - model.miny) / 100
# example for coloring specific triangles
groups = model.get_flat_areas(min_area)
all_flat_ids = []
......
This diff is collapsed.
......@@ -359,9 +359,9 @@ process: 3
tasks=None):
text = self.get_config_text(tools, processes, bounds, tasks)
try:
fi = open(filename, "w")
fi.write(text)
fi.close()
handle = open(filename, "w")
handle.write(text)
handle.close()
except IOError, err_msg:
log.error("Settings: Failed to write configuration to file " \
+ "(%s): %s" % (filename, err_msg))
......@@ -417,7 +417,8 @@ process: 3
try:
try:
value_raw = self.config.get(
prefix + self.DEFAULT_SUFFIX, key, raw=raw)
prefix + self.DEFAULT_SUFFIX, key,
raw=raw)
except (ConfigParser.NoSectionError,
ConfigParser.NoOptionError):
value_raw = None
......@@ -474,13 +475,13 @@ process: 3
def get_config_text(self, tools=None, processes=None, bounds=None,
tasks=None):
def get_dictionary_of_bounds(b):
def get_dictionary_of_bounds(boundary):
""" this function should be the inverse operation of
'_get_bounds_instance_from_dict'
"""
result = {}
result["name"] = b.get_name()
bounds_type_num = b.get_type()
result["name"] = boundary.get_name()
bounds_type_num = boundary.get_type()
if bounds_type_num == Bounds.TYPE_RELATIVE_MARGIN:
bounds_type_name = "relative_margin"
elif bounds_type_num == Bounds.TYPE_FIXED_MARGIN:
......@@ -488,12 +489,12 @@ process: 3
else:
bounds_type_name = "custom"
result["type"] = bounds_type_name
low, high = b.get_bounds()
low, high = boundary.get_bounds()
for index, axis in enumerate("xyz"):
result["%s_low" % axis] = low[index]
result["%s_high" % axis] = high[index]
# special handler to allow tasks to track this new object
result[self.REFERENCE_TAG] = b
result[self.REFERENCE_TAG] = boundary
return result
result = []
if tools is None:
......
......@@ -44,7 +44,7 @@ DEPENDENCY_DESCRIPTION = {
+ "'glxgears' to locate this problem."),
}
REQUIREMENTS_LINK = "http://sourceforge.net/apps/mediawiki/pycam/index.php?title=Requirements"
REQUIREMENTS_LINK = "http://sf.net/apps/mediawiki/pycam/?title=Requirements"
# Usually the windows registry "HKEY_LOCAL_MACHINE/SOFTWARE/Gtk+/Path" contains
# something like: C:\Programs\Common files\GTK
......@@ -80,8 +80,8 @@ def import_gtk_carefully():
except NameError:
# GTK is probably not installed - the next import will fail
pass
except WindowsError:
# this happens with pyinstaller binaries - just ignore it
except OSError:
# "WindowsError" - this happens with pyinstaller binaries
pass
else:
# add the new path to the PATH environment variable
......
......@@ -183,8 +183,9 @@ class DXFParser(object):
for index in range(len(p_array)):
if p_array[index] is None:
if (index == 0) or (index == 1):
log.debug("DXFImporter: weird LWPOLYLINE input data " \
+ "in line %d: %s" % (self.line_number, p_array))
log.debug("DXFImporter: weird LWPOLYLINE input " + \
"date in line %d: %s" % \
(self.line_number, p_array))
p_array[index] = 0
points.append(Point(p_array[0], p_array[1], p_array[2]))
start_line = self.line_number
......@@ -323,8 +324,8 @@ class DXFParser(object):
center = Point(center[0], center[1], center[2])
xy_point_coords = pycam.Geometry.get_points_of_arc(center, radius,
angle_start, angle_end)
# Somehow the order of points seems to be the opposite of the what
# is expected.
# Somehow the order of points seems to be the opposite of what is
# expected.
xy_point_coords.reverse()
if len(xy_point_coords) > 1:
for index in range(len(xy_point_coords) - 1):
......@@ -334,9 +335,9 @@ class DXFParser(object):
p2 = Point(p2[0], p2[1], center.z)
self.lines.append(Line(p1, p2))
else:
log.warn("DXFImporter: Ignoring zero-length LINE (between " \
+ "input line %d and %d): %s" % (start_line, end_line,
line))
log.warn("DXFImporter: Ignoring tiny ARC (between input " + \
"line %d and %d): %s / %s (%s - %s)" % (start_line,
end_line, center, radius, angle_start, angle_end))
def check_header(self):
# TODO: this function is not used?
......@@ -367,8 +368,8 @@ def import_model(filename, program_locations=None, unit=None,
if lines:
model = pycam.Geometry.Model.ContourModel()
for index, l in enumerate(lines):
model.append(l)
for index, line in enumerate(lines):
model.append(line)
# keep the GUI smooth
if callback and (index % 50 == 0):
callback()
......@@ -390,7 +391,7 @@ def import_model(filename, program_locations=None, unit=None,
% (len(lines), len(model.get_polygons())))
return model
else:
link = "http://sourceforge.net/apps/mediawiki/pycam/index.php?title=SupportedFormats"
link = "http://sf.net/apps/mediawiki/pycam/?title=SupportedFormats"
log.error('DXFImporter: No supported elements found in DXF file!\n' \
+ '<a href="%s">Read PyCAM\'s modelling hints.</a>' % link)
return None
......
......@@ -23,7 +23,6 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Importers.SVGImporter import convert_eps2dxf
import pycam.Importers.DXFImporter
import tempfile
import subprocess
import os
log = pycam.Utils.log.get_logger()
......
......@@ -145,9 +145,9 @@ def ImportModel(filename, use_kdtree=True, program_locations=None, unit=None,
t = Triangle(p1, p3, p2)
elif dotcross < 0:
if not normal_conflict_warning_seen:
log.warn(("Inconsistent normal/vertices found in facet " \
+ "definition %d of '%s'. Please validate the STL " \
+ "file!") % (i, filename))
log.warn(("Inconsistent normal/vertices found in facet " + \
"definition %d of '%s'. Please validate the " + \
"STL file!") % (i, filename))
normal_conflict_warning_seen = True
t = Triangle(p1, p2, p3)
else:
......@@ -245,9 +245,9 @@ def ImportModel(filename, use_kdtree=True, program_locations=None, unit=None,
t = Triangle(p1, p3, p2, n)
elif dotcross < 0:
if not normal_conflict_warning_seen:
log.warn(("Inconsistent normal/vertices found in line " \
+ "%d of '%s'. Please validate the STL file!") \
% (current_line, filename))
log.warn(("Inconsistent normal/vertices found in " + \
"line %d of '%s'. Please validate the STL " + \
"file!") % (current_line, filename))
normal_conflict_warning_seen = True
t = Triangle(p1, p2, p3, n)
else:
......
......@@ -68,10 +68,11 @@ def convert_eps2dxf(eps_filename, dxf_filename, location=None, unit="mm"):
if returncode == 0:
return True
elif returncode == -11:
log.warn(("SVGImporter: maybe there was a problem with the " \
+ "conversion from EPS (%s) to DXF\n Users of Ubuntu 'lucid' should install " \
+ "the package 'libpstoedit0c2a' from the 'maverick' " \
+ "repository to avoid this warning.") % str(eps_filename))
log.warn(("SVGImporter: maybe there was a problem with the " + \
"conversion from EPS (%s) to DXF\n Users of Ubuntu 'lucid' " + \
"should install the package 'libpstoedit0c2a' from the " + \
"'maverick' repository to avoid this warning.") % \
str(eps_filename))
return True
else:
log.warn(("SVGImporter: failed to convert EPS file (%s) to DXF file " \
......@@ -96,7 +97,8 @@ def import_model(filename, program_locations=None, unit="mm", callback=None):
# the "right" way would be:
# inkscape --print='| pstoedit -dt -f dxf:-polyaslines - -' input.svg
# Sadly a bug in v0.47 breaks this: https://bugs.launchpad.net/inkscape/+bug/511361
# Sadly a bug in v0.47 breaks this:
# https://bugs.launchpad.net/inkscape/+bug/511361
# convert svg to eps via inkscape
eps_file_handle, eps_file_name = tempfile.mkstemp(suffix=".eps")
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
"""
$Id$
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
Copyright 2010-2011 Lars Kruse <devel@sumpfralle.de>
Copyright 2008-2009 Lode Leroy
This file is part of PyCAM.
......@@ -21,8 +21,6 @@ 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.Point import Point
from pycam.Geometry.utils import INFINITE, ceil
from pycam.PathGenerators import get_max_height_dynamic
from pycam.Utils import ProgressCounter
from pycam.Utils.threading import run_in_parallel
......@@ -117,17 +115,17 @@ class DropCutter:
# cancel requested
quit_requested = True
break
for p in points:
if p is None:
for point in points:
if point is None:
# exceeded maxz - the cutter has to skip this point
self.pa.end_scanline()
self.pa.new_scanline()
continue
self.pa.append(p)
self.pa.append(point)
# "draw_callback" returns true, if the user requested to quit
# via the GUI.
# The progress counter may return True, if cancel was requested.
if draw_callback and draw_callback(tool_position=p,
if draw_callback and draw_callback(tool_position=point,
toolpath=self.pa.paths):
quit_requested = True
break
......
......@@ -22,9 +22,10 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.PathProcessors.PathAccumulator
from pycam.Geometry.Point import Point
from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Line import Line
from pycam.Geometry.Plane import Plane
from pycam.Geometry.utils import ceil
from pycam.PathGenerators import get_max_height_dynamic
from pycam.PathGenerators import get_max_height_dynamic, get_free_paths_ode, \
get_free_paths_triangles
from pycam.Utils import ProgressCounter
......@@ -178,19 +179,19 @@ class EngraveCutter:
# for both point pairs.
factor = (z - line.p1.z) / (line.p2.z - line.p1.z)
plane_point = line.p1.add(line.vector.mul(factor))
GenerateToolPathLinePush(pa, Line(line.p1, plane_point), z,
self.GenerateToolPathLinePush(pa, Line(line.p1, plane_point), z,
previous_z, draw_callback=draw_callback)
GenerateToolPathLinePush(pa, Line(plane_point, line.p2), z,
self.GenerateToolPathLinePush(pa, Line(plane_point, line.p2), z,
previous_z, draw_callback=draw_callback)
elif line.minz < previous_z < line.maxz:
plane = Plane(Point(0, 0, previous_z), Vector(0, 0, 1))
cp, d = plane.intersect_point(line.dir, line.p1)
cp = plane.intersect_point(line.dir, line.p1)[0]
# we can be sure that there is an intersection
if line.p1.z > previous_z:
p1, p2 = cp, line.p2
else:
p1, p2 = line.p1, cp
GenerateToolPathLinePush(pa, Line(p1, p2), z, previous_z,
self.GenerateToolPathLinePush(pa, Line(p1, p2), z, previous_z,
draw_callback=draw_callback)
else:
if line.maxz <= z:
......@@ -212,12 +213,13 @@ class EngraveCutter:
elif self.physics:
points = get_free_paths_ode(self.physics, p1, p2)
else:
points = get_free_paths_triangles(relevant_models, self.cutter, p1, p2)
points = get_free_paths_triangles(relevant_models, self.cutter,
p1, p2)
if points:
for p in points:
pa.append(p)
for point in points:
pa.append(point)
if draw_callback:
draw_callback(tool_position=p, toolpath=pa.paths)
draw_callback(tool_position=points[-1], toolpath=pa.paths)
def GenerateToolPathLineDrop(self, pa, line, minz, maxz, horiz_step,
......@@ -245,16 +247,17 @@ class EngraveCutter:
x_steps = [(p1.x + i * x_step) for i in range(num_of_steps)]
y_steps = [(p1.y + i * y_step) for i in range(num_of_steps)]
step_coords = zip(x_steps, y_steps)
# TODO: this "min(..)" is not correct for inclided lines. This should be fixed in "get_max_height".
# TODO: this "min(..)" is not correct for inclided lines. This
# should be fixed in "get_max_height".
points = get_max_height_dynamic(self.combined_model, self.cutter,
step_coords, min(p1.z, p2.z), maxz, self.physics)
for p in points:
if p is None:
for point in points:
if point is None:
# exceeded maxz - the cutter has to skip this point
pa.end_scanline()
pa.new_scanline()
continue
pa.append(p)
pa.append(point)
if draw_callback and points:
draw_callback(tool_position=points[-1], toolpath=pa.paths)
pa.end_scanline()
......
......@@ -21,10 +21,9 @@ 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.Point import Point
from pycam.PathGenerators import get_free_paths_ode, get_free_paths_triangles
import pycam.PathProcessors
from pycam.Geometry.utils import epsilon, ceil
from pycam.Geometry.utils import ceil
from pycam.Utils.threading import run_in_parallel
from pycam.Utils import ProgressCounter
import pycam.Utils.log
......@@ -86,7 +85,8 @@ class PushCutter:
break
self.pa.new_direction(0)
self.GenerateToolPathSlice(layer_grid, draw_callback, progress_counter)
self.GenerateToolPathSlice(layer_grid, draw_callback,
progress_counter)
self.pa.end_direction()
self.pa.finish()
......@@ -106,8 +106,8 @@ class PushCutter:
for p1, p2 in pairs:
free_points = get_free_paths_triangles(other_models,
self.cutter, p1, p2)
for p in free_points:
final_pa.append(p)
for point in free_points:
final_pa.append(point)
final_pa.end_scanline()
final_pa.finish()
return final_pa.paths
......@@ -144,10 +144,10 @@ class PushCutter:
callback=progress_counter.update):
if points:
self.pa.new_scanline()
for p in points:
self.pa.append(p)
for point in points:
self.pa.append(point)
if draw_callback:
draw_callback(tool_position=p, toolpath=self.pa.paths)
draw_callback(tool_position=points[-1], toolpath=self.pa.paths)
self.pa.end_scanline()
# update the progress counter
if progress_counter and progress_counter.increment():
......
......@@ -129,7 +129,7 @@ def get_free_paths_triangles(models, cutter, p1, p2, return_triangles=False):
return points
else:
# return only the cutter locations (without triangles)
return [cl for (cl, t, cp) in points]
return [cut_info[0] for cut_info in points]
def get_free_paths_ode(physics, p1, p2, depth=8):
......@@ -281,9 +281,10 @@ def get_max_height_dynamic(model, cutter, positions, minz, maxz, physics=None):
p1 = result[index]
p2 = result[index + 1]
p3 = result[index + 2]
if (not p1 is None) and (not p2 is None) and (not p3 is None) \
and not _check_deviance_of_adjacent_points(p1, p2, p3, min_distance) \
and (depth_count < max_depth):
if (not p1 is None) and (not p2 is None) and (not p3 is None) and \
not _check_deviance_of_adjacent_points(p1, p2, p3,
min_distance) and \
(depth_count < max_depth):
# distribute the new point two before the middle and one after
if depth_count % 3 != 2:
# insert between the 1st and 2nd point
......
......@@ -23,6 +23,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
from pycam.Geometry.utils import sqrt
from pycam.Geometry.Point import Point
import ctypes
import math
try:
......
......@@ -251,7 +251,6 @@ def generate_toolpath(model, tool_settings=None,
if (not contour_model is None) and (pocketing_type != "none"):
if not callback is None:
callback(text="Generating pocketing polygons ...")
new_polygons = []
pocketing_offset = cutter.radius * 1.8
# TODO: this is an arbitrary limit to avoid infinite loops
pocketing_limit = 1000
......@@ -273,8 +272,8 @@ def generate_toolpath(model, tool_settings=None,
else:
other_polygons.append(poly)
else:
return "Unknown pocketing type given (not one of 'none', 'holes', " \
+ "'enclosed'): %s" % str(pocketing_type)
return "Unknown pocketing type given (not one of 'none', " + \
"'holes', 'enclosed'): %s" % str(pocketing_type)
# For now we use only the polygons that do not surround eny other
# polygons. Sorry - the pocketing is currently very simple ...
base_filtered_polygons = []
......@@ -402,8 +401,9 @@ def _get_pathgenerator_instance(trimesh_models, contour_model, cutter,
elif pathprocessor == "ContourCutter":
processor = ContourCutter.ContourCutter()
else:
return ("Invalid postprocessor (%s) for 'PushCutter' - it should " \
+ "be one of these: %s") % (pathprocessor, PATH_POSTPROCESSORS)
return ("Invalid postprocessor (%s) for 'PushCutter' - it " + \
"should be one of these: %s") % \
(pathprocessor, PATH_POSTPROCESSORS)
return PushCutter.PushCutter(cutter, trimesh_models, processor,
physics=physics)
elif pathgenerator == "EngraveCutter":
......
......@@ -110,11 +110,13 @@ def get_fixed_grid_layer(minx, maxx, miny, maxy, z, line_distance,
if milling_style == MILLING_STYLE_IGNORE:
# just move forward - milling style is not important
pass
elif (milling_style == MILLING_STYLE_CLIMB) == (grid_direction == GRID_DIRECTION_X):
elif (milling_style == MILLING_STYLE_CLIMB) == \
(grid_direction == GRID_DIRECTION_X):
if bool(start_position & START_X) == bool(start_position & START_Y):
# we can't start from here - choose an alternative
start_position = get_alternative_start_position(start_position)
elif (milling_style == MILLING_STYLE_CONVENTIONAL) == (grid_direction == GRID_DIRECTION_X):
elif (milling_style == MILLING_STYLE_CONVENTIONAL) == \
(grid_direction == GRID_DIRECTION_X):
if bool(start_position & START_X) != bool(start_position & START_Y):
# we can't start from here - choose an alternative
start_position = get_alternative_start_position(start_position)
......
......@@ -21,7 +21,6 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Line import Line
from pycam.Geometry.Triangle import Triangle
from pycam.Geometry.Plane import Plane
from pycam.Geometry.Model import Model
......@@ -129,8 +128,8 @@ def get_support_grid_locations(minx, maxx, miny, maxy, dist_x, dist_y,
def get_support_grid(minx, maxx, miny, maxy, z_plane, dist_x, dist_y, thickness,
height, offset_x=0.0, offset_y=0.0, adjustments_x=None,
adjustments_y=None):
lines_x, lines_y = get_support_grid_locations(minx, maxx, miny, maxy, dist_x,
dist_y, offset_x, offset_y, adjustments_x, adjustments_y)
lines_x, lines_y = get_support_grid_locations(minx, maxx, miny, maxy,
dist_x, dist_y, offset_x, offset_y, adjustments_x, adjustments_y)
# create all x grid lines
grid_model = Model()
# convert all inputs to "number"
......@@ -214,7 +213,8 @@ class _BridgeCorner(object):
return "%s (%s) - %s" % (self.position, self.location, self.priority)
def _get_corner_bridges(polygon, z_plane, min_bridges, average_distance, avoid_distance):
def _get_corner_bridges(polygon, z_plane, min_bridges, average_distance,
avoid_distance):
""" try to place support bridges at corners of a polygon
Priorities:
- bigger corner angles are preferred
......@@ -264,7 +264,8 @@ def _get_corner_bridges(polygon, z_plane, min_bridges, average_distance, avoid_d
corners.remove(suitable_corners[0])
return [(c.position, c.direction) for c in bridge_corners]
def _get_edge_bridges(polygon, z_plane, min_bridges, average_distance, avoid_distance):
def _get_edge_bridges(polygon, z_plane, min_bridges, average_distance,
avoid_distance):
def is_near_list(point_list, point, distance):
for p in point_list:
if p.sub(point).norm <= distance:
......
......@@ -116,14 +116,15 @@ class Toolpath(object):
self.append = self.append_with_movement_limit
def append_with_movement_limit(self, new_position, rapid):
if self.last_pos is None:
# first movement with unknown start position - thus we ignore it
# first move with unknown start position - ignore it
self.moves.append((new_position, rapid))
self.last_pos = new_position
return True
else:
distance = new_position.sub(self.last_pos).norm
if self.moved_distance + distance > self.max_movement:
partial = (self.max_movement - self.moved_distance) / distance
partial = (self.max_movement - self.moved_distance) / \
distance
partial_dest = self.last_pos.add(new_position.sub(
self.last_pos).mul(partial))
self.moves.append((partial_dest, rapid))
......@@ -213,7 +214,8 @@ class Toolpath(object):
for path in self.toolpath:
if path:
for index in range(len(path.points) - 1):
open_lines.append(Line(path.points[index], path.points[index + 1]))
open_lines.append(Line(path.points[index],
path.points[index + 1]))
# go through all polygons and add "inner" lines (or parts thereof) to
# the final list of remaining lines
inner_lines = []
......
......@@ -99,9 +99,9 @@ def get_external_program_location(key):
location = win32api.FindExecutable(key)[1]
if location:
return location
except:
# Wildcard exeception to match "ImportError" and "pywintypes.error"
# (for "not found").
except Exception:
# Wildcard (non-system exiting) exeception to match "ImportError" and
# "pywintypes.error" (for "not found").
pass
# go through the PATH environment variable
if "PATH" in os.environ:
......
......@@ -45,7 +45,7 @@ try:
# prevent connection errors to trigger exceptions
try:
SyncManager._run_server(*args)
except socket.error, err_msg:
except socket.error:
pass
except ImportError:
pass
......@@ -151,7 +151,7 @@ class ManagerInfo(object):
def init_threading(number_of_processes=None, enable_server=False, remote=None,
run_server=False, server_credentials="", local_port=DEFAULT_PORT):
global __multiprocessing, __num_of_processes, __manager, __closing,
global __multiprocessing, __num_of_processes, __manager, __closing, \
__task_source_uuid
if __multiprocessing:
# kill the manager and clean everything up for a re-initialization
......@@ -465,8 +465,8 @@ def _handle_tasks(tasks, results, stats, cache, pending_tasks, closing):
def run_in_parallel_remote(func, args_list, unordered=False,
disable_multiprocessing=False, callback=None):
global __multiprocessing, __num_of_processes, __manager, __task_source_uuid,
__finished_jobs
global __multiprocessing, __num_of_processes, __manager, \
__task_source_uuid, __finished_jobs
if __multiprocessing is None:
# threading was not configured before
init_threading()
......
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