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 run(starter): """This function goes through the complete Pychop3D process, including the beam search for the optimal cutting planes, determining the connector locations, adding the connectors to the part meshes, then saving the STLs, the tree json and the configuration file. :param starter: Either an unpartitioned mesh or an already partitioned tree to begin the process using :type starter: `trimesh.Trimesh` :type starter: `bsp_tree.BSPTree` """ config = Configuration.config # basic logging setup logging.basicConfig( level=logging.INFO, format="%(asctime)s %(name)s [%(levelname)s] %(message)s", handlers=[ logging.FileHandler(os.path.join(config.directory, "info.log")), logging.StreamHandler() ]) # mark starting time t0 = time.time() # complete the beam search using the starter, no search will take place if the starter tree is already # adequately partitioned tree = beam_search(starter) logger.info(f"Best BSP-tree found in {time.time() - t0} seconds") # save the tree now in case the connector placement fails utils.save_tree(tree, "final_tree.json") # mark starting time t0 = time.time() logger.info("finding best connector arrangement") # 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() logger.info( f"Best connector arrangement found in {time.time() - t0} seconds") # 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 logger.info(f"inserting {state.sum()} connectors...") tree = connector_placer.insert_connectors(tree, state) # export the parts of the partitioned object utils.export_tree_stls(tree) logger.info("Finished")
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 run(starter): """This function goes through the complete Pychop3D process, including the beam search for the optimal cutting planes, determining the connector locations, adding the connectors to the part meshes, then saving the STLs, the tree json and the configuration file. :param starter: Either an unpartitioned mesh or an already partitioned tree to begin the process using :type starter: `trimesh.Trimesh` :type starter: `bsp_tree.BSPTree` """ # mark starting time t0 = time.time() # complete the beam search using the starter, no search will take place if the starter tree is already # adequately partitioned tree = beam_search(starter) logger.info(f"Best BSP-tree found in {time.time() - t0} seconds") # 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) logger.info( f"Best connector arrangement found in {time.time() - t0} seconds") except Exception as e: # fail gently so that the STLs still get exported logger.error("Connector placement failed") logger.error(e) # export the parts of the partitioned object utils.export_tree_stls(tree) logger.info("Finished")
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])