mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -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
|
||||
"""
|
||||
|
||||
from math import sin, cos, tan, radians
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-01 Bearing Bracket
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-02 Post Cap
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-03 C Clamp Base
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-04 Angle Bracket
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-05 Paste Sleeve
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-06 Bearing Jig
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-07 Flanged Hub
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-08 Tie Plate
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-09 Corner Tie
|
||||
"""
|
||||
|
||||
from math import sqrt
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Too Tall Toby Party Pack 01-10 Light Cap
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
from ocp_vscode import *
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ license:
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ license:
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from build123d import *
|
||||
|
||||
exporter = ExportSVG(scale=1)
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
"""scm version"""
|
||||
|
||||
import os.path as pth
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
# pylint has trouble with the OCP imports
|
||||
# pylint: disable=no-name-in-module, import-error
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from math import inf
|
||||
|
|
|
|||
|
|
@ -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({
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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=[
|
||||
tangents=(
|
||||
[
|
||||
t * s if isinstance(t, Vector) else Vector(*t) * s
|
||||
for t, s in zip(spline_tangents, scalars)
|
||||
]
|
||||
if spline_tangents
|
||||
else None,
|
||||
else None
|
||||
),
|
||||
periodic=periodic,
|
||||
scale=tangent_scalars is None,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from math import radians, tan
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import trianglesolver
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
import copy
|
||||
import logging
|
||||
from math import radians, tan, isclose
|
||||
|
|
|
|||
|
|
@ -16,9 +16,12 @@ from typing import Callable, Collection, Optional, cast
|
|||
|
||||
from build123d import Location, Shape
|
||||
|
||||
def _pack2d(objects: Collection[object],
|
||||
|
||||
def _pack2d(
|
||||
objects: Collection[object],
|
||||
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
|
||||
arrangement, and return a list of (x,y) locations to place each to
|
||||
achieve the packing.
|
||||
|
|
@ -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)
|
||||
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,13 +118,15 @@ 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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
# pylint has trouble with the OCP imports
|
||||
# pylint: disable=no-name-in-module, import-error
|
||||
|
||||
|
|
|
|||
|
|
@ -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_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((
|
||||
faces_dist.append(
|
||||
(
|
||||
intersect_maker.Face(),
|
||||
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()
|
||||
|
||||
|
|
@ -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((
|
||||
intersections.append(
|
||||
(
|
||||
Face(intersect_maker.Face()),
|
||||
Vector(inter_pt),
|
||||
distance,
|
||||
))
|
||||
)
|
||||
)
|
||||
intersect_maker.Next()
|
||||
|
||||
intersections.sort(key=lambda x: x[2])
|
||||
|
|
@ -3713,12 +3719,12 @@ class GroupBy(Generic[T, K]):
|
|||
|
||||
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,7 +3813,8 @@ class Compound(Mixin3D, Shape):
|
|||
) * (7 - l_a)
|
||||
|
||||
unknown_args = ", ".join(
|
||||
set(kwargs.keys()).difference([
|
||||
set(kwargs.keys()).difference(
|
||||
[
|
||||
"shapes",
|
||||
"obj",
|
||||
"label",
|
||||
|
|
@ -3816,7 +3823,8 @@ class Compound(Mixin3D, Shape):
|
|||
"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([
|
||||
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([
|
||||
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([
|
||||
set(kwargs.keys()).difference(
|
||||
[
|
||||
"face",
|
||||
"faces",
|
||||
"obj",
|
||||
"label",
|
||||
"color",
|
||||
"parent",
|
||||
])
|
||||
]
|
||||
)
|
||||
)
|
||||
if unknown_args:
|
||||
raise ValueError(f"Unexpected argument(s) {unknown_args}")
|
||||
|
|
@ -6246,7 +6260,8 @@ class Solid(Mixin3D, Shape):
|
|||
)
|
||||
|
||||
unknown_args = ", ".join(
|
||||
set(kwargs.keys()).difference([
|
||||
set(kwargs.keys()).difference(
|
||||
[
|
||||
"shell",
|
||||
"obj",
|
||||
"label",
|
||||
|
|
@ -6254,7 +6269,8 @@ class Solid(Mixin3D, Shape):
|
|||
"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,7 +7286,8 @@ class Wire(Mixin1D, Shape):
|
|||
edges, sequenced, label, color, parent = args[:5] + (None,) * (5 - l_a)
|
||||
|
||||
unknown_args = ", ".join(
|
||||
set(kwargs.keys()).difference([
|
||||
set(kwargs.keys()).difference(
|
||||
[
|
||||
"curve",
|
||||
"wire",
|
||||
"edge",
|
||||
|
|
@ -7280,7 +7297,8 @@ class Wire(Mixin1D, Shape):
|
|||
"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([
|
||||
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((
|
||||
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((
|
||||
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_wires_distances.append(
|
||||
(
|
||||
output_wire,
|
||||
(output_wire_center - planar_wire_center).length,
|
||||
))
|
||||
)
|
||||
)
|
||||
else:
|
||||
output_wires_distances.append((
|
||||
output_wires_distances.append(
|
||||
(
|
||||
output_wire,
|
||||
(output_wire_center - center_point).length,
|
||||
))
|
||||
)
|
||||
)
|
||||
|
||||
output_wires_distances.sort(key=lambda x: x[1])
|
||||
logger.debug(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Export a version string.
|
||||
"""
|
||||
|
||||
try:
|
||||
try:
|
||||
from ._dev.scm_version import version # pylint: disable=unused-import
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from math import pi
|
||||
from build123d import *
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from build123d import *
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from math import pi, sqrt
|
||||
from build123d import *
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from math import sqrt, pi
|
||||
from build123d import *
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ license:
|
|||
limitations under the License.
|
||||
|
||||
"""
|
||||
|
||||
import copy
|
||||
import unittest
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue