Adding toy truck code

This commit is contained in:
gumyr 2025-04-05 11:15:45 -04:00
parent bf6206377d
commit 91034a6745

185
examples/toy_truck.py Normal file
View file

@ -0,0 +1,185 @@
"""
name: toy_truck.py
by: Gumyr
date: April 4th 2025
desc:
This example demonstrates how to design a toy truck using BuildPart and
BuildSketch in Builder mode. The model includes a detailed body, cab, grill,
and bumper, showcasing techniques like sketch reuse, symmetry, tapered
extrusions, selective filleting, and the use of joints for part assembly.
Ideal for learning complex part construction and hierarchical modeling in
build123d.
license:
Copyright 2025 Gumyr
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
# [Code]
import pathlib
from build123d import *
from ocp_vscode import ImageFace, show, show_object
# Create an ocp_vscode image object to use as a design reference
project_root = pathlib.Path(__file__).resolve().parents[1]
reference_image_path = (
project_root / "docs" / "assets" / "examples" / "toy_truck_picture.jpg"
)
image = ImageFace(
str(reference_image_path),
scale=0.012,
location=Location((0, 0, -1), (0, 0, 90)),
)
show_object(image)
# Toy Truck Blue
truck_color = Color(0x4683CE)
# Create the main truck body — from bumper to bed, excluding the cab
with BuildPart() as body:
# The body has two axes of symmetry, so we start with a centered sketch.
# The default workplane is Plane.XY.
with BuildSketch() as body_skt:
Rectangle(20, 35)
# Fillet all the corners of the sketch.
# Alternatively, you could use RectangleRounded.
fillet(body_skt.vertices(), 1)
# Extrude the body shape upward
extrude(amount=10, taper=4)
# Reuse the sketch by accessing it explicitly
extrude(body_skt.sketch, amount=8, taper=2)
# Create symmetric fenders on Plane.YZ
with BuildSketch(Plane.YZ) as fender:
# The trapezoid has asymmetric angles (80°, 88°)
Trapezoid(18, 6, 80, 88, align=Align.MIN)
# Fillet top edge vertices (Y-direction highest group)
fillet(fender.vertices().group_by(Axis.Y)[-1], 1.5)
# Extrude the fender in both directions
extrude(amount=10.5, both=True)
# Create wheel wells with a shifted sketch on Plane.YZ
with BuildSketch(Plane.YZ.shift_origin((0, 3.5, 0))) as wheel_well:
Trapezoid(12, 4, 70, 85, align=Align.MIN)
fillet(wheel_well.vertices().group_by(Axis.Y)[-1], 2)
# Subtract the wheel well geometry
extrude(amount=10.5, both=True, mode=Mode.SUBTRACT)
# Fillet the top edges of the body
fillet(body.edges().group_by(Axis.Z)[-1], 1)
# Isolate a set of body edges and preview before filleting
body_edges = body.edges().group_by(Axis.Z)[-6]
fillet(body_edges, 0.1)
# Combine edge groups from both sides of the fender and fillet them
fender_edges = body.edges().group_by(Axis.X)[0] + body.edges().group_by(Axis.X)[-1]
fender_edges = fender_edges.group_by(Axis.Z)[1:]
fillet(fender_edges, 0.4)
# Create a sketch on the front of the truck for the grill
with BuildSketch(
Plane.XZ.offset(-body.vertices().sort_by(Axis.Y)[-1].Y - 0.5)
) as grill:
Rectangle(16, 8.5, align=(Align.CENTER, Align.MIN))
fillet(grill.vertices().group_by(Axis.Y)[-1], 1)
# Add headlights (subtractive circles)
with Locations((0, 6.5)):
with GridLocations(12, 0, 2, 1):
Circle(1, mode=Mode.SUBTRACT)
# Add air vents (subtractive slots)
with Locations((0, 3)):
with GridLocations(0, 0.8, 1, 4):
SlotOverall(10, 0.5, mode=Mode.SUBTRACT)
# Extrude the grill forward
extrude(amount=2)
# Fillet only the outer grill edges (exclude headlight/vent cuts)
grill_perimeter = body.faces().sort_by(Axis.Y)[-1].outer_wire()
fillet(grill_perimeter.edges(), 0.2)
# Create the bumper as a separate part inside the body
with BuildPart() as bumper:
# Find the midpoint of a front edge and shift slightly to position the bumper
front_cnt = body.edges().group_by(Axis.Z)[0].sort_by(Axis.Y)[-1] @ 0.5 - (0, 3)
with BuildSketch() as bumper_plan:
# Use BuildLine to draw an elliptical arc and offset
with BuildLine():
EllipticalCenterArc(front_cnt, 20, 4, start_angle=60, end_angle=120)
offset(amount=1)
make_face()
# Extrude the bumper symmetrically
extrude(amount=1, both=True)
fillet(bumper.edges(), 0.25)
# Define a joint on top of the body to connect the cab later
RigidJoint("body_top", joint_location=Location((0, -7.5, 10)))
body.part.color = truck_color
# Create the cab as an independent part to mount on the body
with BuildPart() as cab:
with BuildSketch() as cab_plan:
RectangleRounded(16, 16, 1)
# Split the sketch to work on one symmetric half
split(bisect_by=Plane.YZ)
# Extrude the cab forward and upward at an angle
extrude(amount=7, dir=(0, 0.15, 1))
fillet(cab.edges().group_by(Axis.Z)[-1].group_by(Axis.X)[1:], 1)
# Rear window
with BuildSketch(Plane.XZ.shift_origin((0, 0, 3))) as rear_window:
RectangleRounded(8, 4, 0.75)
extrude(amount=10, mode=Mode.SUBTRACT)
# Front window
with BuildSketch(Plane.XZ) as front_window:
RectangleRounded(15.2, 11, 0.75)
extrude(amount=-10, mode=Mode.SUBTRACT)
# Side windows
with BuildSketch(Plane.YZ) as side_window:
with Locations((3.5, 0)):
with GridLocations(10, 0, 2, 1):
Trapezoid(9, 5.5, 80, 100, align=(Align.CENTER, Align.MIN))
fillet(side_window.vertices().group_by(Axis.Y)[-1], 0.5)
extrude(amount=12, both=True, mode=Mode.SUBTRACT)
# Mirror to complete the cab
mirror(about=Plane.YZ)
# Define joint on cab base
RigidJoint("cab_base", joint_location=Location((0, 0, 0)))
cab.part.color = truck_color
# Attach the cab to the truck body using joints
body.joints["body_top"].connect_to(cab.joints["cab_base"])
# Show the result
show(image, body.part, cab.part)
# [End]