Commit 8749bd22 authored by sumpfralle's avatar sumpfralle

added optional rounded corners for spiral path pattern


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1183 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 06009c2d
...@@ -96,8 +96,8 @@ def get_points_of_arc(center, radius, a1, a2, plane=None, cords=32): ...@@ -96,8 +96,8 @@ def get_points_of_arc(center, radius, a1, a2, plane=None, cords=32):
@type plane: pycam.Geometry.Plane.Plane @type plane: pycam.Geometry.Plane.Plane
@param cords: number of lines for a full circle @param cords: number of lines for a full circle
@type cords: int @type cords: int
@return: a list of lines approximating the arc @return: a list of points approximating the arc
@rtype: list(pycam.Geometry.Line.Line) @rtype: list(pycam.Geometry.Point.Point)
""" """
# TODO: implement 3D arc and respect "plane" # TODO: implement 3D arc and respect "plane"
a1 = math.pi * a1 / 180 a1 = math.pi * a1 / 180
...@@ -105,6 +105,8 @@ def get_points_of_arc(center, radius, a1, a2, plane=None, cords=32): ...@@ -105,6 +105,8 @@ def get_points_of_arc(center, radius, a1, a2, plane=None, cords=32):
angle_diff = a2 - a1 angle_diff = a2 - a1
if angle_diff < 0: if angle_diff < 0:
angle_diff += 2 * math.pi angle_diff += 2 * math.pi
if angle_diff >= 2 * math.pi:
angle_diff -= 2 * math.pi
if angle_diff == 0: if angle_diff == 0:
return [] return []
num_of_segments = ceil(angle_diff / (2 * math.pi) * cords) num_of_segments = ceil(angle_diff / (2 * math.pi) * cords)
......
...@@ -219,7 +219,6 @@ class PathParamPattern(pycam.Plugins.PluginBase): ...@@ -219,7 +219,6 @@ class PathParamPattern(pycam.Plugins.PluginBase):
self.choices.append((pattern["label"], pattern["name"])) self.choices.append((pattern["label"], pattern["name"]))
self.control.update_choices(self.choices) self.control.update_choices(self.choices)
if not self.control.get_value() and self.choices: if not self.control.get_value() and self.choices:
print {"name": self.choices[0][1], "parameters": {}}
self.control.set_value({"name": self.choices[0][1], "parameters": {}}) self.control.set_value({"name": self.choices[0][1], "parameters": {}})
def _get_pattern(self): def _get_pattern(self):
...@@ -230,6 +229,27 @@ class PathParamPattern(pycam.Plugins.PluginBase): ...@@ -230,6 +229,27 @@ class PathParamPattern(pycam.Plugins.PluginBase):
return None return None
class PathParamRoundedSpiralCorners(pycam.Plugins.PluginBase):
DEPENDS = ["Processes"]
CATEGORIES = ["Process", "Parameter"]
def setup(self):
self.control = pycam.Gui.ControlsGTK.InputCheckBox(
change_handler=lambda widget=None: self.core.emit_event(
"process-changed"))
self.core.get("register_parameter")("path_pattern", "rounded_corners",
self.control)
self.core.register_ui("process_path_parameters", "Rounded corners",
self.control.get_widget(), weight=80)
return True
def teardown(self):
self.core.unregister_ui("process_path_parameters",
self.control.get_widget())
self.core.get("unregister_parameter")("path_pattern", "rounded_corners")
class PathParamRadiusCompensation(pycam.Plugins.PluginBase): class PathParamRadiusCompensation(pycam.Plugins.PluginBase):
DEPENDS = ["Processes"] DEPENDS = ["Processes"]
......
...@@ -28,13 +28,15 @@ import pycam.Toolpath.MotionGrid ...@@ -28,13 +28,15 @@ import pycam.Toolpath.MotionGrid
class PathPatternSpiral(pycam.Plugins.PluginBase): class PathPatternSpiral(pycam.Plugins.PluginBase):
DEPENDS = ["ParameterGroupManager", "PathParamPattern", DEPENDS = ["ParameterGroupManager", "PathParamPattern",
"PathParamMillingStyle", "PathParamSpiralDirection"] "PathParamMillingStyle", "PathParamSpiralDirection",
CATEGORIES = ["Process"] "PathParamRoundedSpiralCorners"]
CATEGORIES = ["Process", "Path pattern"]
def setup(self): def setup(self):
parameters = { parameters = {
"milling_style": pycam.Toolpath.MotionGrid.MILLING_STYLE_IGNORE, "milling_style": pycam.Toolpath.MotionGrid.MILLING_STYLE_IGNORE,
"spiral_direction": None, "spiral_direction": None,
"rounded_corners": False,
} }
self.core.get("register_parameter_set")("path_pattern", "spiral", self.core.get("register_parameter_set")("path_pattern", "spiral",
"Spiral", self.get_grid_generator, parameters=parameters, "Spiral", self.get_grid_generator, parameters=parameters,
...@@ -54,7 +56,7 @@ class PathPatternGrid(pycam.Plugins.PluginBase): ...@@ -54,7 +56,7 @@ class PathPatternGrid(pycam.Plugins.PluginBase):
DEPENDS = ["ParameterGroupManager", "PathParamPattern", DEPENDS = ["ParameterGroupManager", "PathParamPattern",
"PathParamMillingStyle", "PathParamGridDirection"] "PathParamMillingStyle", "PathParamGridDirection"]
CATEGORIES = ["Process"] CATEGORIES = ["Process", "Path pattern"]
def setup(self): def setup(self):
parameters = { parameters = {
......
...@@ -127,7 +127,7 @@ class ProgressGTK(object): ...@@ -127,7 +127,7 @@ class ProgressGTK(object):
def disable_cancel(self): def disable_cancel(self):
self._cancel_button.set_sensitive(False) self._cancel_button.set_sensitive(False)
def cancel(self): def cancel(self, widget=None):
self._cancel_requested = True self._cancel_requested = True
def finish(self): def finish(self):
......
...@@ -20,10 +20,11 @@ You should have received a copy of the GNU General Public License ...@@ -20,10 +20,11 @@ You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>. along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
from pycam.Geometry.Point import Point from pycam.Geometry.Point import Point, Vector
from pycam.Geometry.Line import Line from pycam.Geometry.Line import Line
from pycam.Geometry.utils import epsilon from pycam.Geometry.utils import epsilon
from pycam.Geometry.Polygon import PolygonSorter from pycam.Geometry.Polygon import PolygonSorter
import pycam.Geometry
import math import math
...@@ -200,11 +201,11 @@ def _get_position(minx, maxx, miny, maxy, z, position): ...@@ -200,11 +201,11 @@ def _get_position(minx, maxx, miny, maxy, z, position):
return Point(x, y, z) return Point(x, y, z)
def get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x, def get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x,
line_distance_y, grid_direction, start_position, line_distance_y, grid_direction, start_position, current_location):
current_location):
xor_map = {GRID_DIRECTION_X: START_X, GRID_DIRECTION_Y: START_Y} xor_map = {GRID_DIRECTION_X: START_X, GRID_DIRECTION_Y: START_Y}
end_position = start_position ^ xor_map[grid_direction] end_position = start_position ^ xor_map[grid_direction]
end_location = _get_position(minx, maxx, miny, maxy, z, end_position) end_location = _get_position(minx, maxx, miny, maxy, z, end_position)
lines = [(current_location, end_location)]
if grid_direction == GRID_DIRECTION_X: if grid_direction == GRID_DIRECTION_X:
next_grid_direction = GRID_DIRECTION_Y next_grid_direction = GRID_DIRECTION_Y
if start_position & START_Y > 0: if start_position & START_Y > 0:
...@@ -217,7 +218,6 @@ def get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x, ...@@ -217,7 +218,6 @@ def get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x,
minx += line_distance_x minx += line_distance_x
else: else:
maxx -= line_distance_x maxx -= line_distance_x
lines = [(current_location, end_location)]
if (minx - epsilon <= maxx ) and (miny - epsilon <= maxy): if (minx - epsilon <= maxx ) and (miny - epsilon <= maxy):
# recursively compute the next lines # recursively compute the next lines
lines.extend(get_spiral_layer_lines(minx, maxx, miny, maxy, z, lines.extend(get_spiral_layer_lines(minx, maxx, miny, maxy, z,
...@@ -226,7 +226,7 @@ def get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x, ...@@ -226,7 +226,7 @@ def get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x,
return lines return lines
def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width, def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width,
grid_direction, start_position, reverse): grid_direction, start_position, rounded_corners, reverse):
current_location = _get_position(minx, maxx, miny, maxy, z, current_location = _get_position(minx, maxx, miny, maxy, z,
start_position) start_position)
if line_distance > 0: if line_distance > 0:
...@@ -240,6 +240,38 @@ def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width, ...@@ -240,6 +240,38 @@ def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width,
if reverse: if reverse:
lines.reverse() lines.reverse()
# turn the lines into steps # turn the lines into steps
if rounded_corners:
rounded_lines = []
previous = None
for index, (start, end) in enumerate(lines):
radius = 0.5 * min(line_distance_x, line_distance_y)
edge_vector = end.sub(start)
# TODO: ellipse would be better than arc
offset = edge_vector.normalized().mul(radius)
if previous:
start = start.add(offset)
center = previous.add(offset)
up_vector = previous.sub(center).cross(start.sub(center)).normalized()
north = center.add(Vector(1.0, 0.0, 0.0))
angle_start = pycam.Geometry.get_angle_pi(north, center, previous, up_vector, pi_factor=True) * 180.0
angle_end = pycam.Geometry.get_angle_pi(north, center, start, up_vector, pi_factor=True) * 180.0
# TODO: remove these exceptions based on up_vector.z (get_points_of_arc does not respect the plane, yet)
if up_vector.z < 0:
angle_start, angle_end = -angle_end, -angle_start
arc_points = pycam.Geometry.get_points_of_arc(center, radius, angle_start, angle_end)
if up_vector.z < 0:
arc_points.reverse()
for arc_index in range(len(arc_points) - 1):
p1_coord = arc_points[arc_index]
p2_coord = arc_points[arc_index + 1]
p1 = Point(p1_coord[0], p1_coord[1], z)
p2 = Point(p2_coord[0], p2_coord[1], z)
rounded_lines.append((p1, p2))
if index != len(lines) - 1:
end = end.sub(offset)
previous = end
rounded_lines.append((start, end))
lines = rounded_lines
for start, end in lines: for start, end in lines:
points = [] points = []
if step_width is None: if step_width is None:
...@@ -260,7 +292,7 @@ def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width, ...@@ -260,7 +292,7 @@ def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width,
def get_spiral((low, high), layer_distance, line_distance=None, def get_spiral((low, high), layer_distance, line_distance=None,
step_width=None, milling_style=MILLING_STYLE_IGNORE, step_width=None, milling_style=MILLING_STYLE_IGNORE,
spiral_direction=SPIRAL_DIRECTION_IN, spiral_direction=SPIRAL_DIRECTION_IN, rounded_corners=False,
start_position=(START_X | START_Y | START_Z)): start_position=(START_X | START_Y | START_Z)):
""" Calculate the grid positions for toolpath moves """ Calculate the grid positions for toolpath moves
""" """
...@@ -282,7 +314,7 @@ def get_spiral((low, high), layer_distance, line_distance=None, ...@@ -282,7 +314,7 @@ def get_spiral((low, high), layer_distance, line_distance=None,
yield get_spiral_layer(low[0], high[0], low[1], high[1], z, yield get_spiral_layer(low[0], high[0], low[1], high[1], z,
line_distance, step_width=step_width, line_distance, step_width=step_width,
grid_direction=start_direction, start_position=start_position, grid_direction=start_direction, start_position=start_position,
reverse=reverse) rounded_corners=rounded_corners, reverse=reverse)
def get_lines_layer(lines, z, last_z=None, step_width=None, def get_lines_layer(lines, z, last_z=None, step_width=None,
milling_style=MILLING_STYLE_CONVENTIONAL): milling_style=MILLING_STYLE_CONVENTIONAL):
......
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