Commit e4544055 authored by sumpfralle's avatar sumpfralle

r1065@erker: lars | 2010-07-06 21:19:15 +0200

 final fixes for the bounds management


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@436 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent fc0b6c0d
...@@ -22,6 +22,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>. ...@@ -22,6 +22,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
from pycam.Geometry import Triangle, Line, Point from pycam.Geometry import Triangle, Line, Point
from pycam.Toolpath import Bounds
from utils import INFINITE from utils import INFINITE
try: try:
...@@ -157,6 +158,10 @@ class BaseModel(object): ...@@ -157,6 +158,10 @@ class BaseModel(object):
matrix = ((scale_x, 0, 0, 0), (0, scale_y, 0, 0), (0, 0, scale_z, 0)) matrix = ((scale_x, 0, 0, 0), (0, scale_y, 0, 0), (0, 0, scale_z, 0))
self.transform_by_matrix(matrix) self.transform_by_matrix(matrix)
def get_bounds(self):
return Bounds(Bounds.TYPE_CUSTOM, (self.minx, self.miny, self.minz),
(self.maxx, self.maxy, self.maxz))
class Model(BaseModel): class Model(BaseModel):
......
...@@ -258,7 +258,7 @@ class ProjectGui: ...@@ -258,7 +258,7 @@ class ProjectGui:
bounds = self.settings.get("current_bounds") bounds = self.settings.get("current_bounds")
if bounds is None: if bounds is None:
return getattr(self.model, key) return getattr(self.model, key)
low, high = bounds.get_absolute_limits() low, high = bounds.get_absolute_limits(reference=self.model.get_bounds())
index = "xyz".index(key[-1]) index = "xyz".index(key[-1])
if key.startswith("min"): if key.startswith("min"):
return low[index] return low[index]
...@@ -612,7 +612,8 @@ class ProjectGui: ...@@ -612,7 +612,8 @@ class ProjectGui:
@gui_activity_guard @gui_activity_guard
def adjust_bounds(self, widget, axis, change): def adjust_bounds(self, widget, axis, change):
bounds = self.settings.get("current_bounds") bounds = self.settings.get("current_bounds")
abs_bounds_low, abs_bounds_high = bounds.get_absolute_limits() abs_bounds_low, abs_bounds_high = bounds.get_absolute_limits(
reference=self.model.get_bounds())
# calculate the "change" for +/- (10% of this axis' model dimension) # calculate the "change" for +/- (10% of this axis' model dimension)
if bounds is None: if bounds is None:
return return
...@@ -640,7 +641,8 @@ class ProjectGui: ...@@ -640,7 +641,8 @@ class ProjectGui:
# not allowed # not allowed
return return
# transfer the new bounds values to the old settings # transfer the new bounds values to the old settings
bounds.adjust_bounds_to_absolute_limits(abs_bounds_low, abs_bounds_high) bounds.adjust_bounds_to_absolute_limits(abs_bounds_low, abs_bounds_high,
reference=self.model.get_bounds())
# update the controls # update the controls
self._put_bounds_settings_to_gui(bounds) self._put_bounds_settings_to_gui(bounds)
# update the visualization # update the visualization
...@@ -654,9 +656,11 @@ class ProjectGui: ...@@ -654,9 +656,11 @@ class ProjectGui:
# no change # no change
return return
# calculate the absolute bounds of the previous configuration # calculate the absolute bounds of the previous configuration
abs_bounds_low, abs_bounds_high = bounds.get_absolute_limits() abs_bounds_low, abs_bounds_high = bounds.get_absolute_limits(
reference=self.model.get_bounds())
bounds.set_type(new_type) bounds.set_type(new_type)
bounds.adjust_bounds_to_absolute_limits(abs_bounds_low, abs_bounds_high) bounds.adjust_bounds_to_absolute_limits(abs_bounds_low, abs_bounds_high,
reference=self.model.get_bounds())
self._put_bounds_settings_to_gui(bounds) self._put_bounds_settings_to_gui(bounds)
self.append_to_queue(self.update_boundary_limits) self.append_to_queue(self.update_boundary_limits)
...@@ -954,7 +958,6 @@ class ProjectGui: ...@@ -954,7 +958,6 @@ class ProjectGui:
#self.append_to_queue(self.reset_bounds) #self.append_to_queue(self.reset_bounds)
self.view3d.reset_view() self.view3d.reset_view()
# disable the "toggle" button, if the 3D view does not work # disable the "toggle" button, if the 3D view does not work
toggle_3d_checkbox.set_active(False)
toggle_3d_checkbox.set_sensitive(self.view3d.enabled) toggle_3d_checkbox.set_sensitive(self.view3d.enabled)
else: else:
# the window is just hidden # the window is just hidden
...@@ -962,7 +965,9 @@ class ProjectGui: ...@@ -962,7 +965,9 @@ class ProjectGui:
self.update_view() self.update_view()
else: else:
self.view3d.hide() self.view3d.hide()
toggle_3d_checkbox.set_active(new_state) # enable the toggle button only, if the 3d view is available
# (e.g. disabled if no OpenGL support is available)
toggle_3d_checkbox.set_active(self.view3d.enabled and new_state)
@gui_activity_guard @gui_activity_guard
def transform_model(self, widget): def transform_model(self, widget):
...@@ -1520,7 +1525,7 @@ class ProjectGui: ...@@ -1520,7 +1525,7 @@ class ProjectGui:
settings.load_file(filename) settings.load_file(filename)
self.tool_list = settings.get_tools() self.tool_list = settings.get_tools()
self.process_list = settings.get_processes() self.process_list = settings.get_processes()
self.bounds_list = settings.get_bounds(lambda: self.model) self.bounds_list = settings.get_bounds()
self.task_list = settings.get_tasks() self.task_list = settings.get_tasks()
self.update_tool_table() self.update_tool_table()
self.update_process_table() self.update_process_table()
...@@ -2028,7 +2033,8 @@ class ProjectGui: ...@@ -2028,7 +2033,8 @@ class ProjectGui:
# this should never happen # this should never happen
log.error("Assertion failed: invalid boundary_mode (%s)" % str(self.settings.get("boundary_mode"))) log.error("Assertion failed: invalid boundary_mode (%s)" % str(self.settings.get("boundary_mode")))
abs_bounds_low, abs_bounds_high = bounds.get_absolute_limits() abs_bounds_low, abs_bounds_high = bounds.get_absolute_limits(
reference=self.model.get_bounds())
minx = float(abs_bounds_low[0])-offset minx = float(abs_bounds_low[0])-offset
miny = float(abs_bounds_low[1])-offset miny = float(abs_bounds_low[1])-offset
......
...@@ -319,7 +319,7 @@ process: 3 ...@@ -319,7 +319,7 @@ process: 3
def get_processes(self): def get_processes(self):
return self._get_category_items("process") return self._get_category_items("process")
def _get_bounds_instance_from_dict(self): def _get_bounds_instance_from_dict(self, indict):
""" get Bounds instances for each bounds definition """ get Bounds instances for each bounds definition
@value model: the model that should be used for relative margins @value model: the model that should be used for relative margins
@type model: pycam.Geometry.Model.Model or callable @type model: pycam.Geometry.Model.Model or callable
...@@ -381,7 +381,7 @@ process: 3 ...@@ -381,7 +381,7 @@ process: 3
item[key] = value item[key] = value
if type_name == "bounds": if type_name == "bounds":
# don't add the pure dictionary, but the "bounds" instance # don't add the pure dictionary, but the "bounds" instance
item_list.append(self.get_bounds_instance_from_dict(item)) item_list.append(self._get_bounds_instance_from_dict(item))
else: else:
item_list.append(item) item_list.append(item)
index += 1 index += 1
...@@ -406,7 +406,8 @@ process: 3 ...@@ -406,7 +406,8 @@ process: 3
def get_config_text(self, tools=None, processes=None, bounds=None, tasks=None): def get_config_text(self, tools=None, processes=None, bounds=None, tasks=None):
def get_dictinary_of_bounds(b): def get_dictinary_of_bounds(b):
""" this function should be the reverse operation of "get_bounds" """ this function should be the inverse operation of
'_get_bounds_instance_from_dict'
""" """
result = {} result = {}
result["name"] = b.get_name() result["name"] = b.get_name()
......
...@@ -120,8 +120,7 @@ class Bounds: ...@@ -120,8 +120,7 @@ class Bounds:
TYPE_FIXED_MARGIN = 1 TYPE_FIXED_MARGIN = 1
TYPE_CUSTOM = 2 TYPE_CUSTOM = 2
def __init__(self, bounds_type=None, bounds_low=None, bounds_high=None, def __init__(self, bounds_type=None, bounds_low=None, bounds_high=None):
ref_low=None, ref_high=None):
""" create a new Bounds instance """ create a new Bounds instance
@value bounds_type: any of TYPE_RELATIVE_MARGIN | TYPE_FIXED_MARGIN | TYPE_CUSTOM @value bounds_type: any of TYPE_RELATIVE_MARGIN | TYPE_FIXED_MARGIN | TYPE_CUSTOM
...@@ -133,44 +132,13 @@ class Bounds: ...@@ -133,44 +132,13 @@ class Bounds:
@type bounds_low: (tuple|list) of float @type bounds_low: (tuple|list) of float
@value bounds_high: see 'bounds_low' @value bounds_high: see 'bounds_low'
@type bounds_high: (tuple|list) of float @type bounds_high: (tuple|list) of float
@value ref_low: a reference object described by a tuple (or list) of
three item. These three values describe only the lower boundary of
this object (for the x, y and z axes). Each item must be callable
or a float value. In case of a callable reference, the up-to-date
result of this callable is used whenever a value is calculated.
Thus there is no need to trigger a boundary update manually when
using callables as references. A mixed tuple of float values and
callables is allowed.
This argument is ignored for the boundary type "TYPE_CUSTOM".
@type ref_low: (tuple|list) of (float|callable)
@value ref_high: see 'ref_low'
@type ref_high: (tuple|list) of (float|callable)
""" """
self.name = "No name" self.name = "No name"
if ref_low is None or ref_high is None:
# only the "custom" bounds model does not depend on a reference
bounds_type = self.TYPE_CUSTOM
# set type # set type
if bounds_type is None: if bounds_type is None:
self.set_type(self.TYPE_RELATIVE_MARGIN) self.set_type(Bounds.TYPE_CUSTOM)
else: else:
self.set_type(bounds_type) self.set_type(bounds_type)
# store all reference values as callables (to simplify later usage)
self.ref_low = []
self.ref_high = []
for in_values, out in ((ref_low, self.ref_low), (ref_high, self.ref_high)):
if not in_values is None:
for index in range(3):
if callable(in_values[index]):
out.append(in_values[index])
else:
# Create new variables within the scope of the lambda
# function.
# The lambda function just returns the float value.
out.append(lambda in_values=in_values, index=index:
in_values[index])
else:
out.extend([0, 0, 0])
# store the bounds values # store the bounds values
if bounds_low is None: if bounds_low is None:
bounds_low = [0, 0, 0] bounds_low = [0, 0, 0]
...@@ -214,28 +182,41 @@ class Bounds: ...@@ -214,28 +182,41 @@ class Bounds:
else: else:
self.bounds_high = list(high[:]) self.bounds_high = list(high[:])
def get_absolute_limits(self): def get_absolute_limits(self, reference=None):
""" calculate the current absolute limits of the Bounds instance """ calculate the current absolute limits of the Bounds instance
@value reference: a reference object described by a tuple (or list) of
three item. These three values describe only the lower boundary of
this object (for the x, y and z axes). Each item must be a float
value. This argument is ignored for the boundary type "TYPE_CUSTOM".
@type reference: (tuple|list) of float
@returns: a tuple of two lists containg the low and high limits @returns: a tuple of two lists containg the low and high limits
@rvalue: tuple(list) @rvalue: tuple(list)
""" """
# copy the original dict # check if a reference is given (if necessary)
if self.bounds_type \
in (Bounds.TYPE_RELATIVE_MARGIN, Bounds.TYPE_FIXED_MARGIN):
if reference is None:
raise ValueError, "any non-custom boundary definition " \
+ "requires an a reference object for caluclating " \
+ "absolute limits"
else:
ref_low, ref_high = reference.get_absolute_limits(reference)
low = [None] * 3 low = [None] * 3
high = [None] * 3 high = [None] * 3
# calculate the absolute limits # calculate the absolute limits
if self.bounds_type == self.TYPE_RELATIVE_MARGIN: if self.bounds_type == Bounds.TYPE_RELATIVE_MARGIN:
for index in range(3): for index in range(3):
dim_width = self.ref_high[index]() - self.ref_low[index]() dim_width = ref_high[index] - ref_low[index]
low[index] = self.ref_low[index]() \ low[index] = ref_low[index] \
- self.bounds_low[index] * dim_width - self.bounds_low[index] * dim_width
high[index] = self.ref_high[index]() \ high[index] = ref_high[index] \
+ self.bounds_high[index] * dim_width + self.bounds_high[index] * dim_width
elif self.bounds_type == self.TYPE_FIXED_MARGIN: elif self.bounds_type == Bounds.TYPE_FIXED_MARGIN:
for index in range(3): for index in range(3):
low[index] = self.ref_low[index]() - self.bounds_low[index] low[index] = ref_low[index] - self.bounds_low[index]
high[index] = self.ref_high[index]() + self.bounds_high[index] high[index] = ref_high[index] + self.bounds_high[index]
elif self.bounds_type == self.TYPE_CUSTOM: elif self.bounds_type == Bounds.TYPE_CUSTOM:
for index in range(3): for index in range(3):
low[index] = self.bounds_low[index] low[index] = self.bounds_low[index]
high[index] = self.bounds_high[index] high[index] = self.bounds_high[index]
...@@ -246,7 +227,7 @@ class Bounds: ...@@ -246,7 +227,7 @@ class Bounds:
+ "'%s'" % str(self.bounds_type) + "'%s'" % str(self.bounds_type)
return low, high return low, high
def adjust_bounds_to_absolute_limits(self, limits_low, limits_high): def adjust_bounds_to_absolute_limits(self, limits_low, limits_high, reference=None):
""" change the current bounds settings according to some absolute values """ change the current bounds settings according to some absolute values
This does not change the type of this bounds instance (e.g. relative). This does not change the type of this bounds instance (e.g. relative).
...@@ -254,21 +235,34 @@ class Bounds: ...@@ -254,21 +235,34 @@ class Bounds:
@type limits_low: (tuple|list) of float @type limits_low: (tuple|list) of float
@value limits_high: a tuple describing the new lower absolute boundary @value limits_high: a tuple describing the new lower absolute boundary
@type limits_high: (tuple|list) of float @type limits_high: (tuple|list) of float
@value reference: a reference object described by a tuple (or list) of
three item. These three values describe only the lower boundary of
this object (for the x, y and z axes). Each item must be a float
value. This argument is ignored for the boundary type "TYPE_CUSTOM".
@type reference: (tuple|list) of float
""" """
# check if a reference is given (if necessary)
if self.bounds_type \
in (Bounds.TYPE_RELATIVE_MARGIN, Bounds.TYPE_FIXED_MARGIN):
if reference is None:
raise ValueError, "any non-custom boundary definition " \
+ "requires an a reference object for caluclating " \
+ "absolute limits"
else:
ref_low, ref_high = reference.get_absolute_limits(reference)
# calculate the new settings # calculate the new settings
if self.bounds_type == self.TYPE_RELATIVE_MARGIN: if self.bounds_type == Bounds.TYPE_RELATIVE_MARGIN:
for index in range(3): for index in range(3):
dim_width = ref_high[index] - ref_low[index]
self.bounds_low[index] = \ self.bounds_low[index] = \
(self.ref_low[index]() - limits_low[index]) \ (ref_low[index] - limits_low[index]) / dim_width
/ (self.ref_high[index]() - self.ref_low[index]())
self.bounds_high[index] = \ self.bounds_high[index] = \
(limits_high[index] - self.ref_high[index]()) \ (limits_high[index] - ref_high[index]) / dim_width
/ (self.ref_high[index]() - self.ref_low[index]()) elif self.bounds_type == Bounds.TYPE_FIXED_MARGIN:
elif self.bounds_type == self.TYPE_FIXED_MARGIN:
for index in range(3): for index in range(3):
self.bounds_low[index] = self.ref_low[index]() - limits_low[index] self.bounds_low[index] = ref_low[index] - limits_low[index]
self.bounds_high[index] = limits_high[index] - self.ref_high[index]() self.bounds_high[index] = limits_high[index] - ref_high[index]
elif self.bounds_type == self.TYPE_CUSTOM: elif self.bounds_type == Bounds.TYPE_CUSTOM:
for index in range(3): for index in range(3):
self.bounds_low[index] = limits_low[index] self.bounds_low[index] = limits_low[index]
self.bounds_high[index] = limits_high[index] self.bounds_high[index] = limits_high[index]
......
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