def test_past_failure(config, config_fn): for xf in xfails: if xf in config_fn: pytest.skip("Can't figure this one out") config.load(config_fn) with tempfile.TemporaryDirectory() as tmpdir: config.directory = tmpdir starter = utils.open_mesh() if config.part_separation and starter.body_count > 1: starter = utils.separate_starter(starter) run(starter) print()
def test_regression(file_number): print() # files tree_file = f"regression_tree_{file_number}.json" config_file = f"regression_config_{file_number}.yml" tree_file = os.path.join(os.path.dirname(__file__), 'regression_test_data', tree_file) config_file = os.path.join(os.path.dirname(__file__), 'regression_test_data', config_file) Configuration.config = Configuration(config_file) # open and prepare mesh mesh = utils.open_mesh() # open tree baseline baseline = utils.open_tree(tree_file) # run new tree tree = search.beam_search(mesh) # verify they are the same print() for baseline_node in baseline.nodes: print(f"path: {baseline_node.path}") # same path node = tree.get_node(baseline_node.path) if node.plane is None: assert baseline_node.plane is None else: # same origin print( f"baseline origin {baseline_node.plane[0]}, test origin {node.plane[0]}" ) # same normal print( f"baseline normal {baseline_node.plane[1]}, test normal {node.plane[1]}" ) assert np.all(baseline_node.plane[0] == node.plane[0]) assert np.all(baseline_node.plane[1] == node.plane[1]) config = Configuration.config for i in range(config.beam_width): os.remove( os.path.join(os.path.dirname(__file__), 'regression_test_data', f'{i}.json')) for stl in glob.glob( os.path.join(os.path.dirname(__file__), 'regression_test_data', '*.stl')): os.remove(stl) config.restore_defaults()
def test_preprocessing_decimate(config): """verify that for preprocessing works with sample Decimate Blender modifier """ # load wing config, doesn't have preprocessor configured config.load( os.path.join(os.path.dirname(__file__), 'test_data', "preprocessor_config_1.yml")) mesh = utils.open_mesh() # load original mesh # configure the preprocessor config.preprocessor = "test/test_data/decimate_preprocessor.py.template" preprocess_mesh = utils.preprocess(mesh) # preprocess the mesh # compare original mesh with preprocessed one (oldFaces, _) = mesh.faces.shape (newFaces, _) = preprocess_mesh.faces.shape newFacesExpected = math.floor(oldFaces * 0.1) # 8032, decimation -> 803 newFacesActual = math.floor(newFaces) # decimation -> 802 assert abs(newFacesExpected - newFacesActual) < 10
def test_modify_configuration(config): """Verify that modifying the configuration modifies the behavior of the other modules. Create a tree with the default part and the default configuration, verify that it will fit in the printer volume, then modify the printer volume in the config and verify that a newly created tree will have a different n_parts objective """ mesh = utils.open_mesh() # create bsp tree tree = bsp_tree.BSPTree(mesh) print(f"n parts: {tree.nodes[0].n_parts}") assert tree.nodes[0].n_parts == 1 config.printer_extents = config.printer_extents / 2 print("modified config") print(f"original tree n parts: {tree.nodes[0].n_parts}") assert tree.nodes[0].n_parts == 1 new_tree = bsp_tree.BSPTree(mesh) print(f"new tree n parts: {new_tree.nodes[0].n_parts}") assert new_tree.nodes[0].n_parts == 2
def main(mesh_filepath): # set configuration options config = Configuration.config config.name = 'output' config.mesh = mesh_filepath config.beam_width = 3 config.connector_diameter = 6 config.connector_spacing = 10 config.part_separation = True config.scale_factor = 5 config.save() # open the input mesh as the starter starter = utils.open_mesh() # separate pieces if config.part_separation and starter.body_count > 1: starter = utils.separate_starter(starter) # complete the beam search using the starter, no search will take place if the starter tree is adequately partitioned tree = beam_search(starter) # save the tree now in case the connector placement fails utils.save_tree(tree, "final_tree.json") try: # mark starting time t0 = time.time() # create connector placer object, this creates all potential connectors and determines their collisions connector_placer = connector.ConnectorPlacer(tree) if connector_placer.n_connectors > 0: # use simulated annealing to determine the best combination of connectors state = connector_placer.simulated_annealing_connector_placement() # save the final tree including the state utils.save_tree(tree, "final_tree_with_connectors.json", state) # add the connectors / subtract the slots from the parts of the partitioned input object tree = connector_placer.insert_connectors(tree, state) except Exception as e: # fail gently so that the STLs still get exported warnings.warn(e, Warning, stacklevel=2) # export the parts of the partitioned object utils.export_tree_stls(tree)
def test_regression(config, file_number): print() # files tree_file = f"regression_tree_{file_number}.json" config_file = f"regression_config_{file_number}.yml" tree_file = os.path.join(os.path.dirname(__file__), 'test_data', tree_file) config_file = os.path.join(os.path.dirname(__file__), 'test_data', config_file) config.load(config_file) with tempfile.TemporaryDirectory() as tmpdir: config.directory = tmpdir # open and prepare mesh mesh = utils.open_mesh() # open tree baseline baseline = utils.open_tree(tree_file) # run new tree tree = search.beam_search(mesh) # verify they are the same print() for baseline_node in baseline.nodes: print(f"path: {baseline_node.path}") # same path node = tree.get_node(baseline_node.path) if node.plane is None: assert baseline_node.plane is None else: # same origin print( f"baseline origin {baseline_node.plane[0]}, test origin {node.plane[0]}" ) # same normal print( f"baseline normal {baseline_node.plane[1]}, test normal {node.plane[1]}" ) assert np.allclose(baseline_node.plane[0], node.plane[0]) assert np.allclose(baseline_node.plane[1], node.plane[1])
except: parser.print_help() traceback.print_exc() sys.exit(0) # override the mesh path in config if specified on command line if args.mesh: config.mesh = args.mesh config.name = os.path.splitext(os.path.basename(args.mesh)[0]) # name the folder based on the name of the object and the current date / time output_folder = f"{config.name}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}" # create the new directory in the 'output' subdirectory of pychop3d new_directory = os.path.abspath( os.path.join(config.directory, output_folder)) os.mkdir(new_directory) config.directory = new_directory # save configuration config.save() Configuration.config = config # open the input mesh as the starter starter = utils.open_mesh() # separate pieces if config.part_separation and starter.body_count > 1: starter = utils.separate_starter(starter) # run through the process print(f"Using config: {args.config}") print(f"Using mesh: {config.mesh}") run(starter)