mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-07 03:01:18 -08:00
bug fixes and Enum improvements
This commit is contained in:
parent
291f897111
commit
cbdadb44d6
4 changed files with 118 additions and 75 deletions
|
|
@ -130,10 +130,12 @@ def _by_area_shape(self) -> float:
|
||||||
|
|
||||||
Shape.by_area = _by_area_shape
|
Shape.by_area = _by_area_shape
|
||||||
|
|
||||||
|
|
||||||
class Select(Enum):
|
class Select(Enum):
|
||||||
ALL = auto()
|
ALL = auto()
|
||||||
LAST = auto()
|
LAST = auto()
|
||||||
|
|
||||||
|
|
||||||
class SortBy(Enum):
|
class SortBy(Enum):
|
||||||
NONE = auto()
|
NONE = auto()
|
||||||
X = auto()
|
X = auto()
|
||||||
|
|
@ -146,6 +148,12 @@ class SortBy(Enum):
|
||||||
DISTANCE = auto()
|
DISTANCE = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class Kind(Enum):
|
||||||
|
ARC = auto()
|
||||||
|
INTERSECTION = auto()
|
||||||
|
TANGENT = auto()
|
||||||
|
|
||||||
|
|
||||||
class FilterBy(Enum):
|
class FilterBy(Enum):
|
||||||
LAST_OPERATION = auto()
|
LAST_OPERATION = auto()
|
||||||
|
|
||||||
|
|
@ -173,13 +181,6 @@ class Font_Style(Enum):
|
||||||
BOLD = auto()
|
BOLD = auto()
|
||||||
ITALIC = auto()
|
ITALIC = auto()
|
||||||
|
|
||||||
def legacy(font_style: "Font_Style") -> str:
|
|
||||||
return {
|
|
||||||
Font_Style.REGULAR: "regular",
|
|
||||||
Font_Style.BOLD: "bold",
|
|
||||||
Font_Style.ITALIC: "italic",
|
|
||||||
}[font_style]
|
|
||||||
|
|
||||||
|
|
||||||
class Halign(Enum):
|
class Halign(Enum):
|
||||||
"""Horizontal Alignment"""
|
"""Horizontal Alignment"""
|
||||||
|
|
@ -188,14 +189,6 @@ class Halign(Enum):
|
||||||
LEFT = auto()
|
LEFT = auto()
|
||||||
RIGHT = auto()
|
RIGHT = auto()
|
||||||
|
|
||||||
def legacy(halign: "Halign") -> str:
|
|
||||||
return {
|
|
||||||
Halign.LEFT: "left",
|
|
||||||
Halign.RIGHT: "right",
|
|
||||||
Halign.CENTER: "center",
|
|
||||||
}[halign]
|
|
||||||
|
|
||||||
|
|
||||||
class Valign(Enum):
|
class Valign(Enum):
|
||||||
"""Vertical Alignment"""
|
"""Vertical Alignment"""
|
||||||
|
|
||||||
|
|
@ -203,14 +196,6 @@ class Valign(Enum):
|
||||||
TOP = auto()
|
TOP = auto()
|
||||||
BOTTOM = auto()
|
BOTTOM = auto()
|
||||||
|
|
||||||
def legacy(valign: "Valign") -> str:
|
|
||||||
return {
|
|
||||||
Valign.TOP: "top",
|
|
||||||
Valign.BOTTOM: "bottom",
|
|
||||||
Valign.CENTER: "center",
|
|
||||||
}[valign]
|
|
||||||
|
|
||||||
|
|
||||||
class Until(Enum):
|
class Until(Enum):
|
||||||
NEXT = auto()
|
NEXT = auto()
|
||||||
LAST = auto()
|
LAST = auto()
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,9 @@ class BuildLine:
|
||||||
edge.forConstruction = mode == Mode.CONSTRUCTION
|
edge.forConstruction = mode == Mode.CONSTRUCTION
|
||||||
context_stack[-1].line.append(edge)
|
context_stack[-1].line.append(edge)
|
||||||
context_stack[-1].last_edges = edges
|
context_stack[-1].last_edges = edges
|
||||||
context_stack[-1].last_vertices = list(set(e.Vertices() for e in edges))
|
context_stack[-1].last_vertices = list(
|
||||||
|
set(v for e in edges for v in e.Vertices())
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_context() -> "BuildLine":
|
def get_context() -> "BuildLine":
|
||||||
|
|
@ -189,7 +191,7 @@ class CenterArc(Edge):
|
||||||
orientation=arc_size > 0,
|
orientation=arc_size > 0,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
p0 = center
|
p0 = Vector(center)
|
||||||
p1 = p0 + radius * Vector(
|
p1 = p0 + radius * Vector(
|
||||||
cos(radians(start_angle)), sin(radians(start_angle))
|
cos(radians(start_angle)), sin(radians(start_angle))
|
||||||
)
|
)
|
||||||
|
|
|
||||||
103
build_sketch.py
103
build_sketch.py
|
|
@ -4,6 +4,8 @@ TODO:
|
||||||
- make distribute a method of edge and wire
|
- make distribute a method of edge and wire
|
||||||
- ensure offset is a method of edge and wire
|
- ensure offset is a method of edge and wire
|
||||||
- if bb planar make face else make solid
|
- if bb planar make face else make solid
|
||||||
|
- bug: offset2D doesn't work on a Wire made from a single Edge
|
||||||
|
- bug: can't substract from empty sketch
|
||||||
"""
|
"""
|
||||||
from math import pi, sin, cos, tan, radians, sqrt
|
from math import pi, sin, cos, tan, radians, sqrt
|
||||||
from typing import Union, Iterable, Sequence, Callable, cast
|
from typing import Union, Iterable, Sequence, Callable, cast
|
||||||
|
|
@ -27,6 +29,7 @@ from cadquery.occ_impl.shapes import VectorLike, Real
|
||||||
import cq_warehouse.extensions
|
import cq_warehouse.extensions
|
||||||
from build123d_common import *
|
from build123d_common import *
|
||||||
from build_part import BuildPart
|
from build_part import BuildPart
|
||||||
|
import build_line as bl
|
||||||
|
|
||||||
|
|
||||||
class BuildSketch:
|
class BuildSketch:
|
||||||
|
|
@ -83,9 +86,9 @@ class BuildSketch:
|
||||||
new_faces = [obj for obj in objects if isinstance(obj, Face)]
|
new_faces = [obj for obj in objects if isinstance(obj, Face)]
|
||||||
new_edges = [obj for obj in objects if isinstance(obj, Edge)]
|
new_edges = [obj for obj in objects if isinstance(obj, Edge)]
|
||||||
|
|
||||||
pre_vertices = list(set(context_stack[-1].sketch.Vertices()))
|
pre_vertices = set(context_stack[-1].sketch.Vertices())
|
||||||
pre_edges = list(set(context_stack[-1].sketch.Edges()))
|
pre_edges = set(context_stack[-1].sketch.Edges())
|
||||||
pre_faces = list(set(context_stack[-1].sketch.Faces()))
|
pre_faces = set(context_stack[-1].sketch.Faces())
|
||||||
if mode == Mode.ADDITION:
|
if mode == Mode.ADDITION:
|
||||||
context_stack[-1].sketch = (
|
context_stack[-1].sketch = (
|
||||||
context_stack[-1].sketch.fuse(*new_faces).clean()
|
context_stack[-1].sketch.fuse(*new_faces).clean()
|
||||||
|
|
@ -103,18 +106,12 @@ class BuildSketch:
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Invalid mode: {mode}")
|
raise ValueError(f"Invalid mode: {mode}")
|
||||||
|
|
||||||
post_vertices = list(set(context_stack[-1].sketch.Vertices()))
|
post_vertices = set(context_stack[-1].sketch.Vertices())
|
||||||
post_edges = list(set(context_stack[-1].sketch.Edges()))
|
post_edges = set(context_stack[-1].sketch.Edges())
|
||||||
post_faces = list(set(context_stack[-1].sketch.Faces()))
|
post_faces = set(context_stack[-1].sketch.Faces())
|
||||||
context_stack[-1].last_vertices = [
|
context_stack[-1].last_vertices = list(post_vertices - pre_vertices)
|
||||||
v for v in post_vertices if v not in pre_vertices
|
context_stack[-1].last_edges = list(post_edges - pre_edges)
|
||||||
]
|
context_stack[-1].last_faces = list(post_faces - pre_faces)
|
||||||
context_stack[-1].last_edges = [
|
|
||||||
e for e in post_edges if e not in pre_edges
|
|
||||||
]
|
|
||||||
context_stack[-1].last_faces = [
|
|
||||||
f for f in post_faces if f not in pre_faces
|
|
||||||
]
|
|
||||||
context_stack[-1].pending_edges.extend(new_edges)
|
context_stack[-1].pending_edges.extend(new_edges)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -284,16 +281,34 @@ class ChamferSketch(Compound):
|
||||||
|
|
||||||
class Offset(Compound):
|
class Offset(Compound):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, face: Union[Face, Compound], amount: float, mode: Mode = Mode.ADDITION
|
self,
|
||||||
|
*objects: Union[Face, Compound],
|
||||||
|
amount: float,
|
||||||
|
kind: Kind = Kind.ARC,
|
||||||
|
mode: Mode = Mode.ADDITION,
|
||||||
):
|
):
|
||||||
perimeter = face.outerWire()
|
faces = []
|
||||||
face = Face.makeFromWires(perimeter.offset2D(perimeter))
|
for obj in objects:
|
||||||
BuildSketch.add_to_context(face, mode=mode)
|
if isinstance(obj, Compound):
|
||||||
BuildSketch.get_context().locations = [Location(Vector())]
|
faces.extend(obj.Faces())
|
||||||
super().__init__(Compound.makeCompound(face.wrapped))
|
elif isinstance(obj, Face):
|
||||||
|
faces.append(obj)
|
||||||
|
else:
|
||||||
|
raise ValueError("Only Faces or Compounds are valid input types")
|
||||||
|
|
||||||
|
new_faces = []
|
||||||
|
for face in faces:
|
||||||
|
new_faces.append(
|
||||||
|
Face.makeFromWires(
|
||||||
|
face.outerWire().offset2D(amount, kind=kind.name.lower())[0]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
BuildSketch.add_to_context(face, mode=mode)
|
||||||
|
|
||||||
|
super().__init__(Compound.makeCompound(new_faces).wrapped)
|
||||||
|
|
||||||
|
|
||||||
class Rect(Compound):
|
class Rectangle(Compound):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
width: float,
|
width: float,
|
||||||
|
|
@ -408,12 +423,10 @@ class SlotCenterToCenter(Compound):
|
||||||
face = Face.makeFromWires(
|
face = Face.makeFromWires(
|
||||||
Wire.assembleEdges(
|
Wire.assembleEdges(
|
||||||
[
|
[
|
||||||
Edge.makeLine(
|
Edge.makeLine(Vector(-center_separation / 2, 0, 0), Vector()),
|
||||||
Vector(-center_separation / 2, 0, 0),
|
Edge.makeLine(Vector(), Vector(+center_separation / 2, 0, 0)),
|
||||||
Vector(+center_separation / 2, 0, 0),
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
).offset2D(height / 2)
|
).offset2D(height / 2)[0]
|
||||||
).rotate(*z_axis, angle)
|
).rotate(*z_axis, angle)
|
||||||
new_faces = [
|
new_faces = [
|
||||||
face.moved(location) for location in BuildSketch.get_context().locations
|
face.moved(location) for location in BuildSketch.get_context().locations
|
||||||
|
|
@ -435,12 +448,10 @@ class SlotOverall(Compound):
|
||||||
face = Face.makeFromWires(
|
face = Face.makeFromWires(
|
||||||
Wire.assembleEdges(
|
Wire.assembleEdges(
|
||||||
[
|
[
|
||||||
Edge.makeLine(
|
Edge.makeLine(Vector(-width / 2 + height / 2, 0, 0), Vector()),
|
||||||
Vector(-width / 2 + height / 2, 0, 0),
|
Edge.makeLine(Vector(), Vector(+width / 2 - height / 2, 0, 0)),
|
||||||
Vector(+width / 2 - height / 2, 0, 0),
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
).offset2D(height / 2)
|
).offset2D(height / 2)[0]
|
||||||
).rotate(*z_axis, angle)
|
).rotate(*z_axis, angle)
|
||||||
new_faces = [
|
new_faces = [
|
||||||
face.moved(location) for location in BuildSketch.get_context().locations
|
face.moved(location) for location in BuildSketch.get_context().locations
|
||||||
|
|
@ -449,6 +460,7 @@ class SlotOverall(Compound):
|
||||||
BuildSketch.add_to_context(face, mode=mode)
|
BuildSketch.add_to_context(face, mode=mode)
|
||||||
BuildSketch.get_context().locations = [Location(Vector())]
|
BuildSketch.get_context().locations = [Location(Vector())]
|
||||||
super().__init__(Compound.makeCompound(new_faces).wrapped)
|
super().__init__(Compound.makeCompound(new_faces).wrapped)
|
||||||
|
# super().__init__(w.wrapped)
|
||||||
|
|
||||||
|
|
||||||
class SlotCenterPoint(Compound):
|
class SlotCenterPoint(Compound):
|
||||||
|
|
@ -460,15 +472,16 @@ class SlotCenterPoint(Compound):
|
||||||
angle: float = 0,
|
angle: float = 0,
|
||||||
mode: Mode = Mode.ADDITION,
|
mode: Mode = Mode.ADDITION,
|
||||||
):
|
):
|
||||||
|
center_v = Vector(center)
|
||||||
|
point_v = Vector(point)
|
||||||
|
half_line = point_v - center_v
|
||||||
face = Face.makeFromWires(
|
face = Face.makeFromWires(
|
||||||
Wire.assembleEdges(
|
Wire.combine(
|
||||||
[
|
[
|
||||||
Edge.makeLine(
|
Edge.makeLine(point_v, center_v),
|
||||||
Vector(center) - (Vector(point) - Vector(center)),
|
Edge.makeLine(center_v, center_v - half_line),
|
||||||
Vector(point),
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
).offset2D(height / 2)
|
)[0].offset2D(height / 2)[0]
|
||||||
).rotate(*z_axis, angle)
|
).rotate(*z_axis, angle)
|
||||||
new_faces = [
|
new_faces = [
|
||||||
face.moved(location) for location in BuildSketch.get_context().locations
|
face.moved(location) for location in BuildSketch.get_context().locations
|
||||||
|
|
@ -487,8 +500,10 @@ class SlotArc(Compound):
|
||||||
angle: float = 0,
|
angle: float = 0,
|
||||||
mode: Mode = Mode.ADDITION,
|
mode: Mode = Mode.ADDITION,
|
||||||
):
|
):
|
||||||
arc_wire = arc if isinstance(arc, Wire) else Wire.assembleEdges([arc])
|
if isinstance(arc, Edge):
|
||||||
face = Face.makeFromWires(arc_wire.offset2D(height / 2)).rotate(*z_axis, angle)
|
raise ("Bug - Edges aren't supported by offset")
|
||||||
|
# arc_wire = arc if isinstance(arc, Wire) else Wire.assembleEdges([arc])
|
||||||
|
face = Face.makeFromWires(arc.offset2D(height / 2)[0]).rotate(*z_axis, angle)
|
||||||
new_faces = [
|
new_faces = [
|
||||||
face.moved(location) for location in BuildSketch.get_context().locations
|
face.moved(location) for location in BuildSketch.get_context().locations
|
||||||
]
|
]
|
||||||
|
|
@ -499,7 +514,7 @@ class SlotArc(Compound):
|
||||||
|
|
||||||
|
|
||||||
class RegularPolygon(Compound):
|
class RegularPolygon(Compound):
|
||||||
def regularPolygon(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
radius: Real,
|
radius: Real,
|
||||||
side_count: int,
|
side_count: int,
|
||||||
|
|
@ -563,9 +578,9 @@ class Text(Compound):
|
||||||
fontsize,
|
fontsize,
|
||||||
font,
|
font,
|
||||||
font_path,
|
font_path,
|
||||||
Font_Style.legacy(font_style),
|
font_style.name.lower(),
|
||||||
Halign.legacy(halign),
|
halign.name.lower(),
|
||||||
Valign.legacy(valign),
|
valign.name.lower(),
|
||||||
position_on_path,
|
position_on_path,
|
||||||
path,
|
path,
|
||||||
).rotate(Vector(), Vector(0, 0, 1), angle)
|
).rotate(Vector(), Vector(0, 0, 1), angle)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
from telnetlib import EL
|
||||||
|
from tkinter import RIGHT
|
||||||
from cadquery import Vector
|
from cadquery import Vector
|
||||||
from build123d_common import *
|
from build123d_common import *
|
||||||
from build_line import *
|
from build_line import *
|
||||||
|
|
@ -5,7 +7,7 @@ from build_sketch import *
|
||||||
|
|
||||||
with BuildSketch() as flag:
|
with BuildSketch() as flag:
|
||||||
PushPoints((-0.75, 0.5), (0.75, 0.5))
|
PushPoints((-0.75, 0.5), (0.75, 0.5))
|
||||||
Rect(0.5, 1)
|
Rectangle(0.5, 1)
|
||||||
with BuildLine() as leaf:
|
with BuildLine() as leaf:
|
||||||
l1 = Polyline((0.0000, 0.0771), (0.0187, 0.0771), (0.0094, 0.2569))
|
l1 = Polyline((0.0000, 0.0771), (0.0187, 0.0771), (0.0094, 0.2569))
|
||||||
l2 = Polyline((0.0325, 0.2773), (0.2115, 0.2458), (0.1873, 0.3125))
|
l2 = Polyline((0.0325, 0.2773), (0.2115, 0.2458), (0.1873, 0.3125))
|
||||||
|
|
@ -25,11 +27,11 @@ with BuildSketch() as flag:
|
||||||
|
|
||||||
with BuildSketch() as din:
|
with BuildSketch() as din:
|
||||||
PushPoints((0, 0.5))
|
PushPoints((0, 0.5))
|
||||||
Rect(35, 1)
|
Rectangle(35, 1)
|
||||||
PushPoints((0, 7.5 / 2))
|
PushPoints((0, 7.5 / 2))
|
||||||
Rect(27, 7.5)
|
Rectangle(27, 7.5)
|
||||||
PushPoints((0, 6.5 / 2))
|
PushPoints((0, 6.5 / 2))
|
||||||
Rect(25, 6.5, mode=Mode.SUBTRACTION)
|
Rectangle(25, 6.5, mode=Mode.SUBTRACTION)
|
||||||
inside_vertices = list(
|
inside_vertices = list(
|
||||||
filter(
|
filter(
|
||||||
lambda v: 7.5 > v.Y > 0 and -17.5 < v.X < 17.5,
|
lambda v: 7.5 > v.Y > 0 and -17.5 < v.X < 17.5,
|
||||||
|
|
@ -37,6 +39,8 @@ with BuildSketch() as din:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
FilletSketch(*inside_vertices, radius=0.8)
|
FilletSketch(*inside_vertices, radius=0.8)
|
||||||
|
# debug(din.edges(Select.LAST), name="after 1st fillet")
|
||||||
|
print(f"{len(din.vertices(Select.LAST))=},{len(din.edges(Select.LAST))=}")
|
||||||
outside_vertices = list(
|
outside_vertices = list(
|
||||||
filter(
|
filter(
|
||||||
lambda v: (v.Y == 0.0 or v.Y == 7.5) and -17.5 < v.X < 17.5,
|
lambda v: (v.Y == 0.0 or v.Y == 7.5) and -17.5 < v.X < 17.5,
|
||||||
|
|
@ -44,7 +48,44 @@ with BuildSketch() as din:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
FilletSketch(*outside_vertices, radius=1.8)
|
FilletSketch(*outside_vertices, radius=1.8)
|
||||||
|
# debug(din.edges(Select.LAST), name="after 2nd fillet")
|
||||||
|
|
||||||
|
with BuildSketch() as shapes:
|
||||||
|
Ellipse(20, 10)
|
||||||
|
PushPoints((10, 5))
|
||||||
|
Rectangle(20, 10)
|
||||||
|
PolarArray(5, 0, 360, 6)
|
||||||
|
RegularPolygon(1, 6, mode=Mode.SUBTRACTION)
|
||||||
|
RectangularArray(3, 3, 2, 2)
|
||||||
|
SlotOverall(2, 1, angle=30, mode=Mode.SUBTRACTION)
|
||||||
|
SlotCenterPoint((-10, 0), (-7, 0), 2, mode=Mode.SUBTRACTION)
|
||||||
|
PushPoints((10, 0))
|
||||||
|
SlotCenterToCenter(5, 3, mode=Mode.SUBTRACTION)
|
||||||
|
PushPoints((0, 8))
|
||||||
|
t = Trapezoid(5, 3, 35, mode=Mode.PRIVATE)
|
||||||
|
Offset(t, amount=1, kind=Kind.TANGENT, mode=Mode.SUBTRACTION)
|
||||||
|
PushPoints((-8, 6))
|
||||||
|
Circle(3, mode=Mode.SUBTRACTION)
|
||||||
|
with BuildLine(mode=Mode.PRIVATE) as wave:
|
||||||
|
c = CenterArc((-10, -7), 2, 0, 45)
|
||||||
|
RadiusArc(c @ 1, (-9, -4), 4)
|
||||||
|
SlotArc(wave.line_as_wire, 2, mode=Mode.SUBTRACTION)
|
||||||
|
Polygon(
|
||||||
|
(8, -6),
|
||||||
|
(9, -7),
|
||||||
|
(10, -7),
|
||||||
|
(11, -6),
|
||||||
|
(10, -5),
|
||||||
|
(9, -5),
|
||||||
|
(8, -6),
|
||||||
|
mode=Mode.SUBTRACTION,
|
||||||
|
)
|
||||||
|
PushPoints((18, 8))
|
||||||
|
Text("Sketch", 3, halign=Halign.RIGHT, mode=Mode.SUBTRACTION)
|
||||||
|
|
||||||
if "show_object" in locals():
|
if "show_object" in locals():
|
||||||
show_object(flag.sketch, name="flag")
|
# show_object(flag.sketch, name="flag")
|
||||||
show_object(din.sketch, name="din rail")
|
# show_object(din.sketch, name="din rail")
|
||||||
|
show_object(shapes.sketch, name="shapes")
|
||||||
|
show_object(wave.line, name="wave")
|
||||||
|
# show_object(s)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue