Commit f459934b authored by sumpfralle's avatar sumpfralle

added the new feature "support bridges" that are supposed to hold the object...

added the new feature "support bridges" that are supposed to hold the object during the machine operation


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@342 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 5782d079
Version 0.2.5 - NOT RELEASED Version 0.2.5 - NOT RELEASED
* added support bridges for holding the object during cutting
* calculate the estimated machine time for each toolpath * calculate the estimated machine time for each toolpath
* changing the unit (mm/inch) now opens a dialog for scaling the model, * changing the unit (mm/inch) now opens a dialog for scaling the model,
processing dimensions or tool dimensions accordingly processing dimensions or tool dimensions accordingly
......
...@@ -593,6 +593,10 @@ def draw_complete_model_view(settings): ...@@ -593,6 +593,10 @@ def draw_complete_model_view(settings):
if settings.get("show_model"): if settings.get("show_model"):
GL.glColor3f(*settings.get("color_model")) GL.glColor3f(*settings.get("color_model"))
settings.get("model").to_OpenGL() settings.get("model").to_OpenGL()
# draw the support grid
if settings.get("show_support_grid") and settings.get("support_grid"):
GL.glColor3f(*settings.get("color_support_grid"))
settings.get("support_grid").to_OpenGL()
# draw the toolpath # draw the toolpath
if settings.get("show_toolpath"): if settings.get("show_toolpath"):
for toolpath_obj in settings.get("toolpath"): for toolpath_obj in settings.get("toolpath"):
......
...@@ -61,6 +61,7 @@ PREFERENCES_DEFAULTS = { ...@@ -61,6 +61,7 @@ PREFERENCES_DEFAULTS = {
"boundary_mode": -1, "boundary_mode": -1,
"unit": "mm", "unit": "mm",
"show_model": True, "show_model": True,
"show_support_grid": True,
"show_axes": True, "show_axes": True,
"show_dimensions": True, "show_dimensions": True,
"show_bounding_box": True, "show_bounding_box": True,
...@@ -68,6 +69,7 @@ PREFERENCES_DEFAULTS = { ...@@ -68,6 +69,7 @@ PREFERENCES_DEFAULTS = {
"show_drill_progress": False, "show_drill_progress": False,
"color_background": (0.0, 0.0, 0.0), "color_background": (0.0, 0.0, 0.0),
"color_model": (0.5, 0.5, 1.0), "color_model": (0.5, 0.5, 1.0),
"color_support_grid": (0.8, 0.8, 0.3),
"color_bounding_box": (0.3, 0.3, 0.3), "color_bounding_box": (0.3, 0.3, 0.3),
"color_cutter": (1.0, 0.2, 0.2), "color_cutter": (1.0, 0.2, 0.2),
"color_toolpath_cut": (1.0, 0.5, 0.5), "color_toolpath_cut": (1.0, 0.5, 0.5),
...@@ -224,8 +226,19 @@ class ProjectGui: ...@@ -224,8 +226,19 @@ class ProjectGui:
# scale model to an axis dimension # scale model to an axis dimension
self.gui.get_object("ScaleDimensionAxis").connect("changed", self.switch_scale_axis) self.gui.get_object("ScaleDimensionAxis").connect("changed", self.switch_scale_axis)
self.gui.get_object("ScaleDimensionButton").connect("clicked", self.scale_model_axis_fit) self.gui.get_object("ScaleDimensionButton").connect("clicked", self.scale_model_axis_fit)
# support grid
self.gui.get_object("SupportGridEnable").connect("clicked", self.update_support_grid_controls)
grid_distance = self.gui.get_object("SupportGridDistance")
self.settings.add_item("support_grid_distance",
grid_distance.get_value, grid_distance.set_value)
grid_thickness = self.gui.get_object("SupportGridThickness")
self.settings.add_item("support_grid_thickness",
grid_thickness.get_value, grid_thickness.set_value)
self.settings.set("support_grid_distance", 5.0)
self.settings.set("support_grid_thickness", 0.5)
# visual and general settings # visual and general settings
for name, objname in (("show_model", "ShowModelCheckBox"), for name, objname in (("show_model", "ShowModelCheckBox"),
("show_support_grid", "ShowSupportGridCheckBox"),
("show_axes", "ShowAxesCheckBox"), ("show_axes", "ShowAxesCheckBox"),
("show_dimensions", "ShowDimensionsCheckBox"), ("show_dimensions", "ShowDimensionsCheckBox"),
("show_bounding_box", "ShowBoundingCheckBox"), ("show_bounding_box", "ShowBoundingCheckBox"),
...@@ -256,6 +269,7 @@ class ProjectGui: ...@@ -256,6 +269,7 @@ class ProjectGui:
return set_gtk_color_by_float return set_gtk_color_by_float
for name, objname in (("color_background", "ColorBackground"), for name, objname in (("color_background", "ColorBackground"),
("color_model", "ColorModel"), ("color_model", "ColorModel"),
("color_support_grid", "ColorSupportGrid"),
("color_bounding_box", "ColorBoundingBox"), ("color_bounding_box", "ColorBoundingBox"),
("color_cutter", "ColorDrill"), ("color_cutter", "ColorDrill"),
("color_toolpath_cut", "ColorToolpathCut"), ("color_toolpath_cut", "ColorToolpathCut"),
...@@ -396,6 +410,7 @@ class ProjectGui: ...@@ -396,6 +410,7 @@ class ProjectGui:
self.update_tasklist_controls() self.update_tasklist_controls()
self.update_save_actions() self.update_save_actions()
self.update_unit_labels() self.update_unit_labels()
self.update_support_grid_controls()
self.switch_scale_axis() self.switch_scale_axis()
def progress_activity_guard(func): def progress_activity_guard(func):
...@@ -435,6 +450,21 @@ class ProjectGui: ...@@ -435,6 +450,21 @@ class ProjectGui:
self.gui.get_object("SaveTaskSettings").set_sensitive(not self.last_task_settings_file is None) self.gui.get_object("SaveTaskSettings").set_sensitive(not self.last_task_settings_file is None)
self.gui.get_object("SaveModel").set_sensitive(not self.last_model_file is None) self.gui.get_object("SaveModel").set_sensitive(not self.last_model_file is None)
def update_support_grid_controls(self, widget=None):
is_enabled = self.gui.get_object("SupportGridEnable").get_active()
self.gui.get_object("SupportGridDetailsBox").set_visible(is_enabled)
if is_enabled:
s = self.settings
s.set("support_grid",
pycam.Toolpath.SupportGrid.get_support_grid(s.get("minx"),
s.get("maxx"), s.get("miny"), s.get("maxy"),
s.get("minz"), s.get("support_grid_distance"),
s.get("support_grid_distance"),
s.get("support_grid_thickness")))
else:
self.settings.set("support_grid", None)
self.update_view()
def update_tasklist_controls(self, widget=None, data=None): def update_tasklist_controls(self, widget=None, data=None):
# check if both the tool and the process table have a selected row # check if both the tool and the process table have a selected row
all_are_active = True all_are_active = True
...@@ -476,7 +506,6 @@ class ProjectGui: ...@@ -476,7 +506,6 @@ class ProjectGui:
lines.append("No task selected") lines.append("No task selected")
self.gui.get_object("CurrentTaskSummary").set_text(os.linesep.join(lines)) self.gui.get_object("CurrentTaskSummary").set_text(os.linesep.join(lines))
def update_tasklist_table(self, new_index=None, skip_model_update=False): def update_tasklist_table(self, new_index=None, skip_model_update=False):
tasklist_model = self.gui.get_object("TaskList") tasklist_model = self.gui.get_object("TaskList")
if new_index is None: if new_index is None:
...@@ -1615,6 +1644,13 @@ class ProjectGui: ...@@ -1615,6 +1644,13 @@ class ProjectGui:
"torus_radius": tool_settings["torus_radius"], "torus_radius": tool_settings["torus_radius"],
} }
self.cutter = pycam.Cutters.get_tool_from_settings(tool_dict) self.cutter = pycam.Cutters.get_tool_from_settings(tool_dict)
# get the support grid options
if self.gui.get_object("SupportGridEnable").get_active():
support_grid_distance = self.settings.get("support_grid_distance")
support_grid_thickness = self.settings.get("support_grid_thickness")
else:
support_grid_distance = None
support_grid_thickness = None
# run the toolpath generation # run the toolpath generation
toolpath = pycam.Toolpath.Generator.generate_toolpath(self.model, toolpath = pycam.Toolpath.Generator.generate_toolpath(self.model,
tool_dict, bounds=bounds, tool_dict, bounds=bounds,
...@@ -1625,6 +1661,8 @@ class ProjectGui: ...@@ -1625,6 +1661,8 @@ class ProjectGui:
safety_height=process_settings["safety_height"], safety_height=process_settings["safety_height"],
overlap=process_settings["overlap_percent"] / 100.0, overlap=process_settings["overlap_percent"] / 100.0,
step_down=process_settings["step_down"], step_down=process_settings["step_down"],
support_grid_distance=support_grid_distance,
support_grid_thickness=support_grid_thickness,
calculation_backend=calculation_backend, callback=draw_callback) calculation_backend=calculation_backend, callback=draw_callback)
print "Time elapsed: %f" % (time.time() - start_time) print "Time elapsed: %f" % (time.time() - start_time)
......
This diff is collapsed.
...@@ -23,6 +23,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -23,6 +23,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
import pycam.PathGenerators import pycam.PathGenerators
import pycam.PathProcessors import pycam.PathProcessors
import pycam.Cutters import pycam.Cutters
import pycam.Toolpath.SupportGrid
import sys import sys
DIRECTIONS = frozenset(("x", "y", "xy")) DIRECTIONS = frozenset(("x", "y", "xy"))
...@@ -32,8 +33,9 @@ CALCULATION_BACKENDS = frozenset((None, "ODE")) ...@@ -32,8 +33,9 @@ CALCULATION_BACKENDS = frozenset((None, "ODE"))
def generate_toolpath(model, tool_settings=None, bounds=None, direction="x", def generate_toolpath(model, tool_settings=None, bounds=None, direction="x",
path_generator="DropCutter", path_postprocessor="ZigZagCutter", path_generator="DropCutter", path_postprocessor="ZigZagCutter",
material_allowance=0.0, safety_height=None, overlap=0.0, material_allowance=0.0, safety_height=None, overlap=0.0, step_down=0.0,
step_down=0.0, calculation_backend=None, callback=None): support_grid_distance=None, support_grid_thickness=None,
calculation_backend=None, callback=None):
""" abstract interface for generating a toolpath """ abstract interface for generating a toolpath
@type model: pycam.Geometry.Model.Model @type model: pycam.Geometry.Model.Model
...@@ -57,6 +59,12 @@ def generate_toolpath(model, tool_settings=None, bounds=None, direction="x", ...@@ -57,6 +59,12 @@ def generate_toolpath(model, tool_settings=None, bounds=None, direction="x",
@value material_allowance: the minimum distance between the tool and the model @value material_allowance: the minimum distance between the tool and the model
@type overlap: float @type overlap: float
@value overlap: the overlap between two adjacent tool paths (0 <= overlap < 1) @value overlap: the overlap between two adjacent tool paths (0 <= overlap < 1)
@type step_down: float
@value step_down: maximum height of each layer (for PushCutter)
@type support_grid_distance: float
@value support_grid_distance: grid size of remaining support material
@type support_grid_thickness: float
@value support_grid_thickness: thickness of the support grid
@type calculation_backend: str | None @type calculation_backend: str | None
@value calculation_backend: any member of the CALCULATION_BACKENDS set @value calculation_backend: any member of the CALCULATION_BACKENDS set
The default is the triangular collision detection. The default is the triangular collision detection.
...@@ -71,6 +79,17 @@ def generate_toolpath(model, tool_settings=None, bounds=None, direction="x", ...@@ -71,6 +79,17 @@ def generate_toolpath(model, tool_settings=None, bounds=None, direction="x",
minz, maxz = model.minz, model.maxz minz, maxz = model.minz, model.maxz
else: else:
minx, maxx, miny, maxy, minz, maxz = bounds minx, maxx, miny, maxy, minz, maxz = bounds
# create the grid model if requested
if (not support_grid_distance is None) \
and (not support_grid_thickness is None):
if support_grid_distance <= 0:
return "The distance of the support grid must be a positive value"
if support_grid_thickness <= 0:
return "The thickness of the support grid must be a positive value"
support_grid_model = pycam.Toolpath.SupportGrid.get_support_grid(
minx, maxx, miny, maxy, minz, support_grid_distance,
support_grid_distance, support_grid_thickness)
model += support_grid_model
# Due to some weirdness the height of the drill must be bigger than the object's size. # Due to some weirdness the height of the drill must be bigger than the object's size.
# Otherwise some collisions are not detected. # Otherwise some collisions are not detected.
cutter_height = 4 * (maxy - miny) cutter_height = 4 * (maxy - miny)
......
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2010 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 import Point, Line, Triangle, Model
def _add_cuboid_to_model(minx, maxx, miny, maxy, minz, maxz):
def get_triangles_for_face(pts):
t1 = Triangle(pts[0], pts[1], pts[2], Line(pts[0], pts[1]),
Line(pts[1], pts[2]), Line(pts[2], pts[0]))
t2 = Triangle(pts[2], pts[3], pts[0], Line(pts[2], pts[3]),
Line(pts[3], pts[0]), Line(pts[0], pts[2]))
return (t1, t2)
points = (
Point(minx, miny, minz),
Point(maxx, miny, minz),
Point(maxx, maxy, minz),
Point(minx, maxy, minz),
Point(minx, miny, maxz),
Point(maxx, miny, maxz),
Point(maxx, maxy, maxz),
Point(minx, maxy, maxz))
triangles = []
# lower face
triangles.extend(get_triangles_for_face((points[0], points[1], points[2], points[3])))
# upper face
triangles.extend(get_triangles_for_face((points[4], points[5], points[6], points[7])))
# front face
triangles.extend(get_triangles_for_face((points[0], points[1], points[5], points[4])))
# back face
triangles.extend(get_triangles_for_face((points[2], points[3], points[7], points[6])))
# right face
triangles.extend(get_triangles_for_face((points[1], points[2], points[6], points[5])))
# left face
triangles.extend(get_triangles_for_face((points[3], points[0], points[4], points[7])))
# add all triangles to the model
model = Model()
for t in triangles:
model.append(t)
return model
def get_support_grid(minx, maxx, miny, maxy, z_plane, dist_x, dist_y, thickness):
lines_x = 1 + int((maxx - minx) / dist_x)
lines_y = 1 + int((maxy - miny) / dist_y)
# we center the grid
start_x = ((maxx - minx) - (lines_x - 1) * dist_x) / 2.0 + minx
start_y = ((maxy - miny) - (lines_y - 1) * dist_y) / 2.0 + miny
# create all x grid lines
grid_model = Model()
radius = thickness / 2.0
for i in range(lines_x):
x = start_x + i * dist_x
# we make the grid slightly longer (by thickness) than necessary
grid_model += _add_cuboid_to_model(x - radius, x + radius,
miny - thickness, maxy + thickness, z_plane, z_plane + thickness)
for i in range(lines_y):
y = start_y + i * dist_y
# we make the grid slightly longer (by thickness) than necessary
grid_model += _add_cuboid_to_model(minx - thickness, maxx + thickness,
y - radius, y + radius, z_plane, z_plane + thickness)
return grid_model
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