Reformatted with black 24.2.0

This commit is contained in:
gumyr 2024-02-22 11:27:01 -05:00
parent 82d5f7a8c1
commit 2e81b9d5df
43 changed files with 261 additions and 157 deletions

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby challenge 23-T-24 CURVED SUPPORT
"""
from math import sin, cos, tan, radians
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-01 Bearing Bracket
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-02 Post Cap
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-03 C Clamp Base
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-04 Angle Bracket
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-05 Paste Sleeve
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-06 Bearing Jig
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-07 Flanged Hub
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-08 Tie Plate
"""
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-09 Corner Tie
"""
from math import sqrt
from build123d import *
from ocp_vscode import *

View file

@ -1,6 +1,7 @@
"""
Too Tall Toby Party Pack 01-10 Light Cap
"""
from build123d import *
from ocp_vscode import *

View file

@ -26,6 +26,7 @@ license:
See the License for the specific language governing permissions and
limitations under the License.
"""
from build123d import *

View file

@ -26,6 +26,7 @@ license:
See the License for the specific language governing permissions and
limitations under the License.
"""
from build123d import *

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from build123d import *
exporter = ExportSVG(scale=1)

View file

@ -24,6 +24,7 @@ license:
See the License for the specific language governing permissions and
limitations under the License.
"""
from build123d import *
from ocp_vscode import *

View file

@ -24,6 +24,7 @@ license:
See the License for the specific language governing permissions and
limitations under the License.
"""
# [import]
from build123d import *
from ocp_vscode import *

View file

@ -1,8 +1,9 @@
"""scm version"""
import os.path as pth
try:
from setuptools_scm import get_version # pylint: disable=import-error
from setuptools_scm import get_version # pylint: disable=import-error
version = get_version(root=pth.join("..", "..", ".."), relative_to=__file__)
except Exception as exc:

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
from typing import Union

View file

@ -28,6 +28,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
from typing import Union

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
from typing import Union

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from dataclasses import dataclass
from datetime import date
from math import copysign, floor, gcd, log2, pi
@ -177,6 +178,7 @@ class Draft:
Defaults to 2.0.
"""
# pylint: disable=too-many-instance-attributes
# Class Attributes

View file

@ -26,7 +26,6 @@ license:
"""
# pylint has trouble with the OCP imports
# pylint: disable=no-name-in-module, import-error
# pylint: disable=too-many-lines

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
# pylint has trouble with the OCP imports
# pylint: disable=no-name-in-module, import-error

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
from math import inf

View file

@ -22,6 +22,7 @@ license:
limitations under the License.
"""
# pylint: disable=no-name-in-module
from json import dumps
from typing import Any, Dict, List
@ -220,12 +221,14 @@ def display(shape: Any) -> Javascript:
if not hasattr(shape, "wrapped"): # Is a "Shape"
raise ValueError(f"Type {type(shape)} is not supported")
payload.append({
"shape": to_vtkpoly_string(shape),
"color": DEFAULT_COLOR,
"position": [0, 0, 0],
"orientation": [0, 0, 0],
})
payload.append(
{
"shape": to_vtkpoly_string(shape),
"color": DEFAULT_COLOR,
"position": [0, 0, 0],
"orientation": [0, 0, 0],
}
)
code = TEMPLATE.format(data=dumps(payload), element="element", ratio=0.5)
return Javascript(code)

View file

@ -78,6 +78,7 @@ license:
See the License for the specific language governing permissions and
limitations under the License.
"""
# pylint has trouble with the OCP imports
# pylint: disable=no-name-in-module, import-error
import copy

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
import copy
@ -814,12 +815,14 @@ class Spline(BaseLineObject):
spline = Edge.make_spline(
[p if isinstance(p, Vector) else Vector(*p) for p in spline_pts],
tangents=[
t * s if isinstance(t, Vector) else Vector(*t) * s
for t, s in zip(spline_tangents, scalars)
]
if spline_tangents
else None,
tangents=(
[
t * s if isinstance(t, Vector) else Vector(*t) * s
for t, s in zip(spline_tangents, scalars)
]
if spline_tangents
else None
),
periodic=periodic,
scale=tangent_scalars is None,
)

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
from math import radians, tan

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
from __future__ import annotations
import trianglesolver

View file

@ -26,6 +26,7 @@ license:
limitations under the License.
"""
import copy
import logging
from math import radians, tan, isclose

View file

@ -16,9 +16,12 @@ from typing import Callable, Collection, Optional, cast
from build123d import Location, Shape
def _pack2d(objects: Collection[object],
width_fn: Callable[[object], float],
length_fn: Callable[[object], float]) -> Collection[tuple[float,float]]:
def _pack2d(
objects: Collection[object],
width_fn: Callable[[object], float],
length_fn: Callable[[object], float],
) -> Collection[tuple[float, float]]:
"""Takes an iterable of objects to pack into a square(ish) 2D
arrangement, and return a list of (x,y) locations to place each to
achieve the packing.
@ -47,16 +50,16 @@ def _pack2d(objects: Collection[object],
def split_node(node, w, h):
assert not node.used
node.used = True
node.down = _Node(x=node.x, y=node.y+h, w=node.w, h=node.h-h)
node.right = _Node(x=node.x+w, y=node.y, w=node.w-w, h=h)
node.down = _Node(x=node.x, y=node.y + h, w=node.w, h=node.h - h)
node.right = _Node(x=node.x + w, y=node.y, w=node.w - w, h=h)
return node
def grow_node(w, h):
nonlocal root
can_grow_down = w <= root.w
can_grow_down = w <= root.w
can_grow_right = h <= root.h
should_grow_right = can_grow_right and (root.h >= (root.w + w))
should_grow_down = can_grow_down and (root.w >= (root.h + h))
should_grow_down = can_grow_down and (root.w >= (root.h + h))
if should_grow_right:
return grow_right(w, h)
if should_grow_down:
@ -69,23 +72,40 @@ def _pack2d(objects: Collection[object],
def grow_right(w, h):
nonlocal root
root = _Node(used=True, x=0, y=0, w=root.w+w, h=root.h,
down=root, right=_Node(x=root.w, w=w, h=root.h))
root = _Node(
used=True,
x=0,
y=0,
w=root.w + w,
h=root.h,
down=root,
right=_Node(x=root.w, w=w, h=root.h),
)
node = find_node(root, w, h)
assert node, "Failed to grow right! root: {root}, w: {w}, h: {h}"
return split_node(node, w, h)
def grow_down(w, h):
nonlocal root
root = _Node(used=True, x=0, y=0, w=root.w, h=root.h+h,
down=_Node(y=root.h, w=root.w, h=h), right=root)
root = _Node(
used=True,
x=0,
y=0,
w=root.w,
h=root.h + h,
down=_Node(y=root.h, w=root.w, h=h),
right=root,
)
node = find_node(root, w, h)
assert node, "Failed to grow down! root: {root}, w: {w}, h: {h}"
return split_node(node, w, h)
assert len(objects)>0
sorted_objects = sorted([(i, width_fn(o), length_fn(o)) for (i, o) in enumerate(objects)],
key=lambda d: min(d[1], d[2]), reverse=True)
assert len(objects) > 0
sorted_objects = sorted(
[(i, width_fn(o), length_fn(o)) for (i, o) in enumerate(objects)],
key=lambda d: min(d[1], d[2]),
reverse=True,
)
sorted_objects = sorted(sorted_objects, key=lambda d: max(d[1], d[2]), reverse=True)
root = _Node(False, w=sorted_objects[0][1], h=sorted_objects[0][2])
translations = []
@ -98,16 +118,18 @@ def _pack2d(objects: Collection[object],
translations.append((o[0], node.x, node.y))
return [(t[1], t[2]) for t in sorted(translations, key=lambda t: t[0])]
def pack(objects: Collection[Shape], padding: float) -> Collection[Shape]:
"""Pack objects in a squarish area in Plane.XY."""
bounding_boxes = {o: o.bounding_box().size + (padding, padding) for o in objects}
translations = _pack2d(
objects,
width_fn=lambda o: bounding_boxes[cast(Shape, o)].X,
length_fn=lambda o: bounding_boxes[cast(Shape, o)].Y)
length_fn=lambda o: bounding_boxes[cast(Shape, o)].Y,
)
translated = [
Location((t[0]-o.bounding_box().min.X, t[1]-o.bounding_box().min.Y, 0)) * o
for (o,t) in zip(objects, translations)
Location((t[0] - o.bounding_box().min.X, t[1] - o.bounding_box().min.Y, 0)) * o
for (o, t) in zip(objects, translations)
]
# Assert the packing didn't cause any overlaps.
@ -118,8 +140,11 @@ def pack(objects: Collection[Shape], padding: float) -> Collection[Shape]:
max_x = min(bb1.max.X, bb2.max.X)
max_y = min(bb1.max.Y, bb2.max.Y)
return max_x > min_x and max_y > min_y
bb = [t.bounding_box() for t in translated]
for (i, bb_i) in enumerate(bb):
for (j, bb_j) in enumerate(bb[i+1:]):
assert not _overlapping(bb_i, bb_j), f"Objects at indexes {i} and {j} overlap!"
for i, bb_i in enumerate(bb):
for j, bb_j in enumerate(bb[i + 1 :]):
assert not _overlapping(
bb_i, bb_j
), f"Objects at indexes {i} and {j} overlap!"
return translated

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
# pylint has trouble with the OCP imports
# pylint: disable=no-name-in-module, import-error

View file

@ -563,9 +563,9 @@ class Mixin1D:
for line in all_lines:
num_points = 2 if line.geom_type == GeomType.LINE else 8
points.extend([
line.position_at(i / (num_points - 1)) for i in range(num_points)
])
points.extend(
[line.position_at(i / (num_points - 1)) for i in range(num_points)]
)
points = list(set(points)) # unique points
extreme_areas = {}
for subset in combinations(points, 3):
@ -2068,9 +2068,9 @@ class Shape(NodeMixin):
def vertices(self) -> ShapeList[Vertex]:
"""vertices - all the vertices in this Shape"""
vertex_list = ShapeList([
Vertex(downcast(i)) for i in self._entities(Vertex.__name__)
])
vertex_list = ShapeList(
[Vertex(downcast(i)) for i in self._entities(Vertex.__name__)]
)
for vertex in vertex_list:
vertex.topo_parent = self
return vertex_list
@ -2085,11 +2085,13 @@ class Shape(NodeMixin):
def edges(self) -> ShapeList[Edge]:
"""edges - all the edges in this Shape"""
edge_list = ShapeList([
Edge(i)
for i in self._entities(Edge.__name__)
if not BRep_Tool.Degenerated_s(TopoDS.Edge_s(i))
])
edge_list = ShapeList(
[
Edge(i)
for i in self._entities(Edge.__name__)
if not BRep_Tool.Degenerated_s(TopoDS.Edge_s(i))
]
)
for edge in edge_list:
edge.topo_parent = self
return edge_list
@ -2637,10 +2639,12 @@ class Shape(NodeMixin):
distance = axis.position.to_pnt().SquareDistance(inter_pt)
faces_dist.append((
intersect_maker.Face(),
abs(distance),
)) # will sort all intersected faces by distance whatever the direction is
faces_dist.append(
(
intersect_maker.Face(),
abs(distance),
)
) # will sort all intersected faces by distance whatever the direction is
intersect_maker.Next()
@ -2950,11 +2954,13 @@ class Shape(NodeMixin):
inter_pt = intersect_maker.Pnt()
# Calculate distance along axis
distance = axis.to_plane().to_local_coords(Vector(inter_pt)).Z
intersections.append((
Face(intersect_maker.Face()),
Vector(inter_pt),
distance,
))
intersections.append(
(
Face(intersect_maker.Face()),
Vector(inter_pt),
distance,
)
)
intersect_maker.Next()
intersections.sort(key=lambda x: x[2])
@ -3711,14 +3717,14 @@ class GroupBy(Generic[T, K]):
def __repr__(self):
return repr(ShapeList(self))
def _repr_pretty_(self, p, cycle = False):
def _repr_pretty_(self, p, cycle=False):
if cycle:
p.text('(...)')
p.text("(...)")
else:
with p.group(1, '[', ']'):
with p.group(1, "[", "]"):
for idx, item in enumerate(self):
if idx:
p.text(',')
p.text(",")
p.breakable()
p.pretty(item)
@ -3807,16 +3813,18 @@ class Compound(Mixin3D, Shape):
) * (7 - l_a)
unknown_args = ", ".join(
set(kwargs.keys()).difference([
"shapes",
"obj",
"label",
"material",
"color",
"joints",
"parent",
"children",
])
set(kwargs.keys()).difference(
[
"shapes",
"obj",
"label",
"material",
"color",
"joints",
"parent",
"children",
]
)
)
if unknown_args:
raise ValueError(f"Unexpected argument(s) {unknown_args}")
@ -3939,9 +3947,9 @@ class Compound(Mixin3D, Shape):
"""Method call after detaching from `parent`."""
logger.debug("Removing parent of %s (%s)", self.label, parent.label)
if parent.children:
parent.wrapped = Compound._make_compound([
c.wrapped for c in parent.children
])
parent.wrapped = Compound._make_compound(
[c.wrapped for c in parent.children]
)
else:
parent.wrapped = None
@ -5162,14 +5170,16 @@ class Face(Shape):
)
unknown_args = ", ".join(
set(kwargs.keys()).difference([
"outer_wire",
"inner_wires",
"obj",
"label",
"color",
"parent",
])
set(kwargs.keys()).difference(
[
"outer_wire",
"inner_wires",
"obj",
"label",
"color",
"parent",
]
)
)
if unknown_args:
raise ValueError(f"Unexpected argument(s) {unknown_args}")
@ -5233,16 +5243,18 @@ class Face(Shape):
if len(flat_face_edges) == 4:
edge_pairs = []
for vertex in flat_face_vertices:
edge_pairs.append([
e for e in flat_face_edges if vertex in e.vertices()
])
edge_pairs.append(
[e for e in flat_face_edges if vertex in e.vertices()]
)
edge_pair_directions = [
[edge.tangent_at(0) for edge in pair] for pair in edge_pairs
]
if all([
edge_directions[0].get_angle(edge_directions[1]) == 90
for edge_directions in edge_pair_directions
]):
if all(
[
edge_directions[0].get_angle(edge_directions[1]) == 90
for edge_directions in edge_pair_directions
]
):
result = "RECTANGLE"
if len(flat_face_edges.group_by(SortBy.LENGTH)) == 1:
result = "SQUARE"
@ -5721,9 +5733,9 @@ class Face(Shape):
)
if isinstance(exterior, Wire):
outside_edges = exterior.edges()
elif isinstance(exterior, Iterable) and all([
isinstance(o, Edge) for o in exterior
]):
elif isinstance(exterior, Iterable) and all(
[isinstance(o, Edge) for o in exterior]
):
outside_edges = exterior
else:
raise ValueError("exterior must be a Wire or list of Edges")
@ -6104,14 +6116,16 @@ class Shell(Shape):
faces, label, color, parent = args[:4] + (None,) * (4 - l_a)
unknown_args = ", ".join(
set(kwargs.keys()).difference([
"face",
"faces",
"obj",
"label",
"color",
"parent",
])
set(kwargs.keys()).difference(
[
"face",
"faces",
"obj",
"label",
"color",
"parent",
]
)
)
if unknown_args:
raise ValueError(f"Unexpected argument(s) {unknown_args}")
@ -6246,15 +6260,17 @@ class Solid(Mixin3D, Shape):
)
unknown_args = ", ".join(
set(kwargs.keys()).difference([
"shell",
"obj",
"label",
"color",
"material",
"joints",
"parent",
])
set(kwargs.keys()).difference(
[
"shell",
"obj",
"label",
"color",
"material",
"joints",
"parent",
]
)
)
if unknown_args:
raise ValueError(f"Unexpected argument(s) {unknown_args}")
@ -6673,9 +6689,9 @@ class Solid(Mixin3D, Shape):
# make an auxiliary spine
pitch = 360.0 / angle * normal.length
aux_spine_w = Wire([
Edge.make_helix(pitch, normal.length, 1, center=center, normal=normal)
]).wrapped
aux_spine_w = Wire(
[Edge.make_helix(pitch, normal.length, 1, center=center, normal=normal)]
).wrapped
# extrude the outer wire
outer_solid = extrude_aux_spine(
@ -7270,17 +7286,19 @@ class Wire(Mixin1D, Shape):
edges, sequenced, label, color, parent = args[:5] + (None,) * (5 - l_a)
unknown_args = ", ".join(
set(kwargs.keys()).difference([
"curve",
"wire",
"edge",
"edges",
"sequenced",
"obj",
"label",
"color",
"parent",
])
set(kwargs.keys()).difference(
[
"curve",
"wire",
"edge",
"edges",
"sequenced",
"obj",
"label",
"color",
"parent",
]
)
)
if unknown_args:
raise ValueError(f"Unexpected argument(s) {unknown_args}")
@ -7492,10 +7510,12 @@ class Wire(Mixin1D, Shape):
# Select the wire containing the start and end points
wire_segments = edges_to_wires(modified_edges + unmodified_edges)
trimmed_wire = filter(
lambda w: all([
w.distance_to(p) <= TOLERANCE
for p in [trim_start_point, trim_end_point]
]),
lambda w: all(
[
w.distance_to(p) <= TOLERANCE
for p in [trim_start_point, trim_end_point]
]
),
wire_segments,
)
try:
@ -7833,10 +7853,12 @@ class Wire(Mixin1D, Shape):
trim_points[edge1] = [simplice[1]]
else:
trim_points[edge1].append(simplice[1])
connecting_edge_data.append((
(edge0, points_lookup[simplice[0]][1], simplice[0]),
(edge1, points_lookup[simplice[1]][1], simplice[1]),
))
connecting_edge_data.append(
(
(edge0, points_lookup[simplice[0]][1], simplice[0]),
(edge1, points_lookup[simplice[1]][1], simplice[1]),
)
)
# Look for connecting edges within an edge
elif abs(simplice[0] - simplice[1]) != 1:
start_pnt = min(simplice.tolist())
@ -7845,10 +7867,12 @@ class Wire(Mixin1D, Shape):
trim_points[edge0] = [start_pnt, end_pnt]
else:
trim_points[edge0].extend([start_pnt, end_pnt])
connecting_edge_data.append((
(edge0, points_lookup[start_pnt][1], start_pnt),
(edge0, points_lookup[end_pnt][1], end_pnt),
))
connecting_edge_data.append(
(
(edge0, points_lookup[start_pnt][1], start_pnt),
(edge0, points_lookup[end_pnt][1], end_pnt),
)
)
trim_data = {}
for edge, points in trim_points.items():
@ -7956,15 +7980,19 @@ class Wire(Mixin1D, Shape):
output_wire_center - planar_wire_center
).normalized()
if output_wire_direction.dot(direction_vector) >= 0:
output_wires_distances.append((
output_wire,
(output_wire_center - planar_wire_center).length,
))
output_wires_distances.append(
(
output_wire,
(output_wire_center - planar_wire_center).length,
)
)
else:
output_wires_distances.append((
output_wire,
(output_wire_center - center_point).length,
))
output_wires_distances.append(
(
output_wire,
(output_wire_center - center_point).length,
)
)
output_wires_distances.sort(key=lambda x: x[1])
logger.debug(

View file

@ -1,12 +1,13 @@
"""
Export a version string.
"""
try:
try:
from ._dev.scm_version import version # pylint: disable=unused-import
from ._dev.scm_version import version # pylint: disable=unused-import
except ImportError:
from ._version import version
except Exception: # pylint: disable=broad-exception-caught
except Exception: # pylint: disable=broad-exception-caught
import warnings
warnings.warn(
@ -15,4 +16,4 @@ except Exception: # pylint: disable=broad-exception-caught
)
del warnings
version = "0.0.0" # pylint: disable=invalid-name
version = "0.0.0" # pylint: disable=invalid-name

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
import unittest
from math import pi
from build123d import *

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
import unittest
from build123d import *

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
import unittest
from math import pi, sqrt
from build123d import *

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
import unittest
from math import sqrt, pi
from build123d import *

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
import unittest
from math import pi, sin
from build123d import *
@ -470,9 +471,7 @@ class TestThicken(unittest.TestCase):
non_planar = Sphere(1).faces()[0]
outer_sphere = thicken(non_planar, amount=0.1)
self.assertAlmostEqual(
outer_sphere.volume, (4 / 3) * pi * (1.1**3 - 1**3), 5
)
self.assertAlmostEqual(outer_sphere.volume, (4 / 3) * pi * (1.1**3 - 1**3), 5)
class TestTorus(unittest.TestCase):

View file

@ -2981,7 +2981,7 @@ class TestShapeList(DirectApiTestCase):
result.group("C")
def test_group_by_str_repr(self):
nonagon = RegularPolygon(5,9)
nonagon = RegularPolygon(5, 9)
expected = [
"[[<build123d.topology.Edge at 0x1277f6e1cd0>],",
@ -3008,7 +3008,9 @@ class TestShapeList(DirectApiTestCase):
" [<build123d.topology.Edge object at 0x000001277FC86F90>,"
" <build123d.topology.Edge object at 0x000001277F6E1CD0>]]"
)
self.assertDunderReprEqual(repr(nonagon.edges().group_by(Axis.X)),expected_repr)
self.assertDunderReprEqual(
repr(nonagon.edges().group_by(Axis.X)), expected_repr
)
f = io.StringIO()
p = pretty.PrettyPrinter(f)

View file

@ -25,6 +25,7 @@ license:
limitations under the License.
"""
import math
import unittest
from datetime import date
@ -101,7 +102,6 @@ def create_test_sketch() -> tuple[Sketch, Sketch, Sketch]:
class TestClassInstantiation(unittest.TestCase):
"""Test Draft class instantiation"""
def test_draft_instantiation(self):

View file

@ -26,6 +26,7 @@ license:
limitations under the License.
"""
import copy
import unittest

View file

@ -7,6 +7,7 @@ date: November 9th 2023
desc: Unit tests for the build123d pack module
"""
import operator
import random
import unittest
@ -14,8 +15,10 @@ from functools import reduce
from build123d import *
class TestPack(unittest.TestCase):
"""Tests for the pack helper."""
def test_simple(self):
"""Test pack with hand-picked data against expected output."""
packed = pack([Box(10, 2, 1), Box(1, 5, 1), Box(1, 5, 1)], padding=1)
@ -27,32 +30,39 @@ class TestPack(unittest.TestCase):
"[bbox: 0.0 <= x <= 10.0, 0.0 <= y <= 2.0, -0.5 <= z <= 0.5,"
" bbox: 0.0 <= x <= 1.0, 3.0 <= y <= 8.0, -0.5 <= z <= 0.5,"
" bbox: 2.0 <= x <= 3.0, 3.0 <= y <= 8.0, -0.5 <= z <= 0.5]",
str([p.bounding_box() for p in packed]))
str([p.bounding_box() for p in packed]),
)
def test_random_boxes(self):
"""Test pack with larger (and randomized) inputs."""
random.seed(123456)
# 50 is an arbitrary number that is large enough to exercise
# different aspects of the packer while still completing quickly.
test_boxes = [Box(random.randint(1, 20), random.randint(1, 20), 1)
for _ in range(50)]
test_boxes = [
Box(random.randint(1, 20), random.randint(1, 20), 1) for _ in range(50)
]
# Not raising in this call shows successfull non-overlap.
packed = pack(test_boxes, 1)
self.assertEqual(
"bbox: 0.0 <= x <= 94.0, 0.0 <= y <= 86.0, -0.5 <= z <= 0.5",
str((Part() + packed).bounding_box()))
str((Part() + packed).bounding_box()),
)
def test_random_slots(self):
"""Test pack for 2D objects."""
random.seed(123456)
# 50 is an arbitrary number that is large enough to exercise
# different aspects of the packer while still completing quickly.
inputs = [SlotOverall(random.randint(1,20), random.randint(1,20)) for _ in range(50)]
inputs = [
SlotOverall(random.randint(1, 20), random.randint(1, 20)) for _ in range(50)
]
# Not raising in this call shows successfull non-overlap.
packed = pack(inputs, 1)
self.assertEqual(
"bbox: 0.0 <= x <= 124.0, 0.0 <= y <= 105.0, 0.0 <= z <= 0.0",
str((Sketch() + packed).bounding_box()))
str((Sketch() + packed).bounding_box()),
)
if __name__ == "__main__":
unittest.main()