# Path: trimesh/constants.py
# class NumericalToleranceMesh(object):
# class NumericalResolutionMesh(object):
# class NumericalTolerancePath(object):
# class NumericalResolutionPath(object):
# class MeshError(Exception):
# class TransformError(Exception):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
# def _log_time(method):
#     def timed(*args, **kwargs):
# 
# Path: trimesh/constants.py
# class NumericalToleranceMesh(object):
# class NumericalResolutionMesh(object):
# class NumericalTolerancePath(object):
# class NumericalResolutionPath(object):
# class MeshError(Exception):
# class TransformError(Exception):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
# def _log_time(method):
#     def timed(*args, **kwargs):
# 
# Path: trimesh/path/polygons.py
# def polygons_obb(polygons):
#     '''
#     Find the OBBs for a list of shapely.geometry.Polygons
#     '''
#     rectangles = [None] * len(polygons)
#     transforms = [None] * len(polygons)
#     for i, p in enumerate(polygons):
#         transforms[i], rectangles[i] = polygon_obb(p)
#     return np.array(transforms), np.array(rectangles)
# 
# def transform_polygon(polygon, transform, plot=False):
#     if is_sequence(polygon):
#         result = [transform_polygon(p, t) for p, t in zip(polygon, transform)]
#     else:
#         shell = transform_points(np.array(polygon.exterior.coords), transform)
#         holes = [transform_points(np.array(i.coords), transform)
#                  for i in polygon.interiors]
#         result = Polygon(shell=shell, holes=holes)
#     if plot:
#         plot_polygon(result)
#     return result


import numpy as np
        import matplotlib.pyplot as plt
from collections import deque
from ..constants import log, time_function
from ..constants import tol_path as tol
from .polygons import polygons_obb, transform_polygon
        self.bounds = bounds
        self.occupied = False

        if size is not None:
            self.bounds = np.append([0, 0], size)

    def insert(self, rectangle_size):
        for child in self.child:
            if child is not None:
                attempt = child.insert(rectangle_size)
                if attempt:
                    return attempt

        if self.occupied:
            return None

        # compare the bin size to the insertion candidate size
        size_test = bounds_to_size(self.bounds) - rectangle_size

        # this means the inserted rectangle is too big for the cell
        if np.any(size_test < -tol.zero):
            return None

        # since the cell is big enough for the current rectangle, either it
        # is going to be inserted here, or the cell is going to be split
        # either way, the cell is now occupied.
        self.occupied = True

        # this means the inserted rectangle fits perfectly
        # since we already checked to see if it was negative, no abs is needed

# Path: trimesh/constants.py
# class NumericalToleranceMesh(object):
# class NumericalResolutionMesh(object):
# class NumericalTolerancePath(object):
# class NumericalResolutionPath(object):
# class MeshError(Exception):
# class TransformError(Exception):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
# def _log_time(method):
#     def timed(*args, **kwargs):
# 
# Path: trimesh/constants.py
# class NumericalToleranceMesh(object):
# class NumericalResolutionMesh(object):
# class NumericalTolerancePath(object):
# class NumericalResolutionPath(object):
# class MeshError(Exception):
# class TransformError(Exception):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
#     def __init__(self, **kwargs):
# def _log_time(method):
#     def timed(*args, **kwargs):
# 
# Path: trimesh/path/polygons.py
# def polygons_obb(polygons):
#     '''
#     Find the OBBs for a list of shapely.geometry.Polygons
#     '''
#     rectangles = [None] * len(polygons)
#     transforms = [None] * len(polygons)
#     for i, p in enumerate(polygons):
#         transforms[i], rectangles[i] = polygon_obb(p)
#     return np.array(transforms), np.array(rectangles)
# 
# def transform_polygon(polygon, transform, plot=False):
#     if is_sequence(polygon):
#         result = [transform_polygon(p, t) for p, t in zip(polygon, transform)]
#     else:
#         shell = transform_points(np.array(polygon.exterior.coords), transform)
#         holes = [transform_points(np.array(i.coords), transform)
#                  for i in polygon.interiors]
#         result = Polygon(shell=shell, holes=holes)
#     if plot:
#         plot_polygon(result)
#     return result


# Path: trimesh/path/packing.py
import numpy as np
        import matplotlib.pyplot as plt
from collections import deque
from ..constants import log, time_function
from ..constants import tol_path as tol
from .polygons import polygons_obb, transform_polygon

        self.bounds = bounds
        self.occupied = False

        if size is not None:
            self.bounds = np.append([0, 0], size)

    def insert(self, rectangle_size):
        for child in self.child:
            if child is not None:
                attempt = child.insert(rectangle_size)
                if attempt:
                    return attempt

        if self.occupied:
            return None

        # compare the bin size to the insertion candidate size
        size_test = bounds_to_size(self.bounds) - rectangle_size

        # this means the inserted rectangle is too big for the cell
        if np.any(size_test < -tol.zero):
            return None

        # since the cell is big enough for the current rectangle, either it
        # is going to be inserted here, or the cell is going to be split
        # either way, the cell is now occupied.
        self.occupied = True

        # this means the inserted rectangle fits perfectly
        # since we already checked to see if it was negative, no abs is needed

        if np.all(size_test < tol.zero):