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/>.
"""
from pycam.Geometry import Triangle, Line, Point
from pycam.Toolpath import Bounds
from utils import INFINITE
try:
......@@ -157,6 +158,10 @@ class BaseModel(object):
matrix = ((scale_x, 0, 0, 0), (0, scale_y, 0, 0), (0, 0, scale_z, 0))
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):
......
......@@ -258,7 +258,7 @@ class ProjectGui:
bounds = self.settings.get("current_bounds")
if bounds is None:
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])
if key.startswith("min"):
return low[index]
......@@ -612,7 +612,8 @@ class ProjectGui:
@gui_activity_guard
def adjust_bounds(self, widget, axis, change):
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)
if bounds is None:
return
......@@ -640,7 +641,8 @@ class ProjectGui:
# not allowed
return
# 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
self._put_bounds_settings_to_gui(bounds)
# update the visualization
......@@ -654,9 +656,11 @@ class ProjectGui:
# no change
return
# 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.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.append_to_queue(self.update_boundary_limits)
......@@ -954,7 +958,6 @@ class ProjectGui:
#self.append_to_queue(self.reset_bounds)
self.view3d.reset_view()
# 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)
else:
# the window is just hidden
......@@ -962,7 +965,9 @@ class ProjectGui:
self.update_view()
else:
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
def transform_model(self, widget):
......@@ -1520,7 +1525,7 @@ class ProjectGui:
settings.load_file(filename)
self.tool_list = settings.get_tools()
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.update_tool_table()
self.update_process_table()
......@@ -2028,7 +2033,8 @@ class ProjectGui:
# this should never happen
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
miny = float(abs_bounds_low[1])-offset
......
......@@ -319,7 +319,7 @@ process: 3
def get_processes(self):
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
@value model: the model that should be used for relative margins
@type model: pycam.Geometry.Model.Model or callable
......@@ -381,7 +381,7 @@ process: 3
item[key] = value
if type_name == "bounds":
# 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:
item_list.append(item)
index += 1
......@@ -406,7 +406,8 @@ process: 3
def get_config_text(self, tools=None, processes=None, bounds=None, tasks=None):
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["name"] = b.get_name()
......
......@@ -120,8 +120,7 @@ class Bounds:
TYPE_FIXED_MARGIN = 1
TYPE_CUSTOM = 2
def __init__(self, bounds_type=None, bounds_low=None, bounds_high=None,
ref_low=None, ref_high=None):
def __init__(self, bounds_type=None, bounds_low=None, bounds_high=None):
""" create a new Bounds instance
@value bounds_type: any of TYPE_RELATIVE_MARGIN | TYPE_FIXED_MARGIN | TYPE_CUSTOM
......@@ -133,44 +132,13 @@ class Bounds:
@type bounds_low: (tuple|list) of float
@value bounds_high: see 'bounds_low'
@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"
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
if bounds_type is None:
self.set_type(self.TYPE_RELATIVE_MARGIN)
self.set_type(Bounds.TYPE_CUSTOM)
else:
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
if bounds_low is None:
bounds_low = [0, 0, 0]
......@@ -214,28 +182,41 @@ class Bounds:
else:
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
@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
@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
high = [None] * 3
# 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):
dim_width = self.ref_high[index]() - self.ref_low[index]()
low[index] = self.ref_low[index]() \
dim_width = ref_high[index] - ref_low[index]
low[index] = ref_low[index] \
- self.bounds_low[index] * dim_width
high[index] = self.ref_high[index]() \
high[index] = ref_high[index] \
+ 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):
low[index] = self.ref_low[index]() - self.bounds_low[index]
high[index] = self.ref_high[index]() + self.bounds_high[index]
elif self.bounds_type == self.TYPE_CUSTOM:
low[index] = ref_low[index] - self.bounds_low[index]
high[index] = ref_high[index] + self.bounds_high[index]
elif self.bounds_type == Bounds.TYPE_CUSTOM:
for index in range(3):
low[index] = self.bounds_low[index]
high[index] = self.bounds_high[index]
......@@ -246,7 +227,7 @@ class Bounds:
+ "'%s'" % str(self.bounds_type)
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
This does not change the type of this bounds instance (e.g. relative).
......@@ -254,21 +235,34 @@ class Bounds:
@type limits_low: (tuple|list) of float
@value limits_high: a tuple describing the new lower absolute boundary
@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
if self.bounds_type == self.TYPE_RELATIVE_MARGIN:
if self.bounds_type == Bounds.TYPE_RELATIVE_MARGIN:
for index in range(3):
dim_width = ref_high[index] - ref_low[index]
self.bounds_low[index] = \
(self.ref_low[index]() - limits_low[index]) \
/ (self.ref_high[index]() - self.ref_low[index]())
(ref_low[index] - limits_low[index]) / dim_width
self.bounds_high[index] = \
(limits_high[index] - self.ref_high[index]()) \
/ (self.ref_high[index]() - self.ref_low[index]())
elif self.bounds_type == self.TYPE_FIXED_MARGIN:
(limits_high[index] - ref_high[index]) / dim_width
elif self.bounds_type == Bounds.TYPE_FIXED_MARGIN:
for index in range(3):
self.bounds_low[index] = self.ref_low[index]() - limits_low[index]
self.bounds_high[index] = limits_high[index] - self.ref_high[index]()
elif self.bounds_type == self.TYPE_CUSTOM:
self.bounds_low[index] = ref_low[index] - limits_low[index]
self.bounds_high[index] = limits_high[index] - ref_high[index]
elif self.bounds_type == Bounds.TYPE_CUSTOM:
for index in range(3):
self.bounds_low[index] = limits_low[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