mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-15 15:20:37 -08:00
Typos and clarification to docs
This commit is contained in:
parent
5027dac7bc
commit
cd6f8f0f13
3 changed files with 96 additions and 54 deletions
|
|
@ -2,20 +2,20 @@
|
|||
Tutorial
|
||||
########
|
||||
|
||||
This tutorial provides a step by step guild to creating a script to build a parametric
|
||||
This tutorial provides a step by step guide to creating a script to build a parametric
|
||||
Lego block.
|
||||
|
||||
*************
|
||||
Step 1: Setup
|
||||
*************
|
||||
|
||||
Before getting to the CAD operations, this lego script needs to import the build123d
|
||||
Before getting to the CAD operations, this Lego script needs to import the build123d
|
||||
environment. There are over 100 python classes in build123d so we'll just import them
|
||||
all with an `from build123d import *` but there are other options that we won't explore
|
||||
here. In addition, the `Plane` object from `cadquery` will be used so we'll import
|
||||
all with a ``from build123d import *`` but there are other options that we won't explore
|
||||
here. In addition, the ``Plane`` object from ``cadquery`` will be used so we'll import
|
||||
that class as well.
|
||||
|
||||
The dimensions of the lego block follow. A key parameter is `pip_count`, the length
|
||||
The dimensions of the Lego block follow. A key parameter is ``pip_count``, the length
|
||||
of the Lego blocks in pips. This parameter must be at least 2.
|
||||
|
||||
.. code-block:: python
|
||||
|
|
@ -43,8 +43,8 @@ of the Lego blocks in pips. This parameter must be at least 2.
|
|||
Step 2: Part Builder
|
||||
********************
|
||||
|
||||
The Lego block will be created by the `BuildPart` builder as it's a discrete three
|
||||
dimensional part; therefore, we'll instantiate a `BuildPart` with the name `lego`.
|
||||
The Lego block will be created by the ``BuildPart`` builder as it's a discrete three
|
||||
dimensional part; therefore, we'll instantiate a ``BuildPart`` with the name ``lego``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
|
@ -60,27 +60,30 @@ object. As this sketch will be part of the lego part, we'll create a sketch bui
|
|||
in the context of the part builder as follows:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 2
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
||||
Note that builder instance names are optional - we'll use `plan` to reference the sketch.
|
||||
Note that builder instance names are optional - we'll use ``plan`` to reference the sketch.
|
||||
Also note that all sketch objects are filled or 2D faces not just perimeter lines.
|
||||
|
||||
***************************
|
||||
Step 4: Perimeter Rectangle
|
||||
***************************
|
||||
|
||||
The first object in the sketch is going to be a rectangle the dimensions of the outside
|
||||
of the lego block. The following step is going to refer to this rectangle, so it will
|
||||
be assigned the identifier `perimeter`.
|
||||
The first object in the sketch is going to be a rectangle with the dimensions of the outside
|
||||
of the Lego block. The following step is going to refer to this rectangle, so it will
|
||||
be assigned the identifier ``perimeter``.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 3
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
perimeter = Rectangle(width=block_length, height=block_width)
|
||||
|
||||
Once the `Rectangle` object is created the sketch appears as follows:
|
||||
Once the ``Rectangle`` object is created the sketch appears as follows:
|
||||
|
||||
.. image:: tutorial_step4.svg
|
||||
:align: center
|
||||
|
|
@ -90,10 +93,11 @@ Step 5: Offset to Create Walls
|
|||
******************************
|
||||
|
||||
To create the walls of the block the rectangle that we've created needs to be
|
||||
hollowed out. This will be done with the `Offset` operation which is going to
|
||||
create a new object from `perimeter`.
|
||||
hollowed out. This will be done with the ``Offset`` operation which is going to
|
||||
create a new object from ``perimeter``.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 4-9
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -105,10 +109,10 @@ create a new object from `perimeter`.
|
|||
mode=Mode.SUBTRACT,
|
||||
)
|
||||
|
||||
The first parameter to `Offset` is the reference object. The `amount` is a
|
||||
negative value to indicate that the offset should be internal. The `kind`
|
||||
parameter controls the shape of the corners - `Kind.INTERSECTION` will create
|
||||
square corners. Finally, the `mode` parameter controls how this object will
|
||||
The first parameter to ``Offset`` is the reference object. The ``amount`` is a
|
||||
negative value to indicate that the offset should be internal. The ``kind``
|
||||
parameter controls the shape of the corners - ``Kind.INTERSECTION`` will create
|
||||
square corners. Finally, the ``mode`` parameter controls how this object will
|
||||
be placed in the sketch - in this case subtracted from the existing sketch.
|
||||
The result is shown here:
|
||||
|
||||
|
|
@ -122,12 +126,15 @@ Step 6: Create Internal Grid
|
|||
****************************
|
||||
|
||||
The interior of the Lego block has small ridges on all four internal walls.
|
||||
These ridges will be created as a double row and column of thin rectangles. To
|
||||
space this grid a pair of `GridLocations` location contexts will be used which
|
||||
provide one or more positions to all of the objects within their scope - in
|
||||
this case a single `Rectangle`.
|
||||
These ridges will be created as a grid of thin rectangles so the positions
|
||||
of the centers of these rectangles need to be defined. A pair of
|
||||
``GridLocations`` location contexts will define these positions, one for
|
||||
the horizontal bars and one for the vertical bars. As the ``Rectangle``
|
||||
objects are in the scope of generators (``GridLocations`` in this case)
|
||||
that defined multiple points, multiple rectangles are created.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 10-13
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -143,9 +150,9 @@ this case a single `Rectangle`.
|
|||
with GridLocations(lego_unit_size, 0, pip_count, 1):
|
||||
Rectangle(width=ridge_width, height=block_width)
|
||||
|
||||
Here we can see that the first `GridLocations` create two positions which causes
|
||||
two horizontal rectangles to be created. The second `GridLocations` works in the same way
|
||||
but creates `pip_count` positions and therefore vertical rectangles. Note that keyword
|
||||
Here we can see that the first ``GridLocations`` creates two positions which causes
|
||||
two horizontal rectangles to be created. The second ``GridLocations`` works in the same way
|
||||
but creates ``pip_count`` positions and therefore ``pip_count`` rectangles. Note that keyword
|
||||
parameter are optional in this case.
|
||||
|
||||
The result looks like this:
|
||||
|
|
@ -158,9 +165,10 @@ Step 7: Create Ridges
|
|||
*********************
|
||||
|
||||
To convert the internal grid to ridges, the center needs to be removed. This will be done
|
||||
with another `Rectangle`.
|
||||
with another ``Rectangle``.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 14-18
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -181,7 +189,7 @@ with another `Rectangle`.
|
|||
mode=Mode.SUBTRACT,
|
||||
)
|
||||
|
||||
The `Rectangle` is subtracted from the sketch to leave the ridges as follows:
|
||||
The ``Rectangle`` is subtracted from the sketch to leave the ridges as follows:
|
||||
|
||||
.. image:: tutorial_step7.svg
|
||||
:align: center
|
||||
|
|
@ -192,9 +200,10 @@ Step 8: Hollow Circles
|
|||
**********************
|
||||
|
||||
Lego blocks use a set of internal hollow cylinders that the pips push against
|
||||
to hold two blocks together. These will be created with `Circle`.
|
||||
to hold two blocks together. These will be created with ``Circle``.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 19-23
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -220,8 +229,8 @@ to hold two blocks together. These will be created with `Circle`.
|
|||
Circle(radius=support_outer_diameter / 2)
|
||||
Circle(radius=support_inner_diameter / 2, mode=Mode.SUBTRACT)
|
||||
|
||||
Here another `GridLocations` is used to position the centers of the circles. Note
|
||||
that since both `Circle` objects are in the scope of the location context, both
|
||||
Here another ``GridLocations`` is used to position the centers of the circles. Note
|
||||
that since both ``Circle`` objects are in the scope of the location context, both
|
||||
Circles will be positioned at these locations.
|
||||
|
||||
Once the Circles are added, the sketch is complete and looks as follows:
|
||||
|
|
@ -237,6 +246,7 @@ Now that the sketch is complete it needs to be extruded into the three dimension
|
|||
wall object.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 24
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -261,11 +271,11 @@ wall object.
|
|||
):
|
||||
Circle(radius=support_outer_diameter / 2)
|
||||
Circle(radius=support_inner_diameter / 2, mode=Mode.SUBTRACT)
|
||||
Extrude(base_height - wall_thickness)
|
||||
Extrude(amount=base_height - wall_thickness)
|
||||
|
||||
Note how the `Extrude` operation is no longer in the `BuildSketch` scope and back into
|
||||
the `BuildPart` scope. This causes `BuildSketch` to exit and transfer the sketch that
|
||||
we've created to `BuildPart` for further processing by `Extrude`.
|
||||
Note how the ``Extrude`` operation is no longer in the ``BuildSketch`` scope and has returned
|
||||
back into the ``BuildPart`` scope. This causes ``BuildSketch`` to exit and transfer the
|
||||
sketch that we've created to ``BuildPart`` for further processing by ``Extrude``.
|
||||
|
||||
The result is:
|
||||
|
||||
|
|
@ -281,6 +291,7 @@ Now that the walls are complete, the top of the block needs to be added. Althoug
|
|||
could be done with another sketch, we'll add a box to the top of the walls.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 25-31
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -305,7 +316,7 @@ could be done with another sketch, we'll add a box to the top of the walls.
|
|||
):
|
||||
Circle(radius=support_outer_diameter / 2)
|
||||
Circle(radius=support_inner_diameter / 2, mode=Mode.SUBTRACT)
|
||||
Extrude(base_height - wall_thickness)
|
||||
Extrude(amount=base_height - wall_thickness)
|
||||
with Locations((0, 0, lego.vertices().sort_by(SortBy.Z)[-1].z)):
|
||||
Box(
|
||||
length=block_length,
|
||||
|
|
@ -314,15 +325,15 @@ could be done with another sketch, we'll add a box to the top of the walls.
|
|||
centered=(True, True, False),
|
||||
)
|
||||
|
||||
To position the top, we'll create a new location context `Locations` at the center
|
||||
and at the height of the walls. To determine the height we'll exact that from the
|
||||
`lego.part` by using the `vertices()` method which returns a list of the positions
|
||||
of all of the vertices of the lego block so far. Since we're interested in the top,
|
||||
To position the top, we'll create a new location context ``Locations`` at the center
|
||||
and at the height of the walls. To determine the height we'll extract that from the
|
||||
``lego.part`` by using the ``vertices()`` method which returns a list of the positions
|
||||
of all of the vertices of the Lego block so far. Since we're interested in the top,
|
||||
we'll sort by the vertical (Z) axis and take the top of the list (index -1). Finally,
|
||||
the `z` property of this vertex will return just the height of the top.
|
||||
the ``z`` property of this vertex will return just the height of the top.
|
||||
|
||||
Within the scope of this `Locations` context, a `Box` is created, centered in over
|
||||
the x and y axis but not in the z thus aligning with the top of the walls.
|
||||
Within the scope of this ``Locations`` context, a ``Box`` is created, centered at
|
||||
the intersection of the x and y axis but not in the z thus aligning with the top of the walls.
|
||||
|
||||
The base is closed now as shown here:
|
||||
|
||||
|
|
@ -337,6 +348,7 @@ The final step is to add the pips to the top of the Lego block. To do this we'll
|
|||
a new workplane on top of the block where we can position the pips.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 32-36
|
||||
|
||||
with BuildPart() as lego:
|
||||
with BuildSketch() as plan:
|
||||
|
|
@ -361,7 +373,7 @@ a new workplane on top of the block where we can position the pips.
|
|||
):
|
||||
Circle(radius=support_outer_diameter / 2)
|
||||
Circle(radius=support_inner_diameter / 2, mode=Mode.SUBTRACT)
|
||||
Extrude(base_height - wall_thickness)
|
||||
Extrude(amount=base_height - wall_thickness)
|
||||
with Locations((0, 0, lego.vertices().sort_by(SortBy.Z)[-1].z)):
|
||||
Box(
|
||||
length=block_length,
|
||||
|
|
@ -375,13 +387,30 @@ a new workplane on top of the block where we can position the pips.
|
|||
radius=pip_diameter / 2, height=pip_height, centered=(True, True, False)
|
||||
)
|
||||
|
||||
Much like the location contexts, the `Workplanes` context creates one or more planes that
|
||||
Much like the location contexts, the ``Workplanes`` context creates one or more planes that
|
||||
can be used to position further features. In this case, the workplane is created from the
|
||||
top Face of the Lego block by using the `faces` method and then sorted as previously discussed.
|
||||
top Face of the Lego block by using the ``faces`` method and then sorted vertically.
|
||||
|
||||
On the new workplane, a grid of locations is created and a number of `Cylinder` are positioned there.
|
||||
|
||||
This completes the Lego block which would now be displayed or exported as a STL or STEP file.
|
||||
On the new workplane, a grid of locations is created and a number of ``Cylinder``'s are positioned
|
||||
at each location.
|
||||
|
||||
.. image:: tutorial_step11.svg
|
||||
:align: center
|
||||
|
||||
|
||||
This completes the Lego block. To access the finished product, refer to the builder's internal
|
||||
object as shown here:
|
||||
|
||||
+-------------+--------+
|
||||
| Builder | Object |
|
||||
+=============+========+
|
||||
| BuildLine | line |
|
||||
+-------------+--------+
|
||||
| BuildSketch | sketch |
|
||||
+-------------+--------+
|
||||
| BuildPart | part |
|
||||
+-------------+--------+
|
||||
|
||||
so in this case the Lego block is ``lego.part``. To display the part use ``show_object(lego.part)``
|
||||
or ``show(lego.part)`` depending on the viewer. The part could also be exported to a STL or STEP
|
||||
file by referencing ``lego.part``.
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ with BuildPart() as lego:
|
|||
Circle(support_outer_diameter / 2)
|
||||
Circle(support_inner_diameter / 2, mode=Mode.SUBTRACT)
|
||||
# Extrude this base sketch to the height of the walls
|
||||
Extrude(base_height - wall_thickness)
|
||||
Extrude(amount=base_height - wall_thickness)
|
||||
# Create a workplane on the top of the walls
|
||||
with Workplanes(
|
||||
Plane(origin=(0, 0, base_height - wall_thickness), normal=(0, 0, 1))
|
||||
|
|
|
|||
|
|
@ -372,7 +372,11 @@ class Extrude(Compound):
|
|||
Extrude a sketch/face and combine with part.
|
||||
|
||||
Args:
|
||||
until (Union[float, Until, Face]): depth of extrude or extrude limit
|
||||
faces (Face): sequence of faces, if not provided use pending_faces.
|
||||
Defaults to None.
|
||||
amount (float): distance to extrude, sign controls direction
|
||||
Defaults to None.
|
||||
until (Union[Until, Face]): depth of extrude or extrude limit
|
||||
both (bool, optional): extrude in both directions. Defaults to False.
|
||||
taper (float, optional): taper during extrusion. Defaults to None.
|
||||
mode (Mode, optional): combination mode. Defaults to Mode.ADD.
|
||||
|
|
@ -380,18 +384,27 @@ class Extrude(Compound):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
until: Union[float, Until, Face],
|
||||
*faces: Face,
|
||||
amount: float = None,
|
||||
until: Union[Until, Face] = None,
|
||||
both: bool = False,
|
||||
taper: float = None,
|
||||
mode: Mode = Mode.ADD,
|
||||
):
|
||||
new_solids: list[Solid] = []
|
||||
context: BuildPart = BuildPart._get_context()
|
||||
for face in context.pending_faces:
|
||||
|
||||
# TODO: add until and taper functionality
|
||||
|
||||
if not faces:
|
||||
faces = context.pending_faces
|
||||
context.pending_faces = []
|
||||
|
||||
for face in faces:
|
||||
new_solids.append(
|
||||
Solid.extrudeLinear(
|
||||
face,
|
||||
face.normalAt(face.Center()) * until,
|
||||
face.normalAt(face.Center()) * amount,
|
||||
0,
|
||||
)
|
||||
)
|
||||
|
|
@ -399,7 +412,7 @@ class Extrude(Compound):
|
|||
new_solids.append(
|
||||
Solid.extrudeLinear(
|
||||
face,
|
||||
face.normalAt(face.Center()) * until * -1.0,
|
||||
face.normalAt(face.Center()) * amount * -1.0,
|
||||
0,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue