Commit dd4b030a authored by sumpfralle's avatar sumpfralle

r689@erker: lars | 2010-02-19 03:52:19 +0100

 enabled "material allowance" (minimum distance between cutter and the model - for rough and semi-finish operations)
 derive the ToroidalCutter shape from the CylindricalCutter (not perfect, but it works)
 prevent all impossible combinations of tool and path settings by disabling the respective controls


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@147 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent ba6da836
......@@ -25,13 +25,23 @@ class CylindricalCutter(BaseCutter):
def __repr__(self):
return "CylindricalCutter<%s,%s>" % (self.location,self.radius)
def get_shape(self, format="ODE"):
def get_shape(self, format="ODE", additional_distance=0.0):
if format == "ODE":
import ode
geom = ode.GeomCylinder(None, self.radius, self.height)
""" We don't handle the the "additional_distance" perfectly, since
the "right" shape would be a cylinder with a small flat cap that
grows to the full expanded radius through a partial sphere. The
following ascii art shows the idea:
| |
\_/
This slight incorrectness should be neglectable and causes no harm.
"""
radius = self.radius + additional_distance
height = self.height + additional_distance
geom = ode.GeomCylinder(None, radius, height)
def set_position(x, y, z):
geom.setPosition((x, y, z))
self.shape[format] = (geom, set_position, (0, 0, 0.5 * self.height))
self.shape[format] = (geom, set_position, (0, 0, 0.5 * height - additional_distance))
return self.shape[format]
def to_OpenGL(self):
......
......@@ -25,13 +25,14 @@ class SphericalCutter(BaseCutter):
def __repr__(self):
return "SphericalCutter<%s,%s>" % (self.location,self.radius)
def get_shape(self, format="ODE"):
def get_shape(self, format="ODE", additional_distance=0.0):
if format == "ODE":
import ode
geom = ode.GeomCapsule(None, self.radius, self.height)
radius = self.radius + additional_distance
geom = ode.GeomCapsule(None, radius, self.height)
def set_position(x, y, z):
geom.setPosition((x, y, z))
self.shape[format] = (geom, set_position, (0, 0, 0.5 * self.height + self.radius))
self.shape[format] = (geom, set_position, (0, 0, 0.5 * self.height + radius))
return self.shape[format]
def to_OpenGL(self):
......
......@@ -30,14 +30,14 @@ class ToroidalCutter(BaseCutter):
def __repr__(self):
return "ToroidalCutter<%s,%f,R=%f,r=%f>" % (self.location,self.radius,self.majorradius,self.minorradius)
def get_shape(self, format="ODE"):
def get_shape(self, format="ODE", additional_distance=0.0):
if format == "ODE":
import ode
from pycam.Cutters.CylindricalCutter import CylindricalCutter
# TODO: use an appromixated trimesh instead (ODE does not support toroidal shapes)
geom = ode.GeomCapsule(None, self.radius, self.height)
def set_position(x, y, z):
geom.setPosition((x, y, z))
self.shape[format] = (geom, set_position, (0, 0, 0.5 * self.height + self.minorradius))
# for now: use the simple cylinder shape - this should not do any harm
self.shape[format] = CylindricalCutter(self.radius, self.location,
height=self.height).get_shape(format, additional_distance)
return self.shape[format]
def to_OpenGL(self):
......
......@@ -370,13 +370,18 @@ class ProjectGui:
self.settings.add_item("path_postprocessor", get_path_postprocessor, set_path_postprocessor)
# path direction (combined get/set function)
def set_get_path_direction(input=None):
for obj, value in [("PathDirectionX", "x"), ("PathDirectionY", "y"), ("PathDirectionXY", "xy")]:
for obj, value in (("PathDirectionX", "x"), ("PathDirectionY", "y"), ("PathDirectionXY", "xy")):
if value == input:
self.gui.get_object(obj).set_active(True)
return
if self.gui.get_object(obj).get_active():
return value
self.settings.add_item("path_direction", set_get_path_direction, set_get_path_direction)
# connect the "consistency check" with all toolpath settings
for objname in ("PathAccumulator", "SimpleCutter", "ZigZagCutter", "PolygonCutter", "ContourCutter",
"DropCutter", "PushCutter", "SphericalCutter", "CylindricalCutter", "ToroidalCutter",
"PathDirectionX", "PathDirectionY", "PathDirectionXY"):
self.gui.get_object(objname).connect("toggled", self.disable_invalid_toolpath_settings)
# load a processing configuration object
self.processing_settings = pycam.Gui.Settings.ProcessingSettings(self.settings)
self.processing_config_selection = self.gui.get_object("ProcessingTemplatesList")
......@@ -398,6 +403,8 @@ class ProjectGui:
filter.add_pattern("*.conf")
load_processing_settings_file_control.add_filter(filter)
load_processing_settings_file_control.set_filter(filter)
# make sure that the toolpath settings are consistent
self.disable_invalid_toolpath_settings()
def gui_activity_guard(func):
def wrapper(self, *args, **kwargs):
......@@ -422,6 +429,30 @@ class ProjectGui:
else:
self.physics = None
def disable_invalid_toolpath_settings(self, widget=None, data=None):
# possible dependencies of the DropCutter
if self.settings.get("path_generator") == "DropCutter":
if self.settings.get("path_direction") == "xy":
self.settings.set("path_direction", "x")
if not self.settings.get("path_postprocessor") in ("PathAccumulator", "ZigZagCutter"):
self.settings.set("path_postprocessor", "PathAccumulator")
dropcutter_active = True
else:
dropcutter_active = False
for objname in ("PathDirectionXY", "SimpleCutter", "PolygonCutter", "ContourCutter"):
self.gui.get_object(objname).set_sensitive(not dropcutter_active)
self.gui.get_object("PathDirectionXY").set_sensitive(not dropcutter_active)
# disable the dropcutter, if "xy" or one of "SimpleCutter", "PolygonCutter", "ContourCutter" is enabled
if (self.settings.get("path_postprocessor") in ("SimpleCutter", "PolygonCutter", "ContourCutter")) \
or (self.settings.get("path_direction") == "xy"):
self.gui.get_object("DropCutter").set_sensitive(False)
else:
self.gui.get_object("DropCutter").set_sensitive(True)
# disable the toroidal radius if the toroidal cutter is not enabled
self.gui.get_object("TorusRadiusControl").set_sensitive(self.settings.get("cutter_shape") == "ToroidalCutter")
# disable "step down" control, if PushCutter is not active
self.gui.get_object("MaxStepDownControl").set_sensitive(self.settings.get("path_generator") == "PushCutter")
@gui_activity_guard
def toggle_3d_view(self, widget=None, value=None):
current_state = not ((self.view3d is None) or (not self.view3d.is_visible))
......@@ -651,6 +682,8 @@ class ProjectGui:
pathgenerator = self.settings.get("path_generator")
pathprocessor = self.settings.get("path_postprocessor")
direction = self.settings.get("path_direction")
# Due to some weirdness the height of the drill must be bigger than the object's size.
# Otherwise some collisions are not detected.
cutter_height = 2 * (self.settings.get("maxz") - self.settings.get("minz"))
if cuttername == "SphericalCutter":
self.cutter = pycam.Cutters.SphericalCutter(radius, height=cutter_height)
......
......@@ -73,7 +73,7 @@ tool_radius: 1.0
torus_radius: 0.25
speed: 1000
feedrate: 200
material_allowance: 0
material_allowance: 0.0
overlap: 20
step_down: 1.0
# default sort weight is low (thus new items will appear above the defaults)
......@@ -85,6 +85,7 @@ cutter_shape: CylindricalCutter
path_generator: PushCutter
path_postprocessor: PolygonCutter
tool_radius: 1.0
material_allowance: 1.0
[Semi-finish]
......@@ -93,6 +94,7 @@ cutter_shape: ToroidalCutter
path_generator: PushCutter
path_postprocessor: ContourCutter
tool_radius: 0.5
material_allowance: 0.3
[Finish]
sort_weight: 92
......@@ -100,6 +102,7 @@ cutter_shape: SphericalCutter
path_generator: DropCutter
path_postprocessor: ZigZagCutter
tool_radius: 0.1
material_allowance: 0.0
"""
SETTING_TYPES = {
......
......@@ -196,7 +196,7 @@ def generate_physics(settings, cutter, physics=None):
#height = 2 * (settings.get("maxz") - settings.get("minz"))
#physics.set_drill(ode_objects.ShapeCylinder(radius, height), (settings.get("minx"), settings.get("miny"), settings.get("maxz")))
#physics.set_drill(ode_objects.ShapeCylinder(radius, height), (0, 0, height/2.0))
shape_info = cutter.get_shape("ODE")
shape_info = cutter.get_shape("ODE", settings.get("material_allowance"))
physics.set_drill(shape_info[0], shape_info[2])
return physics
......
......@@ -3,6 +3,7 @@
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="ProjectWindow">
<property name="title" translatable="yes">PyCAM Settings</property>
<property name="destroy_with_parent">True</property>
<child>
<object class="GtkNotebook" id="Tasks">
......@@ -1222,6 +1223,7 @@
<object class="GtkSpinButton" id="TorusRadiusControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Radius of the "doughnut" top of a Toroidal Cutter.</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">torusradius</property>
<property name="digits">3</property>
......@@ -1386,6 +1388,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">The Drop Cutter abrades a limited slice of material in each step.
It does not work with the "xy" direction and it requires the "Path Accumulator" or the "ZigZag Cutter".</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -1481,6 +1485,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Dynamic switching between x and y axis direction.
Only available for the Push Cutter.</property>
<property name="draw_indicator">True</property>
<property name="group">PathDirectionX</property>
</object>
......@@ -1543,6 +1549,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Practically useless path processor for testing purposes.</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
......@@ -1557,6 +1564,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Practically useless path processor for testing purposes.
Only available for the Push Cutter.</property>
<property name="draw_indicator">True</property>
<property name="group">PathAccumulator</property>
</object>
......@@ -1571,6 +1580,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Quite simple path processor for finishing operations.</property>
<property name="draw_indicator">True</property>
<property name="group">PathAccumulator</property>
</object>
......@@ -1585,6 +1595,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Complex path processor for first rough operations.
Only available for the Push Cutter.</property>
<property name="draw_indicator">True</property>
<property name="group">PathAccumulator</property>
</object>
......@@ -1599,6 +1611,8 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Complex path processor for semi-finish operations.
Only available for the Push Cutter.</property>
<property name="draw_indicator">True</property>
<property name="group">PathAccumulator</property>
</object>
......@@ -1709,6 +1723,7 @@
<object class="GtkSpinButton" id="MaxStepDownControl">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Height of each slice abraded by the Push Cutter.</property>
<property name="invisible_char">&#x2022;</property>
<property name="adjustment">MaxStepDownValue</property>
<property name="digits">2</property>
......@@ -2095,6 +2110,7 @@
<property name="page_size">10</property>
</object>
<object class="GtkWindow" id="view3dwindow">
<property name="title" translatable="yes">PyCAM Visualization</property>
<child>
<object class="GtkVBox" id="view3dbox">
<property name="visible">True</property>
......
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