Sorted filter by axis, added Centered option

This commit is contained in:
Roger Maitland 2022-07-11 16:27:34 -04:00
parent 630e6d7529
commit ad431bed99
3 changed files with 93 additions and 48 deletions

View file

@ -160,10 +160,12 @@ class Kind(Enum):
INTERSECTION = auto()
TANGENT = auto()
class Keep(Enum):
TOP = auto()
BOTTOM = auto()
class FilterBy(Enum):
LAST_OPERATION = auto()
@ -270,13 +272,19 @@ class ShapeList(list):
return super().__init_subclass__()
def filter_by_normal(self, axis: Axis):
return ShapeList(
filter(
lambda o: o.normalAt(o.Center()) == Vector(*ShapeList.axis_map[axis][0])
or o.normalAt(o.Center()) == Vector(*ShapeList.axis_map[axis][1]),
self,
)
result = filter(
lambda o: o.normalAt(o.Center()) == Vector(*ShapeList.axis_map[axis][0])
or o.normalAt(o.Center()) == Vector(*ShapeList.axis_map[axis][1]),
self,
)
if axis == Axis.X:
result = sorted(result, key=lambda obj: obj.Center().x)
elif axis == Axis.Y:
result = sorted(result, key=lambda obj: obj.Center().y)
elif axis == Axis.Z:
result = sorted(result, key=lambda obj: obj.Center().z)
return ShapeList(result)
def filter_by_position(
self,

View file

@ -1,11 +1,10 @@
"""
TODO:
- add TwistExtrude, ProjectText
- add centered to each object
- add centered to wedge
"""
from math import pi, sin, cos, radians, sqrt, tan
from typing import Union, Iterable, Callable
from enum import Enum, auto
from math import radians, tan
from typing import Union
import cadquery as cq
from cadquery import (
Edge,
@ -19,7 +18,7 @@ from cadquery import (
Solid,
Plane,
)
from cadquery.occ_impl.shapes import VectorLike, Real
from cadquery.occ_impl.shapes import VectorLike
import cq_warehouse.extensions
from build123d_common import *
@ -540,12 +539,20 @@ class Box(Compound):
width: float,
height: float,
rotation: RotationLike = (0, 0, 0),
centered: tuple[bool, bool, bool] = (True, True, True),
mode: Mode = Mode.ADDITION,
):
rotate = Rotation(*rotation) if isinstance(rotation, tuple) else rotation
position_planes = BuildPart.get_context().get_and_clear_locations()
center_offset = Vector(
-length / 2 if centered[0] else 0,
-width / 2 if centered[1] else 0,
-height / 2 if centered[2] else 0,
)
new_solids = [
Solid.makeBox(length, width, height, pos, plane.zDir).moved(rotate)
Solid.makeBox(length, width, height, pos + center_offset, plane.zDir).moved(
rotate
)
for pos, plane in position_planes
]
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
@ -560,16 +567,22 @@ class Cone(Compound):
height: float,
angle: float = 360,
rotation: RotationLike = (0, 0, 0),
centered: tuple[bool, bool, bool] = (True, True, True),
mode: Mode = Mode.ADDITION,
):
rotate = Rotation(*rotation) if isinstance(rotation, tuple) else rotation
position_planes = BuildPart.get_context().get_and_clear_locations()
center_offset = Vector(
0 if centered[0] else max(bottom_radius, top_radius),
0 if centered[1] else max(bottom_radius, top_radius),
-height / 2 if centered[2] else 0,
)
new_solids = [
Solid.makeCone(
bottom_radius,
top_radius,
height,
pos,
pos + center_offset,
plane.zDir,
angle,
).moved(rotate)
@ -586,12 +599,20 @@ class Cylinder(Compound):
height: float,
angle: float = 360,
rotation: RotationLike = (0, 0, 0),
centered: tuple[bool, bool, bool] = (True, True, True),
mode: Mode = Mode.ADDITION,
):
rotate = Rotation(*rotation) if isinstance(rotation, tuple) else rotation
position_planes = BuildPart.get_context().get_and_clear_locations()
center_offset = Vector(
0 if centered[0] else radius,
0 if centered[1] else radius,
-height / 2 if centered[2] else 0,
)
new_solids = [
Solid.makeCylinder(radius, height, pos, plane.zDir, angle).moved(rotate)
Solid.makeCylinder(
radius, height, pos + center_offset, plane.zDir, angle
).moved(rotate)
for pos, plane in position_planes
]
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
@ -606,14 +627,20 @@ class Sphere(Compound):
angle2: float = 90,
angle3: float = 360,
rotation: RotationLike = (0, 0, 0),
centered: tuple[bool, bool, bool] = (True, True, True),
mode: Mode = Mode.ADDITION,
):
rotate = Rotation(*rotation) if isinstance(rotation, tuple) else rotation
position_planes = BuildPart.get_context().get_and_clear_locations()
center_offset = Vector(
0 if centered[0] else radius,
0 if centered[1] else radius,
0 if centered[2] else radius,
)
new_solids = [
Solid.makeSphere(radius, pos, plane.zDir, angle1, angle2, angle3).moved(
rotate
)
Solid.makeSphere(
radius, pos + center_offset, plane.zDir, angle1, angle2, angle3
).moved(rotate)
for pos, plane in position_planes
]
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
@ -628,13 +655,24 @@ class Torus(Compound):
angle1: float = 0,
angle2: float = 360,
rotation: RotationLike = (0, 0, 0),
centered: tuple[bool, bool, bool] = (True, True, True),
mode: Mode = Mode.ADDITION,
):
rotate = Rotation(*rotation) if isinstance(rotation, tuple) else rotation
position_planes = BuildPart.get_context().get_and_clear_locations()
center_offset = Vector(
0 if centered[0] else major_radius,
0 if centered[1] else major_radius,
0 if centered[2] else minor_radius,
)
new_solids = [
Solid.makeTorus(
major_radius, minor_radius, pos, plane.zDir, angle1, angle2
major_radius,
minor_radius,
pos + center_offset,
plane.zDir,
angle1,
angle2,
).moved(rotate)
for pos, plane in position_planes
]

View file

@ -5,37 +5,36 @@ TODO:
from build_part import *
from build_sketch import *
# with BuildPart(workplane=Plane.named("XZ")) as rail:
# with BuildSketch() as din:
# PushPointsToSketch((0, 0.5))
# Rectangle(35, 1)
# PushPointsToSketch((0, 7.5 / 2))
# Rectangle(27, 7.5)
# PushPointsToSketch((0, 6.5 / 2))
# Rectangle(25, 6.5, mode=Mode.SUBTRACTION)
# inside_vertices = (
# din.vertices()
# .filter_by_position(Axis.Y, 0.0, 7.5, inclusive=(False, False))
# .filter_by_position(Axis.X, -17.5, 17.5, inclusive=(False, False))
# )
# FilletSketch(*inside_vertices, radius=0.8)
# outside_vertices = list(
# filter(
# lambda v: (v.Y == 0.0 or v.Y == 7.5) and -17.5 < v.X < 17.5,
# din.vertices(),
# )
# )
# FilletSketch(*outside_vertices, radius=1.8)
# Extrude(1000)
# top = rail.faces().filter_by_normal(Axis.Z).sort_by(SortBy.Z)[-1]
# WorkplanesFromFaces(top, replace=True)
# with BuildSketch() as slots:
# RectangularArrayToSketch(0, 25, 1, 39)
# SlotOverall(15, 6.2, rotation=90)
# slot_holes = Extrude(-20, mode=Mode.SUBTRACTION)
with BuildPart(workplane=Plane.named("XZ")) as rail:
with BuildSketch() as din:
PushPointsToSketch((0, 0.5))
Rectangle(35, 1)
PushPointsToSketch((0, 7.5 / 2))
Rectangle(27, 7.5)
PushPointsToSketch((0, 6.5 / 2))
Rectangle(25, 6.5, mode=Mode.SUBTRACTION)
inside_vertices = (
din.vertices()
.filter_by_position(Axis.Y, 0.0, 7.5, inclusive=(False, False))
.filter_by_position(Axis.X, -17.5, 17.5, inclusive=(False, False))
)
FilletSketch(*inside_vertices, radius=0.8)
outside_vertices = list(
filter(
lambda v: (v.Y == 0.0 or v.Y == 7.5) and -17.5 < v.X < 17.5,
din.vertices(),
)
)
FilletSketch(*outside_vertices, radius=1.8)
Extrude(1000)
top = rail.faces().filter_by_normal(Axis.Z)[-1]
WorkplanesFromFaces(top, replace=True)
with BuildSketch() as slots:
RectangularArrayToSketch(0, 25, 1, 39)
SlotOverall(15, 6.2, rotation=90)
slot_holes = Extrude(-20, mode=Mode.SUBTRACTION)
with BuildPart() as cube:
PushPointsToPart((-5, -5, -5))
Box(10, 10, 10, rotation=(10, 20, 30))
WorkplanesFromFaces(*cube.faces(), replace=True)
with BuildSketch() as pipe:
@ -73,7 +72,7 @@ with BuildPart() as hole:
CounterBoreHole(2, 4, 1)
if "show_object" in locals():
# show_object(rail.part, name="rail")
show_object(rail.part, name="rail")
show_object(cube.part, name="cube")
# show_object(s.part, name="sphere")
# show_object(c.part, name="cone")