Example #1
0
def _get_sorted_polygons(models, callback=None):
    # Sort the polygons according to their directions (first inside, then
    # outside. This reduces the problem of break-away pieces.
    inner_polys = []
    outer_polys = []
    for model in models:
        for poly in model.get_polygons():
            if poly.get_area() <= 0:
                inner_polys.append(poly)
            else:
                outer_polys.append(poly)
    inner_sorter = PolygonSorter(inner_polys, callback=callback)
    outer_sorter = PolygonSorter(outer_polys, callback=callback)
    return inner_sorter.get_polygons() + outer_sorter.get_polygons()
Example #2
0
def _get_sorted_polygons(models, callback=None):
    # Sort the polygons according to their directions (first inside, then
    # outside. This reduces the problem of break-away pieces.
    inner_polys = []
    outer_polys = []
    for model in models:
        for poly in model.get_polygons():
            if poly.get_area() <= 0:
                inner_polys.append(poly)
            else:
                outer_polys.append(poly)
    inner_sorter = PolygonSorter(inner_polys, callback=callback)
    outer_sorter = PolygonSorter(outer_polys, callback=callback)
    return inner_sorter.get_polygons() + outer_sorter.get_polygons()
Example #3
0
    def GenerateToolPath(self, minz, maxz, horiz_step, dz, draw_callback=None):
        quit_requested = False
        # calculate the number of steps
        num_of_layers = 1 + ceil(abs(maxz - minz) / dz)
        if num_of_layers > 1:
            z_step = abs(maxz - minz) / (num_of_layers - 1)
            z_steps = [(maxz - i * z_step) for i in range(num_of_layers)]
            # The top layer is treated as the current surface - thus it does not
            # require engraving.
            z_steps = z_steps[1:]
        else:
            z_steps = [minz]
        num_of_layers = len(z_steps)

        current_layer = 0
        num_of_lines = self.contour_model.get_num_of_lines()
        progress_counter = ProgressCounter(len(z_steps) * num_of_lines, draw_callback)

        if draw_callback:
            draw_callback(text="Engrave: optimizing polygon order")
        # Sort the polygons according to their directions (first inside, then
        # outside. This reduces the problem of break-away pieces.
        inner_polys = []
        outer_polys = []
        for poly in self.contour_model.get_polygons():
            if poly.get_area() <= 0:
                inner_polys.append(poly)
            else:
                outer_polys.append(poly)
        inner_sorter = PolygonSorter(inner_polys, callback=draw_callback)
        outer_sorter = PolygonSorter(outer_polys, callback=draw_callback)
        line_groups = inner_sorter.get_polygons() + outer_sorter.get_polygons()
        if self.clockwise:
            for line_group in line_groups:
                line_group.reverse_direction()

        # push slices for all layers above ground
        if maxz == minz:
            # only one layer - use PushCutter instead of DropCutter
            # put "last_z" clearly above the model plane
            last_z = maxz + 1
            push_steps = z_steps
            drop_steps = []
        else:
            # multiple layers
            last_z = maxz
            push_steps = z_steps[:-1]
            drop_steps = [z_steps[-1]]

        for z in push_steps:
            # update the progress bar and check, if we should cancel the process
            if draw_callback and draw_callback(
                text="Engrave: processing" + " layer %d/%d" % (current_layer + 1, num_of_layers)
            ):
                # cancel immediately
                break
            for line_group in line_groups:
                for line in line_group.get_lines():
                    self.GenerateToolPathLinePush(self.pa_push, line, z, last_z, draw_callback=draw_callback)
                    if progress_counter.increment():
                        # cancel requested
                        quit_requested = True
                        # finish the current path
                        self.pa_push.finish()
                        break
            self.pa_push.finish()
            # break the outer loop if requested
            if quit_requested:
                break
            current_layer += 1
            last_z = z

        if quit_requested:
            return self.pa_push.paths

        for z in drop_steps:
            if draw_callback:
                draw_callback(text="Engrave: processing layer %d/%d" % (current_layer + 1, num_of_layers))
            # process the final layer with a drop cutter
            for line_group in line_groups:
                self.pa_drop.new_direction(0)
                self.pa_drop.new_scanline()
                for line in line_group.get_lines():
                    self.GenerateToolPathLineDrop(
                        self.pa_drop, line, z, maxz, horiz_step, last_z, draw_callback=draw_callback
                    )
                    if progress_counter.increment():
                        # quit requested
                        quit_requested = True
                        break
                self.pa_drop.end_scanline()
                self.pa_drop.end_direction()
                # break the outer loop if requested
                if quit_requested:
                    break
            current_layer += 1
            last_z = z
        self.pa_drop.finish()

        return self.pa_push.paths + self.pa_drop.paths
Example #4
0
    def GenerateToolPath(self, minz, maxz, horiz_step, dz, draw_callback=None):
        quit_requested = False
        # calculate the number of steps
        num_of_layers = 1 + ceil(abs(maxz - minz) / dz)
        if num_of_layers > 1:
            z_step = abs(maxz - minz) / (num_of_layers - 1)
            z_steps = [(maxz - i * z_step) for i in range(num_of_layers)]
            # The top layer is treated as the current surface - thus it does not
            # require engraving.
            z_steps = z_steps[1:]
        else:
            z_steps = [minz]
        num_of_layers = len(z_steps)

        current_layer = 0
        num_of_lines = self.contour_model.get_num_of_lines()
        progress_counter = ProgressCounter(len(z_steps) * num_of_lines,
                draw_callback)

        if draw_callback:
            draw_callback(text="Engrave: optimizing polygon order")
        # Sort the polygons according to their directions (first inside, then
        # outside. This reduces the problem of break-away pieces.
        inner_polys = []
        outer_polys = []
        for poly in self.contour_model.get_polygons():
            if poly.get_area() <= 0:
                inner_polys.append(poly)
            else:
                outer_polys.append(poly)
        inner_sorter = PolygonSorter(inner_polys, callback=draw_callback)
        outer_sorter = PolygonSorter(outer_polys, callback=draw_callback)
        line_groups = inner_sorter.get_polygons() + outer_sorter.get_polygons()
        if self.clockwise:
            for line_group in line_groups:
                line_group.reverse_direction()

        # push slices for all layers above ground
        if maxz == minz:
            # only one layer - use PushCutter instead of DropCutter
            # put "last_z" clearly above the model plane
            last_z = maxz + 1
            push_steps = z_steps
            drop_steps = []
        else:
            # multiple layers
            last_z = maxz
            push_steps = z_steps[:-1]
            drop_steps = [z_steps[-1]]

        for z in push_steps:
            # update the progress bar and check, if we should cancel the process
            if draw_callback and draw_callback(text="Engrave: processing" \
                        + " layer %d/%d" % (current_layer + 1, num_of_layers)):
                # cancel immediately
                break
            for line_group in line_groups:
                for line in line_group.get_lines():
                    self.GenerateToolPathLinePush(self.pa_push, line, z, last_z,
                            draw_callback=draw_callback)
                    if progress_counter.increment():
                        # cancel requested
                        quit_requested = True
                        # finish the current path
                        self.pa_push.finish()
                        break
            self.pa_push.finish()
            # break the outer loop if requested
            if quit_requested:
                break
            current_layer += 1
            last_z = z

        if quit_requested:
            return self.pa_push.paths

        for z in drop_steps:
            if draw_callback:
                draw_callback(text="Engrave: processing layer %d/%d" \
                        % (current_layer + 1, num_of_layers))
            # process the final layer with a drop cutter
            for line_group in line_groups:
                self.pa_drop.new_direction(0)
                self.pa_drop.new_scanline()
                for line in line_group.get_lines():
                    self.GenerateToolPathLineDrop(self.pa_drop, line, z, maxz,
                            horiz_step, last_z, draw_callback=draw_callback)
                    if progress_counter.increment():
                        # quit requested
                        quit_requested = True
                        break
                self.pa_drop.end_scanline()
                self.pa_drop.end_direction()
                # break the outer loop if requested
                if quit_requested:
                    break
            current_layer += 1
            last_z = z
        self.pa_drop.finish()
        
        return self.pa_push.paths + self.pa_drop.paths