Commit d1ba6ef7 authored by sumpfralle's avatar sumpfralle

implemented functions for tools, processes (except for contour) and tasks

fixed some problems in line-based motion grid (still incomplete)


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1151 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 896808b4
...@@ -53,11 +53,13 @@ class EngraveCutter(object): ...@@ -53,11 +53,13 @@ class EngraveCutter(object):
if draw_callback: if draw_callback:
draw_callback(text="Engrave: optimizing polygon order") draw_callback(text="Engrave: optimizing polygon order")
# resolve the generator
motion_grid = list(motion_grid)
num_of_layers = len(motion_grid) num_of_layers = len(motion_grid)
push_layers = motion_grid[:-1] push_layers = motion_grid[:-1]
push_generator = pycam.PathGenerators.PushCutter(self.pa_push, push_generator = pycam.PathGenerators.PushCutter.PushCutter(
physics=self.physics) self.pa_push, physics=self.physics)
current_layer = 0 current_layer = 0
for push_layer in push_layers: for push_layer in push_layers:
# update the progress bar and check, if we should cancel the process # update the progress bar and check, if we should cancel the process
...@@ -67,7 +69,7 @@ class EngraveCutter(object): ...@@ -67,7 +69,7 @@ class EngraveCutter(object):
quit_requested = True quit_requested = True
break break
# no callback: otherwise the status text gets lost # no callback: otherwise the status text gets lost
push_generator.GenerateToolpath(cutter, [model], push_layer) push_generator.GenerateToolPath(cutter, [model], [push_layer])
if draw_callback and draw_callback(): if draw_callback and draw_callback():
# cancel requested # cancel requested
quit_requested = True quit_requested = True
...@@ -78,10 +80,11 @@ class EngraveCutter(object): ...@@ -78,10 +80,11 @@ class EngraveCutter(object):
return self.pa_push.paths return self.pa_push.paths
drop_generator = pycam.PathGenerators.PushCutter(self.pa_drop) drop_generator = pycam.PathGenerators.PushCutter(self.pa_drop)
drop_layers = motion_grid[-1:]
if draw_callback: if draw_callback:
draw_callback(text="Engrave: processing layer" + \ draw_callback(text="Engrave: processing layer" + \
"%d/%d" % (current_layer + 1, num_of_layers)) "%d/%d" % (current_layer + 1, num_of_layers))
push_generator.GenerateToolpath(cutter, [model], push_layer, drop_generator.GenerateToolPath(cutter, [model], drop_layers,
minz=None, maxz=None) minz=None, maxz=None)
return self.pa_push.paths + self.pa_drop.paths return self.pa_push.paths + self.pa_drop.paths
...@@ -22,6 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -22,6 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
import pycam.Plugins import pycam.Plugins
import pycam.PathGenerators.PushCutter
import pycam.PathProcessors.PathAccumulator
import pycam.Toolpath.MotionGrid
class ProcessStrategySlicing(pycam.Plugins.PluginBase): class ProcessStrategySlicing(pycam.Plugins.PluginBase):
...@@ -34,19 +37,32 @@ class ProcessStrategySlicing(pycam.Plugins.PluginBase): ...@@ -34,19 +37,32 @@ class ProcessStrategySlicing(pycam.Plugins.PluginBase):
parameters = {"overlap": 0.1, parameters = {"overlap": 0.1,
"step_down": 1.0, "step_down": 1.0,
"material_allowance": 0, "material_allowance": 0,
"milling_style": "ignore", "milling_style": pycam.Toolpath.MotionGrid.MILLING_STYLE_IGNORE,
"grid_direction": "x", "grid_direction": pycam.Toolpath.MotionGrid.GRID_DIRECTION_X,
} }
self.core.get("register_parameter_set")("process", "slicing", self.core.get("register_parameter_set")("process", "slicing",
"Slice removal", self.run_strategy, parameters=parameters, "Slice removal", self.run_process, parameters=parameters,
weight=10) weight=10)
return True return True
def teardown(self): def teardown(self):
self.core.get("unregister_strategy")("slicing") self.core.get("unregister_parameter_set")("process", "slicing")
def run_strategy(self): def run_process(self, process, environment=None):
pass tool = environment["tool"]
tool_params = tool["parameters"]
low, high = environment["bounds"].get_absolute_limits(
tool=tool, models=environment["collision_models"])
line_distance = 2 * tool_params["radius"] * \
(1.0 - process["parameters"]["overlap"])
path_generator = pycam.PathGenerators.PushCutter.PushCutter(
pycam.PathProcessors.PathAccumulator.PathAccumulator())
motion_grid = pycam.Toolpath.MotionGrid.get_fixed_grid(
(low, high), process["parameters"]["step_down"],
line_distance=line_distance,
grid_direction=process["parameters"]["grid_direction"],
milling_style=process["parameters"]["milling_style"])
return path_generator, motion_grid, (low, high)
class ProcessStrategyContour(pycam.Plugins.PluginBase): class ProcessStrategyContour(pycam.Plugins.PluginBase):
...@@ -57,17 +73,17 @@ class ProcessStrategyContour(pycam.Plugins.PluginBase): ...@@ -57,17 +73,17 @@ class ProcessStrategyContour(pycam.Plugins.PluginBase):
def setup(self): def setup(self):
parameters = {"step_down": 1.0, parameters = {"step_down": 1.0,
"material_allowance": 0, "material_allowance": 0,
"milling_style": "ignore", "milling_style": pycam.Toolpath.MotionGrid.MILLING_STYLE_IGNORE,
} }
self.core.get("register_parameter_set")("process", "contour", self.core.get("register_parameter_set")("process", "contour",
"Waterline", self.run_strategy, parameters=parameters, "Waterline", self.run_process, parameters=parameters,
weight=20) weight=20)
return True return True
def teardown(self): def teardown(self):
self.core.get("unregister_parameter_set")("process", "contour") self.core.get("unregister_parameter_set")("process", "contour")
def run_strategy(self): def run_process(self, strategy, environment=None):
pass pass
...@@ -80,19 +96,33 @@ class ProcessStrategySurfacing(pycam.Plugins.PluginBase): ...@@ -80,19 +96,33 @@ class ProcessStrategySurfacing(pycam.Plugins.PluginBase):
def setup(self): def setup(self):
parameters = {"overlap": 0.6, parameters = {"overlap": 0.6,
"material_allowance": 0, "material_allowance": 0,
"milling_style": "ignore", "milling_style": pycam.Toolpath.MotionGrid.MILLING_STYLE_IGNORE,
"grid_direction": "x", "grid_direction": pycam.Toolpath.MotionGrid.GRID_DIRECTION_X,
} }
self.core.get("register_parameter_set")("process", "surfacing", self.core.get("register_parameter_set")("process", "surfacing",
"Surfacing", self.run_strategy, parameters=parameters, "Surfacing", self.run_process, parameters=parameters,
weight=50) weight=50)
return True return True
def teardown(self): def teardown(self):
self.core.get("unregister_strategy")("surfacing") self.core.get("unregister_parameter_set")("process", "surfacing")
def run_strategy(self): def run_process(self, process, environment=None):
pass tool = environment["tool"]
tool_params = tool["parameters"]
low, high = environment["bounds"].get_absolute_limits(
tool=tool, models=environment["collision_models"])
line_distance = 2 * tool_params["radius"] * \
(1.0 - process["parameters"]["overlap"])
path_generator = pycam.PathGenerators.DropCutter.DropCutter(
pycam.PathProcessors.PathAccumulator.PathAccumulator())
motion_grid = pycam.Toolpath.MotionGrid.get_fixed_grid(
(low, high), process["parameters"]["step_down"],
line_distance=line_distance,
step_width=(tool_params["radius"] / 4.0),
grid_direction=process["parameters"]["grid_direction"],
milling_style=process["parameters"]["milling_style"])
return path_generator, motion_grid, (low, high)
class ProcessStrategyEngraving(pycam.Plugins.PluginBase): class ProcessStrategyEngraving(pycam.Plugins.PluginBase):
...@@ -103,19 +133,30 @@ class ProcessStrategyEngraving(pycam.Plugins.PluginBase): ...@@ -103,19 +133,30 @@ class ProcessStrategyEngraving(pycam.Plugins.PluginBase):
def setup(self): def setup(self):
parameters = {"step_down": 1.0, parameters = {"step_down": 1.0,
"milling_style": "ignore", "milling_style": pycam.Toolpath.MotionGrid.MILLING_STYLE_IGNORE,
"radius_compensation": False, "radius_compensation": False,
"trace_models": [], "trace_models": [],
} }
self.core.get("register_parameter_set")("process", "engraving", self.core.get("register_parameter_set")("process", "engraving",
"Engraving", self.run_strategy, parameters=parameters, "Engraving", self.run_process, parameters=parameters,
weight=80) weight=80)
return True return True
def teardown(self): def teardown(self):
self.core.get("unregister_strategy")("engraving") self.core.get("unregister_parameter_set")("process", "engraving")
def run_strategy(self): def run_process(self, process, environment=None):
pass tool = environment["tool"]
tool_params = tool["parameters"]
low, high = environment["bounds"].get_absolute_limits(
tool=tool, models=environment["collision_models"])
path_generator = pycam.PathGenerators.EngraveCutter.EngraveCutter(
pycam.PathProcessors.SimpleCutter.SimpleCutter())
# TODO: handle radius compensation
motion_grid = pycam.Toolpath.MotionGrid.get_lines_grid(
process["parameters"]["trace_models"],
(low, high), process["parameters"]["step_down"],
step_width=(tool_params["radius"] / 4.0),
milling_style=process["parameters"]["milling_style"])
return path_generator, motion_grid, (low, high)
...@@ -43,7 +43,20 @@ class TaskTypeMilling(pycam.Plugins.PluginBase): ...@@ -43,7 +43,20 @@ class TaskTypeMilling(pycam.Plugins.PluginBase):
def teardown(self): def teardown(self):
self.core.get("unregister_parameter_set")("task", "milling") self.core.get("unregister_parameter_set")("task", "milling")
def run_task(self): def run_task(self, task):
pass environment = {}
for key in task["parameters"]:
environment[key] = task["parameters"][key]
funcs = {}
for key, set_name in (("tool", "shape"), ("process", "strategy")):
funcs[key] = self.core.get("get_parameter_sets")(
key)[environment[key][set_name]]["func"]
tool = funcs["tool"](tool=environment["tool"], environment=environment)
path_generator, motion_grid, (low, high) = funcs["process"](
environment["process"], environment=environment)
models = task["parameters"]["collision_models"]
# TODO: low[2]/high[2]
toolpath = path_generator.GenerateToolPath(tool, models, motion_grid,
minz=low[2], maxz=high[2])
return toolpath
...@@ -22,6 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -22,6 +22,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
import pycam.Plugins import pycam.Plugins
import pycam.Cutters.SphericalCutter
import pycam.Cutters.ToroidalCutter
import pycam.Cutters.CylindricalCutter
class ToolTypeBallNose(pycam.Plugins.PluginBase): class ToolTypeBallNose(pycam.Plugins.PluginBase):
...@@ -41,8 +44,8 @@ class ToolTypeBallNose(pycam.Plugins.PluginBase): ...@@ -41,8 +44,8 @@ class ToolTypeBallNose(pycam.Plugins.PluginBase):
def teardown(self): def teardown(self):
self.core.get("unregister_parameter_set")("tool", "ballnose") self.core.get("unregister_parameter_set")("tool", "ballnose")
def get_tool(self): def get_tool(self, tool, environment=None):
pass return pycam.Cutters.SphericalCutter(tool["parameters"]["radius"])
class ToolTypeBullNose(pycam.Plugins.PluginBase): class ToolTypeBullNose(pycam.Plugins.PluginBase):
...@@ -64,8 +67,10 @@ class ToolTypeBullNose(pycam.Plugins.PluginBase): ...@@ -64,8 +67,10 @@ class ToolTypeBullNose(pycam.Plugins.PluginBase):
def teardown(self): def teardown(self):
self.core.get("unregister_parameter_set")("tool", "bullnose") self.core.get("unregister_parameter_set")("tool", "bullnose")
def get_tool(self): def get_tool(self, tool, environment=None):
pass return pycam.Cutters.ToroidalCutter(
tool["parameters"]["radius"],
tool["parameters"]["torus_radius"])
class ToolTypeFlat(pycam.Plugins.PluginBase): class ToolTypeFlat(pycam.Plugins.PluginBase):
...@@ -84,6 +89,6 @@ class ToolTypeFlat(pycam.Plugins.PluginBase): ...@@ -84,6 +89,6 @@ class ToolTypeFlat(pycam.Plugins.PluginBase):
def teardown(self): def teardown(self):
self.core.get("unregister_parameter_set")("tool", "flat") self.core.get("unregister_parameter_set")("tool", "flat")
def get_tool(self): def get_tool(self, tool, environment=None):
pass return pycam.Cutters.CylindricalCutter(tool["parameters"]["radius"])
...@@ -21,6 +21,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -21,6 +21,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
from pycam.Geometry.Point import Point from pycam.Geometry.Point import Point
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 math import math
...@@ -162,7 +163,11 @@ def get_fixed_grid(bounds, layer_distance, line_distance=None, step_width=None, ...@@ -162,7 +163,11 @@ def get_fixed_grid(bounds, layer_distance, line_distance=None, step_width=None,
start_position=START_Z): start_position=START_Z):
""" Calculate the grid positions for toolpath moves """ Calculate the grid positions for toolpath moves
""" """
#TODO: remove the obsolete "get_absolute_limits" call
if hasattr(bounds, "get_absolute_limits"):
low, high = bounds.get_absolute_limits() low, high = bounds.get_absolute_limits()
else:
low, high = bounds
if isiterable(layer_distance): if isiterable(layer_distance):
layers = layer_distance layers = layer_distance
elif layer_distance is None: elif layer_distance is None:
...@@ -254,9 +259,13 @@ def _get_sorted_polygons(models, callback=None): ...@@ -254,9 +259,13 @@ def _get_sorted_polygons(models, callback=None):
return inner_sorter.get_polygons() + outer_sorter.get_polygons() return inner_sorter.get_polygons() + outer_sorter.get_polygons()
def get_lines_grid(models, bounds, layer_distance, line_distance=None, def get_lines_grid(models, bounds, layer_distance, line_distance=None,
step_width=None, grid_direction=None, step_width=None, milling_style=MILLING_STYLE_CONVENTIONAL,
milling_style=MILLING_STYLE_CONVENTIONAL, start_position=START_Z, callback=None):
start_position=None, callback=None): #TODO: remove the obsolete "get_absolute_limits" call
if hasattr(bounds, "get_absolute_limits"):
low, high = bounds.get_absolute_limits()
else:
low, high = bounds
lines = [] lines = []
for polygon in _get_sorted_polygons(models, callback=callback): for polygon in _get_sorted_polygons(models, callback=callback):
if polygon.is_closed and \ if polygon.is_closed and \
...@@ -265,7 +274,6 @@ def get_lines_grid(models, bounds, layer_distance, line_distance=None, ...@@ -265,7 +274,6 @@ def get_lines_grid(models, bounds, layer_distance, line_distance=None,
polygon.reverse() polygon.reverse()
for line in polygon.get_lines(): for line in polygon.get_lines():
lines.append(line) lines.append(line)
low, high = bounds.get_absolute_limits()
# the lower limit is never below the model # the lower limit is never below the model
low_limit_lines = min([line.minz for line in lines]) low_limit_lines = min([line.minz for line in lines])
low[2] = max(low[2], low_limit_lines) low[2] = max(low[2], low_limit_lines)
...@@ -278,6 +286,8 @@ def get_lines_grid(models, bounds, layer_distance, line_distance=None, ...@@ -278,6 +286,8 @@ def get_lines_grid(models, bounds, layer_distance, line_distance=None,
layers = floatrange(low[2], high[2], inc=layer_distance, layers = floatrange(low[2], high[2], inc=layer_distance,
reverse=bool(start_position & START_Z)) reverse=bool(start_position & START_Z))
last_z = None last_z = None
# turn the generator into a list - otherwise the slicing fails
layers = list(layers)
if layers: if layers:
# the upper layers are used for PushCutter operations # the upper layers are used for PushCutter operations
for z in layers[:-1]: for z in layers[:-1]:
......
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