Commit 85c63cb1 authored by sumpfralle's avatar sumpfralle

added a Lock to prevent parallel access to the cutter's "moveto" function...

added a Lock to prevent parallel access to the cutter's "moveto" function (this would cause problems with the collision detection)
fixed a weird namespace issue in the startup script


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@729 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 02ce4015
......@@ -22,6 +22,7 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Utils.threading
from pycam.Geometry.Point import Point
from pycam.Geometry.utils import number, INFINITE, epsilon
from pycam.Geometry.intersection import intersect_circle_point, \
......@@ -91,10 +92,15 @@ class BaseCutter(object):
def get_required_distance(self):
return self.required_distance
def moveto(self, location):
def moveto(self, location, keep_lock=False):
# "moveto" is used for collision detection calculation.
# We need to prevent multiple changes during one calculation.
pycam.Utils.threading.acquire_lock()
self.location = location
for shape, set_pos_func in self.shape.values():
set_pos_func(location.x, location.y, location.z)
if not keep_lock:
pycam.Utils.threading.release_lock()
def intersect(self, direction, triangle):
raise NotImplementedError("Inherited class of BaseCutter does not " \
......
......@@ -129,8 +129,8 @@ class CylindricalCutter(BaseCutter):
GLU.gluDisk(self._disk, 0, self.radius, 10, 10)
GL.glPopMatrix()
def moveto(self, location):
BaseCutter.moveto(self, location)
def moveto(self, location, **kwargs):
BaseCutter.moveto(self, location, **kwargs)
self.center = Point(location.x, location.y, location.z - self.get_required_distance())
def intersect_circle_plane(self, direction, triangle):
......
......@@ -137,8 +137,8 @@ class SphericalCutter(BaseCutter):
10, 10)
GL.glPopMatrix()
def moveto(self, location):
BaseCutter.moveto(self, location)
def moveto(self, location, **kwargs):
BaseCutter.moveto(self, location, **kwargs)
self.center = Point(location.x, location.y, location.z + self.radius)
def intersect_sphere_plane(self, direction, triangle):
......
......@@ -111,8 +111,8 @@ class ToroidalCutter(BaseCutter):
GLU.gluDisk(self._disk, 0, self.majorradius, 20, 10)
GL.glPopMatrix()
def moveto(self, location):
BaseCutter.moveto(self, location)
def moveto(self, location, **kwargs):
BaseCutter.moveto(self, location, **kwargs)
self.center = Point(location.x, location.y, location.z+self.minorradius)
def intersect_torus_plane(self, direction, triangle):
......
......@@ -264,7 +264,6 @@ class ContourFollow:
self.pa.new_scanline()
for p in points:
self.pa.append(p)
self.cutter.moveto(p)
if draw_callback:
draw_callback(tool_position=p, toolpath=self.pa.paths)
last_position = p
......
......@@ -151,7 +151,6 @@ class DropCutter:
for p in points:
self.pa.append(p)
self.cutter.moveto(p)
# "draw_callback" returns true, if the user requested to quit
# via the GUI.
# The progress counter may return True, if cancel was requested.
......
......@@ -162,7 +162,6 @@ class EngraveCutter:
if points:
for p in points:
pa.append(p)
self.cutter.moveto(p)
if draw_callback:
draw_callback(tool_position=p, toolpath=pa.paths)
......@@ -206,7 +205,6 @@ class EngraveCutter:
+ "of the boundary box: using a safe height " \
+ "instead. This warning is reported only once.")
self._boundary_warning_already_shown = True
self.cutter.moveto(p)
# "draw_callback" returns true, if the user requested quitting via
# the GUI.
if draw_callback \
......
......@@ -145,7 +145,6 @@ class PushCutter:
self.pa.new_scanline()
for p in points:
self.pa.append(p)
self.cutter.moveto(p)
if draw_callback:
draw_callback(tool_position=p, toolpath=self.pa.paths)
self.pa.end_scanline()
......
......@@ -25,6 +25,7 @@ __all__ = ["DropCutter", "PushCutter", "EngraveCutter", "ContourFollow"]
from pycam.Geometry.utils import INFINITE, epsilon, sqrt
from pycam.Geometry.Point import Point
import pycam.Utils.threading
class Hit:
......@@ -59,13 +60,14 @@ def get_free_paths_triangles(model, cutter, p1, p2, return_triangles=False):
maxy + cutter.distance_radius, INFINITE)
for t in triangles:
cutter.moveto(p1)
(cl, d, cp) = cutter.intersect(backward, t)
if cl:
hits.append(Hit(cl, cp, t, -d, backward))
(cl, d, cp) = cutter.intersect(forward, t)
if cl:
hits.append(Hit(cl, cp, t, d, forward))
cutter.moveto(p1, keep_lock=True)
(cl1, d1, cp1) = cutter.intersect(backward, t)
(cl2, d2, cp2) = cutter.intersect(forward, t)
pycam.Utils.threading.release_lock()
if cl1:
hits.append(Hit(cl1, cp1, t, -d1, backward))
if cl2:
hits.append(Hit(cl2, cp2, t, d2, forward))
# sort along the scan direction
hits.sort(key=lambda h: h.d)
......@@ -211,7 +213,6 @@ def get_max_height_triangles(model, cutter, x, y, minz, maxz, order=None,
height_max = None
cut_max = None
triangle_max = None
cutter.moveto(p)
box_x_min = cutter.minx
box_x_max = cutter.maxx
box_y_min = cutter.miny
......@@ -220,12 +221,14 @@ def get_max_height_triangles(model, cutter, x, y, minz, maxz, order=None,
box_z_max = maxz
triangles = model.triangles(box_x_min, box_y_min, box_z_min, box_x_max,
box_y_max, box_z_max)
cutter.moveto(p, keep_lock=True)
for t in triangles:
cut = cutter.drop(t)
if cut and ((height_max is None) or (cut.z > height_max)):
height_max = cut.z
cut_max = cut
triangle_max = t
pycam.Utils.threading.release_lock()
# don't do a complete boundary check for the height
# this avoids zero-cuts for models that exceed the bounding box height
if not cut_max or cut_max.z < minz + epsilon:
......
......@@ -21,6 +21,9 @@ along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import pycam.Utils.log
# multiprocessing is imported later
#import multiprocessing
log = pycam.Utils.log.get_logger()
......@@ -34,9 +37,11 @@ __multiprocessing = None
# needs to be initialized, if multiprocessing is enabled
__num_of_processes = None
__lock = None
def init_threading(number_of_processes=None):
global __multiprocessing, __num_of_processes
global __multiprocessing, __num_of_processes, __lock
try:
import multiprocessing
mp_is_available = True
......@@ -62,6 +67,7 @@ def init_threading(number_of_processes=None):
if __multiprocessing is False:
log.info("Disabled multi-threading")
else:
__lock = multiprocessing.Lock()
log.info("Enabled multi-threading with %d parallel processes" % __num_of_processes)
......@@ -86,3 +92,11 @@ def run_in_parallel(func, args, unordered=False, disable_multiprocessing=False):
for arg in args:
yield func(arg)
def acquire_lock():
if __multiprocessing:
__lock.acquire()
def release_lock():
if __multiprocessing:
__lock.release()
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