mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-06 02:30:55 -08:00
Refactoring and bug fixes
This commit is contained in:
parent
1cef9705b5
commit
06f4a84ebc
3 changed files with 146 additions and 151 deletions
|
|
@ -14,7 +14,7 @@ f1.wrapped.TShape() == f2.wrapped.TShape() <=== TRUE
|
|||
Thanks. Playing around a bit more, it seems like translate() makes the underlying TShapes unequal, but Shape.moved() preserves TShape. This returns true, which could be useful: x1 = cq.Workplane().box(3,4,5) x2 = cq.Workplane(x1.findSolid().moved(cq.Location(cq.Vector(1,2,3),cq.Vector(4,5,6),7))) f1 = x1.faces(">Z").val() f2 = x2.faces(">Z").val() f1.wrapped.TShape() == f2.wrapped.TShape() <=== TRUE
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
from functools import partial
|
||||
from math import pi, sin, cos, radians, sqrt
|
||||
from pstats import SortKey
|
||||
|
|
@ -38,7 +38,7 @@ from cadquery import (
|
|||
from cadquery.occ_impl.shapes import VectorLike, Real
|
||||
import cq_warehouse.extensions
|
||||
|
||||
cq.Wire.makeHelix
|
||||
|
||||
|
||||
z_axis = (Vector(0, 0, 0), Vector(0, 0, 1))
|
||||
|
||||
|
|
|
|||
219
build_part.py
219
build_part.py
|
|
@ -26,6 +26,14 @@ from cadquery.occ_impl.shapes import VectorLike, Real
|
|||
import cq_warehouse.extensions
|
||||
from build123d_common import *
|
||||
|
||||
logging.basicConfig(
|
||||
filename="build123D.log",
|
||||
encoding="utf-8",
|
||||
level=logging.DEBUG,
|
||||
# level=logging.CRITICAL,
|
||||
format="%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)s - %(funcName)20s() ] - %(message)s",
|
||||
)
|
||||
|
||||
|
||||
class BuildPart:
|
||||
@property
|
||||
|
|
@ -201,39 +209,17 @@ class BuildPart:
|
|||
self.add_to_pending(*new_edges)
|
||||
self.add_to_pending(*new_faces)
|
||||
|
||||
|
||||
class AddPart(Compound):
|
||||
def __init__(
|
||||
self,
|
||||
*objects: Union[Edge, Wire, Face, Solid, Compound],
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
new_faces = [obj for obj in objects if isinstance(obj, Face)]
|
||||
new_solids = [obj for obj in objects if isinstance(obj, Solid)]
|
||||
for compound in filter(lambda o: isinstance(o, Compound), objects):
|
||||
new_faces.extend(compound.Faces())
|
||||
new_solids.extend(compound.Solids())
|
||||
new_edges = [obj for obj in objects if isinstance(obj, Edge)]
|
||||
for compound in filter(lambda o: isinstance(o, Wire), objects):
|
||||
new_edges.extend(compound.Edges())
|
||||
|
||||
# Add to pending faces and edges
|
||||
BuildPart.get_context().add_to_pending(new_faces)
|
||||
BuildPart.get_context().add_to_pending(new_edges)
|
||||
|
||||
# Locate the solids to the predefined positions
|
||||
locations = [
|
||||
location for location in BuildPart.get_context().locations.values()
|
||||
]
|
||||
# If no locations have been specified, use the origin
|
||||
if not locations:
|
||||
locations = [Location(Vector())]
|
||||
|
||||
located_solids = [
|
||||
solid.moved(location) for solid in new_solids for location in locations
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*located_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(located_solids).wrapped)
|
||||
def get_and_clear_locations(self) -> list:
|
||||
position_normals = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
pending_locations = BuildPart.get_context().locations[i]
|
||||
locations = pending_locations if pending_locations else [Location(Vector())]
|
||||
position_normals = [
|
||||
(location.position(), workplane.zDir) for location in locations
|
||||
]
|
||||
# Clear used locations
|
||||
self.locations[i] = []
|
||||
return position_normals
|
||||
|
||||
|
||||
class Extrude(Compound):
|
||||
|
|
@ -395,6 +381,45 @@ class PushPointsPart:
|
|||
# print(f"{len(BuildPart.get_context().locations[i])=}")
|
||||
|
||||
|
||||
class AddPart(Compound):
|
||||
def __init__(
|
||||
self,
|
||||
*objects: Union[Edge, Wire, Face, Solid, Compound],
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
new_faces = [obj for obj in objects if isinstance(obj, Face)]
|
||||
new_solids = [obj for obj in objects if isinstance(obj, Solid)]
|
||||
for compound in filter(lambda o: isinstance(o, Compound), objects):
|
||||
new_faces.extend(compound.Faces())
|
||||
new_solids.extend(compound.Solids())
|
||||
new_edges = [obj for obj in objects if isinstance(obj, Edge)]
|
||||
for compound in filter(lambda o: isinstance(o, Wire), objects):
|
||||
new_edges.extend(compound.Edges())
|
||||
|
||||
# Add to pending faces and edges
|
||||
BuildPart.get_context().add_to_pending(new_faces)
|
||||
BuildPart.get_context().add_to_pending(new_edges)
|
||||
|
||||
# Locate the solids to the predefined positions
|
||||
locations = [
|
||||
location for location in BuildPart.get_context().locations.values()
|
||||
]
|
||||
# If no locations have been specified, use the origin
|
||||
if not locations:
|
||||
locations = [Location(Vector())]
|
||||
|
||||
located_solids = [
|
||||
solid.moved(location) for solid in new_solids for location in locations
|
||||
]
|
||||
|
||||
# Clear used locations
|
||||
for i in range(len(BuildPart.get_context().workplanes)):
|
||||
self.locations[i] = []
|
||||
|
||||
BuildPart.get_context().add_to_context(*located_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(located_solids).wrapped)
|
||||
|
||||
|
||||
class Box(Compound):
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -403,15 +428,11 @@ class Box(Compound):
|
|||
height: float,
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
new_solids = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
for location in BuildPart.get_context().locations[i]:
|
||||
new_solids.append(
|
||||
Solid.makeBox(
|
||||
length, width, height, location.position(), workplane.zDir
|
||||
)
|
||||
)
|
||||
|
||||
position_normals = BuildPart.get_context().get_and_clear_locations()
|
||||
new_solids = [
|
||||
Solid.makeBox(length, width, height, pos, normal)
|
||||
for pos, normal in position_normals
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(new_solids).wrapped)
|
||||
|
||||
|
|
@ -419,27 +440,24 @@ class Box(Compound):
|
|||
class Cone(Compound):
|
||||
def __init__(
|
||||
self,
|
||||
radius1: float,
|
||||
radius2: float,
|
||||
bottom_radius: float,
|
||||
top_radius: float,
|
||||
height: float,
|
||||
angle: float = 360,
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
|
||||
new_solids = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
for location in BuildPart.get_context().locations[i]:
|
||||
new_solids.append(
|
||||
Solid.makeCone(
|
||||
radius1,
|
||||
radius2,
|
||||
height,
|
||||
location.position(),
|
||||
workplane.zDir,
|
||||
angle,
|
||||
)
|
||||
)
|
||||
|
||||
position_normals = BuildPart.get_context().get_and_clear_locations()
|
||||
new_solids = [
|
||||
Solid.makeCone(
|
||||
bottom_radius,
|
||||
top_radius,
|
||||
height,
|
||||
pos,
|
||||
normal,
|
||||
angle,
|
||||
)
|
||||
for pos, normal in position_normals
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(new_solids).wrapped)
|
||||
|
||||
|
|
@ -452,16 +470,11 @@ class Cylinder(Compound):
|
|||
angle: float = 360,
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
|
||||
new_solids = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
for location in BuildPart.get_context().locations[i]:
|
||||
new_solids.append(
|
||||
Solid.makeCylinder(
|
||||
radius, height, location.position(), workplane.zDir, angle
|
||||
)
|
||||
)
|
||||
|
||||
position_normals = BuildPart.get_context().get_and_clear_locations()
|
||||
new_solids = [
|
||||
Solid.makeCylinder(radius, height, pos, normal, angle)
|
||||
for pos, normal in position_normals
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(new_solids).wrapped)
|
||||
|
||||
|
|
@ -470,26 +483,16 @@ class Sphere(Compound):
|
|||
def __init__(
|
||||
self,
|
||||
radius: float,
|
||||
angle1: float = 0,
|
||||
angle1: float = -90,
|
||||
angle2: float = 90,
|
||||
angle3: float = 360,
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
|
||||
new_solids = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
for location in BuildPart.get_context().locations[i]:
|
||||
new_solids.append(
|
||||
Solid.makeSphere(
|
||||
radius,
|
||||
location.position(),
|
||||
workplane.zDir,
|
||||
angle1,
|
||||
angle2,
|
||||
angle3,
|
||||
)
|
||||
)
|
||||
|
||||
position_normals = BuildPart.get_context().get_and_clear_locations()
|
||||
new_solids = [
|
||||
Solid.makeSphere(radius, pos, normal, angle1, angle2, angle3)
|
||||
for pos, normal in position_normals
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(new_solids).wrapped)
|
||||
|
||||
|
|
@ -497,26 +500,17 @@ class Sphere(Compound):
|
|||
class Torus(Compound):
|
||||
def __init__(
|
||||
self,
|
||||
radius1: float,
|
||||
radius2: float,
|
||||
major_radius: float,
|
||||
minor_radius: float,
|
||||
angle1: float = 0,
|
||||
angle2: float = 360,
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
new_solids = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
for location in BuildPart.get_context().locations[i]:
|
||||
new_solids.append(
|
||||
Solid.makeTorus(
|
||||
radius1,
|
||||
radius2,
|
||||
location.position(),
|
||||
workplane.zDir,
|
||||
angle1,
|
||||
angle2,
|
||||
)
|
||||
)
|
||||
|
||||
position_normals = BuildPart.get_context().get_and_clear_locations()
|
||||
new_solids = [
|
||||
Solid.makeTorus(major_radius, minor_radius, pos, normal, angle1, angle2)
|
||||
for pos, normal in position_normals
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(new_solids).wrapped)
|
||||
|
||||
|
|
@ -533,23 +527,10 @@ class Wedge(Compound):
|
|||
zmax: float,
|
||||
mode: Mode = Mode.ADDITION,
|
||||
):
|
||||
|
||||
new_solids = []
|
||||
for i, workplane in enumerate(BuildPart.get_context().workplanes):
|
||||
for location in BuildPart.get_context().locations[i]:
|
||||
new_solids.append(
|
||||
Solid.makeWedge(
|
||||
dx,
|
||||
dy,
|
||||
dz,
|
||||
xmin,
|
||||
zmin,
|
||||
xmax,
|
||||
zmax,
|
||||
location.position(),
|
||||
workplane.zDir,
|
||||
)
|
||||
)
|
||||
|
||||
position_normals = BuildPart.get_context().get_and_clear_locations()
|
||||
new_solids = [
|
||||
Solid.makeWedge(dx, dy, dz, xmin, zmin, xmax, zmax, pos, normal)
|
||||
for pos, normal in position_normals
|
||||
]
|
||||
BuildPart.get_context().add_to_context(*new_solids, mode=mode)
|
||||
super().__init__(Compound.makeCompound(new_solids).wrapped)
|
||||
|
|
|
|||
|
|
@ -13,34 +13,34 @@ from build_sketch import *
|
|||
# )
|
||||
# )
|
||||
|
||||
# with BuildPart(workplane=Plane.named("XZ")) as rail:
|
||||
# with BuildSketch() as din:
|
||||
# PushPoints((0, 0.5))
|
||||
# Rectangle(35, 1)
|
||||
# PushPoints((0, 7.5 / 2))
|
||||
# Rectangle(27, 7.5)
|
||||
# PushPoints((0, 6.5 / 2))
|
||||
# Rectangle(25, 6.5, mode=Mode.SUBTRACTION)
|
||||
# inside_vertices = (
|
||||
# din.vertices()
|
||||
# .filter_by_position(Axis.Y, 0.1, 7.4)
|
||||
# .filter_by_position(Axis.X, -17.4, 17.4)
|
||||
# )
|
||||
# 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]
|
||||
# rail.faces_to_workplanes(top, replace=True)
|
||||
# with BuildSketch() as slots:
|
||||
# RectangularArray(0, 25, 1, 39)
|
||||
# SlotOverall(15, 6.2, 90)
|
||||
# slot_holes = Extrude(-20, mode=Mode.SUBTRACTION)
|
||||
with BuildPart(workplane=Plane.named("XZ")) as rail:
|
||||
with BuildSketch() as din:
|
||||
PushPoints((0, 0.5))
|
||||
Rectangle(35, 1)
|
||||
PushPoints((0, 7.5 / 2))
|
||||
Rectangle(27, 7.5)
|
||||
PushPoints((0, 6.5 / 2))
|
||||
Rectangle(25, 6.5, mode=Mode.SUBTRACTION)
|
||||
inside_vertices = (
|
||||
din.vertices()
|
||||
.filter_by_position(Axis.Y, 0.1, 7.4)
|
||||
.filter_by_position(Axis.X, -17.4, 17.4)
|
||||
)
|
||||
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]
|
||||
rail.faces_to_workplanes(top, replace=True)
|
||||
with BuildSketch() as slots:
|
||||
RectangularArray(0, 25, 1, 39)
|
||||
SlotOverall(15, 6.2, 90)
|
||||
slot_holes = Extrude(-20, mode=Mode.SUBTRACTION)
|
||||
|
||||
with BuildPart() as cube:
|
||||
PushPointsPart((-5, -5, -5))
|
||||
|
|
@ -49,16 +49,30 @@ with BuildPart() as cube:
|
|||
with BuildSketch() as pipe:
|
||||
Circle(4)
|
||||
Extrude(-5, mode=Mode.SUBTRACTION)
|
||||
# print(cube.workplane_count)
|
||||
with BuildSketch() as pipe:
|
||||
Circle(4.5)
|
||||
Circle(4, mode=Mode.SUBTRACTION)
|
||||
Extrude(10)
|
||||
FilletPart(*cube.edges(Select.LAST), radius=0.2)
|
||||
|
||||
with BuildPart() as s:
|
||||
Sphere(5)
|
||||
with BuildPart() as c:
|
||||
Cone(20, 10, 20)
|
||||
with BuildPart() as cyl:
|
||||
Cylinder(10, 30)
|
||||
with BuildPart() as t:
|
||||
Torus(50, 10)
|
||||
with BuildPart() as w:
|
||||
Wedge(10, 10, 10, 5, 5, 20, 20)
|
||||
|
||||
if "show_object" in locals():
|
||||
# show_object(rail.part, name="rail")
|
||||
show_object(rail.part, name="rail")
|
||||
# show_object(slots.sketch, name="slots")
|
||||
# show_object(slot_holes, name="slot_holes")
|
||||
show_object(cube.part, name="cube")
|
||||
show_object(s.part, name="sphere")
|
||||
show_object(c.part, name="cone")
|
||||
show_object(cyl.part, name="cylinder")
|
||||
show_object(t.part, name="torus")
|
||||
show_object(w.part, name="wedge")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue