Open KilowattSynthesis opened 2 days ago
I agree -- this is planned for inclusion in example 37, it is already also included in this example as well https://build123d.readthedocs.io/en/latest/examples_1.html#handle and also mentioned on the cheat sheet https://build123d.readthedocs.io/en/latest/cheat_sheet.html
I'm struggling to grasp what's going on in that example; it's too bad it's not a bit more intuitive.
I'm looking at the algebraic code.
How does the sections
variable get lined up with the handle_center_line
? Is it strictly based on the location
? Or does index play a part? What would happen if those rectangles/circles weren't right on the handle_center_line
?
It's also too bad that readthedocs can't handle a search for a caret correctly (i.e., it returns no results): https://build123d.readthedocs.io/en/latest/search.html?q=%5E&check_keywords=yes&area=default
Here is a detailed explanation of that example provided by ChatGPT 4o (unedited outside of formatting):
This code creates a handle shape by sweeping a series of cross-sectional shapes (circles and rounded rectangles) along a path defined by a spline. Here’s a breakdown of each part:
Imports:
from build123d import *
from ocp_vscode import show_object
This imports necessary modules. build123d provides tools for CAD operations, and ocp_vscode is used for visualizing objects.
Define segment_count
:
segment_count = 6
This specifies the number of segments along the handle path. This will determine how many cross-sections are created along the path.
Create the Path (handle_center_line
):
handle_center_line = Spline(
(-10, 0, 0),
(0, 0, 5),
(10, 0, 0),
tangents=((0, 0, 1), (0, 0, -1)),
tangent_scalars=(1.5, 1.5),
)
A 3D spline path is created for the handle’s central line. The path starts at (-10, 0, 0)
, arcs upwards to (0, 0, 5)
, and ends at (10, 0, 0)
. Tangents are specified at each end to control the slope, with scalar values that adjust the influence of each tangent.
Define Cross-Sections (sections
):
sections = Sketch()
for i in range(segment_count + 1):
location = handle_center_line ^ (i / segment_count)
if i % segment_count == 0:
circle = location * Circle(1)
else:
circle = location * Rectangle(1.25, 3)
circle = fillet(circle.vertices(), radius=0.2)
sections += circle
This loop creates cross-sections at intervals along the spline path:
location = handle_center_line ^ (i / segment_count)
: Places each cross-section along the path using parametric division.if i % segment_count == 0
: If it’s the first or last section, a circular cross-section with radius 1 is created.Sweep Operation to Create the Handle (handle):
handle = sweep(sections, path=handle_center_line, multisection=True)
The sweep
function uses sections as the cross-sections and handle_center_line
as the path, creating a 3D handle by sweeping the cross-sections along the spline. multisection=True
enables smooth transition between different shapes along the path.
Visualize the Objects:
show_object(handle_center_line, name="handle_path")
for i, circle in enumerate(sections):
show_object(circle, name="section" + str(i))
show_object(handle, name="handle", options=dict(alpha=0.6))
handle_center_line
is displayed as the path of the handle.Overall, this code demonstrates how to model a handle shape in build123d by defining a path and sweeping different cross-sectional profiles along it.
I can read the code haha, thank you though.
How does the sections variable get lined up with the handle_center_line? Is it strictly based on the location? Or does index play a part? What would happen if those rectangles/circles weren't right on the handle_center_line?
circle = location * Circle(1)
creates a circle positioned at location
. Try messing about with the alignment of Circle
and Rectangle
and see how it changes the sweep (e.g. Circle(1, align=Align.MIN)
.
It appears that the term "caret", which describes the
^
symbol, is not currently in the build123d docs.From an example I stumbled across, it appears that the caret operator moves a plane/flat object to the end of a line (to both its point and facing its tangent).
This would be a great thing to cover near the docs about "sweep", as it's hugely useful for the sweep method.