mirror of
https://github.com/nophead/NopSCADlib.git
synced 2025-09-03 12:22:46 +02:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4cb324ed37 | ||
|
eb997aa18c | ||
|
f09343a285 | ||
|
54aab027bd | ||
|
cc61a11602 | ||
|
9cf2e9d7c3 | ||
|
9da8a3cb26 | ||
|
36521cf0b9 | ||
|
f760aaa20a | ||
|
1c445385b4 | ||
|
45f3fc275f | ||
|
f7fbbd5fe4 | ||
|
a769a38dff | ||
|
0485eeeb34 | ||
|
0a7208ff5a |
@@ -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
|
||||
|
@@ -15,6 +15,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||

|
||||
|
||||
<span></span>
|
||||
|
||||
---
|
||||
## Table of Contents
|
||||
@@ -24,6 +25,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
1. [Mains In Assembly](#mains_in_assembly)
|
||||
1. [Main Assembly](#main_assembly)
|
||||
|
||||
<span></span>
|
||||
[Top](#TOP)
|
||||
|
||||
---
|
||||
@@ -54,6 +56,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
| 1 | . | . | . | 1 | socket_box.stl |
|
||||
| 1 | 4 | . | . | 5 | Total 3D printed parts count |
|
||||
|
||||
<span></span>
|
||||
[Top](#TOP)
|
||||
|
||||
---
|
||||
@@ -81,6 +84,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||

|
||||
|
||||
<span></span>
|
||||
[Top](#TOP)
|
||||
|
||||
---
|
||||
@@ -117,6 +121,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||

|
||||
|
||||
<span></span>
|
||||
[Top](#TOP)
|
||||
|
||||
---
|
||||
@@ -156,6 +161,7 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||

|
||||
|
||||
<span></span>
|
||||
[Top](#TOP)
|
||||
|
||||
---
|
||||
@@ -199,4 +205,5 @@ Earth leakage can be measured Canadian CSA style by disconnected the neutral lin
|
||||
|
||||

|
||||
|
||||
<span></span>
|
||||
[Top](#TOP)
|
||||
|
BIN
libtest.png
BIN
libtest.png
Binary file not shown.
Before Width: | Height: | Size: 875 KiB After Width: | Height: | Size: 875 KiB |
@@ -284,7 +284,7 @@ module camera_bracket(cam) { //! Make the STL for the camera bracket
|
||||
}
|
||||
|
||||
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);
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -129,7 +129,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);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -81,7 +81,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();
|
||||
|
||||
|
@@ -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))
|
||||
|
@@ -143,7 +143,7 @@ module psu_shroud(type, cable_d, name, cables = 1) { //! Generate the STL file f
|
||||
}
|
||||
|
||||
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()
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -59,7 +59,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);
|
||||
|
@@ -107,7 +107,7 @@ module ssr_shroud(type, cable_d, name) { //! Generate the STL file for a spec
|
||||
}
|
||||
|
||||
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()
|
||||
|
@@ -162,7 +162,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);
|
||||
|
||||
|
18
readme.md
18
readme.md
@@ -2666,11 +2666,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 +2686,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 +2705,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 +3808,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,6 +6002,9 @@ 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.
|
||||
|
||||
@@ -6022,7 +6024,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 |
|
||||
|
@@ -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},
|
||||
|
412
scripts/views.py
412
scripts/views.py
@@ -36,6 +36,7 @@ import blurb
|
||||
import bom
|
||||
import shutil
|
||||
import re
|
||||
import copy
|
||||
from colorama import Fore
|
||||
|
||||
def is_assembly(s):
|
||||
@@ -74,19 +75,17 @@ def bom_to_assemblies(bom_dir, bounds_map):
|
||||
# Remove the main assembly if it is a shell
|
||||
#
|
||||
if flat_bom:
|
||||
ass = flat_bom[-1]
|
||||
ass = flat_bom[-1]
|
||||
if len(ass["assemblies"]) < 2 and not ass["vitamins"] and not ass["printed"] and not ass["routed"]:
|
||||
flat_bom = flat_bom[:-1]
|
||||
return [assembly["name"] for assembly in flat_bom]
|
||||
|
||||
def eop(print_mode, doc_file, last = False, first = False):
|
||||
if print_mode:
|
||||
print('\n<div style="page-break-after: always;"></div>', file = doc_file)
|
||||
else:
|
||||
if not first:
|
||||
print('[Top](#TOP)', file = doc_file)
|
||||
if not last:
|
||||
print("\n---", file = doc_file)
|
||||
def eop(doc_file, last = False, first = False):
|
||||
print('<span></span>', file = doc_file) # An invisable marker for page breaks because markdown takes much longer if the document contains a div
|
||||
if not first:
|
||||
print('[Top](#TOP)', file = doc_file)
|
||||
if not last:
|
||||
print("\n---", file = doc_file)
|
||||
|
||||
def pad(s, before, after = 0):
|
||||
return ' ' * before + str(s) + ' ' * after
|
||||
@@ -103,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 = []
|
||||
#
|
||||
@@ -202,193 +222,217 @@ def views(target, do_assemblies = None):
|
||||
if module == 'main_assembly':
|
||||
main_blurb = blurb.scrape_module_blurb(lines[:line_no])
|
||||
line_no += 1
|
||||
times.print_times()
|
||||
#
|
||||
# Build the document
|
||||
#
|
||||
for print_mode in [True, False]:
|
||||
doc_name = top_dir + "readme.md"
|
||||
with open(doc_name, "wt") as doc_file:
|
||||
#
|
||||
# Title, description and picture
|
||||
#
|
||||
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
|
||||
print('<a name="TOP"></a>\n# %s' % project, file = doc_file)
|
||||
main_file = bom.find_scad_file('main_assembly')
|
||||
if not main_file:
|
||||
raise Exception("can't find source for main_assembly")
|
||||
text = blurb.scrape_blurb(source_dir + '/' + main_file)
|
||||
blurbs = blurb.split_blurb(text)
|
||||
if len(text):
|
||||
print(blurbs[0], file = doc_file)
|
||||
else:
|
||||
if print_mode:
|
||||
print(Fore.MAGENTA + "Missing project description" + Fore.WHITE)
|
||||
#
|
||||
# Only add the image if the first blurb section doesn't contain one.
|
||||
#
|
||||
if not re.search(r'\!\[.*\]\(.*\)', blurbs[0], re.MULTILINE):
|
||||
print('\n' % flat_bom[-1]["name"].replace('_assembly', '_assembled'), file = doc_file)
|
||||
eop(print_mode, doc_file, first = True)
|
||||
#
|
||||
# Build TOC
|
||||
#
|
||||
print('## Table of Contents', file = doc_file)
|
||||
print('1. [Parts list](#Parts_list)', file = doc_file)
|
||||
for ass in flat_bom:
|
||||
name = ass["name"]
|
||||
cap_name = titalise(name)
|
||||
print('1. [%s](#%s)' % (cap_name, name), file = doc_file)
|
||||
print(file = doc_file)
|
||||
if len(blurbs) > 1:
|
||||
print(blurbs[1], file = doc_file)
|
||||
eop(print_mode, doc_file)
|
||||
#
|
||||
# Global BOM
|
||||
#
|
||||
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 = {}
|
||||
doc_name = top_dir + "readme.md"
|
||||
with open(doc_name, "wt") as doc_file:
|
||||
#
|
||||
# Title, description and picture
|
||||
#
|
||||
project = ' '.join(word[0].upper() + word[1:] for word in os.path.basename(os.getcwd()).split('_'))
|
||||
print('<a name="TOP"></a>', file = doc_file)
|
||||
print('# %s' % project, file = doc_file)
|
||||
main_file = bom.find_scad_file('main_assembly')
|
||||
if not main_file:
|
||||
raise Exception("can't find source for main_assembly")
|
||||
text = blurb.scrape_blurb(source_dir + '/' + main_file)
|
||||
blurbs = blurb.split_blurb(text)
|
||||
if len(text):
|
||||
print(blurbs[0], file = doc_file)
|
||||
else:
|
||||
print(Fore.MAGENTA + "Missing project description" + Fore.WHITE)
|
||||
#
|
||||
# Only add the image if the first blurb section doesn't contain one.
|
||||
#
|
||||
if not re.search(r'\!\[.*\]\(.*\)', blurbs[0], re.MULTILINE):
|
||||
print('\n' % flat_bom[-1]["name"].replace('_assembly', '_assembled'), file = doc_file)
|
||||
eop(doc_file, first = True)
|
||||
#
|
||||
# Build TOC
|
||||
#
|
||||
print('## Table of Contents', file = doc_file)
|
||||
print('1. [Parts list](#Parts_list)', file = doc_file)
|
||||
for ass in flat_bom:
|
||||
name = ass["name"]
|
||||
cap_name = titalise(name)
|
||||
print('1. [%s](#%s)' % (cap_name, name), file = doc_file)
|
||||
print(file = doc_file)
|
||||
if len(blurbs) > 1:
|
||||
print(blurbs[1], file = doc_file)
|
||||
eop(doc_file)
|
||||
#
|
||||
# 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)
|
||||
headings = {"vitamins" : "vitamins", "printed" : "3D printed parts", "routed" : "CNC routed parts"}
|
||||
things = {}
|
||||
for t in types:
|
||||
things[t] = {}
|
||||
for ass in flat_bom:
|
||||
for t in types:
|
||||
things[t] = {}
|
||||
for ass in flat_bom:
|
||||
for t in types:
|
||||
for thing in ass[t]:
|
||||
if thing in things[t]:
|
||||
things[t][thing] += ass[t][thing]["count"]
|
||||
else:
|
||||
things[t][thing] = ass[t][thing]["count"]
|
||||
for ass in flat_bom:
|
||||
name = titalise(ass["name"][:-9]).replace(' ',' ')
|
||||
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)
|
||||
for thing in ass[t]:
|
||||
if thing in things[t]:
|
||||
things[t][thing] += ass[t][thing]["count"]
|
||||
else:
|
||||
things[t][thing] = ass[t][thing]["count"]
|
||||
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(global_bom) + '|---:|:---|'), file = doc_file)
|
||||
|
||||
print(('|---:' * len(flat_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)
|
||||
for thing in sorted(things[t], key = lambda s: s.split(":")[-1]):
|
||||
for ass in flat_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"]
|
||||
if name in totals:
|
||||
totals[name] += count
|
||||
else:
|
||||
totals[name] = 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 t in types:
|
||||
if things[t]:
|
||||
totals = {}
|
||||
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 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"]
|
||||
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)
|
||||
if name in totals:
|
||||
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)
|
||||
|
||||
print(file = doc_file)
|
||||
if len(blurbs) > 2:
|
||||
print(blurbs[2], file = doc_file)
|
||||
eop(print_mode, doc_file)
|
||||
#
|
||||
# Assembly instructions
|
||||
#
|
||||
for ass in flat_bom:
|
||||
name = ass["name"]
|
||||
cap_name = titalise(name)
|
||||
|
||||
if ass["count"] > 1:
|
||||
print('<a name="%s"></a>\n## %d x %s' % (name, ass["count"], cap_name), file = doc_file)
|
||||
else:
|
||||
print('<a name="%s"></a>\n## %s' % (name, cap_name), file = doc_file)
|
||||
vitamins = ass["vitamins"]
|
||||
if vitamins:
|
||||
print("### Vitamins", file = doc_file)
|
||||
print("|Qty|Description|", file = doc_file)
|
||||
print("|---:|:----------|", file = doc_file)
|
||||
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
|
||||
print("|%d|%s|" % (vitamins[v]["count"], v.split(":")[1]), file = doc_file)
|
||||
print("\n", file = doc_file)
|
||||
|
||||
printed = ass["printed"]
|
||||
if printed:
|
||||
print('### 3D Printed parts', file = doc_file)
|
||||
keys = sorted(list(printed.keys()))
|
||||
for i, p in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p]["count"], p), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(printed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.stl','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
routed = ass["routed"]
|
||||
if routed:
|
||||
print("### CNC Routed parts", file = doc_file)
|
||||
keys = sorted(list(routed.keys()))
|
||||
for i, r in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r]["count"], r), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(routed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
sub_assemblies = ass["assemblies"]
|
||||
if sub_assemblies:
|
||||
print("### Sub-assemblies", file = doc_file)
|
||||
keys = sorted(list(sub_assemblies.keys()))
|
||||
for i, a in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(keys) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
a = keys[i - n + j + 1].replace('_assembly', '_assembled')
|
||||
print('|  %s' % (a, a + '_tn.png', '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
small = not ass["big"]
|
||||
suffix = '_tn.png' if small else '.png'
|
||||
print('### Assembly instructions', file = doc_file)
|
||||
print('\n' % (name, name + suffix), file = doc_file)
|
||||
|
||||
if "blurb" in ass and ass["blurb"]:
|
||||
print(ass["blurb"], file = doc_file)
|
||||
else:
|
||||
if print_mode:
|
||||
print(Fore.MAGENTA + "Missing instructions for %s" % name, Fore.WHITE)
|
||||
|
||||
name = name.replace('_assembly', '_assembled')
|
||||
print('\n' % (name, name + suffix), file = doc_file)
|
||||
eop(print_mode, doc_file, last = ass == flat_bom[-1] and not main_blurb)
|
||||
#
|
||||
# If main module is suppressed print any blurb here
|
||||
#
|
||||
if main_blurb:
|
||||
print(main_blurb, file = doc_file)
|
||||
eop(print_mode, doc_file, last = True)
|
||||
grand_total = 0
|
||||
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)
|
||||
eop(doc_file)
|
||||
#
|
||||
# Convert to HTML
|
||||
# Assembly instructions
|
||||
#
|
||||
html_name = "printme.html" if print_mode else "readme.html"
|
||||
with open(top_dir + html_name, "wt") as html_file:
|
||||
do_cmd(("python -m markdown -x tables -x sane_lists " + doc_name).split(), html_file)
|
||||
for ass in flat_bom:
|
||||
name = ass["name"]
|
||||
cap_name = titalise(name)
|
||||
|
||||
print('<a name="%s"></a>' % name, file = doc_file)
|
||||
if ass["count"] > 1:
|
||||
print('## %d x %s' % (ass["count"], cap_name), file = doc_file)
|
||||
else:
|
||||
print('## %s' % cap_name, file = doc_file)
|
||||
vitamins = ass["vitamins"]
|
||||
if vitamins:
|
||||
print("### Vitamins", file = doc_file)
|
||||
print("|Qty|Description|", file = doc_file)
|
||||
print("|---:|:----------|", file = doc_file)
|
||||
for v in sorted(vitamins, key = lambda s: s.split(":")[-1]):
|
||||
print("|%d|%s|" % (vitamins[v]["count"], v.split(":")[1]), file = doc_file)
|
||||
print("\n", file = doc_file)
|
||||
|
||||
printed = ass["printed"]
|
||||
if printed:
|
||||
print('### 3D Printed parts', file = doc_file)
|
||||
keys = sorted(list(printed.keys()))
|
||||
for i, p in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', printed[p]["count"], p), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(printed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.stl','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
routed = ass["routed"]
|
||||
if routed:
|
||||
print("### CNC Routed parts", file = doc_file)
|
||||
keys = sorted(list(routed.keys()))
|
||||
for i, r in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', routed[r]["count"], r), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(routed) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
part = keys[i - n + j + 1]
|
||||
print('|  %s' % (part, part.replace('.dxf','.png'), '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
sub_assemblies = ass["assemblies"]
|
||||
if sub_assemblies:
|
||||
print("### Sub-assemblies", file = doc_file)
|
||||
keys = sorted(list(sub_assemblies.keys()))
|
||||
for i, a in enumerate(keys):
|
||||
print('%s %d x %s |' % ('\n|' if not (i % 3) else '', sub_assemblies[a], a), file = doc_file, end = '')
|
||||
if (i % 3) == 2 or i == len(keys) - 1:
|
||||
n = (i % 3) + 1
|
||||
print('\n|%s' % ('---|' * n), file = doc_file)
|
||||
for j in range(n):
|
||||
a = keys[i - n + j + 1].replace('_assembly', '_assembled')
|
||||
print('|  %s' % (a, a + '_tn.png', '|\n' if j == j - 1 else ''), end = '', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
print('\n', file = doc_file)
|
||||
|
||||
small = not ass["big"]
|
||||
suffix = '_tn.png' if small else '.png'
|
||||
print('### Assembly instructions', file = doc_file)
|
||||
print('\n' % (name, name + suffix), file = doc_file)
|
||||
|
||||
if "blurb" in ass and ass["blurb"]:
|
||||
print(ass["blurb"], file = doc_file)
|
||||
else:
|
||||
print(Fore.MAGENTA + "Missing instructions for %s" % name, Fore.WHITE)
|
||||
|
||||
name = name.replace('_assembly', '_assembled')
|
||||
print('\n' % (name, name + suffix), file = doc_file)
|
||||
eop(doc_file, last = ass == flat_bom[-1] and not main_blurb)
|
||||
#
|
||||
# If main module is suppressed print any blurb here
|
||||
#
|
||||
if main_blurb:
|
||||
print(main_blurb, file = doc_file)
|
||||
eop(doc_file, last = True)
|
||||
#
|
||||
# Convert to HTML
|
||||
#
|
||||
html_name = 'readme.html'
|
||||
t = time.time()
|
||||
with open(top_dir + 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()
|
||||
#
|
||||
# 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:
|
||||
lines = src.readlines()
|
||||
|
||||
i = 0
|
||||
with open(top_dir + 'printme.html', 'wt') as dst:
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if line.startswith('<p><span></span>'): # Empty span used to mark page breaks
|
||||
i += 1
|
||||
if lines[i].startswith('<a href="#TOP">Top</a>'): # The first page break won't have one
|
||||
i += 1
|
||||
if i < len(lines) and lines[i] == '<hr />\n': # The last page break doesn't have one
|
||||
dst.write('<div style="page-break-after: always;"></div>\n')
|
||||
i += 1
|
||||
else:
|
||||
dst.write(line)
|
||||
i += 1
|
||||
#
|
||||
# Spell check
|
||||
#
|
||||
do_cmd('codespell -L od readme.md'.split())
|
||||
do_cmd(('codespell -L od ' + top_dir + 'readme.md').split())
|
||||
#
|
||||
# List the ones we didn't find
|
||||
#
|
||||
|
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,6 +25,9 @@
|
||||
//! 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.
|
||||
//
|
||||
@@ -84,9 +87,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()
|
||||
|
@@ -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/>.
|
||||
//
|
||||
|
||||
//
|
||||
// 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, 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, 7.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 ];
|
||||
//
|
||||
// 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 ];
|
||||
// Carriages
|
||||
//
|
||||
// L L1 W H H1 C B
|
||||
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