def main(): compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL)) move_mesh_to_point(compas_mesh, Point(0, 0, 0)) # Slicing slicer = PlanarSlicer(compas_mesh, slicer_type="cgal", layer_height=5.0) slicer.slice_model() # Sorting into vertical layers and reordering sort_into_vertical_layers(slicer, max_paths_per_layer=10) reorder_vertical_layers(slicer, align_with="x_axis") # Post-processing generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=5) simplify_paths_rdp_igl(slicer, threshold=0.7) seams_smooth(slicer, smooth_distance=10) slicer.printout_info() save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json') # PlanarPrintOrganization print_organizer = PlanarPrintOrganizer(slicer) print_organizer.create_printpoints() set_extruder_toggle(print_organizer, slicer) add_safety_printpoints(print_organizer, z_hop=10.0) set_linear_velocity_constant(print_organizer, v=25.0) set_blend_radius(print_organizer, d_fillet=10.0) print_organizer.printout_info() printpoints_data = print_organizer.output_printpoints_dict() utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json')
def main(): compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL)) delta = get_param({}, key='delta', defaults_type='gcode') # boolean for delta printers print_volume_x = get_param({}, key='print_volume_x', defaults_type='gcode') # in mm print_volume_y = get_param({}, key='print_volume_y', defaults_type='gcode') # in mm if delta: move_mesh_to_point(compas_mesh, Point(0, 0, 0)) else: move_mesh_to_point(compas_mesh, Point(print_volume_x / 2, print_volume_y / 2, 0)) # ----- slicing slicer = PlanarSlicer(compas_mesh, slicer_type="cgal", layer_height=4.5) slicer.slice_model() generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=4) simplify_paths_rdp_igl(slicer, threshold=0.6) seams_smooth(slicer, smooth_distance=10) slicer.printout_info() save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json') # ----- print organization print_organizer = PlanarPrintOrganizer(slicer) print_organizer.create_printpoints() # Set fabrication-related parameters set_extruder_toggle(print_organizer, slicer) print_organizer.printout_info() # create and output gcode gcode_parameters = {} # leave all to default gcode_text = print_organizer.output_gcode(gcode_parameters) utils.save_to_text_file(gcode_text, OUTPUT_DIR, 'my_gcode.gcode')
def test_planar_add_safety_printpoints_for_horizontal_layers(): """ Tests add_safety_printpoints on planar slicer. """ for filename in stl_to_test: slicer, print_organizer = create_setup(filename) set_extruder_toggle(print_organizer, slicer) # has already been don pp_dict = print_organizer.printpoints_dict # (1) find total number of ppts and interruptions before addition of safety ppts initial_ppts_number = print_organizer.number_of_printpoints all_extruder_toggles = [] for i, layer_key in enumerate(pp_dict): for j, path_key in enumerate(pp_dict[layer_key]): all_extruder_toggles.extend([ pp.extruder_toggle for pp in pp_dict[layer_key][path_key] ]) all_Trues = np.sum(np.array(all_extruder_toggles)) total_interruptions = len(all_extruder_toggles) - all_Trues # (2) add safety ppts add_safety_printpoints(print_organizer, z_hop=10.0) # (3) find resulting number of ppts resulting_ppts_number = print_organizer.number_of_printpoints assert initial_ppts_number + 2 * total_interruptions == resulting_ppts_number, \ "Wrong number of safety points added on file : " + str(filename)
def main(): start_time = time.time() # ========================================================================== # Load mesh # ========================================================================== compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL)) # ========================================================================== # Move to origin # ========================================================================== move_mesh_to_point(compas_mesh, Point(0, 0, 0)) # ========================================================================== # Slicing # options: 'default': Both for open and closed paths. But slow # 'cgal': Very fast. Only for closed paths. # Requires additional installation (compas_cgal). # ========================================================================== slicer = PlanarSlicer(compas_mesh, slicer_type="cgal", layer_height=1.5) slicer.slice_model() # ========================================================================== # Generate brim / raft # ========================================================================== # NOTE: Typically you would want to use either a brim OR a raft, # however, in this example both are used to explain the functionality generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=4) generate_raft(slicer, raft_offset=20, distance_between_paths=5, direction="xy_diagonal", raft_layers=1) # ========================================================================== # Simplify the paths by removing points with a certain threshold # change the threshold value to remove more or less points # ========================================================================== simplify_paths_rdp_igl(slicer, threshold=0.6) # ========================================================================== # Smooth the seams between layers # change the smooth_distance value to achieve smoother, or more abrupt seams # ========================================================================== seams_smooth(slicer, smooth_distance=10) # ========================================================================== # Prints out the info of the slicer # ========================================================================== slicer.printout_info() # ========================================================================== # Save slicer data to JSON # ========================================================================== save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json') # ========================================================================== # Initializes the PlanarPrintOrganizer and creates PrintPoints # ========================================================================== print_organizer = PlanarPrintOrganizer(slicer) print_organizer.create_printpoints() # ========================================================================== # Set fabrication-related parameters # ========================================================================== set_extruder_toggle(print_organizer, slicer) add_safety_printpoints(print_organizer, z_hop=10.0) set_linear_velocity_constant(print_organizer, v=25.0) set_blend_radius(print_organizer, d_fillet=10.0) # ========================================================================== # Prints out the info of the PrintOrganizer # ========================================================================== print_organizer.printout_info() # ========================================================================== # Converts the PrintPoints to data and saves to JSON # ========================================================================= printpoints_data = print_organizer.output_printpoints_dict() utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json') # ========================================================================== # Initializes the compas_viewer and visualizes results # ========================================================================== viewer = app.App(width=1600, height=1000) # slicer.visualize_on_viewer(viewer, visualize_mesh=False, visualize_paths=True) print_organizer.visualize_on_viewer(viewer, visualize_printpoints=True) viewer.show() end_time = time.time() print("Total elapsed time", round(end_time - start_time, 2), "seconds")
# ========================================================================== # Save slicer data to JSON # ========================================================================== save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json') # ========================================================================== # Initializes the PlanarPrintOrganizer and creates PrintPoints # ========================================================================== print_organizer = PlanarPrintOrganizer(slicer) print_organizer.create_printpoints() # ========================================================================== # Set fabrication-related parameters # ========================================================================== set_extruder_toggle(print_organizer, slicer) add_safety_printpoints(print_organizer, z_hop=10.0) set_linear_velocity(print_organizer, "constant", v=25.0) set_blend_radius(print_organizer, d_fillet=10.0) # ========================================================================== # Prints out the info of the PrintOrganizer # ========================================================================== print_organizer.printout_info() # ========================================================================== # Converts the PrintPoints to data and saves to JSON # ========================================================================= printpoints_data = print_organizer.output_printpoints_dict() utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json')
def main(): start_time = time.time() # --- Load initial_mesh mesh = Mesh.from_obj(os.path.join(DATA_PATH, OBJ_INPUT_NAME)) # --- Load targets (boundaries) low_boundary_vs = utils.load_from_json(DATA_PATH, 'boundaryLOW.json') high_boundary_vs = utils.load_from_json(DATA_PATH, 'boundaryHIGH.json') create_mesh_boundary_attributes(mesh, low_boundary_vs, high_boundary_vs) avg_layer_height = 15.0 parameters = { 'avg_layer_height': avg_layer_height, # controls number of curves that will be generated 'min_layer_height': 0.3, 'max_layer_height': 5.0 # 2.0, } preprocessor = InterpolationSlicingPreprocessor(mesh, parameters, DATA_PATH) preprocessor.create_compound_targets() g_eval = preprocessor.create_gradient_evaluation( norm_filename='gradient_norm.json', g_filename='gradient.json', target_1=preprocessor.target_LOW, target_2=preprocessor.target_HIGH) preprocessor.find_critical_points( g_eval, output_filenames=['minima.json', 'maxima.json', 'saddles.json']) # --- slicing slicer = InterpolationSlicer(mesh, preprocessor, parameters) slicer.slice_model() # compute_norm_of_gradient contours generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=5) seams_smooth(slicer, smooth_distance=10) simplify_paths_rdp_igl(slicer, threshold=0.5) slicer.printout_info() utils.save_to_json(slicer.to_data(), OUTPUT_PATH, 'curved_slicer.json') # --- Print organizer print_organizer = InterpolationPrintOrganizer(slicer, parameters, DATA_PATH) print_organizer.create_printpoints() set_linear_velocity_by_range( print_organizer, param_func=lambda ppt: ppt.layer_height, parameter_range=[avg_layer_height * 0.5, avg_layer_height * 2.0], velocity_range=[150, 70], bound_remapping=False) set_extruder_toggle(print_organizer, slicer) add_safety_printpoints(print_organizer, z_hop=10.0) smooth_printpoints_up_vectors(print_organizer, strength=0.5, iterations=10) smooth_printpoints_layer_heights(print_organizer, strength=0.5, iterations=5) # --- Save printpoints dictionary to json file printpoints_data = print_organizer.output_printpoints_dict() utils.save_to_json(printpoints_data, OUTPUT_PATH, 'out_printpoints.json') # ----- Visualize viewer = app.App(width=1600, height=1000) # slicer.visualize_on_viewer(viewer, visualize_mesh=False, visualize_paths=True) print_organizer.visualize_on_viewer(viewer, visualize_printpoints=True) viewer.show() end_time = time.time() print("Total elapsed time", round(end_time - start_time, 2), "seconds")
def main(): start_time = time.time() # ========================================================================== # Load mesh # ========================================================================== compas_mesh = Mesh.from_obj(os.path.join(DATA, MODEL)) # ========================================================================== # Move to origin # ========================================================================== move_mesh_to_point(compas_mesh, Point(0, 0, 0)) # ========================================================================== # Slicing # options: 'default': Both for open and closed paths. But slow # 'cgal': Very fast. Only for closed paths. # Requires additional installation (compas_cgal). # ========================================================================== slicer = PlanarSlicer(compas_mesh, slicer_type="default", layer_height=1.5) slicer.slice_model() # ========================================================================== # Generate brim # ========================================================================== generate_brim(slicer, layer_width=3.0, number_of_brim_paths=3) # ========================================================================== # Simplify the paths by removing points with a certain threshold # change the threshold value to remove more or less points # ========================================================================== simplify_paths_rdp(slicer, threshold=0.3) # ========================================================================== # Smooth the seams between layers # change the smooth_distance value to achieve smoother, or more abrupt seams # ========================================================================== seams_smooth(slicer, smooth_distance=10) # ========================================================================== # Prints out the info of the slicer # ========================================================================== slicer.printout_info() # ========================================================================== # Save slicer data to JSON # ========================================================================== save_to_json(slicer.to_data(), OUTPUT_DIR, 'slicer_data.json') # ========================================================================== # Initializes the PlanarPrintOrganizer and creates PrintPoints # ========================================================================== print_organizer = PlanarPrintOrganizer(slicer) print_organizer.create_printpoints() # ========================================================================== # Set fabrication-related parameters # ========================================================================== set_extruder_toggle(print_organizer, slicer) add_safety_printpoints(print_organizer, z_hop=10.0) set_linear_velocity(print_organizer, "constant", v=25.0) set_blend_radius(print_organizer, d_fillet=10.0) # ========================================================================== # Prints out the info of the PrintOrganizer # ========================================================================== slicer.printout_info() print_organizer.printout_info() # ========================================================================== # Converts the PrintPoints to data and saves to JSON # ========================================================================= printpoints_data = print_organizer.output_printpoints_dict() utils.save_to_json(printpoints_data, OUTPUT_DIR, 'out_printpoints.json') # ========================================================================== # Initializes the compas_viewer and visualizes results # ========================================================================== """
def test_planar_set_extruder_toggle_for_horizontal_layers(): """ Tests set_extruder_toggle on planar slicer. """ for filename in stl_to_test: slicer, print_organizer = create_setup(filename) pp_dict = print_organizer.printpoints_dict set_extruder_toggle(print_organizer, slicer) assert check_assigned_extruder_toggle(print_organizer), \ "Not all extruder toggles have been assigned after using 'set_extruder_toggle()'. \nFilename : " + \ str(filename) for i, layer in enumerate(slicer.layers): layer_key = 'layer_%d' % i assert not isinstance(layer, compas_slicer.geometry.VerticalLayer), \ "You are testing vertical layers on a test for planar layers. \nFilename : " + str(filename) # --------------- check each individual path for j, path in enumerate(layer.paths): path_key = 'path_%d' % j # (1) --- Find how many trues and falses exist in the path path_extruder_toggles = [ pp.extruder_toggle for pp in pp_dict[layer_key][path_key] ] path_Trues = np.sum(np.array(path_extruder_toggles)) path_Falses = len(path_extruder_toggles) - path_Trues # (2) Decide if the path should be interrupted path_should_be_interrupted_at_end = False # open path if not path.is_closed: path_should_be_interrupted_at_end = True # closed path else: if len(layer.paths) > 1: if layer.is_brim: # brim if (j + 1) % layer.number_of_brim_offsets == 0: path_should_be_interrupted_at_end = True else: path_should_be_interrupted_at_end = True else: # should only have interruption if it is the last layer of the print if i == len(slicer.layers) - 1 and j == len( slicer.layers[i].paths) - 1: path_should_be_interrupted_at_end = True # (3) Check if path has the correct number of interruptions that you decided on step (2) if path_should_be_interrupted_at_end: assert path_Falses == 1, \ "On an path that should be interrupted there should be 1 extruder_toggle = " \ "False, instead you have %d Falses.\n The error came up on layer %d out of " \ "total %d layers, \n path %d out of total %d paths, \n with %d printpoints. " \ "" % (path_Falses, i, len(slicer.layers) - 1, j, len(slicer.layers[i].paths) - 1, len(path_extruder_toggles)) + "\nFilename: " + str(filename) assert path_extruder_toggles[-1] is False, \ "Last printpoint of open path does not have extruder_toggle = False. \n The error is on layer " \ "%d out of total %d layers, \n path %d of total %d paths,\n with %d printpoints. " \ % (i, len(slicer.layers) - 1, j, len(slicer.layers[i].paths) - 1, len(path_extruder_toggles)) + "\nFilename: " + str(filename) else: assert path_Falses == 0, \ "On an path that should NOT be interrupted there should be 0 extruder_toggle " \ "= False, instead you have %d Falses.\n The error came up on layer %d out " \ "of total %d layers, \n path %d out of total %d paths, \n with %d " \ "printpoints. " % (path_Falses, i, len(slicer.layers) - 1, j, len(slicer.layers[i].paths) - 1, len(path_extruder_toggles)) + "\nFilename: " + str(filename)
def main(): start_time = time.time() avg_layer_height = 4.0 parameters = { 'avg_layer_height': avg_layer_height, # controls number of curves that will be generated 'min_layer_height': 0.2, 'max_layer_height': 4.0, 'uneven_upper_targets_offset': 0, 'target_HIGH_smooth_union': [True, [25.0]], # on/off, blend radius } ### --- Load initial_mesh mesh = Mesh.from_obj(os.path.join(DATA_PATH, OBJ_INPUT_NAME)) # --- Load targets (boundaries) low_boundary_vs = utils.load_from_json(DATA_PATH, 'boundaryLOW.json') high_boundary_vs = utils.load_from_json(DATA_PATH, 'boundaryHIGH.json') create_mesh_boundary_attributes(mesh, low_boundary_vs, high_boundary_vs) # --- Create pre-processor preprocessor = InterpolationSlicingPreprocessor(mesh, parameters, DATA_PATH) preprocessor.create_compound_targets() preprocessor.targets_laplacian_smoothing(iterations=4, strength=0.05) ######################################### # --- region split if REGION_SPLIT: # --- ADVANCED slicing with region split g_eval = preprocessor.create_gradient_evaluation( target_1=preprocessor.target_LOW, target_2=preprocessor.target_HIGH, save_output=True) preprocessor.find_critical_points( g_eval, output_filenames=['minima.json', 'maxima.json', 'saddles.json']) preprocessor.region_split( save_split_meshes=True) # split mesh regions on saddle points # utils.interrupt() ######################################### # --- slicing if SLICER: slicers = [] filenames = utils.get_all_files_with_name('split_mesh_', '.json', OUTPUT_PATH) split_meshes = [ Mesh.from_json(os.path.join(OUTPUT_PATH, filename)) for filename in filenames ] for i, split_mesh in enumerate(split_meshes): preprocessor_split = InterpolationSlicingPreprocessor( split_mesh, parameters, DATA_PATH) preprocessor_split.create_compound_targets() preprocessor_split.create_gradient_evaluation( norm_filename='gradient_norm_%d.json' % i, g_filename='gradient_%d.json' % i, target_1=preprocessor_split.target_LOW, target_2=preprocessor_split.target_HIGH) slicer = InterpolationSlicer(split_mesh, preprocessor_split, parameters) if i == 3: slicer.n_multiplier = 0.85 slicer.slice_model() if i == 0: generate_brim(slicer, layer_width=3.0, number_of_brim_offsets=5) seams_smooth(slicer, smooth_distance=0.1) simplify_paths_rdp_igl(slicer, threshold=0.25) utils.save_to_json(slicer.to_data(), OUTPUT_PATH, 'curved_slicer_%d.json' % i) slicers.append(slicer) # utils.interrupt() ######################################### # --- print organization if PRINT_ORGANIZER: filenames = utils.get_all_files_with_name('curved_slicer_', '.json', OUTPUT_PATH) slicers = [ InterpolationSlicer.from_data( utils.load_from_json(OUTPUT_PATH, filename)) for filename in filenames ] for i, slicer in enumerate(slicers): print_organizer = InterpolationPrintOrganizer( slicer, parameters, DATA_PATH) print_organizer.create_printpoints() set_extruder_toggle(print_organizer, slicer) set_blend_radius(print_organizer) add_safety_printpoints(print_organizer, z_hop=10.0) smooth_printpoints_up_vectors(print_organizer, strength=0.5, iterations=10) set_wait_time_on_sharp_corners(print_organizer, threshold=0.5 * math.pi, wait_time=0.2) # --- Save printpoints dictionary to json file printpoints_data = print_organizer.output_printpoints_dict() utils.save_to_json(printpoints_data, OUTPUT_PATH, 'out_printpoints_%d.json' % i) end_time = time.time() print("Total elapsed time", round(end_time - start_time, 2), "seconds")