bug fixes and Enum improvements

This commit is contained in:
Roger Maitland 2022-07-07 13:33:54 -04:00
parent 291f897111
commit cbdadb44d6
4 changed files with 118 additions and 75 deletions

View file

@ -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()

View file

@ -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))
) )

View file

@ -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)

View file

@ -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)