mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 10:41:20 -08:00
Reformatted with black 24.2.0
This commit is contained in:
parent
82d5f7a8c1
commit
2e81b9d5df
43 changed files with 261 additions and 157 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby challenge 23-T-24 CURVED SUPPORT
|
Too Tall Toby challenge 23-T-24 CURVED SUPPORT
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from math import sin, cos, tan, radians
|
from math import sin, cos, tan, radians
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-01 Bearing Bracket
|
Too Tall Toby Party Pack 01-01 Bearing Bracket
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-02 Post Cap
|
Too Tall Toby Party Pack 01-02 Post Cap
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-03 C Clamp Base
|
Too Tall Toby Party Pack 01-03 C Clamp Base
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-04 Angle Bracket
|
Too Tall Toby Party Pack 01-04 Angle Bracket
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-05 Paste Sleeve
|
Too Tall Toby Party Pack 01-05 Paste Sleeve
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-06 Bearing Jig
|
Too Tall Toby Party Pack 01-06 Bearing Jig
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-07 Flanged Hub
|
Too Tall Toby Party Pack 01-07 Flanged Hub
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-08 Tie Plate
|
Too Tall Toby Party Pack 01-08 Tie Plate
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-09 Corner Tie
|
Too Tall Toby Party Pack 01-09 Corner Tie
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Too Tall Toby Party Pack 01-10 Light Cap
|
Too Tall Toby Party Pack 01-10 Light Cap
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ license:
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ license:
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
||||||
exporter = ExportSVG(scale=1)
|
exporter = ExportSVG(scale=1)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ license:
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ license:
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# [import]
|
# [import]
|
||||||
from build123d import *
|
from build123d import *
|
||||||
from ocp_vscode import *
|
from ocp_vscode import *
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
"""scm version"""
|
"""scm version"""
|
||||||
|
|
||||||
import os.path as pth
|
import os.path as pth
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from math import copysign, floor, gcd, log2, pi
|
from math import copysign, floor, gcd, log2, pi
|
||||||
|
|
@ -177,6 +178,7 @@ class Draft:
|
||||||
Defaults to 2.0.
|
Defaults to 2.0.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
|
|
||||||
# Class Attributes
|
# Class Attributes
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ license:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# pylint has trouble with the OCP imports
|
# pylint has trouble with the OCP imports
|
||||||
# pylint: disable=no-name-in-module, import-error
|
# pylint: disable=no-name-in-module, import-error
|
||||||
# pylint: disable=too-many-lines
|
# pylint: disable=too-many-lines
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint has trouble with the OCP imports
|
# pylint has trouble with the OCP imports
|
||||||
# pylint: disable=no-name-in-module, import-error
|
# pylint: disable=no-name-in-module, import-error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from math import inf
|
from math import inf
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=no-name-in-module
|
# pylint: disable=no-name-in-module
|
||||||
from json import dumps
|
from json import dumps
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
@ -220,12 +221,14 @@ def display(shape: Any) -> Javascript:
|
||||||
if not hasattr(shape, "wrapped"): # Is a "Shape"
|
if not hasattr(shape, "wrapped"): # Is a "Shape"
|
||||||
raise ValueError(f"Type {type(shape)} is not supported")
|
raise ValueError(f"Type {type(shape)} is not supported")
|
||||||
|
|
||||||
payload.append({
|
payload.append(
|
||||||
|
{
|
||||||
"shape": to_vtkpoly_string(shape),
|
"shape": to_vtkpoly_string(shape),
|
||||||
"color": DEFAULT_COLOR,
|
"color": DEFAULT_COLOR,
|
||||||
"position": [0, 0, 0],
|
"position": [0, 0, 0],
|
||||||
"orientation": [0, 0, 0],
|
"orientation": [0, 0, 0],
|
||||||
})
|
}
|
||||||
|
)
|
||||||
code = TEMPLATE.format(data=dumps(payload), element="element", ratio=0.5)
|
code = TEMPLATE.format(data=dumps(payload), element="element", ratio=0.5)
|
||||||
|
|
||||||
return Javascript(code)
|
return Javascript(code)
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ license:
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint has trouble with the OCP imports
|
# pylint has trouble with the OCP imports
|
||||||
# pylint: disable=no-name-in-module, import-error
|
# pylint: disable=no-name-in-module, import-error
|
||||||
import copy
|
import copy
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
@ -814,12 +815,14 @@ class Spline(BaseLineObject):
|
||||||
|
|
||||||
spline = Edge.make_spline(
|
spline = Edge.make_spline(
|
||||||
[p if isinstance(p, Vector) else Vector(*p) for p in spline_pts],
|
[p if isinstance(p, Vector) else Vector(*p) for p in spline_pts],
|
||||||
tangents=[
|
tangents=(
|
||||||
|
[
|
||||||
t * s if isinstance(t, Vector) else Vector(*t) * s
|
t * s if isinstance(t, Vector) else Vector(*t) * s
|
||||||
for t, s in zip(spline_tangents, scalars)
|
for t, s in zip(spline_tangents, scalars)
|
||||||
]
|
]
|
||||||
if spline_tangents
|
if spline_tangents
|
||||||
else None,
|
else None
|
||||||
|
),
|
||||||
periodic=periodic,
|
periodic=periodic,
|
||||||
scale=tangent_scalars is None,
|
scale=tangent_scalars is None,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from math import radians, tan
|
from math import radians, tan
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import trianglesolver
|
import trianglesolver
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
from math import radians, tan, isclose
|
from math import radians, tan, isclose
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,12 @@ from typing import Callable, Collection, Optional, cast
|
||||||
|
|
||||||
from build123d import Location, Shape
|
from build123d import Location, Shape
|
||||||
|
|
||||||
def _pack2d(objects: Collection[object],
|
|
||||||
|
def _pack2d(
|
||||||
|
objects: Collection[object],
|
||||||
width_fn: Callable[[object], float],
|
width_fn: Callable[[object], float],
|
||||||
length_fn: Callable[[object], float]) -> Collection[tuple[float,float]]:
|
length_fn: Callable[[object], float],
|
||||||
|
) -> Collection[tuple[float, float]]:
|
||||||
"""Takes an iterable of objects to pack into a square(ish) 2D
|
"""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
|
arrangement, and return a list of (x,y) locations to place each to
|
||||||
achieve the packing.
|
achieve the packing.
|
||||||
|
|
@ -69,23 +72,40 @@ def _pack2d(objects: Collection[object],
|
||||||
|
|
||||||
def grow_right(w, h):
|
def grow_right(w, h):
|
||||||
nonlocal root
|
nonlocal root
|
||||||
root = _Node(used=True, x=0, y=0, w=root.w+w, h=root.h,
|
root = _Node(
|
||||||
down=root, right=_Node(x=root.w, w=w, h=root.h))
|
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)
|
node = find_node(root, w, h)
|
||||||
assert node, "Failed to grow right! root: {root}, w: {w}, h: {h}"
|
assert node, "Failed to grow right! root: {root}, w: {w}, h: {h}"
|
||||||
return split_node(node, w, h)
|
return split_node(node, w, h)
|
||||||
|
|
||||||
def grow_down(w, h):
|
def grow_down(w, h):
|
||||||
nonlocal root
|
nonlocal root
|
||||||
root = _Node(used=True, x=0, y=0, w=root.w, h=root.h+h,
|
root = _Node(
|
||||||
down=_Node(y=root.h, w=root.w, h=h), right=root)
|
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)
|
node = find_node(root, w, h)
|
||||||
assert node, "Failed to grow down! root: {root}, w: {w}, h: {h}"
|
assert node, "Failed to grow down! root: {root}, w: {w}, h: {h}"
|
||||||
return split_node(node, w, h)
|
return split_node(node, w, h)
|
||||||
|
|
||||||
assert len(objects) > 0
|
assert len(objects) > 0
|
||||||
sorted_objects = sorted([(i, width_fn(o), length_fn(o)) for (i, o) in enumerate(objects)],
|
sorted_objects = sorted(
|
||||||
key=lambda d: min(d[1], d[2]), reverse=True)
|
[(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)
|
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])
|
root = _Node(False, w=sorted_objects[0][1], h=sorted_objects[0][2])
|
||||||
translations = []
|
translations = []
|
||||||
|
|
@ -98,13 +118,15 @@ def _pack2d(objects: Collection[object],
|
||||||
translations.append((o[0], node.x, node.y))
|
translations.append((o[0], node.x, node.y))
|
||||||
return [(t[1], t[2]) for t in sorted(translations, key=lambda t: t[0])]
|
return [(t[1], t[2]) for t in sorted(translations, key=lambda t: t[0])]
|
||||||
|
|
||||||
|
|
||||||
def pack(objects: Collection[Shape], padding: float) -> Collection[Shape]:
|
def pack(objects: Collection[Shape], padding: float) -> Collection[Shape]:
|
||||||
"""Pack objects in a squarish area in Plane.XY."""
|
"""Pack objects in a squarish area in Plane.XY."""
|
||||||
bounding_boxes = {o: o.bounding_box().size + (padding, padding) for o in objects}
|
bounding_boxes = {o: o.bounding_box().size + (padding, padding) for o in objects}
|
||||||
translations = _pack2d(
|
translations = _pack2d(
|
||||||
objects,
|
objects,
|
||||||
width_fn=lambda o: bounding_boxes[cast(Shape, o)].X,
|
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 = [
|
translated = [
|
||||||
Location((t[0] - o.bounding_box().min.X, t[1] - o.bounding_box().min.Y, 0)) * o
|
Location((t[0] - o.bounding_box().min.X, t[1] - o.bounding_box().min.Y, 0)) * o
|
||||||
for (o, t) in zip(objects, translations)
|
for (o, t) in zip(objects, translations)
|
||||||
|
|
@ -118,8 +140,11 @@ def pack(objects: Collection[Shape], padding: float) -> Collection[Shape]:
|
||||||
max_x = min(bb1.max.X, bb2.max.X)
|
max_x = min(bb1.max.X, bb2.max.X)
|
||||||
max_y = min(bb1.max.Y, bb2.max.Y)
|
max_y = min(bb1.max.Y, bb2.max.Y)
|
||||||
return max_x > min_x and max_y > min_y
|
return max_x > min_x and max_y > min_y
|
||||||
|
|
||||||
bb = [t.bounding_box() for t in translated]
|
bb = [t.bounding_box() for t in translated]
|
||||||
for (i, bb_i) in enumerate(bb):
|
for i, bb_i in enumerate(bb):
|
||||||
for (j, bb_j) in enumerate(bb[i+1:]):
|
for j, bb_j in enumerate(bb[i + 1 :]):
|
||||||
assert not _overlapping(bb_i, bb_j), f"Objects at indexes {i} and {j} overlap!"
|
assert not _overlapping(
|
||||||
|
bb_i, bb_j
|
||||||
|
), f"Objects at indexes {i} and {j} overlap!"
|
||||||
return translated
|
return translated
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint has trouble with the OCP imports
|
# pylint has trouble with the OCP imports
|
||||||
# pylint: disable=no-name-in-module, import-error
|
# pylint: disable=no-name-in-module, import-error
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -563,9 +563,9 @@ class Mixin1D:
|
||||||
|
|
||||||
for line in all_lines:
|
for line in all_lines:
|
||||||
num_points = 2 if line.geom_type == GeomType.LINE else 8
|
num_points = 2 if line.geom_type == GeomType.LINE else 8
|
||||||
points.extend([
|
points.extend(
|
||||||
line.position_at(i / (num_points - 1)) for i in range(num_points)
|
[line.position_at(i / (num_points - 1)) for i in range(num_points)]
|
||||||
])
|
)
|
||||||
points = list(set(points)) # unique points
|
points = list(set(points)) # unique points
|
||||||
extreme_areas = {}
|
extreme_areas = {}
|
||||||
for subset in combinations(points, 3):
|
for subset in combinations(points, 3):
|
||||||
|
|
@ -2068,9 +2068,9 @@ class Shape(NodeMixin):
|
||||||
|
|
||||||
def vertices(self) -> ShapeList[Vertex]:
|
def vertices(self) -> ShapeList[Vertex]:
|
||||||
"""vertices - all the vertices in this Shape"""
|
"""vertices - all the vertices in this Shape"""
|
||||||
vertex_list = ShapeList([
|
vertex_list = ShapeList(
|
||||||
Vertex(downcast(i)) for i in self._entities(Vertex.__name__)
|
[Vertex(downcast(i)) for i in self._entities(Vertex.__name__)]
|
||||||
])
|
)
|
||||||
for vertex in vertex_list:
|
for vertex in vertex_list:
|
||||||
vertex.topo_parent = self
|
vertex.topo_parent = self
|
||||||
return vertex_list
|
return vertex_list
|
||||||
|
|
@ -2085,11 +2085,13 @@ class Shape(NodeMixin):
|
||||||
|
|
||||||
def edges(self) -> ShapeList[Edge]:
|
def edges(self) -> ShapeList[Edge]:
|
||||||
"""edges - all the edges in this Shape"""
|
"""edges - all the edges in this Shape"""
|
||||||
edge_list = ShapeList([
|
edge_list = ShapeList(
|
||||||
|
[
|
||||||
Edge(i)
|
Edge(i)
|
||||||
for i in self._entities(Edge.__name__)
|
for i in self._entities(Edge.__name__)
|
||||||
if not BRep_Tool.Degenerated_s(TopoDS.Edge_s(i))
|
if not BRep_Tool.Degenerated_s(TopoDS.Edge_s(i))
|
||||||
])
|
]
|
||||||
|
)
|
||||||
for edge in edge_list:
|
for edge in edge_list:
|
||||||
edge.topo_parent = self
|
edge.topo_parent = self
|
||||||
return edge_list
|
return edge_list
|
||||||
|
|
@ -2637,10 +2639,12 @@ class Shape(NodeMixin):
|
||||||
|
|
||||||
distance = axis.position.to_pnt().SquareDistance(inter_pt)
|
distance = axis.position.to_pnt().SquareDistance(inter_pt)
|
||||||
|
|
||||||
faces_dist.append((
|
faces_dist.append(
|
||||||
|
(
|
||||||
intersect_maker.Face(),
|
intersect_maker.Face(),
|
||||||
abs(distance),
|
abs(distance),
|
||||||
)) # will sort all intersected faces by distance whatever the direction is
|
)
|
||||||
|
) # will sort all intersected faces by distance whatever the direction is
|
||||||
|
|
||||||
intersect_maker.Next()
|
intersect_maker.Next()
|
||||||
|
|
||||||
|
|
@ -2950,11 +2954,13 @@ class Shape(NodeMixin):
|
||||||
inter_pt = intersect_maker.Pnt()
|
inter_pt = intersect_maker.Pnt()
|
||||||
# Calculate distance along axis
|
# Calculate distance along axis
|
||||||
distance = axis.to_plane().to_local_coords(Vector(inter_pt)).Z
|
distance = axis.to_plane().to_local_coords(Vector(inter_pt)).Z
|
||||||
intersections.append((
|
intersections.append(
|
||||||
|
(
|
||||||
Face(intersect_maker.Face()),
|
Face(intersect_maker.Face()),
|
||||||
Vector(inter_pt),
|
Vector(inter_pt),
|
||||||
distance,
|
distance,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
intersect_maker.Next()
|
intersect_maker.Next()
|
||||||
|
|
||||||
intersections.sort(key=lambda x: x[2])
|
intersections.sort(key=lambda x: x[2])
|
||||||
|
|
@ -3713,12 +3719,12 @@ class GroupBy(Generic[T, K]):
|
||||||
|
|
||||||
def _repr_pretty_(self, p, cycle=False):
|
def _repr_pretty_(self, p, cycle=False):
|
||||||
if cycle:
|
if cycle:
|
||||||
p.text('(...)')
|
p.text("(...)")
|
||||||
else:
|
else:
|
||||||
with p.group(1, '[', ']'):
|
with p.group(1, "[", "]"):
|
||||||
for idx, item in enumerate(self):
|
for idx, item in enumerate(self):
|
||||||
if idx:
|
if idx:
|
||||||
p.text(',')
|
p.text(",")
|
||||||
p.breakable()
|
p.breakable()
|
||||||
p.pretty(item)
|
p.pretty(item)
|
||||||
|
|
||||||
|
|
@ -3807,7 +3813,8 @@ class Compound(Mixin3D, Shape):
|
||||||
) * (7 - l_a)
|
) * (7 - l_a)
|
||||||
|
|
||||||
unknown_args = ", ".join(
|
unknown_args = ", ".join(
|
||||||
set(kwargs.keys()).difference([
|
set(kwargs.keys()).difference(
|
||||||
|
[
|
||||||
"shapes",
|
"shapes",
|
||||||
"obj",
|
"obj",
|
||||||
"label",
|
"label",
|
||||||
|
|
@ -3816,7 +3823,8 @@ class Compound(Mixin3D, Shape):
|
||||||
"joints",
|
"joints",
|
||||||
"parent",
|
"parent",
|
||||||
"children",
|
"children",
|
||||||
])
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if unknown_args:
|
if unknown_args:
|
||||||
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
||||||
|
|
@ -3939,9 +3947,9 @@ class Compound(Mixin3D, Shape):
|
||||||
"""Method call after detaching from `parent`."""
|
"""Method call after detaching from `parent`."""
|
||||||
logger.debug("Removing parent of %s (%s)", self.label, parent.label)
|
logger.debug("Removing parent of %s (%s)", self.label, parent.label)
|
||||||
if parent.children:
|
if parent.children:
|
||||||
parent.wrapped = Compound._make_compound([
|
parent.wrapped = Compound._make_compound(
|
||||||
c.wrapped for c in parent.children
|
[c.wrapped for c in parent.children]
|
||||||
])
|
)
|
||||||
else:
|
else:
|
||||||
parent.wrapped = None
|
parent.wrapped = None
|
||||||
|
|
||||||
|
|
@ -5162,14 +5170,16 @@ class Face(Shape):
|
||||||
)
|
)
|
||||||
|
|
||||||
unknown_args = ", ".join(
|
unknown_args = ", ".join(
|
||||||
set(kwargs.keys()).difference([
|
set(kwargs.keys()).difference(
|
||||||
|
[
|
||||||
"outer_wire",
|
"outer_wire",
|
||||||
"inner_wires",
|
"inner_wires",
|
||||||
"obj",
|
"obj",
|
||||||
"label",
|
"label",
|
||||||
"color",
|
"color",
|
||||||
"parent",
|
"parent",
|
||||||
])
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if unknown_args:
|
if unknown_args:
|
||||||
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
||||||
|
|
@ -5233,16 +5243,18 @@ class Face(Shape):
|
||||||
if len(flat_face_edges) == 4:
|
if len(flat_face_edges) == 4:
|
||||||
edge_pairs = []
|
edge_pairs = []
|
||||||
for vertex in flat_face_vertices:
|
for vertex in flat_face_vertices:
|
||||||
edge_pairs.append([
|
edge_pairs.append(
|
||||||
e for e in flat_face_edges if vertex in e.vertices()
|
[e for e in flat_face_edges if vertex in e.vertices()]
|
||||||
])
|
)
|
||||||
edge_pair_directions = [
|
edge_pair_directions = [
|
||||||
[edge.tangent_at(0) for edge in pair] for pair in edge_pairs
|
[edge.tangent_at(0) for edge in pair] for pair in edge_pairs
|
||||||
]
|
]
|
||||||
if all([
|
if all(
|
||||||
|
[
|
||||||
edge_directions[0].get_angle(edge_directions[1]) == 90
|
edge_directions[0].get_angle(edge_directions[1]) == 90
|
||||||
for edge_directions in edge_pair_directions
|
for edge_directions in edge_pair_directions
|
||||||
]):
|
]
|
||||||
|
):
|
||||||
result = "RECTANGLE"
|
result = "RECTANGLE"
|
||||||
if len(flat_face_edges.group_by(SortBy.LENGTH)) == 1:
|
if len(flat_face_edges.group_by(SortBy.LENGTH)) == 1:
|
||||||
result = "SQUARE"
|
result = "SQUARE"
|
||||||
|
|
@ -5721,9 +5733,9 @@ class Face(Shape):
|
||||||
)
|
)
|
||||||
if isinstance(exterior, Wire):
|
if isinstance(exterior, Wire):
|
||||||
outside_edges = exterior.edges()
|
outside_edges = exterior.edges()
|
||||||
elif isinstance(exterior, Iterable) and all([
|
elif isinstance(exterior, Iterable) and all(
|
||||||
isinstance(o, Edge) for o in exterior
|
[isinstance(o, Edge) for o in exterior]
|
||||||
]):
|
):
|
||||||
outside_edges = exterior
|
outside_edges = exterior
|
||||||
else:
|
else:
|
||||||
raise ValueError("exterior must be a Wire or list of Edges")
|
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)
|
faces, label, color, parent = args[:4] + (None,) * (4 - l_a)
|
||||||
|
|
||||||
unknown_args = ", ".join(
|
unknown_args = ", ".join(
|
||||||
set(kwargs.keys()).difference([
|
set(kwargs.keys()).difference(
|
||||||
|
[
|
||||||
"face",
|
"face",
|
||||||
"faces",
|
"faces",
|
||||||
"obj",
|
"obj",
|
||||||
"label",
|
"label",
|
||||||
"color",
|
"color",
|
||||||
"parent",
|
"parent",
|
||||||
])
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if unknown_args:
|
if unknown_args:
|
||||||
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
||||||
|
|
@ -6246,7 +6260,8 @@ class Solid(Mixin3D, Shape):
|
||||||
)
|
)
|
||||||
|
|
||||||
unknown_args = ", ".join(
|
unknown_args = ", ".join(
|
||||||
set(kwargs.keys()).difference([
|
set(kwargs.keys()).difference(
|
||||||
|
[
|
||||||
"shell",
|
"shell",
|
||||||
"obj",
|
"obj",
|
||||||
"label",
|
"label",
|
||||||
|
|
@ -6254,7 +6269,8 @@ class Solid(Mixin3D, Shape):
|
||||||
"material",
|
"material",
|
||||||
"joints",
|
"joints",
|
||||||
"parent",
|
"parent",
|
||||||
])
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if unknown_args:
|
if unknown_args:
|
||||||
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
||||||
|
|
@ -6673,9 +6689,9 @@ class Solid(Mixin3D, Shape):
|
||||||
|
|
||||||
# make an auxiliary spine
|
# make an auxiliary spine
|
||||||
pitch = 360.0 / angle * normal.length
|
pitch = 360.0 / angle * normal.length
|
||||||
aux_spine_w = Wire([
|
aux_spine_w = Wire(
|
||||||
Edge.make_helix(pitch, normal.length, 1, center=center, normal=normal)
|
[Edge.make_helix(pitch, normal.length, 1, center=center, normal=normal)]
|
||||||
]).wrapped
|
).wrapped
|
||||||
|
|
||||||
# extrude the outer wire
|
# extrude the outer wire
|
||||||
outer_solid = extrude_aux_spine(
|
outer_solid = extrude_aux_spine(
|
||||||
|
|
@ -7270,7 +7286,8 @@ class Wire(Mixin1D, Shape):
|
||||||
edges, sequenced, label, color, parent = args[:5] + (None,) * (5 - l_a)
|
edges, sequenced, label, color, parent = args[:5] + (None,) * (5 - l_a)
|
||||||
|
|
||||||
unknown_args = ", ".join(
|
unknown_args = ", ".join(
|
||||||
set(kwargs.keys()).difference([
|
set(kwargs.keys()).difference(
|
||||||
|
[
|
||||||
"curve",
|
"curve",
|
||||||
"wire",
|
"wire",
|
||||||
"edge",
|
"edge",
|
||||||
|
|
@ -7280,7 +7297,8 @@ class Wire(Mixin1D, Shape):
|
||||||
"label",
|
"label",
|
||||||
"color",
|
"color",
|
||||||
"parent",
|
"parent",
|
||||||
])
|
]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
if unknown_args:
|
if unknown_args:
|
||||||
raise ValueError(f"Unexpected argument(s) {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
|
# Select the wire containing the start and end points
|
||||||
wire_segments = edges_to_wires(modified_edges + unmodified_edges)
|
wire_segments = edges_to_wires(modified_edges + unmodified_edges)
|
||||||
trimmed_wire = filter(
|
trimmed_wire = filter(
|
||||||
lambda w: all([
|
lambda w: all(
|
||||||
|
[
|
||||||
w.distance_to(p) <= TOLERANCE
|
w.distance_to(p) <= TOLERANCE
|
||||||
for p in [trim_start_point, trim_end_point]
|
for p in [trim_start_point, trim_end_point]
|
||||||
]),
|
]
|
||||||
|
),
|
||||||
wire_segments,
|
wire_segments,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|
@ -7833,10 +7853,12 @@ class Wire(Mixin1D, Shape):
|
||||||
trim_points[edge1] = [simplice[1]]
|
trim_points[edge1] = [simplice[1]]
|
||||||
else:
|
else:
|
||||||
trim_points[edge1].append(simplice[1])
|
trim_points[edge1].append(simplice[1])
|
||||||
connecting_edge_data.append((
|
connecting_edge_data.append(
|
||||||
|
(
|
||||||
(edge0, points_lookup[simplice[0]][1], simplice[0]),
|
(edge0, points_lookup[simplice[0]][1], simplice[0]),
|
||||||
(edge1, points_lookup[simplice[1]][1], simplice[1]),
|
(edge1, points_lookup[simplice[1]][1], simplice[1]),
|
||||||
))
|
)
|
||||||
|
)
|
||||||
# Look for connecting edges within an edge
|
# Look for connecting edges within an edge
|
||||||
elif abs(simplice[0] - simplice[1]) != 1:
|
elif abs(simplice[0] - simplice[1]) != 1:
|
||||||
start_pnt = min(simplice.tolist())
|
start_pnt = min(simplice.tolist())
|
||||||
|
|
@ -7845,10 +7867,12 @@ class Wire(Mixin1D, Shape):
|
||||||
trim_points[edge0] = [start_pnt, end_pnt]
|
trim_points[edge0] = [start_pnt, end_pnt]
|
||||||
else:
|
else:
|
||||||
trim_points[edge0].extend([start_pnt, end_pnt])
|
trim_points[edge0].extend([start_pnt, end_pnt])
|
||||||
connecting_edge_data.append((
|
connecting_edge_data.append(
|
||||||
|
(
|
||||||
(edge0, points_lookup[start_pnt][1], start_pnt),
|
(edge0, points_lookup[start_pnt][1], start_pnt),
|
||||||
(edge0, points_lookup[end_pnt][1], end_pnt),
|
(edge0, points_lookup[end_pnt][1], end_pnt),
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
trim_data = {}
|
trim_data = {}
|
||||||
for edge, points in trim_points.items():
|
for edge, points in trim_points.items():
|
||||||
|
|
@ -7956,15 +7980,19 @@ class Wire(Mixin1D, Shape):
|
||||||
output_wire_center - planar_wire_center
|
output_wire_center - planar_wire_center
|
||||||
).normalized()
|
).normalized()
|
||||||
if output_wire_direction.dot(direction_vector) >= 0:
|
if output_wire_direction.dot(direction_vector) >= 0:
|
||||||
output_wires_distances.append((
|
output_wires_distances.append(
|
||||||
|
(
|
||||||
output_wire,
|
output_wire,
|
||||||
(output_wire_center - planar_wire_center).length,
|
(output_wire_center - planar_wire_center).length,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
output_wires_distances.append((
|
output_wires_distances.append(
|
||||||
|
(
|
||||||
output_wire,
|
output_wire,
|
||||||
(output_wire_center - center_point).length,
|
(output_wire_center - center_point).length,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
output_wires_distances.sort(key=lambda x: x[1])
|
output_wires_distances.sort(key=lambda x: x[1])
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Export a version string.
|
Export a version string.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
from ._dev.scm_version import version # pylint: disable=unused-import
|
from ._dev.scm_version import version # pylint: disable=unused-import
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from math import pi
|
from math import pi
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from math import pi, sqrt
|
from math import pi, sqrt
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from math import sqrt, pi
|
from math import sqrt, pi
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from math import pi, sin
|
from math import pi, sin
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
@ -470,9 +471,7 @@ class TestThicken(unittest.TestCase):
|
||||||
|
|
||||||
non_planar = Sphere(1).faces()[0]
|
non_planar = Sphere(1).faces()[0]
|
||||||
outer_sphere = thicken(non_planar, amount=0.1)
|
outer_sphere = thicken(non_planar, amount=0.1)
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(outer_sphere.volume, (4 / 3) * pi * (1.1**3 - 1**3), 5)
|
||||||
outer_sphere.volume, (4 / 3) * pi * (1.1**3 - 1**3), 5
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestTorus(unittest.TestCase):
|
class TestTorus(unittest.TestCase):
|
||||||
|
|
|
||||||
|
|
@ -3008,7 +3008,9 @@ class TestShapeList(DirectApiTestCase):
|
||||||
" [<build123d.topology.Edge object at 0x000001277FC86F90>,"
|
" [<build123d.topology.Edge object at 0x000001277FC86F90>,"
|
||||||
" <build123d.topology.Edge object at 0x000001277F6E1CD0>]]"
|
" <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()
|
f = io.StringIO()
|
||||||
p = pretty.PrettyPrinter(f)
|
p = pretty.PrettyPrinter(f)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
@ -101,7 +102,6 @@ def create_test_sketch() -> tuple[Sketch, Sketch, Sketch]:
|
||||||
|
|
||||||
|
|
||||||
class TestClassInstantiation(unittest.TestCase):
|
class TestClassInstantiation(unittest.TestCase):
|
||||||
|
|
||||||
"""Test Draft class instantiation"""
|
"""Test Draft class instantiation"""
|
||||||
|
|
||||||
def test_draft_instantiation(self):
|
def test_draft_instantiation(self):
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ license:
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ date: November 9th 2023
|
||||||
|
|
||||||
desc: Unit tests for the build123d pack module
|
desc: Unit tests for the build123d pack module
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import operator
|
import operator
|
||||||
import random
|
import random
|
||||||
import unittest
|
import unittest
|
||||||
|
|
@ -14,8 +15,10 @@ from functools import reduce
|
||||||
|
|
||||||
from build123d import *
|
from build123d import *
|
||||||
|
|
||||||
|
|
||||||
class TestPack(unittest.TestCase):
|
class TestPack(unittest.TestCase):
|
||||||
"""Tests for the pack helper."""
|
"""Tests for the pack helper."""
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
"""Test pack with hand-picked data against expected output."""
|
"""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)
|
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 <= 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: 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]",
|
" 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):
|
def test_random_boxes(self):
|
||||||
"""Test pack with larger (and randomized) inputs."""
|
"""Test pack with larger (and randomized) inputs."""
|
||||||
random.seed(123456)
|
random.seed(123456)
|
||||||
# 50 is an arbitrary number that is large enough to exercise
|
# 50 is an arbitrary number that is large enough to exercise
|
||||||
# different aspects of the packer while still completing quickly.
|
# different aspects of the packer while still completing quickly.
|
||||||
test_boxes = [Box(random.randint(1, 20), random.randint(1, 20), 1)
|
test_boxes = [
|
||||||
for _ in range(50)]
|
Box(random.randint(1, 20), random.randint(1, 20), 1) for _ in range(50)
|
||||||
|
]
|
||||||
# Not raising in this call shows successfull non-overlap.
|
# Not raising in this call shows successfull non-overlap.
|
||||||
packed = pack(test_boxes, 1)
|
packed = pack(test_boxes, 1)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"bbox: 0.0 <= x <= 94.0, 0.0 <= y <= 86.0, -0.5 <= z <= 0.5",
|
"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):
|
def test_random_slots(self):
|
||||||
"""Test pack for 2D objects."""
|
"""Test pack for 2D objects."""
|
||||||
random.seed(123456)
|
random.seed(123456)
|
||||||
# 50 is an arbitrary number that is large enough to exercise
|
# 50 is an arbitrary number that is large enough to exercise
|
||||||
# different aspects of the packer while still completing quickly.
|
# 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.
|
# Not raising in this call shows successfull non-overlap.
|
||||||
packed = pack(inputs, 1)
|
packed = pack(inputs, 1)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"bbox: 0.0 <= x <= 124.0, 0.0 <= y <= 105.0, 0.0 <= z <= 0.0",
|
"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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue