Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When reusing bins and items in a packer old data persists #33

Open
Kyle772 opened this issue Jul 17, 2022 · 7 comments
Open

When reusing bins and items in a packer old data persists #33

Kyle772 opened this issue Jul 17, 2022 · 7 comments

Comments

@Kyle772
Copy link

Kyle772 commented Jul 17, 2022

This isn't so much of an issue moreso a problem I ran into which took some time to debug.

Since the three objects are built out as standalone classes bins keep their mutated data between runs. To work around this I had to manually reset the data back to the init values on every loop in each bin. This isn't really an issue with the code but more an issue with the implementation/design. If a new packer is initialized and bins are added those bins should be reinitialized as well.

More of a PSA I suppose since nobody in the gh issues brought this up (Except maybe #15 ?)

@deydist
Copy link

deydist commented Oct 31, 2022

I am experiencing this same strange "issue". What is the best way to manually reset the data?

@Johetan
Copy link

Johetan commented Mar 8, 2023

I ran into the same issue, trying to use it for the repo for simplicity.
How would i go about that in the loop?

@deydist
Copy link

deydist commented Mar 10, 2023

@Kyle772 Can you share your method for resetting the data back to the init values? In my implementation I am having to use 3 different Bin lists but would like to standardize to one.

@Kyle772
Copy link
Author

Kyle772 commented Mar 10, 2023

Sorry for the late response I needed to hunt down the code for this and kept putting it off.

If you persist the packer between different bins it will maintain the values.

To avoid this what I ended up doing was reinitializing a new packer and bins with each request/cycle. You could also manually go through the init variables (found in main.py Packer.init()) and reset them manually. I don't have a huge data set so recreating the classes wasn't an issue for me but if you need the original set you could deep copy it into a variable and pull values from there on reset.

If you're still having troubles consider reading through this article, it's not immediately relevant to this library but may give you the insight as to why this needs to happen
https://realpython.com/python-pass-by-reference/

@Johetan
Copy link

Johetan commented Mar 11, 2023

Hi, thank you for the reply!
This worked for me. Had to initialize every object inside the loop.
Items, Bins and Backer.
I'll post the snippet here later on.

@deydist
Copy link

deydist commented Mar 13, 2023

Thanks to both of you! I'm curious how your solution looks Johetan. I'm currently reinitializing the list of Bins in each function... however ideally I want to have just 1 list of bins that reset so I can use that to manage changes when box sizes change.

@Johetan
Copy link

Johetan commented Mar 13, 2023

It's a bit rough


import os
import trimesh
import pandas as pd
import py3dbp as packing
from typing import Tuple

# Define the folder path containing the STL files
cwd = os.getcwd()
folder_path = os.path.join(cwd, "DataFolder")
# Init Dataframe containing the bbox data

# Bedinung einbauen, bin muss größer sein als größte dimension einzelteil

#define the size of the box in mm
max_x_dim = 150
max_y_dim = 150
max_z_dim = 120
max_weight = 1

class Drawable_Box:
    def __init__(self, depth, height, width, name, items):
        self.depth = depth
        self.height = height
        self.width = width
        self.name = name
        self.items = items
        
class Drawable_Item:
    def __init__(self, depth, height, width, x_pos, y_pos, z_pos, name):
        self.depth = depth
        self.height = height
        self.width = width
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.z_pos = z_pos
        self.name = name

def get_bounding_box_dimensions(mesh_data: trimesh.Trimesh)-> pd.DataFrame:
    x_min, y_min, z_min = mesh_data.bounds[0]
    x_max, y_max, z_max = mesh_data.bounds[1]
    x_size, y_size, z_size = x_max - x_min, y_max - y_min, z_max - z_min
    return x_size, y_size, z_size

def create_packing_items(dataframe_items: pd.DataFrame) -> list:
    return [packing.Item(row["part_id"], row["x_size"], row["z_size"], row["y_size"], 0) for index, row in dataframe_items.iterrows()]

def import_files(folder_path: str) -> pd.DataFrame:    
    results_df = pd.DataFrame(columns=["part_id", "x_size", "y_size", "z_size"])
    for filename in os.listdir(folder_path):
        if filename.endswith(".stl"):
            part_id = os.path.splitext(filename)[0]
            mesh_data = trimesh.load(os.path.join(folder_path, filename))
            x_size, y_size, z_size = get_bounding_box_dimensions(mesh_data)
            series = pd.Series({"part_id": part_id, "x_size": x_size, "y_size": y_size, "z_size": z_size})
            results_df = pd.concat([results_df, series.to_frame().T], ignore_index=True)
            results_df = results_df.sort_values(by=["x_size", "y_size", "z_size"])
    return results_df
    
def pack_it(item_list: list) -> Tuple[list, list]:
    standart_bin = packing.Bin("printerbin", max_x_dim, max_y_dim, max_z_dim, max_weight)
    packer = packing.Packer()
    not_fitted = []
    not_fitted.clear()
    for item in item_list:
        packer.add_item(item)
    packer.add_bin(standart_bin)
    packer.pack(bigger_first=True)
    for b in packer.bins:
        not_fitted = b.unfitted_items
    return packer.bins, not_fitted

def pack_list_from_unfit(not_fitted_items_list: list) -> list:
    new_list = []
    new_list.clear()
    for parts in not_fitted_items_list:
        item = packing.Item(parts.name, parts.width, parts.height, parts.depth, parts.weight)
        new_list.append(item)
        new_list
    return new_list

results_df = import_files(folder_path)
item_list = create_packing_items(results_df)
print(type(item_list))
packed_containers = []
remaining_items_list = [1]
drawable_bins = []

while len(remaining_items_list) > 0:
    print("Packing")
    container, remaining_items_list = pack_it(item_list)
    print("Bin done")
    item_list = pack_list_from_unfit(remaining_items_list)
    print("Remaining Items")
    packed_containers.append(container)

for objects in packed_containers:
    print("::::: A Container ::::::")
    for single_bin in objects:
        print(single_bin.string())
        # drawable_bins.append(single_bin)
        print("FITTED ITEMS:")
        for item in single_bin.items:
            print("====> ", item.string())
        print("UNFITTED ITEMS:")
        for item in single_bin.unfitted_items:
            print("====> ", item.string())

# for bins in packed_containers:
#     box = Drawable_Box(bins[0].depth, bins[0].height, bins[0].width, bins[0].name, bins[0].items )
#     drawable_bins.append(box)
    
# for drawings in drawable_bins:
#     for items in drawings.items:
#         print(items.depth)
#         print(items.height)
#         print(items.width)
#         print(float(items.position[0]))
#         print(float(items.position[1]))
#         print(float(items.position[2]))
#         print(items.name)    
      
# for i, filename in enumerate(os.listdir(folder_path)):
#     if filename.endswith(".stl"):  
#         print(filename)
#         os.rename(folder_path + "\\" + filename, folder_path + "\\" + str(i)+ ".stl")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants