mirror of
https://github.com/nophead/NopSCADlib.git
synced 2025-09-06 05:12:54 +02:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
613152f589 | ||
|
d90c00d140 | ||
|
b52ca9589a | ||
|
a3ced6de45 | ||
|
1cdfe3267c | ||
|
b67cf4ce97 | ||
|
5bac2bf46d | ||
|
079168142b | ||
|
cb30f0c63d | ||
|
812fbc106c | ||
|
dd38fa6e5d | ||
|
5cdcd4ad37 | ||
|
4cb324ed37 | ||
|
eb997aa18c | ||
|
f09343a285 | ||
|
54aab027bd | ||
|
cc61a11602 | ||
|
9cf2e9d7c3 | ||
|
9da8a3cb26 | ||
|
36521cf0b9 | ||
|
f760aaa20a | ||
|
1c445385b4 | ||
|
45f3fc275f |
@@ -172,7 +172,7 @@ This is achieved by having a pair of modules: -
|
||||
//! Place inserts in the bottom of the posts and push them home with a soldering iron with a conical bit heated to 200°C.
|
||||
//
|
||||
module handle_assembly() pose([225, 0, 150], [0, 0, 14]) //! Printed part with inserts in place
|
||||
assembly("handle") {
|
||||
assembly("handle", ngb = true) {
|
||||
translate_z(handle_height())
|
||||
stl_colour(pp1_colour) vflip() handle_stl();
|
||||
|
||||
@@ -201,6 +201,9 @@ When the parent assembly is shown exploded the handle's screws will be exploded
|
||||
Note also the `pose([225, 0, 150], [0, 0, 14])` call before the `assembly()` call. This allows the sub-assembly to be posed differently in its build step but doesn't
|
||||
affect its orientation in the parent assembly. The pose parameters are the rotation and the translation taken from the GUI.
|
||||
|
||||
Setting `ngb = true` in the `assembly()` prevents the handle assembly appearing as a columun in the top level BOM in the build instructions.
|
||||
Instead its parts are merged into the parent BOM so the correct quantites are listed.
|
||||
|
||||
### Exploded diagrams
|
||||
|
||||
A lot of vitamins explode themselves when `$explode=1`. This is done with module `explode()` that can be passed a Z offset, or a 3D vector that gives the displacement
|
||||
|
@@ -2,6 +2,7 @@
|
||||
{
|
||||
"name": "base_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"count": 1,
|
||||
"assemblies": {},
|
||||
"vitamins": {
|
||||
@@ -20,6 +21,7 @@
|
||||
{
|
||||
"name": "feet_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"count": 1,
|
||||
"assemblies": {
|
||||
"base_assembly": 1
|
||||
@@ -46,6 +48,7 @@
|
||||
{
|
||||
"name": "mains_in_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"count": 1,
|
||||
"assemblies": {
|
||||
"feet_assembly": 1
|
||||
@@ -82,6 +85,7 @@
|
||||
{
|
||||
"name": "main_assembly",
|
||||
"big": null,
|
||||
"ngb": false,
|
||||
"count": 1,
|
||||
"assemblies": {
|
||||
"mains_in_assembly": 1
|
||||
|
BIN
libtest.png
BIN
libtest.png
Binary file not shown.
Before Width: | Height: | Size: 875 KiB After Width: | Height: | Size: 876 KiB |
@@ -139,9 +139,9 @@ module box_corner_profile_2D(type) { //! The 2D shape of the corner profile.
|
||||
}
|
||||
|
||||
module box_corner_profile(type) { //! Generates the corner profile STL for 3D printing.
|
||||
stl("box_corner_profile");
|
||||
|
||||
length = box_height(type) - 2 * box_margin(type);
|
||||
|
||||
stl("box_corner_profile")
|
||||
difference() {
|
||||
linear_extrude(length, center = true, convexity = 5)
|
||||
box_corner_profile_2D(type);
|
||||
@@ -209,7 +209,6 @@ module box_corner_quadrants(type, width, depth)
|
||||
}
|
||||
|
||||
module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
|
||||
stl(bottom ? "bottom_bezel" : "top_bezel");
|
||||
feet = bottom && box_feet(type);
|
||||
t = box_sheet_slot(type);
|
||||
outset = box_outset(type);
|
||||
@@ -221,6 +220,7 @@ module box_bezel(type, bottom) { //! Generates top and bottom bezel STLs
|
||||
height = box_bezel_height(type, bottom);
|
||||
foot_extension = foot_height - height;
|
||||
|
||||
stl(bottom ? "bottom_bezel" : "top_bezel")
|
||||
difference() {
|
||||
w = box_width(type);
|
||||
d = box_depth(type);
|
||||
@@ -485,7 +485,6 @@ module box_shelf_screw_positions(type, screw_positions, thickness = 0, wall = un
|
||||
}
|
||||
|
||||
module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a shelf bracket, the first optional child is a 2D cutout and the second 3D cutouts
|
||||
stl("shelf_bracket");
|
||||
w = is_undef(wall) ? box_wall(type) : wall;
|
||||
insert = box_shelf_insert(type);
|
||||
lip = 2 * insert_boss_radius(insert, w);
|
||||
@@ -513,6 +512,7 @@ module box_shelf_bracket(type, screw_positions, wall = undef) { //! Generates a
|
||||
square([lip, eps]);
|
||||
}
|
||||
|
||||
stl("shelf_bracket")
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(w)
|
||||
|
@@ -49,12 +49,12 @@ module ribbon_grommet_hole(ways, h = 50, expand = true) { //! Generate a hole fo
|
||||
}
|
||||
|
||||
module ribbon_grommet(ways, thickness) { //! Generate the STL for a printed ribbon grommet
|
||||
stl(str("ribbon_grommet_", ways, "_", thickness));
|
||||
|
||||
width = 2 * (wall + clearance) + thickness;
|
||||
slot_length = ribbon_clamp_slot(ways);
|
||||
length = slot_length + 2 * wall + 2 * overlap;
|
||||
|
||||
stl(str("ribbon_grommet_", ways, "_", thickness))
|
||||
rotate([90, 0, 0])
|
||||
union() {
|
||||
for(side = [-1, 1])
|
||||
@@ -84,13 +84,13 @@ module ribbon_grommet(ways, thickness) { //! Generate the STL for a printed ribb
|
||||
}
|
||||
|
||||
module round_grommet_top(diameter, thickness, od = undef) { //! Generate the STL for a round grommet top half
|
||||
stl(str("round_grommet_top_", round(diameter * 10), "_", thickness));
|
||||
chamfer = layer_height;
|
||||
h = wall + thickness + wall;
|
||||
r1 = diameter / 2;
|
||||
r2 = od == undef ? corrected_radius(r1) + wall : od / 2;
|
||||
r3 = r2 + overlap;
|
||||
r0 = r1 + 1;
|
||||
stl(str("round_grommet_top_", round(diameter * 10), "_", thickness))
|
||||
union() {
|
||||
rotate_extrude()
|
||||
polygon([
|
||||
@@ -113,11 +113,11 @@ module round_grommet_top(diameter, thickness, od = undef) { //! Generate the STL
|
||||
}
|
||||
|
||||
module round_grommet_bottom(diameter, od = undef) { //! Generate the STL for a round grommet bottom half
|
||||
stl(str("round_grommet_bottom_", round(diameter * 10)));
|
||||
chamfer = layer_height;
|
||||
r1 = diameter / 2;
|
||||
r2 = od == undef ? corrected_radius(r1) + wall : od / 2;
|
||||
r3 = r2 + max(overlap, wall + chamfer);
|
||||
stl(str("round_grommet_bottom_", round(diameter * 10)))
|
||||
rotate_extrude()
|
||||
polygon([
|
||||
[r2, chamfer],
|
||||
@@ -161,11 +161,11 @@ module mouse_grommet_hole(r, h = 50, z = undef, expand = wall + clearance) //! M
|
||||
function mouse_grommet_offset(r) = r + wall;
|
||||
|
||||
module mouse_grommet(r, thickness) { //! Make the STL for a mouse grommet
|
||||
stl(str("mouse_grommet_", r * 10, "_", thickness));
|
||||
|
||||
width = 2 * (wall + clearance) + thickness;
|
||||
length = 2 * r + 2 * wall + 2 * overlap;
|
||||
|
||||
stl(str("mouse_grommet_", r * 10, "_", thickness))
|
||||
rotate([90, 0, 0])
|
||||
union() {
|
||||
for(side = [-1, 1])
|
||||
|
@@ -82,7 +82,6 @@ module cam_holes(cam) {
|
||||
}
|
||||
|
||||
module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
|
||||
stl("rpi_camera_focus_ring");
|
||||
|
||||
rad = 15 / 2;
|
||||
hole_r1 = 2.5 / 2;
|
||||
@@ -93,6 +92,7 @@ module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
|
||||
x = rad / (sin(angle / 2) + cos(angle / 2));
|
||||
r = x * sin(angle / 2);
|
||||
|
||||
stl("rpi_camera_focus_ring")
|
||||
difference() {
|
||||
linear_extrude(height = thickness, convexity = 5)
|
||||
difference() {
|
||||
@@ -118,12 +118,12 @@ module rpi_camera_focus_ring_stl() { //! Focus ring the glue onto RPI lens
|
||||
}
|
||||
|
||||
module camera_back(cam) { //! Make the STL for a camera case back
|
||||
stl(str("camera_back_", cam[0]));
|
||||
pcb = camera_pcb(cam);
|
||||
back = cam_back_size(cam);
|
||||
screw = pcb_screw(pcb);
|
||||
nut = screw_nut(screw);
|
||||
|
||||
stl(str("camera_back_", cam[0]))
|
||||
translate_z(back.z)
|
||||
hflip()
|
||||
difference() {
|
||||
@@ -144,7 +144,6 @@ module camera_back(cam) { //! Make the STL for a camera case back
|
||||
}
|
||||
|
||||
module camera_front(cam, hinge = 0) { //! Make the STL for a camera case front
|
||||
stl(str("camera_front_", cam[0]));
|
||||
front = cam_front_size(cam);
|
||||
back = cam_back_size(cam);
|
||||
pcb = camera_pcb(cam);
|
||||
@@ -170,6 +169,7 @@ module camera_front(cam, hinge = 0) { //! Make the STL for a camera case front
|
||||
translate([0, (hinge ? front.x * hinge : front.y) / 2 + hinge_offset, hinge_r])
|
||||
children();
|
||||
|
||||
stl(str("camera_front_", cam[0]))
|
||||
difference() {
|
||||
union() {
|
||||
hull()
|
||||
@@ -253,10 +253,10 @@ module camera_bracket_position(cam) //! Position children at the bracket positio
|
||||
children();
|
||||
|
||||
module camera_bracket(cam) { //! Make the STL for the camera bracket
|
||||
stl(str("camera_bracket_", cam[0]));
|
||||
|
||||
t = bracket_thickness(cam);
|
||||
z = hinge_z(cam);
|
||||
|
||||
stl(str("camera_bracket_", cam[0])) union() {
|
||||
translate([hinge_h / 2, 0])
|
||||
difference() {
|
||||
hull() {
|
||||
@@ -282,9 +282,10 @@ module camera_bracket(cam) { //! Make the STL for the camera bracket
|
||||
poly_circle(screw_clearance_radius(bracket_screw));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module camera_assembly(cam, angle = 0) //! Camera case assembly
|
||||
assembly(str("camera_", cam[0])) {
|
||||
assembly(str("camera_", cam[0]), ngb = true) {
|
||||
front = cam_front_size(cam);
|
||||
screw = pcb_screw(camera_pcb(cam));
|
||||
nut = screw_nut(screw);
|
||||
|
@@ -27,7 +27,6 @@ include <../utils/core/core.scad>
|
||||
function carrier_height() = 3; //! Height of PCB carrier
|
||||
|
||||
module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
|
||||
stl("ESP12F_carrier");
|
||||
pins = 8;
|
||||
pitch1 = 2;
|
||||
pitch2 = 2.54;
|
||||
@@ -43,6 +42,7 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
|
||||
width1 = wpitch1 + hole + squeezed_wall * 2;
|
||||
width2 = wpitch2 + hole2 + squeezed_wall * 2;
|
||||
|
||||
stl("ESP12F_carrier")
|
||||
difference() {
|
||||
hull() {
|
||||
translate_z(height - eps / 2)
|
||||
@@ -65,7 +65,6 @@ module ESP12F_carrier_stl() { //! Generate the STL for an ESP12 carrier
|
||||
}
|
||||
|
||||
module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two required
|
||||
stl("TP4056_carrier");
|
||||
pitch = 2.54;
|
||||
outer_pitch = 13.9;
|
||||
inner_pitch = 7.54;
|
||||
@@ -78,6 +77,7 @@ module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two re
|
||||
width = hole + squeezed_wall * 2;
|
||||
spacing = inch(0.9);
|
||||
|
||||
stl("TP4056_carrier")
|
||||
difference() {
|
||||
hull() {
|
||||
translate_z(height - eps / 2)
|
||||
@@ -101,7 +101,6 @@ module TP4056_carrier_stl() { //! Generate the STL for an TP4056 carrier, two re
|
||||
}
|
||||
|
||||
module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two required
|
||||
stl("MT3608_carrier");
|
||||
pcb_width = 17;
|
||||
w_pitch_top = 6.81;
|
||||
w_pitch_bot = inch(0.3);
|
||||
@@ -113,6 +112,7 @@ module MT3608_carrier_stl() { //! Generate the STL for an MT3608 carrier, two re
|
||||
width = hole + 2 * wall;
|
||||
offset = (l_pitch_top - l_pitch_bot) / 2;
|
||||
|
||||
stl("MT3608_carrier")
|
||||
difference() {
|
||||
hull() {
|
||||
translate([offset, 0, height - eps / 2])
|
||||
|
@@ -72,8 +72,6 @@ module corner_block_holes(screw = def_screw) //! Place children at all the holes
|
||||
children();
|
||||
|
||||
module corner_block(screw = def_screw, name = false) { //! Generate the STL for a printed corner block
|
||||
stl(name ? name : str("corner_block", "_M", screw_radius(screw) * 20));
|
||||
|
||||
r = 1;
|
||||
cb_width = corner_block_width(screw);
|
||||
cb_height = cb_width;
|
||||
@@ -81,6 +79,8 @@ module corner_block(screw = def_screw, name = false) { //! Generate the STL for
|
||||
insert = screw_insert(screw);
|
||||
corner_rad = insert_outer_d(insert) / 2 + wall;
|
||||
offset = corner_block_hole_offset(screw);
|
||||
|
||||
stl(name ? name : str("corner_block", "_M", screw_radius(screw) * 20))
|
||||
difference() {
|
||||
hull() {
|
||||
translate([r, r])
|
||||
@@ -117,7 +117,7 @@ module corner_block(screw = def_screw, name = false) { //! Generate the STL for
|
||||
}
|
||||
|
||||
module corner_block_assembly(screw = def_screw, name = false) //! The printed block with inserts
|
||||
assembly(str("corner_block_M", 20 * screw_radius(screw))) {
|
||||
assembly(str("corner_block_M", 20 * screw_radius(screw)), ngb = true) {
|
||||
insert = screw_insert(screw);
|
||||
|
||||
stl_colour(name ? pp2_colour : pp1_colour)
|
||||
|
@@ -54,10 +54,10 @@ module door_hinge_hole_positions(dir = 0) { //! Position chidren
|
||||
}
|
||||
|
||||
module door_hinge(door_thickness) { //! Generates STL for the moving part of the hinge
|
||||
stl(str("door_hinge_", door_thickness));
|
||||
|
||||
hole_pitch = width - 10;
|
||||
|
||||
stl(str("door_hinge_", door_thickness))
|
||||
union() {
|
||||
rotate([90, 0, 0])
|
||||
linear_extrude(width, center = true)
|
||||
|
@@ -38,9 +38,9 @@ function door_latch_offset() = width / 2 + 1; //! Offset of the axle from the do
|
||||
nut_trap_depth = round_to_layer(screw_head_height(screw)) + 4 * layer_height;
|
||||
|
||||
module door_latch_stl() { //! Generates the STL for the printed part
|
||||
stl("door_latch");
|
||||
|
||||
ridge = 4;
|
||||
|
||||
stl("door_latch")
|
||||
difference() {
|
||||
union() {
|
||||
hull() {
|
||||
|
@@ -311,7 +311,7 @@ module _drag_chain_assembly(type, pos = 0, render = false) {
|
||||
//! 1. Remove the support material from the links with side cutters.
|
||||
//! 1. Clip the links together with the special ones at the ends.
|
||||
module drag_chain_assembly(type, pos = 0, render = false) //! Drag chain assembly
|
||||
assembly(str(drag_chain_name(type), "_drag_chain"), big = true)
|
||||
assembly(str(drag_chain_name(type), "_drag_chain"), big = true, ngb = true)
|
||||
if($children == 2)
|
||||
_drag_chain_assembly(type, pos, render) {
|
||||
children(0);
|
||||
|
@@ -71,7 +71,6 @@ module fixing_block_h_hole_2D(screw = def_screw) //! Position 2D child on the ho
|
||||
children();
|
||||
|
||||
module fixing_block(screw = def_screw) { //! Generate the STL
|
||||
stl(str("fixing_block_M", screw_radius(screw) * 20));
|
||||
r = 1;
|
||||
insert = screw_insert(screw);
|
||||
corner_rad = insert_outer_d(insert) / 2 + wall;
|
||||
@@ -79,6 +78,7 @@ module fixing_block(screw = def_screw) { //! Generate the STL
|
||||
fb_height = fixing_block_height(screw);
|
||||
fb_depth = fixing_block_depth(screw);
|
||||
|
||||
stl(str("fixing_block_M", screw_radius(screw) * 20))
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(fb_height, convexity = 5)
|
||||
@@ -106,7 +106,7 @@ module fixing_block(screw = def_screw) { //! Generate the STL
|
||||
}
|
||||
|
||||
module fixing_block_assembly(screw = def_screw) pose([55, 180, 25], [0, 4.8, 4.8]) //! Printed part with the inserts inserted
|
||||
assembly(str("fixing_block_M", 20 * screw_radius(screw))) {
|
||||
assembly(str("fixing_block_M", 20 * screw_radius(screw)), ngb = true) {
|
||||
translate_z(fixing_block_height(screw))
|
||||
rotate([0, 180, 0])
|
||||
stl_colour(pp1_colour) render() fixing_block(screw);
|
||||
|
@@ -65,8 +65,6 @@ module hinge_screw_positions(type) { //! Place children at the screw positions
|
||||
}
|
||||
|
||||
module hinge_male(type, female = false) { //! The half with the stationary pin
|
||||
stl(str("hinge_", female ? "fe": "", "male_", type[0]));
|
||||
|
||||
r = hinge_radius(type);
|
||||
w = hinge_width(type);
|
||||
t = hinge_thickness(type);
|
||||
@@ -85,6 +83,8 @@ module hinge_male(type, female = false) { //! The half with the stationary
|
||||
teardrop_r = kr / cos(22.5); // The corner on the teardrop
|
||||
inset = sqrt(sqr(teardrop_r + gap) - sqr(kr - t)) - kr;
|
||||
|
||||
stl(str("hinge_", female ? "fe": "", "male_", type[0]))
|
||||
union() {
|
||||
linear_extrude(t)
|
||||
difference() {
|
||||
hull() {
|
||||
@@ -117,6 +117,7 @@ module hinge_male(type, female = false) { //! The half with the stationary
|
||||
teardrop_plus(r = pr + (female ? gap : 0), h = 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module hinge_female(type) hinge_male(type, true);
|
||||
|
||||
@@ -129,7 +130,7 @@ module hinge_both(type) { //! Both parts together for printing
|
||||
}
|
||||
|
||||
module hinge_assembly(type, angle = 0)
|
||||
assembly(str("hinge_", type[0])) { //! Assembled hinge
|
||||
assembly(str("hinge_", type[0]), ngb = true) { //! Assembled hinge
|
||||
kr = hinge_knuckle_dia(type) / 2;
|
||||
hr = hinge_pin_dia(type) / 2;
|
||||
w = hinge_width(type);
|
||||
|
@@ -39,7 +39,6 @@ function foot_screw(type = foot) = type[4]; //! Screw type
|
||||
function foot_slant(type = foot) = type[5]; //! Taper angle
|
||||
|
||||
module foot(type = foot) { //! Generate STL
|
||||
stl("foot");
|
||||
h = foot_height(type);
|
||||
t = foot_thickness(type);
|
||||
r1 = washer_radius(screw_washer(foot_screw(type)));
|
||||
@@ -47,6 +46,7 @@ module foot(type = foot) { //! Generate STL
|
||||
r2 = r3 - h * tan(foot_slant(type));
|
||||
r = foot_rad(type);
|
||||
|
||||
stl("foot")
|
||||
union() {
|
||||
rotate_extrude(convexity = 3) {
|
||||
hull() {
|
||||
@@ -93,7 +93,6 @@ module foot_assembly(t = 0, type = foot, flip = false) { //! Assembly with faste
|
||||
}
|
||||
|
||||
module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
|
||||
stl("insert_foot");
|
||||
h = foot_height(type);
|
||||
r3 = foot_diameter(type) / 2;
|
||||
r2 = r3 - h * tan(foot_slant(type));
|
||||
@@ -103,6 +102,7 @@ module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
|
||||
h2 = insert_hole_length(insert);
|
||||
r4 = insert_hole_radius(insert);
|
||||
r5 = r4 + 1;
|
||||
stl("insert_foot")
|
||||
union() {
|
||||
rotate_extrude() {
|
||||
union() {
|
||||
@@ -132,7 +132,7 @@ module insert_foot(type = insert_foot) { //! Generate STL for foot with insert
|
||||
//! Place the insert in the bottom of the foot and push home with a soldering iron with a conical bit heated to 200°C.
|
||||
//
|
||||
module insert_foot_assembly(type = insert_foot) //! Printed part with insert in place
|
||||
assembly("insert_foot") {
|
||||
assembly("insert_foot", ngb = true) {
|
||||
screw = foot_screw(type);
|
||||
insert = screw_insert(screw);
|
||||
|
||||
|
@@ -46,8 +46,6 @@ module handle_holes(h = 100) //! Drills holes for the screws
|
||||
drill(screw_clearance_radius(screw), h);
|
||||
|
||||
module handle_stl() { //! generate the STL
|
||||
stl("handle");
|
||||
|
||||
module end(end)
|
||||
translate([end * pitch / 2, 0])
|
||||
rotate_extrude()
|
||||
@@ -59,6 +57,7 @@ module handle_stl() { //! generate the STL
|
||||
square([dia / 2 + 1, dia + 1]);
|
||||
}
|
||||
|
||||
stl("handle")
|
||||
translate_z(dia / 2)
|
||||
union() {
|
||||
hull() {
|
||||
@@ -81,7 +80,7 @@ module handle_stl() { //! generate the STL
|
||||
//! Place inserts in the bottom of the posts and push them home with a soldering iron with a conical bit heated to 200°C.
|
||||
//
|
||||
module handle_assembly() pose([225, 0, 150], [0, 0, 14]) //! Printed part with inserts in place
|
||||
assembly("handle") {
|
||||
assembly("handle", ngb = true) {
|
||||
translate_z(handle_height())
|
||||
stl_colour(pp1_colour) vflip() handle_stl();
|
||||
|
||||
|
@@ -66,11 +66,10 @@ module pcb_mount_washer_stl() //! A plastic washer to clamp a PCB
|
||||
pcb_mount_ring();
|
||||
|
||||
module pcb_mount(pcb, height = 5, washers = true) { //! Make the STL of a pcb mount for the specified PCB.
|
||||
stl(str("pcb_mount_", pcb[0], "_", height));
|
||||
|
||||
y_pitch = pcb_width(pcb) > 4 * pillar_r + 4 ? pillar_r + 1
|
||||
: pcb_width(pcb) / 2 + frame_w + 1 + pillar_r;
|
||||
|
||||
stl(str("pcb_mount_", pcb[0], "_", height)) union() {
|
||||
if(washers)
|
||||
for(x = [-1, 1], y = [-1, 1])
|
||||
translate([x * (pillar_r + 1), y * y_pitch, 0])
|
||||
@@ -96,6 +95,7 @@ module pcb_mount(pcb, height = 5, washers = true) { //! Make the STL of a pcb mo
|
||||
square([pcb_length(pcb) + 2 * clearance, pcb_width(pcb) + 2 * clearance], center = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module pcb_mount_assembly(pcb, thickness, height = 5) { //! A PCB mount assembly with fasteners
|
||||
translate_z(height)
|
||||
|
@@ -129,8 +129,9 @@ module pbox_outer_shape(type) //! 2D outer shape of the box
|
||||
offset(pbox_wall(type) / 2) pbox_mid_shape(type);
|
||||
|
||||
module pbox_base(type) { //! Generate the STL for the base
|
||||
stl(str(pbox_name(type),"_base"));
|
||||
t = pbox_base(type);
|
||||
|
||||
stl(str(pbox_name(type),"_base"))
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(t)
|
||||
@@ -149,8 +150,6 @@ module pbox_base(type) { //! Generate the STL for the base
|
||||
}
|
||||
|
||||
module pbox(type) { //! Generate the STL for the main case
|
||||
stl(pbox_name(type));
|
||||
|
||||
height = pbox_height(type);
|
||||
total_height = pbox_total_height(type);
|
||||
top_thickness = pbox_top(type);
|
||||
@@ -159,6 +158,7 @@ module pbox(type) { //! Generate the STL for the main case
|
||||
ledge_inset = base_outset - base_overlap;
|
||||
ledge_h = pbox_base(type) ? (ledge_outset - ledge_inset) * 2 : 0;
|
||||
|
||||
stl(pbox_name(type))
|
||||
difference() {
|
||||
union() {
|
||||
linear_extrude(total_height)
|
||||
|
@@ -93,7 +93,6 @@ module printed_pulley(type) { //! Draw a printable pulley
|
||||
or = pulley_od(type) / 2;
|
||||
screw_z = pulley_screw_z(type);
|
||||
|
||||
stl(str("printed_pulley_", type[0]));
|
||||
|
||||
module core() {
|
||||
translate_z(pulley_hub_length(type) + ft)
|
||||
@@ -129,6 +128,7 @@ module printed_pulley(type) { //! Draw a printable pulley
|
||||
circle(d = pulley_bore(type));
|
||||
}
|
||||
|
||||
stl(str("printed_pulley_", type[0]))
|
||||
translate_z(printed_pulley_inverted(type) ? - hl : 0) {
|
||||
// hub
|
||||
if(hl)
|
||||
@@ -180,7 +180,7 @@ module printed_pulley(type) { //! Draw a printable pulley
|
||||
}
|
||||
|
||||
module printed_pulley_assembly(type, colour = pp1_colour) //! Draw a printed pulley with its grub screws in place
|
||||
assembly(str("printed_pulley_", type[0])) {
|
||||
assembly(str("printed_pulley_", type[0]), ngb = true) {
|
||||
translate_z(pulley_offset(type)) {
|
||||
stl_colour(colour)
|
||||
if(printed_pulley_inverted(type))
|
||||
|
@@ -79,8 +79,6 @@ module psu_shroud_holes(type, cable_d, cables = 1) {
|
||||
}
|
||||
|
||||
module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file for a specified ssr and cable
|
||||
stl(str("psu_shroud_", name));
|
||||
|
||||
extent = psu_shroud_extent(type);
|
||||
depth = psu_shroud_depth(type);
|
||||
width = psu_shroud_width(type);
|
||||
@@ -109,6 +107,7 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
|
||||
}
|
||||
}
|
||||
|
||||
stl(str("psu_shroud_", name)) {
|
||||
// base and sides
|
||||
translate([centre_x, -centre_y]) {
|
||||
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
|
||||
@@ -141,9 +140,10 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
|
||||
rotate($side * 90)
|
||||
insert_lug(insert, wall, counter_bore);
|
||||
}
|
||||
}
|
||||
|
||||
module psu_shroud_assembly(type, cable_d, name, cables = 1) //! The printed parts with inserts fitted
|
||||
assembly(str("PSU_shroud_", name)) {
|
||||
assembly(str("PSU_shroud_", name), ngb = true) {
|
||||
|
||||
translate_z(psu_shroud_height(type))
|
||||
vflip()
|
||||
|
@@ -47,7 +47,6 @@ module ribbon_clamp_holes(ways, h = 20, screw = screw) //! Drill screw holes
|
||||
|
||||
module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of ways
|
||||
screw_d = screw_radius(screw) * 2;
|
||||
stl(str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : ""));
|
||||
|
||||
pitch = ribbon_clamp_hole_pitch(ways, screw);
|
||||
d = ribbon_clamp_width(screw);
|
||||
@@ -55,6 +54,7 @@ module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of
|
||||
t = round_to_layer(ribbon_clamp_slot_depth() + wall);
|
||||
insert = screw_insert(screw);
|
||||
|
||||
stl(str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : ""))
|
||||
difference() {
|
||||
union() {
|
||||
hull() {
|
||||
@@ -82,7 +82,7 @@ module ribbon_clamp(ways, screw = screw) { //! Generate STL for given number of
|
||||
}
|
||||
|
||||
module ribbon_clamp_assembly(ways, screw = screw) pose([55, 180, 25]) //! Printed part with inserts in place
|
||||
assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : "")) {
|
||||
assembly(let(screw_d = screw_radius(screw) * 2)str("ribbon_clamp_", ways, screw_d != 3 ? str("_", screw_d) : ""), ngb = true) {
|
||||
h = ribbon_clamp_height(screw);
|
||||
insert = screw_insert(screw);
|
||||
|
||||
|
@@ -34,12 +34,11 @@ knob_height = knob_stem_h + knob_thickness;
|
||||
function knob_height() = knob_height;
|
||||
|
||||
module screw_knob(screw) { //! Generate the STL for a knob to fit the specified hex screw
|
||||
stl(str("screw_knob_M", screw_radius(screw) * 20));
|
||||
|
||||
knob_stem_r = nut_trap_radius(screw_nut(screw)) + knob_wall;
|
||||
|
||||
function wave(a) = knob_r + sin(a * knob_waves) * knob_wave;
|
||||
|
||||
stl(str("screw_knob_M", screw_radius(screw) * 20))
|
||||
union() {
|
||||
render() difference() {
|
||||
cylinder(r = knob_stem_r, h = knob_thickness + knob_stem_h);
|
||||
@@ -59,7 +58,7 @@ module screw_knob(screw) { //! Generate the STL for a knob to fit the specified
|
||||
|
||||
//! Place the screw through the printed part
|
||||
module screw_knob_assembly(screw, length) //! Assembly with the screw in place
|
||||
assembly(str("screw_knob_M", 20 * screw_radius(screw), "_", length)) {
|
||||
assembly(str("screw_knob_M", 20 * screw_radius(screw), "_", length), ngb = true) {
|
||||
translate_z(knob_height)
|
||||
vflip()
|
||||
stl_colour(pp1_colour) screw_knob(screw);
|
||||
|
@@ -41,7 +41,6 @@ height = base_thickness + box_height;
|
||||
function socket_box_depth() = height; //! Outside depth of the backbox
|
||||
|
||||
module socket_box(type) { //! Generate STL of the backbox for the specified socket
|
||||
stl(str("socket_box_",type[0]));
|
||||
|
||||
screw = mains_socket_screw(type);
|
||||
screw_clearance_radius = screw_clearance_radius(screw);
|
||||
@@ -51,6 +50,7 @@ module socket_box(type) { //! Generate STL of the backbox for the specified sock
|
||||
insert_boss = mains_socket_insert_boss(type);
|
||||
insert_hole_radius = insert_hole_radius(insert);
|
||||
|
||||
stl(str("socket_box_",type[0]))
|
||||
difference() {
|
||||
linear_extrude(height, convexity = 5)
|
||||
face_plate(type);
|
||||
|
@@ -61,14 +61,14 @@ module ssr_shroud_holes(type, cable_d) { //! Drill the screw and ziptie holes
|
||||
}
|
||||
|
||||
module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a specified ssr and cable
|
||||
stl(str("ssr_shroud_", name));
|
||||
|
||||
width = ssr_shroud_width(type);
|
||||
depth = ssr_length(type) / 3 + ssr_shroud_extent(type, cable_d);
|
||||
height = ssr_shroud_height(type);
|
||||
cable_x = ssr_shroud_cable_x(type, cable_d);
|
||||
center_x = -ssr_length(type) / 6 - depth / 2;
|
||||
|
||||
|
||||
stl(str("ssr_shroud_", name)) {
|
||||
// base and sides
|
||||
translate([center_x, 0]) {
|
||||
rounded_rectangle([depth - eps, width - eps, top], rad, center = false);
|
||||
@@ -105,9 +105,10 @@ module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a spec
|
||||
rotate($side * 90)
|
||||
insert_lug(insert, wall, counter_bore);
|
||||
}
|
||||
}
|
||||
|
||||
module ssr_shroud_assembly(type, cable_d, name) //! The printed parts with inserts fitted
|
||||
assembly(str("SSR_shroud_", name)) {
|
||||
assembly(str("SSR_shroud_", name), ngb = true) {
|
||||
|
||||
translate_z(ssr_shroud_height(type))
|
||||
vflip()
|
||||
|
@@ -75,11 +75,10 @@ module strap_holes(length, type = strap, h = 100) //! The panel cut outs
|
||||
strap_boss_shape(type);
|
||||
|
||||
module strap(length, type = strap) { //! Generate the STL for the rubber strap
|
||||
stl("strap");
|
||||
|
||||
len = length - 2 * (wall + clearance);
|
||||
w = strap_width(type);
|
||||
|
||||
stl("strap")
|
||||
linear_extrude(strap_thickness(type), convexity = 3)
|
||||
difference() {
|
||||
rounded_square([len, w], w / 2 - eps);
|
||||
@@ -99,8 +98,6 @@ module strap(length, type = strap) { //! Generate the STL for the rubber strap
|
||||
}
|
||||
|
||||
module strap_end(type = strap) { //! Generate the STL for end piece
|
||||
stl("strap_end");
|
||||
|
||||
z1 = strap_height(type) - strap_thickness(type) - clearance;
|
||||
z2 = strap_height(type) + strap_key(type);
|
||||
r1 = strap_boss_r(type) - 1;
|
||||
@@ -121,6 +118,7 @@ module strap_end(type = strap) { //! Generate the STL for end piece
|
||||
circle(r1);
|
||||
}
|
||||
|
||||
stl("strap_end")
|
||||
union() {
|
||||
linear_extrude(z1)
|
||||
with_hole()
|
||||
@@ -162,7 +160,7 @@ module strap_end(type = strap) { //! Generate the STL for end piece
|
||||
//! * Place the insert into the hole and push home with a soldering iron with a tapered bit heated to 200°C.
|
||||
//
|
||||
module strap_end_assembly(type = strap)
|
||||
assembly("strap_end") {
|
||||
assembly("strap_end", ngb = true) {
|
||||
stl_colour(pp1_colour)
|
||||
strap_end(type);
|
||||
|
||||
|
36
readme.md
36
readme.md
@@ -288,6 +288,8 @@ Models of radial blowers.
|
||||
| `blower_screw_holes(type)` | List of XY coordinates of the screw holes |
|
||||
| `blower_top(type)` | Thickness of the top |
|
||||
| `blower_wall(type)` | Side wall thickness |
|
||||
| `blower_wall_left(type)` | Left side wall thickness |
|
||||
| `blower_wall_right(type)` | Right wall thickness (for square fans) |
|
||||
| `blower_width(type)` | Width of enclosing rectangle |
|
||||
|
||||
### Functions
|
||||
@@ -311,10 +313,12 @@ Models of radial blowers.
|
||||
| 1 | `blower(PE4020)` | Blower Pengda Technology 4020 |
|
||||
| 1 | `blower(RB5015)` | Blower Runda RB5015 |
|
||||
| 4 | `screw(M2_cap_screw, 8)` | Screw M2 cap x 8mm |
|
||||
| 2 | `screw(M2_cap_screw, 10)` | Screw M2 cap x 10mm |
|
||||
| 3 | `screw(M3_cap_screw, 20)` | Screw M3 cap x 20mm |
|
||||
| 2 | `screw(M4_cap_screw, 25)` | Screw M4 cap x 25mm |
|
||||
| 1 | `blower(BL30x10)` | Square radial fan 3010 |
|
||||
| 1 | `blower(BL40x10)` | Square radial fan 4010 |
|
||||
| 4 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
|
||||
| 6 | `washer(M2_washer)` | Washer M2 x 5mm x 0.3mm |
|
||||
| 3 | `washer(M3_washer)` | Washer M3 x 7mm x 0.5mm |
|
||||
| 2 | `washer(M4_washer)` | Washer M4 x 9mm x 0.8mm |
|
||||
|
||||
@@ -2666,11 +2670,11 @@ Linear rails with carriages.
|
||||
| `carriage_length(type)` | Overall length |
|
||||
| `carriage_pitch_x(type)` | Screw hole x pitch |
|
||||
| `carriage_pitch_y(type)` | Screw hole y pitch |
|
||||
| `carriage_rail(type)` | Rail type |
|
||||
| `carriage_screw(type)` | Carriage screw type |
|
||||
| `carriage_width(type)` | Width of carriage |
|
||||
| `rail_bore(type)` | Counter bore diameter for screw head |
|
||||
| `rail_bore_depth(type)` | Counter bore depth |
|
||||
| `rail_carriage(type)` | Carriage type |
|
||||
| `rail_end(type)` | Minimum distance screw can be from the end |
|
||||
| `rail_end_screw(type)` | Screw used for ends only (Countersink used for better location) |
|
||||
| `rail_groove_offset(type)` | Offset of centre of groove from top of rail |
|
||||
@@ -2686,17 +2690,17 @@ Linear rails with carriages.
|
||||
|:--- |:--- |
|
||||
| `carriage_screw_depth(type)` | Carriage thread depth |
|
||||
| `carriage_size(type)` | Size of carriage |
|
||||
| `carriage_travel(type, rail_length)` | How far the carriage can travel on a given length rail |
|
||||
| `rail_holes(type, length)` | Number of holes in a rail given its `length` |
|
||||
| `rail_screw_height(type, screw)` | Position screw taking into account countersink into counterbored hole |
|
||||
| `rail_travel(type, length)` | How far the carriage can travel |
|
||||
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `carriage(type, rail, end_colour = grey(20)` | Draw the specified carriage |
|
||||
| `carriage(type, end_colour = grey(20)` | Draw the specified carriage |
|
||||
| `carriage_hole_positions(type)` | Position children over screw holes |
|
||||
| `rail(type, length, colour = grey(90)` | Draw the specified rail |
|
||||
| `rail_assembly(type, length, pos, carriage_end_colour = grey(20)` | Rail and carriage assembly |
|
||||
| `rail_assembly(carriage, length, pos, carriage_end_colour = grey(20)` | Rail and carriage assembly |
|
||||
| `rail_hole_positions(type, length, first = 0, screws = 100, both_ends = true)` | Position children over screw holes |
|
||||
| `rail_screws(type, length, thickness, screws = 100, index_screws = undef)` | Place screws in the rail |
|
||||
|
||||
@@ -2705,8 +2709,7 @@ Linear rails with carriages.
|
||||
### Vitamins
|
||||
| Qty | Module call | BOM entry |
|
||||
| ---:|:--- |:---|
|
||||
| 1 | `rail(MGN12, 200)` | Linear rail MGN12 x 200mm |
|
||||
| 1 | `rail(MGN12H, 200)` | Linear rail MGN12H x 200mm |
|
||||
| 2 | `rail(MGN12, 200)` | Linear rail MGN12 x 200mm |
|
||||
| 1 | `rail(MGN15, 200)` | Linear rail MGN15 x 200mm |
|
||||
| 1 | `rail(MGN5, 200)` | Linear rail MGN5 x 200mm |
|
||||
| 1 | `rail(MGN7, 200)` | Linear rail MGN7 x 200mm |
|
||||
@@ -3809,7 +3812,7 @@ Veroboard with mounting holes, track breaks, removed tracks, solder points and c
|
||||
| `vero_mounting_hole_positions(type)` | Positions children at the mounting holes |
|
||||
| `vero_mounting_holes(type, h = 100)` | Drill mounting holes in a panel |
|
||||
| `veroboard(type)` | Draw specified veroboard with missing tracks and track breaks |
|
||||
| `veroboard_assembly(type, height, thickness, flip = false)` | Draw the assembly with components and fasteners in place |
|
||||
| `veroboard_assembly(type, height, thickness, flip = false, ngb = false)` | Draw the assembly with components and fasteners in place |
|
||||
|
||||

|
||||
|
||||
@@ -6003,9 +6006,16 @@ Assembly views shown in the instructions can be large or small and this is deduc
|
||||
parts are used.
|
||||
This heuristic isn't always correct, so the default can be overridden by setting the `big` parameter of `assembly` to `true` or `false`.
|
||||
|
||||
Setting the `ngb` parameter of `assembly` to `true` removes its column from the global BOM and merges it parts into its parent assembly column of the global BOM.
|
||||
This is to prevent the global BOM page becoming too wide in large projects by having it include just the major assemblies.
|
||||
|
||||
The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
|
||||
The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
|
||||
|
||||
If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
|
||||
it with code.
|
||||
This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
|
||||
|
||||
[utils/core/bom.scad](utils/core/bom.scad) Implementation.
|
||||
|
||||
[tests/BOM.scad](tests/BOM.scad) Code for this example.
|
||||
@@ -6022,7 +6032,7 @@ The resulting flat BOM is shown but heirachical BOMs are also generated for real
|
||||
### Modules
|
||||
| Module | Description |
|
||||
|:--- |:--- |
|
||||
| `assembly(name, big = undef)` | Name an assembly that will appear on the BOM, there needs to a module named `<name>_assembly` to make it. `big` can force big or small assembly diagrams. |
|
||||
| `assembly(name, big = undef, ngb = false)` | Name an assembly that will appear on the BOM, there needs to a module named `<name>_assembly` to make it. `big` can force big or small assembly diagrams. |
|
||||
| `dxf(name)` | Name a dxf that will appear on the BOM, there needs to a module named `<name>_dxf` to make it |
|
||||
| `explode(d, explode_children = false, offset = [0,0,0])` | Explode children by specified Z distance or vector `d`, option to explode grand children |
|
||||
| `hidden()` | Make item invisible, except on the BOM |
|
||||
@@ -6034,7 +6044,9 @@ The resulting flat BOM is shown but heirachical BOMs are also generated for real
|
||||
| `pose_vflip(exploded = undef)` | Pose an STL or assembly for rendering to png by flipping around the X axis, `exploded = true for` just the exploded view or `false` for unexploded only. |
|
||||
| `stl(name)` | Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it |
|
||||
| `stl_colour(colour = pp1_colour, alpha = 1)` | Colour an stl where it is placed in an assembly. `alpha` can be used to make it appear transparent. |
|
||||
| `vitamin(description)` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "wigit(42): Type 42 widget" |
|
||||
| `use_dxf(name)` | Import a DXF to make a build panel |
|
||||
| `use_stl(name)` | Import an STL to make a build platter |
|
||||
| `vitamin(description)` | Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "widget(42): Widget size 42" |
|
||||
|
||||

|
||||
|
||||
@@ -6061,9 +6073,9 @@ The resulting flat BOM is shown but heirachical BOMs are also generated for real
|
||||
### Assemblies
|
||||
| Qty | Name |
|
||||
| ---:|:--- |
|
||||
| 1 | widget_assembly |
|
||||
| 1 | widget_base_assembly |
|
||||
| 1 | widget_top_assembly |
|
||||
| 1 | widgit_base_assembly |
|
||||
| 1 | wigdit_assembly |
|
||||
|
||||
|
||||
<a href="#top">Top</a>
|
||||
|
@@ -60,6 +60,7 @@ class BOM:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.big = None
|
||||
self.ngb = False
|
||||
self.count = 1
|
||||
self.vitamins = {}
|
||||
self.printed = {}
|
||||
@@ -73,6 +74,7 @@ class BOM:
|
||||
return {
|
||||
"name" : self.name,
|
||||
"big" : self.big,
|
||||
"ngb" : self.ngb,
|
||||
"count" : self.count,
|
||||
"assemblies" : assemblies,
|
||||
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
|
||||
|
@@ -72,10 +72,11 @@ def make_parts(target, part_type, parts = None):
|
||||
#
|
||||
# Decide which files to make
|
||||
#
|
||||
all_parts = bom_to_parts(bom_dir, part_type)
|
||||
if parts:
|
||||
targets = list(parts) #copy the list so we dont modify the list passed in
|
||||
else:
|
||||
targets = bom_to_parts(bom_dir, part_type)
|
||||
targets = list(all_parts)
|
||||
for file in os.listdir(target_dir):
|
||||
if file.endswith('.' + part_type):
|
||||
if not file in targets:
|
||||
@@ -150,4 +151,4 @@ def make_parts(target, part_type, parts = None):
|
||||
for part in targets:
|
||||
print("Could not find a module called", part[:-4] + module_suffix, "to make", part)
|
||||
usage(part_type)
|
||||
times.print_times()
|
||||
times.print_times(all_parts)
|
||||
|
@@ -72,7 +72,9 @@ def plateup(target, part_type, usage = None):
|
||||
changed = check_deps(part_file, dname)
|
||||
if changed:
|
||||
print(changed)
|
||||
openscad.run("-D$bom=1", "-d", dname, "-o", part_file, src_file)
|
||||
target_def = ['-D$target="%s"' % target] if target else []
|
||||
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
|
||||
openscad.run_list(["-D$bom=1"] + target_def + cwd_def + ["-d", dname, "-o", part_file, src_file])
|
||||
if part_type == 'stl':
|
||||
c14n_stl.canonicalise(part_file)
|
||||
log_name = 'openscad.log'
|
||||
|
@@ -52,23 +52,34 @@ def add_time(name, start):
|
||||
del times[name.lower()]
|
||||
times[name] = round(time.time() - start, 3)
|
||||
|
||||
def print_times():
|
||||
write_times()
|
||||
def print_times(files = None):
|
||||
sorted_times = sorted(times.items(), key=lambda kv: kv[1])
|
||||
total = 0
|
||||
old_total = 0
|
||||
for entry in sorted_times:
|
||||
colour = Fore.WHITE
|
||||
key = entry[0]
|
||||
if files and not key in files:
|
||||
del times[key]
|
||||
else:
|
||||
new = entry[1]
|
||||
delta = 0
|
||||
colour = Fore.WHITE
|
||||
if key in last_times:
|
||||
old = last_times[key]
|
||||
old_total += old
|
||||
delta = new - old
|
||||
if delta > 0.3:
|
||||
colour = Fore.RED
|
||||
if delta < -0.3:
|
||||
colour = Fore.GREEN
|
||||
print(colour + "%5.1f %5.1f %s" % (new, delta, key))
|
||||
print(colour + "%6.1f %5.1f %s" % (new, delta, key))
|
||||
total += new
|
||||
write_times()
|
||||
if sorted_times:
|
||||
print(Fore.WHITE + "%5.1f" % total)
|
||||
colour = Fore.WHITE
|
||||
delta = total - old_total
|
||||
if delta > 1:
|
||||
colour = Fore.RED
|
||||
if delta < -1:
|
||||
colour = Fore.GREEN
|
||||
print(colour + "%6.1f %5.1f TOTAL%s" % (total, delta, Fore.WHITE))
|
||||
|
@@ -36,6 +36,7 @@ import blurb
|
||||
import bom
|
||||
import shutil
|
||||
import re
|
||||
import copy
|
||||
from colorama import Fore
|
||||
|
||||
def is_assembly(s):
|
||||
@@ -101,6 +102,27 @@ def usage():
|
||||
print("\nusage:\n\t views [target_config] [<name1>_assembly] ... [<nameN>_assembly] - Create assembly images and readme.")
|
||||
sys.exit(1)
|
||||
|
||||
types = ["vitamins", "printed", "routed"]
|
||||
|
||||
def merged(bom):
|
||||
bom = copy.deepcopy(bom)
|
||||
for aname in bom["assemblies"]:
|
||||
count = bom["assemblies"][aname]
|
||||
for ass in flat_bom:
|
||||
if ass['name'] == aname and ass['ngb']:
|
||||
merged_assembly = merged(ass)
|
||||
total = ass['count']
|
||||
for t in types:
|
||||
for thing in merged_assembly[t]:
|
||||
items = merged_assembly[t][thing]['count'] * count // total
|
||||
if thing in bom[t]:
|
||||
bom[t][thing]['count'] += items
|
||||
else:
|
||||
bom[t][thing] = merged_assembly[t][thing]
|
||||
bom[t][thing]['count'] = items
|
||||
break
|
||||
return bom
|
||||
|
||||
def views(target, do_assemblies = None):
|
||||
done_assemblies = []
|
||||
#
|
||||
@@ -137,6 +159,7 @@ def views(target, do_assemblies = None):
|
||||
# Find all the scad files
|
||||
#
|
||||
main_blurb = None
|
||||
pngs = []
|
||||
for dir in source_dirs(bom_dir):
|
||||
if os.path.isdir(dir):
|
||||
for filename in os.listdir(dir):
|
||||
@@ -163,15 +186,21 @@ def views(target, do_assemblies = None):
|
||||
if not "blurb" in ass:
|
||||
ass["blurb"] = blurb.scrape_module_blurb(lines[:line_no])
|
||||
break
|
||||
if not do_assemblies or real_name in do_assemblies:
|
||||
|
||||
#
|
||||
# Run openscad on the created file
|
||||
#
|
||||
dname = deps_name(deps_dir, filename)
|
||||
for explode in [0, 1]:
|
||||
#
|
||||
# Generate png name
|
||||
#
|
||||
png_name = target_dir + '/' + real_name + '.png'
|
||||
if not explode:
|
||||
png_name = png_name.replace('_assembly', '_assembled')
|
||||
pngs.append(png_name)
|
||||
|
||||
if not do_assemblies or real_name in do_assemblies:
|
||||
changed = check_deps(png_name, dname)
|
||||
changed = times.check_have_time(changed, png_name)
|
||||
changed = options.have_changed(changed, png_name)
|
||||
@@ -186,7 +215,9 @@ def views(target, do_assemblies = None):
|
||||
f.write("use <%s/%s>\n" % (dir, filename))
|
||||
f.write("%s();\n" % module);
|
||||
t = time.time()
|
||||
openscad.run_list(options.list() + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
|
||||
target_def = ['-D$target="%s"' % target] if target else []
|
||||
cwd_def = ['-D$cwd="%s"' % os.getcwd().replace('\\', '/')]
|
||||
openscad.run_list(options.list() + target_def + cwd_def + ["-D$pose=1", "-D$explode=%d" % explode, colour_scheme, "--projection=p", "--imgsize=4096,4096", "--autocenter", "--viewall", "-d", dname, "-o", tmp_name, png_maker_name]);
|
||||
times.add_time(png_name, t)
|
||||
do_cmd(["magick", tmp_name, "-trim", "-resize", "1004x1004", "-bordercolor", background, "-border", "10", tmp_name])
|
||||
update_image(tmp_name, png_name)
|
||||
@@ -242,8 +273,8 @@ def views(target, do_assemblies = None):
|
||||
#
|
||||
# Global BOM
|
||||
#
|
||||
global_bom = [merged(ass) for ass in flat_bom if not ass['ngb']]
|
||||
print('<a name="Parts_list"></a>\n## Parts list', file = doc_file)
|
||||
types = ["vitamins", "printed", "routed"]
|
||||
headings = {"vitamins" : "vitamins", "printed" : "3D printed parts", "routed" : "CNC routed parts"}
|
||||
things = {}
|
||||
for t in types:
|
||||
@@ -255,19 +286,22 @@ def views(target, do_assemblies = None):
|
||||
things[t][thing] += ass[t][thing]["count"]
|
||||
else:
|
||||
things[t][thing] = ass[t][thing]["count"]
|
||||
for ass in flat_bom:
|
||||
for ass in global_bom:
|
||||
name = titalise(ass["name"][:-9]).replace(' ',' ')
|
||||
if ass["count"] > 1:
|
||||
name = "%d x %s" % (ass["count"], name)
|
||||
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">%s</span> ' % name, file = doc_file, end = '')
|
||||
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |', file = doc_file)
|
||||
print(('|---:' * len(flat_bom) + '|---:|:---|'), file = doc_file)
|
||||
print(('|---:' * len(global_bom) + '|---:|:---|'), file = doc_file)
|
||||
|
||||
for t in types:
|
||||
if things[t]:
|
||||
totals = {}
|
||||
heading = headings[t][0:1].upper() + headings[t][1:]
|
||||
print(('| ' * len(flat_bom) + '| | **%s** |') % heading, file = doc_file)
|
||||
grand_total2 = 0
|
||||
heading = headings[t][0].upper() + headings[t][1:]
|
||||
print(('| ' * len(global_bom) + '| | **%s** |') % heading, file = doc_file)
|
||||
for thing in sorted(things[t], key = lambda s: s.split(":")[-1]):
|
||||
for ass in flat_bom:
|
||||
for ass in global_bom:
|
||||
count = ass[t][thing]["count"] if thing in ass[t] else 0
|
||||
print('| %s ' % pad(count if count else '.', 2, 1), file = doc_file, end = '')
|
||||
name = ass["name"]
|
||||
@@ -275,15 +309,17 @@ def views(target, do_assemblies = None):
|
||||
totals[name] += count
|
||||
else:
|
||||
totals[name] = count
|
||||
grand_total2 += count
|
||||
print('| %s | %s |' % (pad(things[t][thing], 2, 1), pad(thing.split(":")[-1], 2)), file = doc_file)
|
||||
|
||||
grand_total = 0
|
||||
for ass in flat_bom:
|
||||
for ass in global_bom:
|
||||
name = ass["name"]
|
||||
total = totals[name] if name in totals else 0
|
||||
print('| %s ' % pad(total if total else '.', 2, 1), file = doc_file, end = '')
|
||||
grand_total += total
|
||||
print("| %s | %s |" % (pad(grand_total, 2, 1), pad('Total %s count' % headings[t], 2)), file = doc_file)
|
||||
assert grand_total == grand_total2
|
||||
print(file = doc_file)
|
||||
if len(blurbs) > 2:
|
||||
print(blurbs[2], file = doc_file)
|
||||
@@ -376,16 +412,16 @@ def views(target, do_assemblies = None):
|
||||
#
|
||||
# Convert to HTML
|
||||
#
|
||||
html_name = 'readme.html'
|
||||
html_name = top_dir + 'readme.html'
|
||||
t = time.time()
|
||||
with open(top_dir + html_name, "wt") as html_file:
|
||||
with open(html_name, "wt") as html_file:
|
||||
do_cmd(("python -m markdown -x tables -x sane_lists " + doc_name).split(), html_file)
|
||||
times.add_time(top_dir + html_name, t)
|
||||
times.print_times()
|
||||
times.add_time(html_name, t)
|
||||
times.print_times(pngs + [html_name])
|
||||
#
|
||||
# Make the printme.html by replacing empty spans that invisbly mark the page breaks by page break divs.
|
||||
#
|
||||
with open(top_dir + 'readme.html', 'rt') as src:
|
||||
with open(html_name, 'rt') as src:
|
||||
lines = src.readlines()
|
||||
|
||||
i = 0
|
||||
|
@@ -43,9 +43,8 @@ module widget(thickness) {
|
||||
}
|
||||
}
|
||||
|
||||
module widgit_stl() {
|
||||
stl("widget");
|
||||
|
||||
module widget_stl() {
|
||||
stl("widget")
|
||||
union() {
|
||||
rounded_rectangle([30, 30, 3], 2);
|
||||
|
||||
@@ -53,9 +52,8 @@ module widgit_stl() {
|
||||
}
|
||||
}
|
||||
|
||||
module widgit_dxf() {
|
||||
dxf("widget");
|
||||
|
||||
module widget_dxf() {
|
||||
dxf("widget")
|
||||
difference() {
|
||||
sheet_2D(sheet, 20, 20, 1);
|
||||
|
||||
@@ -64,10 +62,10 @@ module widgit_dxf() {
|
||||
}
|
||||
|
||||
//! * Push the insert into the base with a soldering iron heated to 200°C
|
||||
module widgit_base_assembly()
|
||||
assembly("widgit_base") {
|
||||
module widget_base_assembly()
|
||||
assembly("widget_base") {
|
||||
stl_colour(pp1_colour)
|
||||
widgit_stl();
|
||||
widget_stl();
|
||||
|
||||
translate_z(height)
|
||||
insert(insert);
|
||||
@@ -80,14 +78,14 @@ assembly("widget_top") {
|
||||
widget(sheet_thickness(sheet));
|
||||
|
||||
render_2D_sheet(sheet) // Must be last because it is transparent
|
||||
widgit_dxf();
|
||||
widget_dxf();
|
||||
}
|
||||
|
||||
//! * Screw the two assemblies together
|
||||
module widgit_assembly()
|
||||
assembly("wigdit") {
|
||||
module widget_assembly()
|
||||
assembly("widget") {
|
||||
|
||||
widgit_base_assembly(); // Note this is not exloded because it is sub-assembly
|
||||
widget_base_assembly(); // Note this is not exloded because it is sub-assembly
|
||||
|
||||
translate_z(height) {
|
||||
translate_z(sheet_thickness(sheet))
|
||||
@@ -100,7 +98,7 @@ assembly("wigdit") {
|
||||
}
|
||||
|
||||
module boms() {
|
||||
widgit_assembly();
|
||||
widget_assembly();
|
||||
}
|
||||
|
||||
boms();
|
||||
|
@@ -22,7 +22,7 @@ use <../utils/layout.scad>
|
||||
include <../vitamins/blowers.scad>
|
||||
|
||||
module blowers()
|
||||
layout([for(b = blowers) blower_width(b)], 10, true) let(b = blowers[$i]){
|
||||
layout([for(b = blowers) blower_width(b)], 5, true) let(b = blowers[$i]){
|
||||
screw = blower_screw(b);
|
||||
h = blower_lug(b);
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 51 KiB |
Binary file not shown.
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 153 KiB |
@@ -26,15 +26,16 @@ sheet = 3;
|
||||
pos = 1; //[-1 : 0.1 : 1]
|
||||
|
||||
module rails()
|
||||
layout([for(l = rails) carriage_width(rail_carriage(l))], 20)
|
||||
layout([for(l = carriages) carriage_width(l)], 20)
|
||||
rotate(-90) {
|
||||
rail = rails[$i];
|
||||
carriage = carriages[$i];
|
||||
rail = carriage_rail(carriage);
|
||||
length = 200;
|
||||
screw = rail_screw(rail);
|
||||
nut = screw_nut(screw);
|
||||
washer = screw_washer(screw);
|
||||
|
||||
rail_assembly(rail, length, pos * rail_travel(rail, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
rail_assembly(carriage, length, pos * carriage_travel(carriage, length) / 2, $i<2 ? grey(20) : "green", $i<2 ? grey(20) : "red");
|
||||
|
||||
rail_screws(rail, length, sheet + nut_thickness(nut, true) + washer_thickness(washer));
|
||||
|
||||
|
@@ -25,8 +25,15 @@
|
||||
//! parts are used.
|
||||
//! This heuristic isn't always correct, so the default can be overridden by setting the `big` parameter of `assembly` to `true` or `false`.
|
||||
//!
|
||||
//! Setting the `ngb` parameter of `assembly` to `true` removes its column from the global BOM and merges it parts into its parent assembly column of the global BOM.
|
||||
//! This is to prevent the global BOM page becoming too wide in large projects by having it include just the major assemblies.
|
||||
//!
|
||||
//! The example below shows how to define a vitamin and incorporate it into an assembly with sub-assemblies and make an exploded view.
|
||||
//! The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
|
||||
//!
|
||||
//! If the code to make an STL or DXF is made a child of the `stl()` or `dxf()` module then the STL or DXF will be used in the assembly views generated by `views.py` instead of generating
|
||||
//! it with code.
|
||||
//! This can speed up the generation of the build instructions greatly but isn't compatible with STLs that include support structures.
|
||||
//
|
||||
function bom_mode(n = 1) = $_bom >= n && (is_undef($on_bom) || $on_bom); //! Current BOM mode, 0 = none, 1 = printed and routed parts and assemblies, 2 includes vitamins as well
|
||||
function exploded() = is_undef($exploded_parent) ? $exploded : 0; //! Returns the value of `$exploded` if it is defined, else `0`
|
||||
@@ -84,9 +91,9 @@ module pose_vflip(exploded = undef) //! Pose an STL or assembly for render
|
||||
children();
|
||||
|
||||
|
||||
module assembly(name, big = undef) { //! Name an assembly that will appear on the BOM, there needs to a module named `<name>_assembly` to make it. `big` can force big or small assembly diagrams.
|
||||
module assembly(name, big = undef, ngb = false) { //! Name an assembly that will appear on the BOM, there needs to a module named `<name>_assembly` to make it. `big` can force big or small assembly diagrams.
|
||||
if(bom_mode()) {
|
||||
args = is_undef(big) ? "" : str("(big=", big, ")");
|
||||
args = is_undef(big) && !ngb ? "" : str("(big=", big, ", ngb=", ngb, ")");
|
||||
echo(str("~", name, "_assembly", args, "{"));
|
||||
}
|
||||
no_pose()
|
||||
@@ -108,19 +115,47 @@ module stl_colour(colour = pp1_colour, alpha = 1) { //! Colour an stl where it i
|
||||
}
|
||||
|
||||
module stl(name) { //! Name an stl that will appear on the BOM, there needs to a module named `<name>_stl` to make it
|
||||
if(bom_mode()) {
|
||||
if(bom_mode() && is_undef($in_stl)) {
|
||||
colour = is_undef($stl_colour) ? pp1_colour : $stl_colour;
|
||||
echo(str("~", name, ".stl(colour='", colour, "')"));
|
||||
}
|
||||
if($children)
|
||||
if(is_undef($pose))
|
||||
let($in_stl = true)
|
||||
children();
|
||||
else {
|
||||
path = is_undef($target) ? "/stls/" : str("/", $target, "/stls/");
|
||||
import(str($cwd, path, name, ".stl"));
|
||||
}
|
||||
}
|
||||
|
||||
module dxf(name) { //! Name a dxf that will appear on the BOM, there needs to a module named `<name>_dxf` to make it
|
||||
if(bom_mode()) {
|
||||
if(bom_mode() && is_undef($in_dxf)) {
|
||||
if(is_undef($dxf_colour))
|
||||
echo(str("~", name, ".dxf"));
|
||||
else
|
||||
echo(str("~", name, ".dxf(colour='", $dxf_colour, "')"));
|
||||
}
|
||||
if($children)
|
||||
if(is_undef($pose))
|
||||
let($in_dfx = true)
|
||||
children();
|
||||
else {
|
||||
path = is_undef($target) ? "/dxfs/" : str("/", $target, "/dxfs/");
|
||||
import(str($cwd, path, name, ".dxf"));
|
||||
}
|
||||
}
|
||||
|
||||
module use_stl(name) { //! Import an STL to make a build platter
|
||||
stl(name);
|
||||
path = is_undef($target) ? "/stls/" : str("/", $target, "/stls/");
|
||||
import(str($cwd, path, name, ".stl"));
|
||||
}
|
||||
|
||||
module use_dxf(name) { //! Import a DXF to make a build panel
|
||||
dxf(name);
|
||||
path = is_undef($target) ? "/dxfs/" : str("/", $target, "/dxfs/");
|
||||
import(str($cwd, path, name, ".dxf"));
|
||||
}
|
||||
|
||||
function value_string(value) = is_string(value) ? str("\"", value, "\"") : str(value); //! Convert `value` to a string or quote it if it is already a string
|
||||
@@ -130,7 +165,7 @@ function arg(value, default, name = "") = //! Create string for arg if not def
|
||||
: name ? str(", ", name, " = ", value_string(value))
|
||||
: str(", ", value_string(value));
|
||||
|
||||
module vitamin(description) { //! Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "wigit(42): Type 42 widget"
|
||||
module vitamin(description) { //! Describe a vitamin for the BOM entry and precede it with a module call that creates it, eg. "widget(42): Widget size 42"
|
||||
if(bom_mode(2))
|
||||
echo(str("~", description, !is_undef($hidden) ? " - not shown" : ""));
|
||||
}
|
||||
|
@@ -25,15 +25,3 @@ include <../../global_defs.scad>
|
||||
// Global functions and modules
|
||||
//
|
||||
use <global.scad>
|
||||
|
||||
module use_stl(name) { //! Import an STL to make a build platter
|
||||
stl(name);
|
||||
path = is_undef($target) ? "../stls/" : str("../", $target, "/stls/");
|
||||
import(str(path, name, ".stl"));
|
||||
}
|
||||
|
||||
module use_dxf(name) { //! Import a DXF to make a build panel
|
||||
dxf(name);
|
||||
path = is_undef($target) ? "../dxfs/" : str("../", $target, "/dxfs/");
|
||||
import(str(path, name, ".dxf"));
|
||||
}
|
||||
|
@@ -40,8 +40,10 @@ function blower_base(type) = type[13]; //! Thickness of the base
|
||||
function blower_top(type) = type[14]; //! Thickness of the top
|
||||
function blower_wall(type) = type[15]; //! Side wall thickness
|
||||
function blower_lug(type) = type[16]; //! Height of the lugs
|
||||
function blower_wall_left(type) = type[15]; //! Left side wall thickness
|
||||
function blower_wall_right(type) = type[17]; //! Right wall thickness (for square fans)
|
||||
|
||||
function blower_casing_is_square(type) = len(blower_screw_holes(type)) > 3; //! True for square radial fans, false for spiral shape radial blowers
|
||||
function blower_casing_is_square(type) = blower_depth(type) < 15; //! True for square radial fans, false for spiral shape radial blowers
|
||||
function blower_exit_offset(type) = blower_casing_is_square(type) ? blower_length(type) / 2 : blower_exit(type) / 2; //! Offset of exit's centre from the edge
|
||||
|
||||
fan_colour = grey(20);
|
||||
@@ -74,41 +76,54 @@ module blower_fan(type, casing_is_square) {
|
||||
module blower_square(type) { //! Draw a square blower
|
||||
width = blower_width(type);
|
||||
depth = blower_depth(type);
|
||||
wall = blower_wall(type);
|
||||
wall_left = blower_wall_left(type);
|
||||
wall_right = blower_wall_right(type);
|
||||
hole_count = len(blower_screw_holes(type));
|
||||
hole_pitch = (blower_screw_holes(type)[1].x - blower_screw_holes(type)[0].x) / 2;
|
||||
corner_radius = width / 2 - hole_pitch;
|
||||
corner_inset = (width - blower_exit(type)) / 2;
|
||||
corner_inset = (width - blower_exit(type) - wall_left - wall_right) / (hole_count == 2 ? 1 : 2);
|
||||
|
||||
module inset_corners()
|
||||
translate([width / 2, width / 2])
|
||||
for(i = hole_count == 2 ? [1, 3] : [0 : 3])
|
||||
rotate(i * 90)
|
||||
translate([-width / 2 - eps, -width/ 2 - eps])
|
||||
quadrant(corner_inset, corner_inset - corner_radius);
|
||||
|
||||
module square_inset_corners(remove_center = false)
|
||||
difference() {
|
||||
//overall outside
|
||||
square([width, width], center = false);
|
||||
rounded_square([width, width], corner_radius, center = false);
|
||||
|
||||
if (remove_center) {
|
||||
// cut out the inside, leaving the corners
|
||||
translate([corner_inset + wall, -eps])
|
||||
square([width - 2 * (wall + corner_inset), width - wall + eps], center = false);
|
||||
|
||||
translate([wall, corner_inset + wall])
|
||||
square([width - 2 * wall, width - 2 * (wall + corner_inset)], center = false);
|
||||
translate([hole_count == 2 ? wall_left : corner_inset + wall_left, -eps])
|
||||
square([blower_exit(type), width / 2], center = false);
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_bore(type) + 1);
|
||||
} else {
|
||||
// cut out the bore for the fan
|
||||
translate(blower_axis(type))
|
||||
circle(d = blower_bore(type));
|
||||
}
|
||||
// corner inset
|
||||
translate([width / 2, width / 2])
|
||||
for(i = [0 : 3])
|
||||
rotate(i * 90)
|
||||
translate([-width / 2 - eps, -width/ 2 - eps])
|
||||
quadrant(corner_inset, corner_inset - corner_radius);
|
||||
inset_corners();
|
||||
}
|
||||
|
||||
base_height = blower_base(type);
|
||||
linear_extrude(base_height)
|
||||
difference () {
|
||||
rounded_square([width, width], corner_radius, center = false);
|
||||
blower_hole_positions(type)
|
||||
circle(d = blower_screw_hole(type));
|
||||
}
|
||||
|
||||
// add the lugs which may be higher than the base
|
||||
linear_extrude(blower_lug(type))
|
||||
difference () {
|
||||
intersection() {
|
||||
rounded_square([width, width], corner_radius, center = false);
|
||||
inset_corners();
|
||||
}
|
||||
blower_hole_positions(type)
|
||||
circle(d = blower_screw_hole(type));
|
||||
}
|
||||
|
@@ -24,8 +24,9 @@
|
||||
// h h s t t
|
||||
RB5015 = ["RB5015", "Blower Runda RB5015", 51.3, 51, 15, 31.5, M4_cap_screw, 26, [27.3, 25.4], 4.5, [[4.3, 45.4], [47.3,7.4]], 20, 14, 1.5, 1.3, 1.2, 15];
|
||||
PE4020 = ["PE4020", "Blower Pengda Technology 4020", 40, 40, 20, 27.5, M3_cap_screw, 22, [21.5, 20 ], 3.2, [[37,3],[3,37],[37,37]], 29.3, 17, 1.7, 1.2, 1.3, 13];
|
||||
BL40x10 =["BL40x10","Square radial fan 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 30 , 9.5, 1.5, 1.5, 1.1, 1.5];
|
||||
BL30x10 =["BL30x10","Square radial fan 3010", 30, 30,10.1,25, M2_cap_screw, 16, [16, 15 ], 2.4, [[3,27],[27,3]], 21.2, 9.5, 1.1, 1.2, 2.5, 2.8, 0.9];
|
||||
BL40x10 =["BL40x10","Square radial fan 4010", 40, 40,9.5, 27, M2_cap_screw, 16, [24, 20 ], 2.4, [[2,2],[38,2],[2,38],[38,38]], 27.8, 9.5, 1.5, 1.5, 1.1, 1.5, 1.1];
|
||||
|
||||
blowers = [BL40x10, PE4020, RB5015];
|
||||
blowers = [BL30x10, BL40x10, PE4020, RB5015];
|
||||
|
||||
use <blower.scad>
|
||||
|
@@ -205,37 +205,34 @@ BTT_SKR_MINI_E3_V2_0 = [
|
||||
grey(30), // color
|
||||
false, // true if parts should be separate BOM items
|
||||
[ // hole positions
|
||||
[ 19.3, -2.89 ],
|
||||
[ 19.3 + 62.15, -2.89 ],
|
||||
[ 2.535, -2.89 - 34.98 ],
|
||||
[ 2.535 + 31.80, -2.89 - 37.63 ],
|
||||
[ 2.535 + 95.68, -2.89 - 64.47 ]
|
||||
for (i = [ [0, 0], [62.15, 0] ])
|
||||
(i + [20.3, -2.89]),
|
||||
for (i = [ [0, -34.98], [31.80, -37.63], [95.68, -64.47] ])
|
||||
(i + [2.535, -2.89])
|
||||
],
|
||||
[ // components
|
||||
// cpu
|
||||
[ 55, 33, 0, "chip", 10, 10, 1, grey(15) ],
|
||||
// hotend and heated bed
|
||||
[ 26, 16, 0, "chip", 9.5, 8.5, 4, grey(15) ],
|
||||
[ 37, 14, 0, "chip", 6, 6, 2.5, grey(15) ],
|
||||
// driver chips
|
||||
[ 10.5,-17.5, 0, "chip", 5, 5, 1, grey(15) ],
|
||||
[ 30.5,-17.5, 0, "chip", 5, 5, 1, grey(15) ],
|
||||
[ 50.5,-17.5, 0, "chip", 5, 5, 1, grey(15) ],
|
||||
[ 70.5,-17.5, 0, "chip", 5, 5, 1, grey(15) ],
|
||||
// heat dissipation under board
|
||||
[ 43, -17.5, 0, "-block", 85, 8, 0.1, gold ],
|
||||
[ 40, 16, 0, "-block", 10, 8, 0.1, gold ],
|
||||
[ 27, 19, 0, "-block", 13,14, 0.1, gold ],
|
||||
[ 12, 28.5, 0, "-block", 11, 7, 0.1, gold ],
|
||||
for (x = [10.5, 30.5, 50.5, 70.5])
|
||||
[ x, -17.5, 0, "chip", 5, 5, 1, grey(15) ],
|
||||
// mock up heat sinks over the chips
|
||||
[ 10.5, -17.5, 0, "chip", 9, 8.5, 2, "DeepSkyBlue" ],
|
||||
for(x = [10.5], y = [-4,-2,0,2,4]) [ x, -17.5 + y, 0, "chip", 9, 0.75, 11, "DeepSkyBlue" ],
|
||||
[ 30.5, -17.5, 0, "chip", 9, 8.5, 2, "DeepSkyBlue" ],
|
||||
for(x = [30.5], y = [-4,-2,0,2,4]) [ x, -17.5 + y, 0, "chip", 9, 0.75, 11, "DeepSkyBlue" ],
|
||||
[ 50.5, -17.5, 0, "chip", 9, 8.5, 2, "DeepSkyBlue" ],
|
||||
for(x = [50.5], y = [-4,-2,0,2,4]) [ x, -17.5 + y, 0, "chip", 9, 0.75, 11, "DeepSkyBlue" ],
|
||||
[ 70.5, -17.5, 0, "chip", 9, 8.5, 2, "DeepSkyBlue" ],
|
||||
for(x = [70.5], y = [-4,-2,0,2,4]) [ x, -17.5 + y, 0, "chip", 9, 0.75, 11, "DeepSkyBlue" ],
|
||||
for (x = [10.5, 30.5, 50.5, 70.5])
|
||||
[ x, -17.5, 0, "block", 9, 8.5, 2, "DeepSkyBlue" ],
|
||||
for(x = [10.5, 30.5, 50.5, 70.5], y = [-4,-2,0,2,4])
|
||||
[ x, -17.5 + y, 0, "block", 9, 0.75, 11, "DeepSkyBlue" ],
|
||||
// heat dissipation for drivers under board
|
||||
[ 43, -17.5, 0, "-block", 85, 8, 0.1, gold ],
|
||||
|
||||
// heated bed
|
||||
[ 26, 16, 0, "chip", 9.5, 8.5, 4, grey(15) ],
|
||||
[ 27, 19, 0, "-block", 13, 14, 0.1, gold ],
|
||||
// hotend
|
||||
[ 37, 14, 0, "chip", 6, 6, 2.5, grey(15) ],
|
||||
[ 40, 16, 0, "-block", 10, 8, 0.1, gold ],
|
||||
|
||||
// voltage regulator heat dissipation
|
||||
[ 12, 28.5, 0, "-block", 11, 7, 0.1, gold ],
|
||||
|
||||
// terminals
|
||||
[ 5.25, 5.3, 180, "gterm", gt_5x17, 2, undef, grey(20) ],
|
||||
|
@@ -31,13 +31,11 @@ function rail_bore(type) = type[5]; //! Counter bore diameter for screw
|
||||
function rail_hole(type) = type[6]; //! Screw hole diameter
|
||||
function rail_bore_depth(type) = type[7]; //! Counter bore depth
|
||||
function rail_screw(type) = type[8]; //! Screw type
|
||||
function rail_carriage(type) = type[9]; //! Carriage type
|
||||
function rail_end_screw(type) = type[10]; //! Screw used for ends only (Countersink used for better location)
|
||||
function rail_groove_offset(type)=type[11]; //! Offset of centre of groove from top of rail
|
||||
function rail_groove_width(type)=type[12]; //! Groove width
|
||||
function rail_end_screw(type) = type[9]; //! Screw used for ends only (Countersink used for better location)
|
||||
function rail_groove_offset(type)=type[10]; //! Offset of centre of groove from top of rail
|
||||
function rail_groove_width(type)=type[11]; //! Groove width
|
||||
|
||||
function rail_screw_height(type, screw) = rail_height(type) - rail_bore_depth(type) + screw_head_depth(screw, rail_hole(type)); //! Position screw taking into account countersink into counterbored hole
|
||||
function rail_travel(type, length) = length - carriage_length(rail_carriage(type)); //! How far the carriage can travel
|
||||
|
||||
function carriage_length(type) = type[0]; //! Overall length
|
||||
function carriage_block_length(type) = type[1]; //! Length of the metal part
|
||||
@@ -48,7 +46,9 @@ function carriage_clearance(type) = type[4]; //! Gap under the carriage
|
||||
function carriage_pitch_x(type) = type[5]; //! Screw hole x pitch
|
||||
function carriage_pitch_y(type) = type[6]; //! Screw hole y pitch
|
||||
function carriage_screw(type) = type[7]; //! Carriage screw type
|
||||
function carriage_rail(type) = type[8]; //! Rail type
|
||||
function carriage_screw_depth(type) = 2 * screw_radius(carriage_screw(type)); //! Carriage thread depth
|
||||
function carriage_travel(type, rail_length) = rail_length - carriage_length(type); //! How far the carriage can travel on a given length rail
|
||||
|
||||
function rail_holes(type, length) = //! Number of holes in a rail given its `length`
|
||||
floor((length - 2 * rail_end(type)) / rail_pitch(type)) + 1;
|
||||
@@ -73,7 +73,7 @@ module carriage_hole_positions(type) { //! Position children over screw holes
|
||||
children();
|
||||
}
|
||||
|
||||
module carriage(type, rail, end_colour = grey(20), wiper_colour = grey(20)) { //! Draw the specified carriage
|
||||
module carriage(type, end_colour = grey(20), wiper_colour = grey(20)) { //! Draw the specified carriage
|
||||
total_l = carriage_length(type);
|
||||
block_l = carriage_block_length(type);
|
||||
block_w = carriage_width(type);
|
||||
@@ -85,9 +85,9 @@ module carriage(type, rail, end_colour = grey(20), wiper_colour = grey(20)) { //
|
||||
screw_depth = carriage_screw_depth(type);
|
||||
|
||||
module cutout() {
|
||||
w = rail_width(rail) + 0.4;
|
||||
w = rail_width(carriage_rail(type)) + 0.4;
|
||||
translate([-w / 2, 0])
|
||||
square([w , rail_height(rail) + 0.2]);
|
||||
square([w , rail_height(carriage_rail(type)) + 0.2]);
|
||||
}
|
||||
|
||||
color(grey(90)) {
|
||||
@@ -179,11 +179,11 @@ module rail(type, length, colour = grey(90), use_polycircles = false) { //! Draw
|
||||
}
|
||||
}
|
||||
|
||||
module rail_assembly(type, length, pos, carriage_end_colour = grey(20), carriage_wiper_colour = grey(20)) { //! Rail and carriage assembly
|
||||
rail(type, length);
|
||||
module rail_assembly(carriage, length, pos, carriage_end_colour = grey(20), carriage_wiper_colour = grey(20)) { //! Rail and carriage assembly
|
||||
rail(carriage_rail(carriage), length);
|
||||
|
||||
translate([pos, 0])
|
||||
carriage(rail_carriage(type), type, carriage_end_colour, carriage_wiper_colour);
|
||||
carriage(carriage, carriage_end_colour, carriage_wiper_colour);
|
||||
}
|
||||
|
||||
module rail_screws(type, length, thickness, screws = 100, index_screws = undef) { //! Place screws in the rail
|
||||
|
@@ -17,30 +17,29 @@
|
||||
// If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
//
|
||||
// Rails
|
||||
//
|
||||
// Wr Hr E P D d h go gw
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.6, 2.4, 0.8, M2_cs_cap_screw, M2_cs_cap_screw, 1, 1 ]; // Screw holes too small for M2 heads
|
||||
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, M2_cs_cap_screw, 1.5, 1.5 ];
|
||||
MGN9 = [ "MGN9", 9, 6, 5, 20, 6.0, 3.5, 3.5, M3_cap_screw, M3_cs_cap_screw, 1.5, 1.5 ];
|
||||
MGN12 =[ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, M3_cs_cap_screw, 2.25, 2.75];
|
||||
MGN15 =[ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, M3_cs_cap_screw, 2.5, 2.75 ];
|
||||
SSR15= [ "SSR15", 15, 12.5, 10, 60, 7.5, 4.5, 5.3, M4_cap_screw, M4_cs_cap_screw, 2.5, 2.75 ];
|
||||
//
|
||||
// Carriages
|
||||
//
|
||||
// L L1 W H H1 C B
|
||||
MGN5_carriage = [ 16, 9.6, 12, 6, 1.5, 0, 8 , M2_cap_screw ];
|
||||
MGN7_carriage = [ 23, 14.3, 17, 8, 1.5, 8, 12, M2_cap_screw ];
|
||||
MGN9_carriage = [ 29.7, 20.8, 20, 10, 2, 10, 15, M3_cap_screw ];
|
||||
MGN12_carriage = [ 34.7, 21.7, 27, 13, 3, 15, 20, M3_cap_screw ];
|
||||
MGN12H_carriage= [ 45.4, 32.4, 27, 13, 3, 20, 20, M3_cap_screw ];
|
||||
MGN15_carriage = [ 43.3, 27.7, 32, 16, 4, 20, 25, M3_cap_screw ];
|
||||
SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw ];
|
||||
//
|
||||
// Rails
|
||||
//
|
||||
//
|
||||
// Wr Hr E P D d h go gw
|
||||
MGN5 = [ "MGN5", 5, 3.6, 5, 15, 3.6, 2.4, 0.8, M2_cs_cap_screw, MGN5_carriage, M2_cs_cap_screw, 1, 1 ]; // Screw holes too small for M2 heads
|
||||
MGN7 = [ "MGN7", 7, 5, 5, 15, 4.3, 2.4, 2.6, M2_cap_screw, MGN7_carriage, M2_cs_cap_screw, 1.5, 1.5 ];
|
||||
MGN9 = [ "MGN9", 9, 6, 7.5, 20, 6.0, 3.5, 3.5, M3_cap_screw, MGN9_carriage, M3_cs_cap_screw, 1.5, 1.5 ];
|
||||
MGN12= [ "MGN12", 12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12_carriage, M3_cs_cap_screw, 2.25, 2.75 ];
|
||||
MGN12H=[ "MGN12H",12, 8, 10, 25, 6.0, 3.5, 4.5, M3_cap_screw, MGN12H_carriage,M3_cs_cap_screw, 2.25, 2.75];
|
||||
MGN15= [ "MGN15", 15, 10, 10, 40, 6.0, 3.5, 5.0, M3_cap_screw, MGN15_carriage, M3_cs_cap_screw, 2.5, 2.75 ];
|
||||
SSR15= [ "SSR15", 15, 12.5,10, 60, 7.5, 4.5, 5.3, M4_cap_screw, SSR15_carriage, M4_cs_cap_screw, 2.5, 2.75 ];
|
||||
MGN5_carriage = [ 16, 9.6, 12, 6, 1.5, 0, 8, M2_cap_screw, MGN5 ];
|
||||
MGN7C_carriage = [ 23, 14.3, 17, 8, 1.5, 8, 12, M2_cap_screw, MGN7 ];
|
||||
MGN9C_carriage = [ 29.7, 20.8, 20, 10, 2, 10, 15, M3_cap_screw, MGN9 ];
|
||||
MGN12C_carriage = [ 34.7, 21.7, 27, 13, 3, 15, 20, M3_cap_screw, MGN12 ];
|
||||
MGN12H_carriage = [ 45.4, 32.4, 27, 13, 3, 20, 20, M3_cap_screw, MGN12 ];
|
||||
MGN15C_carriage = [ 43.3, 27.7, 32, 16, 4, 20, 25, M3_cap_screw, MGN15 ];
|
||||
SSR15_carriage = [ 40.3, 23.3, 34, 24, 4.5, 0, 26, M4_cap_screw, SSR15 ];
|
||||
|
||||
rails = [MGN5, MGN7, MGN9, MGN12, MGN12H, MGN15, SSR15];
|
||||
|
||||
carriages = [MGN5_carriage, MGN7C_carriage, MGN9C_carriage, MGN12C_carriage, MGN12H_carriage, MGN15C_carriage, SSR15_carriage];
|
||||
|
||||
use <rail.scad>
|
||||
|
@@ -143,8 +143,8 @@ module vero_components(type, cutouts = false, angle = undef)
|
||||
|
||||
module vero_cutouts(type, angle = undef) vero_components(type, true, angle); //! Make cutouts to clear components
|
||||
|
||||
module veroboard_assembly(type, height, thickness, flip = false) //! Draw the assembly with components and fasteners in place
|
||||
assembly(vero_assembly(type)) {
|
||||
module veroboard_assembly(type, height, thickness, flip = false, ngb = false) //! Draw the assembly with components and fasteners in place
|
||||
assembly(vero_assembly(type), ngb = ngb) {
|
||||
screw = vero_screw(type);
|
||||
nut = screw_nut(screw);
|
||||
screw_length = screw_length(screw, height + thickness + vero_thickness(type), 2, nyloc = true);
|
||||
|
Reference in New Issue
Block a user