More customization
This commit is contained in:
parent
60444e3584
commit
0761bacc12
2 changed files with 97 additions and 63 deletions
110
divider.scad
110
divider.scad
|
@ -1,11 +1,42 @@
|
||||||
|
/* [Main settings] */
|
||||||
|
// path to the tab icon
|
||||||
|
icon = "icons/classes/Guardian.svg";
|
||||||
|
|
||||||
|
// number of tabs
|
||||||
|
tabs = 4;
|
||||||
|
// index of the tab, 0 for first tab. must be smaller than number of tabs
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
// generate a card for each tab index for testing overlap
|
||||||
|
test_tabs = false;
|
||||||
|
|
||||||
|
/* [Dimensions] */
|
||||||
|
|
||||||
|
// horizontal size of the card
|
||||||
|
horizontal = 87.0;
|
||||||
|
// vertical size of the card (not including the tab)
|
||||||
|
vertical = 61.0;
|
||||||
|
|
||||||
|
// width of the tab's top (excluding the slope)
|
||||||
|
tab_width = 16.0;
|
||||||
|
|
||||||
|
// height of the tab
|
||||||
|
tab_height = 10.0;
|
||||||
|
|
||||||
|
// angle of the slope. lower angle means steeper slope, i.e. 0 makes square tabs
|
||||||
|
tab_angle = 45; // [0:89]
|
||||||
|
|
||||||
|
// height of the icon (will be resized). Must be smaller than tab_height
|
||||||
|
target_icon_height = 9.0;
|
||||||
|
// width of the icon. If set to zero, will keep aspect, but may cause it to be off center if it isn't square
|
||||||
|
target_icon_width = 0.0;
|
||||||
|
|
||||||
|
base_color = "black";
|
||||||
|
icon_color = "lime";
|
||||||
|
|
||||||
|
/* [Hidden] */
|
||||||
$fa = 1;
|
$fa = 1;
|
||||||
$fs = 0.4;
|
$fs = 0.4;
|
||||||
index = 0;
|
|
||||||
icon = "icons/classes/Mystic.svg";
|
|
||||||
|
|
||||||
tab_offset = 14;
|
|
||||||
target_icon_height = 9;
|
|
||||||
target_icon_width = 9;
|
|
||||||
|
|
||||||
module outer_tab(tab_height = 10, tab_width = 16, tab_angle = 45, flip = false)
|
module outer_tab(tab_height = 10, tab_width = 16, tab_angle = 45, flip = false)
|
||||||
{
|
{
|
||||||
|
@ -39,46 +70,11 @@ module inner_tab(tab_height = 10, tab_width = 16, tab_angle = 45)
|
||||||
polygon(tab);
|
polygon(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
module card(index = 0, thickness = 0.6, icon = "", icon_thickness = 0.4, horizontal = 87, vertical = 61,
|
module card(index = 0, thickness = 0.6, icon = "", icon_thickness = 0.4, horizontal = 87, vertical = 61, tabs = 4,
|
||||||
tab_height = 10, tab_width = 16, tab_angle = 45)
|
tab_height = 10, tab_width = 16, tab_angle = 45, target_icon_height = 9, target_icon_width = 9)
|
||||||
{
|
|
||||||
slope_width = tab_height * tan(tab_angle);
|
|
||||||
is_inner = index > 0 && index < 3;
|
|
||||||
inner_tab_width = tab_width + 2 * slope_width;
|
|
||||||
outer_tab_width = tab_width + slope_width;
|
|
||||||
positions = [
|
|
||||||
0,
|
|
||||||
tab_offset,
|
|
||||||
horizontal - tab_offset - inner_tab_width,
|
|
||||||
horizontal - outer_tab_width,
|
|
||||||
];
|
|
||||||
|
|
||||||
linear_extrude(thickness)
|
|
||||||
{
|
|
||||||
square([ horizontal, vertical ]);
|
|
||||||
translate([ positions[index], vertical, 0 ])
|
|
||||||
{
|
|
||||||
if (is_inner)
|
|
||||||
inner_tab(tab_height, tab_width, tab_angle);
|
|
||||||
else
|
|
||||||
outer_tab(tab_height, tab_width, tab_angle, index == 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (icon != "")
|
|
||||||
{
|
|
||||||
// If no icon width is given, we assume the icon is square.
|
|
||||||
icon_width = (target_icon_width == 0 ? target_icon_height : target_icon_width);
|
|
||||||
icon_offset = (index > 0 ? slope_width : 0) + tab_width / 2 - icon_width / 2;
|
|
||||||
translate([ positions[index] + icon_offset, vertical + 0.5, thickness - 0.001 ]) color("blue")
|
|
||||||
linear_extrude(icon_thickness + 0.001) resize([ target_icon_width, target_icon_height, 0 ], auto = true)
|
|
||||||
offset(delta = 0.001) import(icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module card2(index = 0, thickness = 0.6, icon = "", icon_thickness = 0.4, horizontal = 87, vertical = 61, tabs = 4,
|
|
||||||
tab_height = 10, tab_width = 16, tab_angle = 45)
|
|
||||||
{
|
{
|
||||||
assert(0 <= index && index < tabs, str("Tab index out of range. Index: ", index, " Tabs: ", tabs));
|
assert(0 <= index && index < tabs, str("Tab index out of range. Index: ", index, " Tabs: ", tabs));
|
||||||
|
assert(target_icon_height <= tab_height, str("Icon larger than tab!"));
|
||||||
|
|
||||||
is_inner = index > 0 && index < tabs - 1;
|
is_inner = index > 0 && index < tabs - 1;
|
||||||
|
|
||||||
|
@ -89,7 +85,7 @@ module card2(index = 0, thickness = 0.6, icon = "", icon_thickness = 0.4, horizo
|
||||||
slope_width = tab_height * tan(tab_angle);
|
slope_width = tab_height * tan(tab_angle);
|
||||||
indent = index == 0 ? 0 : (tab_width + tab_spacing) * index - slope_width;
|
indent = index == 0 ? 0 : (tab_width + tab_spacing) * index - slope_width;
|
||||||
|
|
||||||
color("black") linear_extrude(thickness)
|
color(base_color) linear_extrude(thickness)
|
||||||
{
|
{
|
||||||
square([ horizontal, vertical ]);
|
square([ horizontal, vertical ]);
|
||||||
translate([ indent, vertical, 0 ])
|
translate([ indent, vertical, 0 ])
|
||||||
|
@ -106,16 +102,26 @@ module card2(index = 0, thickness = 0.6, icon = "", icon_thickness = 0.4, horizo
|
||||||
icon_width = (target_icon_width == 0 ? target_icon_height : target_icon_width);
|
icon_width = (target_icon_width == 0 ? target_icon_height : target_icon_width);
|
||||||
icon_x_offset = (index > 0 ? slope_width : 0) + tab_width / 2 - icon_width / 2;
|
icon_x_offset = (index > 0 ? slope_width : 0) + tab_width / 2 - icon_width / 2;
|
||||||
icon_y_offset = tab_height / 2 - target_icon_height / 2;
|
icon_y_offset = tab_height / 2 - target_icon_height / 2;
|
||||||
translate([ indent + icon_x_offset, vertical + icon_y_offset, thickness - 0.001 ]) color("lime")
|
translate([ indent + icon_x_offset, vertical + icon_y_offset, thickness ]) color(icon_color)
|
||||||
linear_extrude(icon_thickness + 0.001) resize([ target_icon_width, target_icon_height, 0 ], auto = true)
|
linear_extrude(icon_thickness) resize([ target_icon_width, target_icon_height, 0 ], auto = true)
|
||||||
offset(delta = 0.001) import(icon);
|
offset(delta = 0.001) import(icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
card(index, icon = icon, horizontal = 61, vertical = 87);
|
if (test_tabs)
|
||||||
translate([ 100, 0, 0 ])
|
|
||||||
{
|
{
|
||||||
card2(index + 0, icon = icon, horizontal = 61, vertical = 87, tab_width = 16, tabs = 3, tab_angle = 30);
|
for (idx = [0:tabs - 1])
|
||||||
card2(index + 1, icon = icon, horizontal = 61, vertical = 87, tab_width = 16, tabs = 3, tab_angle = 30);
|
{
|
||||||
card2(index + 2, icon = icon, horizontal = 61, vertical = 87, tab_width = 16, tabs = 3, tab_angle = 30);
|
translate([ 0, 0, idx ])
|
||||||
|
card(index = idx, icon = icon, horizontal = horizontal, vertical = vertical, tab_width = tab_width,
|
||||||
|
tabs = tabs, tab_height = tab_height, tab_angle = tab_angle, target_icon_height = target_icon_height,
|
||||||
|
target_icon_width = target_icon_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
card(index, icon = icon, horizontal = horizontal, vertical = vertical, tab_width = tab_width, tabs = tabs,
|
||||||
|
tab_height = tab_height, tab_angle = tab_angle, target_icon_height = target_icon_height,
|
||||||
|
target_icon_width = target_icon_width);
|
||||||
}
|
}
|
||||||
|
|
50
generate.zsh
50
generate.zsh
|
@ -1,29 +1,57 @@
|
||||||
#!/bin/zsh
|
#!/bin/zsh
|
||||||
|
|
||||||
zparseopts -D -E -tabs:=tabs -vertical=vertical
|
zparseopts -D -E -vertical=vertical
|
||||||
|
|
||||||
|
get-icon-size() {
|
||||||
|
xmllint --xpath 'string(/*[local-name()="svg"]/@viewBox)' $1 | cut -d' ' -f3,4
|
||||||
|
}
|
||||||
|
|
||||||
tabs=${tabs[2]:-4}
|
|
||||||
index=0
|
index=0
|
||||||
|
|
||||||
scad_args=(
|
scad_args=()
|
||||||
-D "icon=\"$icon\""
|
|
||||||
-D "index=$index"
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ $vertical ]]; then
|
if [[ $vertical ]]; then
|
||||||
scad_args+=(-D "vertical=87.0" -D "horizontal=61.0")
|
scad_args+=(-D "vertical=87.0" -D "horizontal=61.0" -D "tabs=3" -D "tab_angle=30" -D "tab_width=14")
|
||||||
out_basedir=generated/vertical
|
out_basedir=generated/vertical
|
||||||
|
tabs=3
|
||||||
else
|
else
|
||||||
out_basedir=generated/horizontal
|
out_basedir=generated/horizontal
|
||||||
|
tabs=4
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -d $1 ]]; then
|
if [[ -d $1 ]]; then
|
||||||
echo "Usage: $0 <path-to-icon-dir> [--tabs <number-of-tabs>]"
|
files=($1/*.svg)
|
||||||
|
else
|
||||||
|
files=($@)
|
||||||
fi
|
fi
|
||||||
for icon in $1/*.svg; do
|
for icon in $files; do
|
||||||
target=$out_basedir/${${icon#*/}:r}.3mf
|
target=$out_basedir/${${icon#*/}:r}.3mf
|
||||||
mkdir -p ${target:h}
|
mkdir -p ${target:h}
|
||||||
|
|
||||||
|
size=( $(get-icon-size $icon) )
|
||||||
|
if (( size[1] < size[2] )); then
|
||||||
|
scale_factor=$(( 9.0 / size[2] ))
|
||||||
|
echo "Scaling factor: $scale_factor"
|
||||||
|
width=$(( size[1] * scale_factor ))
|
||||||
|
echo "Width: $width"
|
||||||
|
scad_args+=(-D "target_icon_width=${width}" -D "target_icon_height=9")
|
||||||
|
echo "\e[1;33mIcon size: ${size[1]} x ${size[2]}; scaled to $width x 9\e[0m"
|
||||||
|
else
|
||||||
|
scale_factor=$(( 9.0 / size[1] ))
|
||||||
|
echo "Scaling factor: $scale_factor"
|
||||||
|
height=$(( size[2] * scale_factor ))
|
||||||
|
echo "Height: $height"
|
||||||
|
scad_args+=(-D "target_icon_width=9" -D "target_icon_height=${height}")
|
||||||
|
echo "\e[1;33mIcon size: ${size[1]} x ${size[2]}; scaled to 9 x $height\e[0m"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Generating card $icon with tab index $index"
|
echo "Generating card $icon with tab index $index"
|
||||||
colorscad -o $target -i divider.scad -- ${scad_args[@]}
|
scad_out=$(colorscad -o $target -i divider.scad -- -D "index=$index" -D "icon=\"$icon\"" ${scad_args[@]})
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "\e[1;31mError generating $target\e[0m"
|
||||||
|
echo "$scad_out"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
(( index = (index + 1) % tabs ))
|
(( index = (index + 1) % tabs ))
|
||||||
done
|
done
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue