def get_potential_contour_lines(self, cutter, model, minx, maxx, miny, maxy, z, progress_counter=None): # use only the first model for the contour follow_model = model waterline_triangles = CollisionPaths() triangles = follow_model.triangles(minx=minx, miny=miny, maxx=maxx, maxy=maxy) args = [(follow_model, cutter, self._up_vector, t, z) for t in triangles if not id(t) in self._processed_triangles] results_iter = run_in_parallel(_process_one_triangle, args, unordered=True, callback=progress_counter.update) for result, ignore_triangle_id_list in results_iter: if ignore_triangle_id_list: self._processed_triangles.extend(ignore_triangle_id_list) for edge, shifted_edge in result: waterline_triangles.add(edge, shifted_edge) if (not progress_counter is None) \ and (progress_counter.increment()): # quit requested break if not _DEBUG_DISABLE_EXTEND_LINES: waterline_triangles.extend_shifted_lines() result = [] for line in waterline_triangles.get_shifted_lines(): cropped_line = line.get_cropped_line(minx, maxx, miny, maxy, z, z) if not cropped_line is None: result.append(cropped_line) return result
def generate_toolpath(self, cutter, models, motion_grid, minz=None, maxz=None, draw_callback=None): path = [] quit_requested = False model = pycam.Geometry.Model.get_combined_model(models) # Transfer the grid (a generator) into a list of lists and count the # items. lines = [] # usually there is only one layer - but an xy-grid consists of two for layer in motion_grid: for line in layer: lines.append(line) num_of_lines = len(lines) progress_counter = ProgressCounter(len(lines), draw_callback) current_line = 0 args = [] for one_grid_line in lines: # simplify the data (useful for remote processing) xy_coords = [(pos[0], pos[1]) for pos in one_grid_line] args.append((xy_coords, minz, maxz, model, cutter)) for points in run_in_parallel(_process_one_grid_line, args, callback=progress_counter.update): if draw_callback and draw_callback( text="DropCutter: processing line %d/%d" % (current_line + 1, num_of_lines)): # cancel requested quit_requested = True break for point in points: if point is None: # exceeded maxz - the cutter has to skip this point path.append(MoveSafety()) else: path.append(MoveStraight(point)) # The progress counter may return True, if cancel was requested. if draw_callback and draw_callback(tool_position=point, toolpath=path): quit_requested = True break # add a move to safety height after each line of moves path.append(MoveSafety()) progress_counter.increment() # update progress current_line += 1 if quit_requested: break return path
def GenerateToolPath(self, cutter, models, motion_grid, minz=None, maxz=None, draw_callback=None): quit_requested = False model = pycam.Geometry.Model.get_combined_model(models) # Transfer the grid (a generator) into a list of lists and count the # items. lines = [] # usually there is only one layer - but an xy-grid consists of two for layer in motion_grid: for line in layer: lines.append(line) num_of_lines = len(lines) progress_counter = ProgressCounter(len(lines), draw_callback) current_line = 0 self.pa.new_direction(0) args = [] for one_grid_line in lines: # simplify the data (useful for remote processing) xy_coords = [(pos.x, pos.y) for pos in one_grid_line] args.append((xy_coords, minz, maxz, model, cutter, self.physics)) for points in run_in_parallel(_process_one_grid_line, args, callback=progress_counter.update): self.pa.new_scanline() if draw_callback and draw_callback(text="DropCutter: processing " \ + "line %d/%d" % (current_line + 1, num_of_lines)): # cancel requested quit_requested = True break for point in points: if point is None: # exceeded maxz - the cutter has to skip this point self.pa.end_scanline() self.pa.new_scanline() continue self.pa.append(point) # "draw_callback" returns true, if the user requested to quit # via the GUI. # The progress counter may return True, if cancel was requested. if draw_callback and draw_callback(tool_position=point, toolpath=self.pa.paths): quit_requested = True break progress_counter.increment() self.pa.end_scanline() # update progress current_line += 1 if quit_requested: break self.pa.end_direction() self.pa.finish() return self.pa.paths
def GenerateToolPathSlice(self, cutter, models, layer_grid, draw_callback=None, progress_counter=None): path = [] # settings for calculation of depth accuracy = 20 max_depth = 20 min_depth = 4 # the ContourCutter pathprocessor does not work with combined models if self.waterlines: models = models[:1] else: models = models args = [] for line in layer_grid: p1, p2 = line # calculate the required calculation depth (recursion) distance = pdist(p2, p1) # TODO: accessing cutter.radius here is slightly ugly depth = math.log(accuracy * distance / cutter.radius) / math.log(2) depth = min(max(ceil(depth), 4), max_depth) args.append((p1, p2, depth, models, cutter, self.physics)) for points in run_in_parallel(_process_one_line, args, callback=progress_counter.update): if points: if self.waterlines: self.pa.new_scanline() for point in points: self.pa.append(point) else: for index in range(len(points) / 2): path.append((MOVE_STRAIGHT, points[2 * index])) path.append((MOVE_STRAIGHT, points[2 * index + 1])) path.append((MOVE_SAFETY, None)) if self.waterlines: if draw_callback: draw_callback(tool_position=points[-1]) self.pa.end_scanline() else: if draw_callback: draw_callback(tool_position=points[-1], toolpath=path) # update the progress counter if progress_counter and progress_counter.increment(): # quit requested break if not self.waterlines: return path
def GenerateToolPath(self, cutter, models, motion_grid, minz=None, maxz=None, draw_callback=None): path = [] quit_requested = False model = pycam.Geometry.Model.get_combined_model(models) # Transfer the grid (a generator) into a list of lists and count the # items. lines = [] # usually there is only one layer - but an xy-grid consists of two for layer in motion_grid: for line in layer: lines.append(line) num_of_lines = len(lines) progress_counter = ProgressCounter(len(lines), draw_callback) current_line = 0 args = [] for one_grid_line in lines: # simplify the data (useful for remote processing) xy_coords = [(pos[0], pos[1]) for pos in one_grid_line] args.append((xy_coords, minz, maxz, model, cutter, self.physics)) for points in run_in_parallel(_process_one_grid_line, args, callback=progress_counter.update): if draw_callback and draw_callback(text="DropCutter: processing " \ + "line %d/%d" % (current_line + 1, num_of_lines)): # cancel requested quit_requested = True break for point in points: if point is None: # exceeded maxz - the cutter has to skip this point path.append((MOVE_SAFETY, None)) else: path.append((MOVE_STRAIGHT, point)) # The progress counter may return True, if cancel was requested. if draw_callback and draw_callback(tool_position=point, toolpath=path): quit_requested = True break # add a move to safety height after each line of moves path.append((MOVE_SAFETY, None)) progress_counter.increment() # update progress current_line += 1 if quit_requested: break return path
def generate_toolpath_slice(self, cutter, models, layer_grid, draw_callback=None, progress_counter=None): path = [] # the ContourCutter pathprocessor does not work with combined models if self.waterlines: models = models[:1] else: models = models args = [] for line in layer_grid: p1, p2 = line args.append((p1, p2, models, cutter)) for points in run_in_parallel(_process_one_line, args, callback=progress_counter.update): if points: if self.waterlines: self.pa.new_scanline() for point in points: self.pa.append(point) else: for index in range(len(points) // 2): path.append(MoveStraight(points[2 * index])) path.append(MoveStraight(points[2 * index + 1])) path.append(MoveSafety()) if self.waterlines: if draw_callback: draw_callback(tool_position=points[-1]) self.pa.end_scanline() else: if draw_callback: draw_callback(tool_position=points[-1], toolpath=path) # update the progress counter if progress_counter and progress_counter.increment(): # quit requested break if not self.waterlines: return path
def GenerateToolPathSlice(self, layer_grid, draw_callback=None, progress_counter=None): """ only dx or (exclusive!) dy may be bigger than zero """ # max_deviation_x = dx/accuracy accuracy = 20 max_depth = 20 # calculate the required number of steps in each direction distance = layer_grid[0][-1].sub(layer_grid[0][0]).norm step_width = distance / len(layer_grid[0]) depth = math.log(accuracy * distance / step_width) / math.log(2) depth = max(ceil(depth), 4) depth = min(depth, max_depth) # the ContourCutter pathprocessor does not work with combined models if self._use_polygon_extractor: models = self.models[:1] else: models = self.models args = [] for line in layer_grid: p1, p2 = line args.append((p1, p2, depth, models, self.cutter, self.physics)) for points in run_in_parallel(_process_one_line, args, callback=progress_counter.update): if points: self.pa.new_scanline() for point in points: self.pa.append(point) if draw_callback: draw_callback(tool_position=points[-1], toolpath=self.pa.paths) self.pa.end_scanline() # update the progress counter if progress_counter and progress_counter.increment(): # quit requested break
def GenerateToolPathSlice(self, cutter, models, layer_grid, draw_callback=None, progress_counter=None): # settings for calculation of depth accuracy = 20 max_depth = 20 min_depth = 4 # the ContourCutter pathprocessor does not work with combined models if self._use_polygon_extractor: models = models[:1] else: models = models args = [] for line in layer_grid: p1, p2 = line # calculate the required calculation depth (recursion) distance = p2.sub(p1).norm # TODO: accessing cutter.radius here is slightly ugly depth = math.log(accuracy * distance / cutter.radius) / math.log(2) depth = min(max(ceil(depth), 4), max_depth) args.append((p1, p2, depth, models, cutter, self.physics)) for points in run_in_parallel(_process_one_line, args, callback=progress_counter.update): if points: self.pa.new_scanline() for point in points: self.pa.append(point) if draw_callback: draw_callback(tool_position=points[-1], toolpath=self.pa.paths) self.pa.end_scanline() # update the progress counter if progress_counter and progress_counter.increment(): # quit requested break