示例#1
0
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()
示例#2
0
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")
示例#3
0
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)
示例#4
0
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")
示例#5
0
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])