mirror of
https://github.com/DJSundog/NopSCADlib.git
synced 2024-11-23 07:13:51 -05:00
Set ngb parameter of assembly() to remove it from the global BOM and merge
its parts into it parent's global BOM column.
This commit is contained in:
parent
f7fbbd5fe4
commit
36521cf0b9
@ -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.
|
//! 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
|
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())
|
translate_z(handle_height())
|
||||||
stl_colour(pp1_colour) vflip() handle_stl();
|
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
|
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.
|
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
|
### 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
|
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",
|
"name": "base_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
|
"ngb": false,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {},
|
"assemblies": {},
|
||||||
"vitamins": {
|
"vitamins": {
|
||||||
@ -20,6 +21,7 @@
|
|||||||
{
|
{
|
||||||
"name": "feet_assembly",
|
"name": "feet_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
|
"ngb": false,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {
|
"assemblies": {
|
||||||
"base_assembly": 1
|
"base_assembly": 1
|
||||||
@ -46,6 +48,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mains_in_assembly",
|
"name": "mains_in_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
|
"ngb": false,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {
|
"assemblies": {
|
||||||
"feet_assembly": 1
|
"feet_assembly": 1
|
||||||
@ -82,6 +85,7 @@
|
|||||||
{
|
{
|
||||||
"name": "main_assembly",
|
"name": "main_assembly",
|
||||||
"big": null,
|
"big": null,
|
||||||
|
"ngb": false,
|
||||||
"count": 1,
|
"count": 1,
|
||||||
"assemblies": {
|
"assemblies": {
|
||||||
"mains_in_assembly": 1
|
"mains_in_assembly": 1
|
||||||
|
@ -3809,7 +3809,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_hole_positions(type)` | Positions children at the mounting holes |
|
||||||
| `vero_mounting_holes(type, h = 100)` | Drill mounting holes in a panel |
|
| `vero_mounting_holes(type, h = 100)` | Drill mounting holes in a panel |
|
||||||
| `veroboard(type)` | Draw specified veroboard with missing tracks and track breaks |
|
| `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 |
|
||||||
|
|
||||||
![veroboard](tests/png/veroboard.png)
|
![veroboard](tests/png/veroboard.png)
|
||||||
|
|
||||||
@ -6003,6 +6003,9 @@ Assembly views shown in the instructions can be large or small and this is deduc
|
|||||||
parts are used.
|
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`.
|
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 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.
|
The resulting flat BOM is shown but heirachical BOMs are also generated for real projects.
|
||||||
|
|
||||||
@ -6022,7 +6025,7 @@ The resulting flat BOM is shown but heirachical BOMs are also generated for real
|
|||||||
### Modules
|
### Modules
|
||||||
| Module | Description |
|
| 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 |
|
| `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 |
|
| `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 |
|
| `hidden()` | Make item invisible, except on the BOM |
|
||||||
|
@ -60,6 +60,7 @@ class BOM:
|
|||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.big = None
|
self.big = None
|
||||||
|
self.ngb = False
|
||||||
self.count = 1
|
self.count = 1
|
||||||
self.vitamins = {}
|
self.vitamins = {}
|
||||||
self.printed = {}
|
self.printed = {}
|
||||||
@ -73,6 +74,7 @@ class BOM:
|
|||||||
return {
|
return {
|
||||||
"name" : self.name,
|
"name" : self.name,
|
||||||
"big" : self.big,
|
"big" : self.big,
|
||||||
|
"ngb" : self.ngb,
|
||||||
"count" : self.count,
|
"count" : self.count,
|
||||||
"assemblies" : assemblies,
|
"assemblies" : assemblies,
|
||||||
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
|
"vitamins" : {v : self.vitamins[v].data() for v in self.vitamins},
|
||||||
|
@ -36,6 +36,7 @@ import blurb
|
|||||||
import bom
|
import bom
|
||||||
import shutil
|
import shutil
|
||||||
import re
|
import re
|
||||||
|
import copy
|
||||||
from colorama import Fore
|
from colorama import Fore
|
||||||
|
|
||||||
def is_assembly(s):
|
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.")
|
print("\nusage:\n\t views [target_config] [<name1>_assembly] ... [<nameN>_assembly] - Create assembly images and readme.")
|
||||||
sys.exit(1)
|
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):
|
def views(target, do_assemblies = None):
|
||||||
done_assemblies = []
|
done_assemblies = []
|
||||||
#
|
#
|
||||||
@ -242,8 +264,8 @@ def views(target, do_assemblies = None):
|
|||||||
#
|
#
|
||||||
# Global BOM
|
# 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)
|
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"}
|
headings = {"vitamins" : "vitamins", "printed" : "3D printed parts", "routed" : "CNC routed parts"}
|
||||||
things = {}
|
things = {}
|
||||||
for t in types:
|
for t in types:
|
||||||
@ -255,19 +277,22 @@ def views(target, do_assemblies = None):
|
|||||||
things[t][thing] += ass[t][thing]["count"]
|
things[t][thing] += ass[t][thing]["count"]
|
||||||
else:
|
else:
|
||||||
things[t][thing] = ass[t][thing]["count"]
|
things[t][thing] = ass[t][thing]["count"]
|
||||||
for ass in flat_bom:
|
for ass in global_bom:
|
||||||
name = titalise(ass["name"][:-9]).replace(' ',' ')
|
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;">%s</span> ' % name, file = doc_file, end = '')
|
||||||
print('| <span style="writing-mode: vertical-rl; text-orientation: mixed;">TOTALS</span> | |', file = doc_file)
|
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:
|
for t in types:
|
||||||
if things[t]:
|
if things[t]:
|
||||||
totals = {}
|
totals = {}
|
||||||
heading = headings[t][0:1].upper() + headings[t][1:]
|
grand_total2 = 0
|
||||||
print(('| ' * len(flat_bom) + '| | **%s** |') % heading, file = doc_file)
|
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 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
|
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 = '')
|
print('| %s ' % pad(count if count else '.', 2, 1), file = doc_file, end = '')
|
||||||
name = ass["name"]
|
name = ass["name"]
|
||||||
@ -275,15 +300,17 @@ def views(target, do_assemblies = None):
|
|||||||
totals[name] += count
|
totals[name] += count
|
||||||
else:
|
else:
|
||||||
totals[name] = count
|
totals[name] = count
|
||||||
|
grand_total2 += count
|
||||||
print('| %s | %s |' % (pad(things[t][thing], 2, 1), pad(thing.split(":")[-1], 2)), file = doc_file)
|
print('| %s | %s |' % (pad(things[t][thing], 2, 1), pad(thing.split(":")[-1], 2)), file = doc_file)
|
||||||
|
|
||||||
grand_total = 0
|
grand_total = 0
|
||||||
for ass in flat_bom:
|
for ass in global_bom:
|
||||||
name = ass["name"]
|
name = ass["name"]
|
||||||
total = totals[name] if name in totals else 0
|
total = totals[name] if name in totals else 0
|
||||||
print('| %s ' % pad(total if total else '.', 2, 1), file = doc_file, end = '')
|
print('| %s ' % pad(total if total else '.', 2, 1), file = doc_file, end = '')
|
||||||
grand_total += total
|
grand_total += total
|
||||||
print("| %s | %s |" % (pad(grand_total, 2, 1), pad('Total %s count' % headings[t], 2)), file = doc_file)
|
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)
|
print(file = doc_file)
|
||||||
if len(blurbs) > 2:
|
if len(blurbs) > 2:
|
||||||
print(blurbs[2], file = doc_file)
|
print(blurbs[2], file = doc_file)
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
//! parts are used.
|
//! 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`.
|
//! 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 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.
|
//! 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();
|
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()) {
|
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, "{"));
|
echo(str("~", name, "_assembly", args, "{"));
|
||||||
}
|
}
|
||||||
no_pose()
|
no_pose()
|
||||||
|
Loading…
Reference in New Issue
Block a user