Skip to content

Commit 5e0cda1

Browse files
Copilotdorkmo
andcommitted
Add assembly.png and cnclayout.svg with auto-generation
Co-authored-by: dorkmo <1923070+dorkmo@users.noreply.github.com>
1 parent ae2bb64 commit 5e0cda1

File tree

7 files changed

+680
-0
lines changed

7 files changed

+680
-0
lines changed

.github/workflows/openscad-render.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,29 @@ jobs:
5656
cd LifeTrac-v25/mechanical_design
5757
mkdir -p output/{stl,dxf,renders,animations}
5858
59+
- name: Generate assembly.png and cnclayout.svg
60+
run: |
61+
cd LifeTrac-v25/mechanical_design
62+
63+
# Generate assembly.png (1024x768 matching CEB-Press example)
64+
echo "Generating assembly.png..."
65+
xvfb-run openscad -o assembly.png \
66+
--camera=3000,3000,2000,0,0,500 \
67+
--imgsize=1024,768 \
68+
--projection=p \
69+
--colorscheme=Nature \
70+
openscad/lifetrac_v25.scad
71+
72+
# Generate cnclayout.svg (2D projection for CNC cutting)
73+
echo "Generating cnclayout.svg..."
74+
xvfb-run openscad -o cnclayout.svg \
75+
--projection=o \
76+
--viewall \
77+
cnclayout.scad
78+
79+
echo "✓ assembly.png and cnclayout.svg generated successfully"
80+
ls -lh assembly.png cnclayout.svg
81+
5982
- name: Render preview images
6083
run: |
6184
cd LifeTrac-v25/mechanical_design
@@ -228,6 +251,28 @@ jobs:
228251
path: LifeTrac-v25/mechanical_design/output/animations/
229252
retention-days: 90
230253

254+
- name: Commit and push assembly.png and cnclayout.svg
255+
run: |
256+
cd LifeTrac-v25/mechanical_design
257+
git config --global user.name 'github-actions[bot]'
258+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
259+
260+
# Add the generated files
261+
git add assembly.png cnclayout.svg
262+
263+
# Check if there are changes
264+
if ! git diff --staged --quiet; then
265+
git commit -m "Update assembly.png and cnclayout.svg [skip ci]"
266+
git push --force-with-lease origin HEAD || {
267+
echo "INFO: git push failed. This is expected on PRs from forks."
268+
echo "The files are available as workflow artifacts."
269+
}
270+
else
271+
echo "No changes to assembly.png or cnclayout.svg"
272+
fi
273+
env:
274+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
275+
231276
- name: Comment on PR with results
232277
if: github.event_name == 'pull_request'
233278
uses: actions/github-script@v7

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ LifeTrac-v25/mechanical_design/output/
1212
*.jpg
1313
*.jpeg
1414

15+
# Except these specific files which should be committed
16+
!LifeTrac-v25/mechanical_design/assembly.png
17+
!LifeTrac-v25/mechanical_design/cnclayout.svg
18+
1519
# OpenSCAD cache
1620
*.csg
1721
*.ast

LifeTrac-v25/mechanical_design/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ The LifeTrac v25 is a remotely-operated compact utility loader designed to be si
1616

1717
```
1818
mechanical_design/
19+
├── assembly.png # 3D render of complete assembly (auto-generated)
20+
├── cnclayout.svg # 2D CNC cutting layout (auto-generated)
21+
├── cnclayout.scad # OpenSCAD file for CNC layout generation
1922
├── openscad/ # Main OpenSCAD design files
2023
│ └── lifetrac_v25.scad # Main assembly file
2124
├── modules/ # Reusable OpenSCAD modules
@@ -34,6 +37,23 @@ mechanical_design/
3437
└── AI_DESIGN_PROGRESS.md # AI design session tracker
3538
```
3639

40+
## Key Files
41+
42+
### assembly.png
43+
![Assembly Preview](assembly.png)
44+
45+
A 3D rendered view of the complete LifeTrac v25 assembly (1024×768px). This image is automatically generated by GitHub Actions whenever the OpenSCAD files are updated. It provides a quick visual reference of the overall design.
46+
47+
### cnclayout.svg
48+
49+
A 2D vector layout of all plate steel parts organized for CNC plasma cutting. Parts are:
50+
- Color-coded by thickness (blue = 1/4", red = 1/2")
51+
- Labeled with part numbers and descriptions
52+
- Laid out with proper spacing for cutting
53+
- All corners pre-rounded to 6.35mm radius
54+
55+
This file can be imported into CAM software (SheetCAM, etc.) for generating G-code.
56+
3757
## Quick Start
3858

3959
### Prerequisites

LifeTrac-v25/mechanical_design/SUMMARY.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,24 @@ A complete parametric 3D CAD system built from scratch:
2727
### Manufacturing Support
2828
Tools for going from design to physical parts:
2929

30+
- **Assembly Visualization**
31+
- `assembly.png` - 1024×768 3D render (auto-generated)
32+
- Shows complete machine from optimal viewing angle
33+
- Updated automatically via GitHub Actions
34+
35+
- **CNC Cutting Layout**
36+
- `cnclayout.svg` - Vector layout for plasma cutting (auto-generated)
37+
- All plate parts organized by thickness
38+
- Color-coded (blue=1/4", red=1/2")
39+
- Ready for CAM software import
40+
3041
- **GitHub Actions Workflow** - Automated rendering
3142
- Syntax validation
3243
- Multi-angle preview renders
3344
- STL generation for 3D printing
3445
- 36-frame animation
3546
- Module examples
47+
- Automatic assembly.png and cnclayout.svg generation
3648

3749
- **CNC Export System**
3850
- Individual part DXF export
36.5 KB
Loading
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// cnclayout.scad
2+
// CNC layout for all plate steel parts
3+
// Generates 2D projection for plasma cutting
4+
// Part of LifeTrac v25 OpenSCAD design
5+
6+
use <modules/plate_steel.scad>
7+
8+
// Plate thicknesses
9+
PLATE_1_4 = 6.35; // 1/4"
10+
PLATE_1_2 = 12.7; // 1/2"
11+
12+
// Layout spacing
13+
SPACING = 20; // mm between parts
14+
START_X = 10;
15+
START_Y = 10;
16+
17+
// Color coding by thickness
18+
COLOR_1_4 = "blue";
19+
COLOR_1_2 = "red";
20+
21+
// Current position tracking
22+
x_offset = START_X;
23+
y_offset = START_Y;
24+
row_height = 0;
25+
26+
module layout_part(width, height, thickness, label, x, y) {
27+
translate([x, y, 0]) {
28+
projection(cut=false) {
29+
color(thickness == PLATE_1_4 ? COLOR_1_4 : COLOR_1_2)
30+
plate_steel(width, height, thickness, 6.35);
31+
}
32+
// Part label
33+
translate([5, 5, 0])
34+
text(label, size=8, font="Liberation Sans:style=Bold");
35+
36+
// Thickness indicator
37+
translate([5, height - 15, 0])
38+
text(str(thickness == PLATE_1_4 ? "1/4\"" : "1/2\""), size=6);
39+
}
40+
}
41+
42+
// Layout all parts in rows
43+
// Row 1: Half-inch plates (wheel mounts and high-stress parts)
44+
layout_part(300, 300, PLATE_1_2, "A2-1 Wheel Mount FL", START_X, START_Y);
45+
layout_part(300, 300, PLATE_1_2, "A2-2 Wheel Mount FR", START_X + 300 + SPACING, START_Y);
46+
layout_part(300, 300, PLATE_1_2, "A2-3 Wheel Mount RL", START_X + 2*(300 + SPACING), START_Y);
47+
layout_part(300, 300, PLATE_1_2, "A2-4 Wheel Mount RR", START_X + 3*(300 + SPACING), START_Y);
48+
49+
// Row 2: Half-inch plates continued
50+
layout_part(200, 200, PLATE_1_2, "C2-1 Bucket Attach L", START_X, START_Y + 300 + SPACING);
51+
layout_part(200, 200, PLATE_1_2, "C2-2 Bucket Attach R", START_X + 200 + SPACING, START_Y + 300 + SPACING);
52+
layout_part(100, 150, PLATE_1_2, "Cyl Lug 1", START_X + 2*(200 + SPACING), START_Y + 300 + SPACING);
53+
layout_part(100, 150, PLATE_1_2, "Cyl Lug 2", START_X + 2*(200 + SPACING) + 100 + SPACING, START_Y + 300 + SPACING);
54+
layout_part(100, 150, PLATE_1_2, "Cyl Lug 3", START_X + 2*(200 + SPACING) + 2*(100 + SPACING), START_Y + 300 + SPACING);
55+
layout_part(100, 150, PLATE_1_2, "Cyl Lug 4", START_X + 2*(200 + SPACING) + 3*(100 + SPACING), START_Y + 300 + SPACING);
56+
57+
// Row 3: Quarter-inch plates (bucket)
58+
layout_part(1100, 600, PLATE_1_4, "E1-1 Bucket Bottom", START_X, START_Y + 2*(300 + SPACING));
59+
60+
// Row 4: Quarter-inch plates (bucket continued)
61+
layout_part(1100, 400, PLATE_1_4, "E1-2 Bucket Back", START_X, START_Y + 2*(300 + SPACING) + 600 + SPACING);
62+
63+
// Row 5: Quarter-inch plates (bucket sides and arms)
64+
layout_part(600, 400, PLATE_1_4, "E1-3 Bucket Side L", START_X, START_Y + 2*(300 + SPACING) + 600 + 400 + 2*SPACING);
65+
layout_part(600, 400, PLATE_1_4, "E1-4 Bucket Side R", START_X + 600 + SPACING, START_Y + 2*(300 + SPACING) + 600 + 400 + 2*SPACING);
66+
67+
// Row 6: Quarter-inch plates (arm reinforcements and deck)
68+
layout_part(150, 1200, PLATE_1_4, "C1-1 Arm Reinf L", START_X, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 3*SPACING);
69+
layout_part(150, 1200, PLATE_1_4, "C1-2 Arm Reinf R", START_X + 150 + SPACING, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 3*SPACING);
70+
71+
// Row 7: Quarter-inch plates (standing deck)
72+
layout_part(1000, 400, PLATE_1_4, "F1 Standing Deck", START_X + 2*(150 + SPACING), START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 3*SPACING);
73+
74+
// Row 8: Quarter-inch plate (control housing base)
75+
layout_part(300, 200, PLATE_1_4, "G1 Housing Base", START_X, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 1200 + 4*SPACING);
76+
77+
// Add title and legend
78+
translate([10, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 1200 + 200 + 5*SPACING, 0])
79+
text("LifeTrac v25 CNC Layout", size=16, font="Liberation Sans:style=Bold");
80+
81+
translate([10, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 1200 + 180 + 5*SPACING, 0])
82+
text("Blue = 1/4\" plate | Red = 1/2\" plate", size=10);
83+
84+
// Add cutting instructions
85+
translate([10, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 1200 + 160 + 5*SPACING, 0])
86+
text("Maintain 3mm spacing between cuts", size=8);
87+
88+
translate([10, START_Y + 2*(300 + SPACING) + 600 + 400 + 400 + 1200 + 145 + 5*SPACING, 0])
89+
text("All corners 6.35mm radius", size=8);

0 commit comments

Comments
 (0)