Code cleaning + add ears to the bottle clip! #22
4 changed files with 740 additions and 143 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +1,6 @@
|
||||||
[submodule "write"]
|
[submodule "write"]
|
||||||
path = write
|
path = write
|
||||||
url = https://github.com/rohieb/Write.scad
|
url = https://github.com/rohieb/Write.scad
|
||||||
|
[submodule "thing-logos"]
|
||||||
|
path = thing-logos
|
||||||
|
url = https://github.com/rohieb/thing-logos.git
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,14 @@
|
||||||
*
|
*
|
||||||
* This file was modified again by djerun to use the catars printed
|
* This file was modified again by djerun to use the catars printed
|
||||||
* by c3cat: https://www.printables.com/model/35076-cat-ears
|
* by c3cat: https://www.printables.com/model/35076-cat-ears
|
||||||
* as the logo and optionally allow use the easrs from
|
* as the logo and optionally allow use the ears from
|
||||||
* https://www.thingiverse.com/thing:5029374
|
* https://www.thingiverse.com/thing:5029374
|
||||||
* printed at scale 0.2 as glue-ins for additional ears.
|
* printed at scale 0.2 as glue-ins for additional ears.
|
||||||
*
|
*
|
||||||
* `Ohren_4.stl` and `catears.stl` need to be placed in `../stls/`
|
* This file has also being modified and reformatted by Ajabep to:
|
||||||
* for the symlinks to work otherwise `catears.stl` needs to be placed
|
* - be easier to understand
|
||||||
* at `./catears.stl` and `Ohren_4.stl` at `./catear.stl`.
|
* - be easier to modify and extend
|
||||||
*
|
* - be easier to use and build
|
||||||
* Version of the modification: 1.0
|
|
||||||
*
|
|
||||||
* See examples.scad for examples on how to use this module.
|
|
||||||
*
|
*
|
||||||
* The contents of this file are licenced under CC-BY-SA 3.0 Unported.
|
* The contents of this file are licenced under CC-BY-SA 3.0 Unported.
|
||||||
* See https://creativecommons.org/licenses/by-sa/3.0/deed for the
|
* See https://creativecommons.org/licenses/by-sa/3.0/deed for the
|
||||||
|
|
@ -28,14 +25,57 @@
|
||||||
include <write/Write.scad>
|
include <write/Write.scad>
|
||||||
use <catear_headband.scad>
|
use <catear_headband.scad>
|
||||||
|
|
||||||
|
|
||||||
|
// The name that is printed on your name tag.
|
||||||
|
NAME = "c3cat";
|
||||||
|
// The logo that is printed on your name tag. Has to be a DXF file. You can use the thing-logo repository for inspiration.
|
||||||
|
LOGO_FILE = ""; // empty string is catear model
|
||||||
|
// The font to be used for the name tag. See Write.scad for details.
|
||||||
|
FONT = ""; // empty string is for Orbitron font
|
||||||
|
|
||||||
|
// Format of the bottle clip you want to create.
|
||||||
|
FORMAT = 0; // [0=Club Mate 50cL, 1=Long Neck as 25cL Club Mate or Fritz-kola, 2=Euroform 2, 3=Steinie bottles]
|
||||||
|
|
||||||
|
// Style of the ears to add... or not add. This parameter can add a LOT of calculation time.
|
||||||
|
EARS_STYLE = 0; // [0=No ears, 1=Just arcs, 2=Filled ears with the same thickness, 3=Filled ears with the a thinner thickness inside, 4=Filled ears with the same thickness but shifted]
|
||||||
|
|
||||||
|
/* [Ear Parameters] */
|
||||||
|
|
||||||
|
// Space between both ears.
|
||||||
|
SPACE_BETWEEN_EARS = 13; // .1
|
||||||
|
|
||||||
|
// The X orientation of the ears, to give a more organic look. Angle in degree
|
||||||
|
EAR_TILT = 15; // .1
|
||||||
|
|
||||||
|
// The depth of the ear
|
||||||
|
EAR_DEPTH = 2; // .1
|
||||||
|
|
||||||
|
// The thickness of the ear arcs
|
||||||
|
EAR_THICKNESS = 1; // .1
|
||||||
|
|
||||||
|
// The width of the ear
|
||||||
|
EAR_SIDE_LEN = 6;
|
||||||
|
|
||||||
|
// How much the ear is bent. 1 = half circle, 0.00001 = almost straight
|
||||||
|
EAR_BEND_FACTOR = 0.5; // [.01:.01:1]
|
||||||
|
|
||||||
|
// How much the ear is stretched, useful for fox ears or this kind of shapes
|
||||||
|
EAR_STRETCH_FACTOR = 1.2;
|
||||||
|
|
||||||
|
|
||||||
|
/* [Render] */
|
||||||
|
// Whether to render the clip, the body.
|
||||||
|
RENDER_COLOR_CLIP = true;
|
||||||
|
// Whether to render the text part.
|
||||||
|
RENDER_COLOR_TEXT = true;
|
||||||
|
// Whether to render the logo part.
|
||||||
|
RENDER_COLOR_LOGO = true;
|
||||||
|
// Whether to render the cat ears part.
|
||||||
|
RENDER_COLOR_EARS = true;
|
||||||
|
|
||||||
|
// Set the number of facets for circles.
|
||||||
$fn = 360;
|
$fn = 360;
|
||||||
|
|
||||||
NAME = "c3cat";
|
|
||||||
LOGO_FILE = ""; // empty string is catear model
|
|
||||||
RENDER_COLOR_ONE = true;
|
|
||||||
RENDER_COLOR_TWO = true;
|
|
||||||
RENDER_COLOR_THREE = true;
|
|
||||||
USE_TINY_EARS = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates one instance of a bottle clip name tag. The default values are
|
* Creates one instance of a bottle clip name tag. The default values are
|
||||||
|
|
@ -48,41 +88,117 @@ USE_TINY_EARS = true;
|
||||||
* rl: the radius on the lower side of the clip
|
* rl: the radius on the lower side of the clip
|
||||||
* ht: the height of the clip
|
* ht: the height of the clip
|
||||||
* width: the thickness of the wall. Values near 2.5 usually result in a good
|
* width: the thickness of the wall. Values near 2.5 usually result in a good
|
||||||
* clippiness for PLA prints.
|
* clippiness for PLA prints.
|
||||||
* name: the name that is printed on your name tag. For the default ru/rt/ht
|
* name: the name that is printed on your name tag. For the default ru/rt/ht
|
||||||
* values, this string should not exceed 18 characters to fit on the name tag.
|
* values, this string should not exceed 18 characters to fit on the name tag.
|
||||||
* font: the path to a font for Write.scad.
|
* font: the path to a font for Write.scad.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* currently openscad fails to render the original `Ohren_4.stl` outside of the preview mode
|
|
||||||
* according to [the wiki](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/FAQ#Why_is_my_imported_STL_file_appearing_with_F5_but_not_F6?) this is the stls fault
|
|
||||||
* using meshlab to run `Filters` -> `Cleaning and Repairing` -> `Remove T-Vertices` by `Edge-Flip` with `Ratio` of `1000000` before importing the stl works but but two errors remain.
|
|
||||||
*/
|
|
||||||
scale([0.2, 0.2, 0.2]) {
|
scale([0.2, 0.2, 0.2]) {
|
||||||
difference() {
|
render_bottle_clip(
|
||||||
scale([5, 5, 5]) rotate(45, [0, 0, 1]) bottle_clip(name=NAME);
|
name=NAME,
|
||||||
translate([ 15*5, 0*5, 18*5]) rotate(80, [0, 1, 0]) catear();
|
font=FONT,
|
||||||
translate([-15*5, 0*5, 18*5]) rotate(-80, [0, 1, 0]) catear();
|
logo=LOGO_FILE,
|
||||||
|
format=FORMAT,
|
||||||
|
ears_style=EARS_STYLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a bottle clip with a name, logo and ears (depending the `ears_style` argument) for a bottle given as `format`.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* name: The name to write on the clip
|
||||||
|
* font: The font file to use
|
||||||
|
* logo: The logo file to print on the clip
|
||||||
|
*
|
||||||
|
* format: id of the bottle clip format
|
||||||
|
* 0: Club Mate 50cL
|
||||||
|
* 1: Long Neck as 25cL Club Mate or Fritz-kola
|
||||||
|
* 2: Euroform 2
|
||||||
|
* 3: Steinie bottles (with logo and name)
|
||||||
|
*
|
||||||
|
* ear_style: id of the ear style we want:
|
||||||
|
* -1 or less: Should NEVER being used. Unknown behavior.
|
||||||
|
* 0: No ears, just a bottle clip with a name and a logo.
|
||||||
|
* 1: Just arcs.
|
||||||
|
* 2: Filled ears with the same thickness
|
||||||
|
* 3: Filled ears with the a thinner thickness inside
|
||||||
|
* 4: Filled ears with the same thickness but shifted
|
||||||
|
*
|
||||||
|
* By default, thus function will generate a clip for a 50cL Club-Mate Bottle, with a headband with cat ears as a logo, and with a cat ears of the clip formed by 2 arcs.
|
||||||
|
*/
|
||||||
|
module render_bottle_clip(name="", font="", logo="", format=0, ears_style=1) {
|
||||||
|
name = name == "" ? "c3cat" : name ;
|
||||||
|
font = font == "" ? "write/orbitron.dxf" : font ;
|
||||||
|
|
||||||
|
if (format < 0 || format > 3) {
|
||||||
|
assert(false, str("Unknown format ", format, "."));
|
||||||
}
|
}
|
||||||
if (RENDER_COLOR_TWO) {
|
|
||||||
color("orange")
|
// Format == 0: Club-Mate 0.5L bottle
|
||||||
translate([ 15*5, 0*5, 18*5])
|
// Format == 1: Long Neck bottle (like fritz-kola) 0.25L
|
||||||
rotate(80, [0, 1, 0])
|
// Format == 2: Euroform 2 bottle
|
||||||
catear();
|
// Format == 3: Steinie bottle
|
||||||
}
|
ru = 13;
|
||||||
if (RENDER_COLOR_THREE) {
|
rl = format == 1 ? 15 : format == 2 ? 22.5 : 17.5 ;
|
||||||
color("yellow")
|
ht = format == 3 ? 13 : 26 ;
|
||||||
translate([-15*5, 0*5, 18*5])
|
width = 2.5;
|
||||||
rotate(-80, [0, 1, 0])
|
|
||||||
catear();
|
|
||||||
|
scale([5, 5, 5]) {
|
||||||
|
difference() {
|
||||||
|
bottle_clip(
|
||||||
|
name=NAME,
|
||||||
|
font=FONT,
|
||||||
|
logo=LOGO_FILE,
|
||||||
|
ru=ru,
|
||||||
|
rl=rl,
|
||||||
|
ht=ht,
|
||||||
|
width=width);
|
||||||
|
|
||||||
|
// Render ears if requested
|
||||||
|
if (ears_style > 0) {
|
||||||
|
ears(
|
||||||
|
ht=ht,
|
||||||
|
ru=ru,
|
||||||
|
rl=rl,
|
||||||
|
clip_width=width,
|
||||||
|
space_between_ears=SPACE_BETWEEN_EARS,
|
||||||
|
ear_tilt=EAR_TILT,
|
||||||
|
ear_depth=EAR_DEPTH,
|
||||||
|
ear_thickness=EAR_THICKNESS,
|
||||||
|
ear_side_len=EAR_SIDE_LEN,
|
||||||
|
ear_bend_factor=EAR_BEND_FACTOR,
|
||||||
|
ear_stretch_factor=EAR_STRETCH_FACTOR,
|
||||||
|
ears_style=ears_style
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render ears if requested
|
||||||
|
if (ears_style > 0 && RENDER_COLOR_EARS) {
|
||||||
|
ears(
|
||||||
|
ht=ht,
|
||||||
|
ru=ru,
|
||||||
|
rl=rl,
|
||||||
|
clip_width=width,
|
||||||
|
space_between_ears=SPACE_BETWEEN_EARS,
|
||||||
|
ear_tilt=EAR_TILT,
|
||||||
|
ear_depth=EAR_DEPTH,
|
||||||
|
ear_thickness=EAR_THICKNESS,
|
||||||
|
ear_side_len=EAR_SIDE_LEN,
|
||||||
|
ear_bend_factor=EAR_BEND_FACTOR,
|
||||||
|
ear_stretch_factor=EAR_STRETCH_FACTOR,
|
||||||
|
ears_style=ears_style
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module name(name, font, rl, ht, ru) {
|
module name(name, font, rl, ht, ru) {
|
||||||
writecylinder(
|
writecylinder(
|
||||||
text=name,
|
text=name,
|
||||||
where=[0,0,0],
|
where=[0, 0, 0],
|
||||||
radius=rl+0.5,
|
radius=rl+0.5,
|
||||||
height=ht/13*7,
|
height=ht/13*7,
|
||||||
h=ht/13*4,
|
h=ht/13*4,
|
||||||
|
|
@ -91,22 +207,23 @@ module name(name, font, rl, ht, ru) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module logo(logo, rl, ht, ru, width) {
|
module logo(logo, rl, ht, ru, width) {
|
||||||
echo("logo: ", logo);
|
echo(logo=logo);
|
||||||
if(logo == "") {
|
if(logo == "") {
|
||||||
|
// No logo file specified? Let's print a catear headband instead!
|
||||||
ear_size=ht;
|
ear_size=ht;
|
||||||
echo("ht: ", ht);
|
echo(ht=ht);
|
||||||
echo("ru: ", ru);
|
echo(ru=ru);
|
||||||
echo("rl: ", rl);
|
echo(rl=rl);
|
||||||
echo("width: ", width);
|
echo(width=width);
|
||||||
translate([0,-max(ru,rl),ht*3/4+.5])
|
translate([0, -max(ru,rl), ht*3/4+.5])
|
||||||
rotate([90,0,0])
|
rotate([90, 0, 0])
|
||||||
scale([1,1,1])
|
scale([1, 1, 1])
|
||||||
scale([ht/100,ht/100,1])
|
scale([ht/100, ht/100, 1])
|
||||||
translate([0, -ht/2,0])
|
translate([0, -ht/2, 0])
|
||||||
rotate(-90, [0, 0, 1])
|
rotate(-90, [0, 0, 1])
|
||||||
catear_headband(
|
catear_headband(
|
||||||
size=ear_size,
|
size=ear_size,
|
||||||
height=max(ru,rl),
|
height=max(ru, rl),
|
||||||
thickness=width,
|
thickness=width,
|
||||||
stretch_len=0,
|
stretch_len=0,
|
||||||
tip_len=0,
|
tip_len=0,
|
||||||
|
|
@ -114,106 +231,562 @@ module logo(logo, rl, ht, ru, width) {
|
||||||
with_rake=false
|
with_rake=false
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// The logo has been split in 3 parts. // well was... TODO
|
translate([0, 0, ht*3/4-0.1])
|
||||||
/*
|
rotate([90, 0, 0])
|
||||||
rotate([0,0,-48]) translate([0,0,ht*3/4-0.1])
|
scale([0.8, 0.8, 1])
|
||||||
rotate([90,0,0])
|
scale([ht/100, ht/100, 1])
|
||||||
scale([0.9,0.9,1])
|
translate([-18, -22, 0.5])
|
||||||
scale([ht/100,ht/100,1])
|
linear_extrude(height=max(ru, rl)*2)
|
||||||
translate([-25,-29,0.5])
|
import(logo);
|
||||||
linear_extrude(height=max(ru,rl)*2)
|
|
||||||
import("logo_1.dxf");
|
|
||||||
*/
|
|
||||||
translate([0,0,ht*3/4-0.1])
|
|
||||||
rotate([90,0,0])
|
|
||||||
scale([0.8,0.8,1])
|
|
||||||
scale([ht/100,ht/100,1])
|
|
||||||
translate([-18,-22,0.5])
|
|
||||||
linear_extrude(height=max(ru,rl)*2)
|
|
||||||
import(logo);
|
|
||||||
/*
|
|
||||||
rotate([0,0,44]) translate([0,0,ht*3/4-0.1])
|
|
||||||
rotate([90,0,0])
|
|
||||||
scale([0.7,0.7,1])
|
|
||||||
scale([ht/100,ht/100,1])
|
|
||||||
translate([-25,-26,0.5])
|
|
||||||
linear_extrude(height=max(ru,rl)*2)
|
|
||||||
import("logo_3.dxf");
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Bootle Clip with logo and/or text, depending what is asked using the RENDER_COLOR_* variables.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* Size:
|
||||||
|
* ht: the height of the bottle clip
|
||||||
|
* ru: the radius on the upper side of the clip
|
||||||
|
* rl: the radius on the lower side of the clip
|
||||||
|
* width: the thickness of the bottle clip
|
||||||
|
*
|
||||||
|
* name: The name to write on the clip
|
||||||
|
* font: The font file to use
|
||||||
|
* logo: The logo file to print on the clip
|
||||||
|
*
|
||||||
|
* By default, will create a Club-Mate 0.5L bottle clip.
|
||||||
|
*
|
||||||
|
* An empty logo file will create a headband with cat ears as a logo.
|
||||||
|
*/
|
||||||
module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="c3cat", font="write/orbitron.dxf", logo="") {
|
module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="c3cat", font="write/orbitron.dxf", logo="") {
|
||||||
e=100; // should be big enough, used for the outer boundary of the text/logo
|
e = 100; // should be big enough, used for the outer boundary of the text/logo
|
||||||
rotate([0,0,-45]) {
|
|
||||||
// main cylinder
|
// main cylinder
|
||||||
if (RENDER_COLOR_ONE) {
|
if (RENDER_COLOR_CLIP) {
|
||||||
color("black") difference() {
|
color("#006168") difference() {
|
||||||
cylinder(r1=rl+width, r2=ru+width, h=ht);
|
cylinder(r1=rl+width, r2=ru+width, h=ht);
|
||||||
difference() {
|
difference() {
|
||||||
union() {
|
union() {
|
||||||
name(name=name, font=font, rl=rl, ht=ht, ru=ru);
|
name(name=name, font=font, rl=rl, ht=ht, ru=ru);
|
||||||
logo(logo=logo, rl=rl, ht=ht, ru=ru, width=width);
|
logo(logo=logo, rl=rl, ht=ht, ru=ru, width=width);
|
||||||
}
|
|
||||||
cylinder(r1=rl+width/2, r2=ru+width/2, h=ht);
|
|
||||||
}
|
}
|
||||||
translate([0,0,-1])
|
|
||||||
cylinder(r1=rl, r2=ru, h=ht+2);
|
|
||||||
// finally, substract a cube as a gap so we can clip it to the bottle
|
|
||||||
rotate([0, 0, 45])
|
|
||||||
translate([0,0,-1])
|
|
||||||
cube([50,50,50]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// text
|
|
||||||
if (RENDER_COLOR_TWO) {
|
|
||||||
color("orange") difference() {
|
|
||||||
name(name=name, font=font, rl=rl, ht=ht, ru=ru);
|
|
||||||
cylinder(r1=rl+width/2, r2=ru+width/2, h=ht);
|
cylinder(r1=rl+width/2, r2=ru+width/2, h=ht);
|
||||||
outer_cutoff(rl, e, ru, ht, width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clear_anti_aliasing = 0.01; // The margin to avoid empty surfaces in the preview.
|
||||||
|
translate([0, 0, -clear_anti_aliasing/2])
|
||||||
|
cylinder(r1=rl, r2=ru, h=ht+clear_anti_aliasing);
|
||||||
|
// finally, subtract a cube as a gap so we can clip it to the bottle
|
||||||
|
rotate([0, 0, 45])
|
||||||
|
translate([0, 0, -1])
|
||||||
|
cube([50, 50, 50]);
|
||||||
}
|
}
|
||||||
// logo
|
}
|
||||||
if (RENDER_COLOR_THREE) {
|
// text
|
||||||
color("yellow") difference() {
|
if (RENDER_COLOR_TEXT) {
|
||||||
logo(logo=logo, rl=rl, ht=ht, ru=ru, width=2*width);
|
color("orange") difference() {
|
||||||
cylinder(r1=rl+width/2, r2=ru+width/2, h=ht);
|
name(name=name, font=font, rl=rl, ht=ht, ru=ru);
|
||||||
outer_cutoff(rl, e, ru, ht, width);
|
cylinder(r1=rl+width/2, r2=ru+width/2, h=ht);
|
||||||
}
|
outer_cutoff(rl, e, ru, ht, width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// logo
|
||||||
|
if (RENDER_COLOR_LOGO) {
|
||||||
|
color("yellow") difference() {
|
||||||
|
logo(logo=logo, rl=rl, ht=ht, ru=ru, width=2*width);
|
||||||
|
cylinder(r1=rl+width/2, r2=ru+width/2, h=ht);
|
||||||
|
outer_cutoff(rl, e, ru, ht, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module outer_cutoff(rl, e, ru, ht, width) {
|
module outer_cutoff(rl, e, ru, ht, width) {
|
||||||
// outer cylinder which is substracted, so the text and the logo end
|
// outer cylinder which is subtracted, so the text and the logo end
|
||||||
// somewhere on the outside ;-)
|
// somewhere on the outside ;-)
|
||||||
difference () {
|
difference () {
|
||||||
cylinder(r1=rl+e, r2=ru+e, h=ht);
|
cylinder(r1=rl+e, r2=ru+e, h=ht);
|
||||||
translate([0,0,-1])
|
translate([0, 0, -1])
|
||||||
// Note: bottom edges of characters are hard to print when character
|
// Note: bottom edges of characters are hard to print when character
|
||||||
// depth is > 0.7
|
// depth is > 0.7
|
||||||
cylinder(r1=rl+width+0.7, r2=ru+width+0.7, h=ht+2);
|
cylinder(r1=rl+width+0.7, r2=ru+width+0.7, h=ht+2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module catear() {
|
/**
|
||||||
if (USE_TINY_EARS) {
|
* Will create a pair of ears to the bottle clip. By default, they are cat ears.
|
||||||
rotate(-90, [0, 0, 1]) union() {
|
*
|
||||||
scale([1, 1 ,1]) translate([0, -85]) import("catear.stl");
|
* Parameters:
|
||||||
scale([1, -1, 1]) translate([0, -85]) import("catear.stl");
|
*
|
||||||
|
* Positioning:
|
||||||
|
* ht: the height of the bottle clip, used to scale the ears
|
||||||
|
* ru: the radius on the upper side of the clip, used to position the ears
|
||||||
|
* rl: the radius on the lower side of the clip, used to position the ears
|
||||||
|
* clip_width: the thickness of the bottle clip
|
||||||
|
*
|
||||||
|
* Ears:
|
||||||
|
* space_between_ears: Space between both ears.
|
||||||
|
* ear_tilt: The X orientation of the ears, to give a more organic look. Angle in degree
|
||||||
|
*
|
||||||
|
* ear_depth: the depth of the ear
|
||||||
|
* ear_thickness: the thickness of the ear arcs
|
||||||
|
* ear_side_len: the width of the ear
|
||||||
|
* ear_bend_factor: how much the ear is bent. 1 = half circle, 0.00001 = almost straight
|
||||||
|
* ear_stretch_factor: how much the ear is stretched, useful for fox ears or this kind of shapes
|
||||||
|
*
|
||||||
|
* ear_chamfer: size of the chamfer to apply to the edges
|
||||||
|
* ear_chamfer_shape: The shape of the chamfer: "cone", "curve", "curve-in", "pyramid", maybe some others
|
||||||
|
* ear_details: whether to chamfer also the partial arcs
|
||||||
|
*
|
||||||
|
* ear_style: id of the ear style we want:
|
||||||
|
* 0 or less: Should NEVER being used. Unknown behavior.
|
||||||
|
* 1: Just arcs.
|
||||||
|
* 2: Filled ears with the same thickness
|
||||||
|
* 3: Filled ears with the a thinner thickness inside
|
||||||
|
* 4: Filled ears with the same thickness but shifted
|
||||||
|
*/
|
||||||
|
module ears(ht, ru, rl, clip_width, space_between_ears = 15, ear_tilt = 15, ear_depth=2, ear_thickness=.6, ear_side_len=6, ear_bend_factor=0.5, ear_stretch_factor=1.2, ear_chamfer=1, ear_chamfer_shape="curve", ear_details=true, ears_style=1) {
|
||||||
|
|
||||||
|
// This is the radius on which the ears has to be to be centered on the clip.
|
||||||
|
radius = ru+(clip_width/2);
|
||||||
|
|
||||||
|
|
||||||
|
// Math time!
|
||||||
|
|
||||||
|
// The ears are not that bad without this calculation, but I want to improve the base and the join between ears and the clip.
|
||||||
|
// Actually, by tilting the ear, a side of the end will go deeper withing the clip, but the other side may be separated from the clip.
|
||||||
|
// So we need to translate the ears more deeper within the clip to avoid any separation
|
||||||
|
//
|
||||||
|
// So! Trigonometry!
|
||||||
|
//
|
||||||
|
// Viewed from the right of the ear, an ear is like that:
|
||||||
|
//
|
||||||
|
// A
|
||||||
|
// |\
|
||||||
|
// | \
|
||||||
|
// h | \ s
|
||||||
|
// | \
|
||||||
|
// +----\ D
|
||||||
|
// C l \
|
||||||
|
// \
|
||||||
|
// \
|
||||||
|
// \
|
||||||
|
// B
|
||||||
|
//
|
||||||
|
// A is the side of the ear which is going upper
|
||||||
|
// B is the side of the ear which is going deeper
|
||||||
|
// C is the clip level
|
||||||
|
// D is the midpoint between A and B
|
||||||
|
// s is the depth of the ear (from A to B!)
|
||||||
|
// h is the heigh we are searching for. We will lower the ear of this size.
|
||||||
|
// l is the half of length of the fingerprint of the ear in the clip.
|
||||||
|
// ADC is the tilt angle
|
||||||
|
// ACD is a 90 degree angle
|
||||||
|
//
|
||||||
|
// So, to find the h length, we can use s and the angle ADC.
|
||||||
|
//
|
||||||
|
// CAH => We don't have the adjacent length. So, we can't use this formula
|
||||||
|
// SOH => sin(ADC) = h / (s/2)
|
||||||
|
// TOA => We don't have the adjacent length. So, we can't use this formula
|
||||||
|
//
|
||||||
|
// sin(ADC) = h / (s/2)
|
||||||
|
// sin(ADC) * (s/2) = h
|
||||||
|
//
|
||||||
|
// BUT! Since we will raise the Clip level C to the end of the ear A, the print of the ear within the clip will be shifted of `l`!
|
||||||
|
// So, let's calculate it!
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// CAH => cos(ADC) = l / (s/2)
|
||||||
|
// SOH => Is not targeting what we want.
|
||||||
|
// TOA => The opposed side is less precise than the hypotenuse, so, we will not use this formula
|
||||||
|
//
|
||||||
|
// cos(ADC) = l / (s/2)
|
||||||
|
// cos(ADC) * (s/2) = l
|
||||||
|
|
||||||
|
tilt_compensation = sin(ear_tilt) * (ear_depth/2);
|
||||||
|
tilt_shift = cos(ear_tilt) * (ear_depth/2);
|
||||||
|
|
||||||
|
// Pythagoras!
|
||||||
|
// Viewed from the top, an ear is like that:
|
||||||
|
//
|
||||||
|
// A s
|
||||||
|
// +----- E
|
||||||
|
// | /
|
||||||
|
// x | / r
|
||||||
|
// | /
|
||||||
|
// |/
|
||||||
|
// c
|
||||||
|
//
|
||||||
|
// c is the center of the circle forming the top surface of the clip
|
||||||
|
// E is the perfect position of the ear
|
||||||
|
// r is the radius, calculated previously
|
||||||
|
// s is the half of the space between ears
|
||||||
|
// x is the position of the ears on the Y axis. It's what we want to calculate
|
||||||
|
// A is the projection of the ears on the Y axis
|
||||||
|
// A is a 90 degrees angle
|
||||||
|
//
|
||||||
|
// x**2 + s**2 = r**2
|
||||||
|
// x**2 = r**2 - s**2
|
||||||
|
// x = sqrt( r**2 - s**2 )
|
||||||
|
s = space_between_ears / 2;
|
||||||
|
pos_ears_yaxis = sqrt(pow(radius, 2) - pow(s, 2));
|
||||||
|
|
||||||
|
// Trigonometry!
|
||||||
|
// Now, lets, rotate the ears to be at tangent to the clip
|
||||||
|
//
|
||||||
|
// From the top, an ear is like this:
|
||||||
|
//
|
||||||
|
// A s
|
||||||
|
// +------- E
|
||||||
|
// | /
|
||||||
|
// | /
|
||||||
|
// x | / r
|
||||||
|
// | /
|
||||||
|
// | /
|
||||||
|
// | /
|
||||||
|
// |/
|
||||||
|
// C
|
||||||
|
//
|
||||||
|
// E is the position of the ears
|
||||||
|
// C is the center of the clip
|
||||||
|
// A is the projection of the ears on the Y axis
|
||||||
|
// r is the radius
|
||||||
|
// s is the half of the space between the ears.
|
||||||
|
// x is the same from the last figure.
|
||||||
|
// A is a 90 degrees angle
|
||||||
|
//
|
||||||
|
// The angle of the ear is the same as the angle ACE.
|
||||||
|
// So, we need to calculate this angle
|
||||||
|
//
|
||||||
|
// Since, we already know every lengths s, r and x, we can choose the formula we want!
|
||||||
|
// IDK which one is faster, but that could be a nice optimization.
|
||||||
|
//
|
||||||
|
// CAH => cos(ACE) = x/r
|
||||||
|
// SOH => sin(ACE) = s/r
|
||||||
|
// TOA => tan(ACE) = x/s
|
||||||
|
//
|
||||||
|
// Let's choose the sine, since it's linked to the our best raw non-rounded values. It will give us values with the best accuracy.
|
||||||
|
ears_angle = asin(s/radius);
|
||||||
|
|
||||||
|
// Like that, it's good enough. And it could be committed like that. Actually, my first model (never published it) was like that.
|
||||||
|
// BUT we can do better and smarter! (and we will probably need to refine it)
|
||||||
|
|
||||||
|
// If we stop our math here, we centered the middle of the ear on the clip. But the end of the ears are NOT centered.
|
||||||
|
//
|
||||||
|
// So, we will use (again) Pythagoras!
|
||||||
|
// We want to position the ear (on its center) to put the end of the ear in the radius.
|
||||||
|
//
|
||||||
|
// Form the top, an ear looks like that:
|
||||||
|
// e
|
||||||
|
// /|
|
||||||
|
// / |
|
||||||
|
// / |
|
||||||
|
// r / | h
|
||||||
|
// / |
|
||||||
|
// / |
|
||||||
|
// / |
|
||||||
|
// C /-------+ E
|
||||||
|
// p
|
||||||
|
//
|
||||||
|
// C is the center of the clip
|
||||||
|
// e is the end of the ear
|
||||||
|
// E is the middle of the ear.
|
||||||
|
// r is the Radius
|
||||||
|
// h is the half of the width of the ear
|
||||||
|
// E is a 90 degrees angles
|
||||||
|
// p is wanted length to position correctly the center of the ear.
|
||||||
|
//
|
||||||
|
// h**2 + p**2 = r**2
|
||||||
|
// p**2 = r**2 - h**2
|
||||||
|
// p = sqrt(r**2 - h**2)
|
||||||
|
|
||||||
|
center_radius = sqrt( pow(radius, 2) - pow((ear_side_len+(tilt_shift))/2, 2) );
|
||||||
|
|
||||||
|
// So, we need to update the projection of the ears on the Y axis, based on center_radius, instead of radius.
|
||||||
|
pos_ears_yaxis_end_ear = sqrt(pow(center_radius, 2) - pow(s, 2));
|
||||||
|
|
||||||
|
translate([0, -pos_ears_yaxis_end_ear, ht-tilt_compensation-(ear_thickness/2)])
|
||||||
|
rotate(90, [0, 0, 1])
|
||||||
|
rotate(90, [0, 1, 0])
|
||||||
|
union() {
|
||||||
|
scale([1, 1 ,1])
|
||||||
|
translate([0, space_between_ears/2, 0])
|
||||||
|
rotate(ears_angle, [1, 0, 0])
|
||||||
|
rotate(-ear_tilt, [0, 1, 0])
|
||||||
|
ear_with_style(
|
||||||
|
style=ears_style,
|
||||||
|
depth=ear_depth,
|
||||||
|
thickness=ear_thickness,
|
||||||
|
side_len=ear_side_len,
|
||||||
|
bend_factor=ear_bend_factor,
|
||||||
|
stretch_factor=ear_stretch_factor,
|
||||||
|
chamfer=ear_chamfer,
|
||||||
|
chamfer_shape=ear_chamfer_shape,
|
||||||
|
details=ear_details
|
||||||
|
);
|
||||||
|
scale([1, -1, 1])
|
||||||
|
translate([0, space_between_ears/2, 0])
|
||||||
|
rotate(ears_angle, [1, 0, 0])
|
||||||
|
rotate(-ear_tilt, [0, 1, 0])
|
||||||
|
ear_with_style(
|
||||||
|
style=ears_style,
|
||||||
|
depth=ear_depth,
|
||||||
|
thickness=ear_thickness,
|
||||||
|
side_len=ear_side_len,
|
||||||
|
bend_factor=ear_bend_factor,
|
||||||
|
stretch_factor=ear_stretch_factor,
|
||||||
|
chamfer=ear_chamfer,
|
||||||
|
chamfer_shape=ear_chamfer_shape,
|
||||||
|
details=ear_details
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module that creates an ear given a style id.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
* style: id of the ear style we want:
|
||||||
|
* 0 or less: Should NEVER being used. Unknown behavior.
|
||||||
|
* 1: Just arcs.
|
||||||
|
* 2: Filled ears with the same thickness
|
||||||
|
* 3: Filled ears with the a thinner thickness inside
|
||||||
|
* 4: Filled ears with the same thickness but shifted
|
||||||
|
*
|
||||||
|
* depth: the depth of the ear
|
||||||
|
* thickness: the thickness of the ear arcs
|
||||||
|
* side_len: the width of the ear
|
||||||
|
* bend_factor: how much the ear is bent. 1 = half circle, 0.00001 = almost straight
|
||||||
|
* stretch_factor: how much the ear is stretched, useful for fox ears or this kind of shapes
|
||||||
|
*
|
||||||
|
* chamfer: size of the chamfer to apply to the edges
|
||||||
|
* chamfer_shape: The shape of the chamfer: "cone", "curve", "curve-in", "pyramid", maybe some others
|
||||||
|
* details: whether to chamfer also the partial arcs
|
||||||
|
*
|
||||||
|
* By default, this module creates a cat ear countour.
|
||||||
|
*/
|
||||||
|
module ear_with_style(style = 1, depth, thickness, side_len=30, bend_factor=0.5, stretch_factor=1.2, chamfer=1, chamfer_shape="curve", details=true) {
|
||||||
|
if (style == 1 || style == 2 || style == 3 || style == 4) {
|
||||||
|
// Style 1: Just arcs
|
||||||
|
// Style 2: Filled ears with the same thickness
|
||||||
|
// Style 3: Filled ears with the a thinner thickness inside
|
||||||
|
// Style 4: Filled ears with the same thickness but shifted
|
||||||
|
|
||||||
|
ear(
|
||||||
|
depth=depth,
|
||||||
|
thickness=thickness,
|
||||||
|
side_len=side_len,
|
||||||
|
bend_factor=bend_factor,
|
||||||
|
stretch_factor=stretch_factor,
|
||||||
|
chamfer=chamfer,
|
||||||
|
chamfer_shape=chamfer_shape,
|
||||||
|
details=details
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (style == 2 || style == 3 || style == 4) {
|
||||||
|
// Style 2: Filled ears with the same thickness
|
||||||
|
// Style 3: Filled ears with the a thinner thickness inside
|
||||||
|
// Style 4: Filled ears with the same thickness but shifted
|
||||||
|
|
||||||
|
thickness_steps = thickness*0.5;
|
||||||
|
depth_steps = (depth-thickness)/((side_len / thickness_steps));
|
||||||
|
|
||||||
|
for (round_side_len = [side_len-thickness_steps:-thickness_steps:0]) {
|
||||||
|
// round_side_len = side_len - (thickness_steps * x)
|
||||||
|
// (thickness_steps * x) + round_side_len = side_len
|
||||||
|
// (thickness_steps * x) = side_len - round_side_len
|
||||||
|
// x = (side_len - round_side_len) / thickness_steps
|
||||||
|
x = (side_len - round_side_len) / thickness_steps;
|
||||||
|
round_shift = depth_steps * x;
|
||||||
|
current_depth = depth - (style == 3 ? round_shift : 0);
|
||||||
|
translation = style == 2 ? 0 : round_shift / 2;
|
||||||
|
|
||||||
|
translate([0, 0, translation])
|
||||||
|
color("green")
|
||||||
|
ear(
|
||||||
|
depth=current_depth,
|
||||||
|
thickness=thickness,
|
||||||
|
side_len=round_side_len,
|
||||||
|
bend_factor=bend_factor,
|
||||||
|
stretch_factor=stretch_factor,
|
||||||
|
chamfer=chamfer,
|
||||||
|
chamfer_shape=chamfer_shape,
|
||||||
|
details=true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates one instance of a bottle clip name tag suitable for 0.33l longneck
|
* Module that creates an ear shape.
|
||||||
* bottles (like fritz cola, etc.). All parameters are passed to the module
|
*
|
||||||
* bottle_clip(), see there for their documentation.
|
* Parameters:
|
||||||
*/
|
*
|
||||||
module bottle_clip_longneck(name="c3cat", width=2.5, font="write/orbitron.dxf") {
|
* depth: the depth of the ear
|
||||||
bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, font=font, logo="");
|
* thickness: the thickness of the ear arcs
|
||||||
|
* side_len: the width of the ear
|
||||||
|
* bend_factor: how much the ear is bent. 1 = half circle, 0.00001 = almost straight
|
||||||
|
* stretch_factor: how much the ear is stretched, useful for fox ears or this kind of shapes
|
||||||
|
*
|
||||||
|
* chamfer: size of the chamfer to apply to the edges
|
||||||
|
* chamfer_shape: The shape of the chamfer: "cone", "curve", "curve-in", "pyramid", maybe some others
|
||||||
|
* details: whether to chamfer also the partial arcs
|
||||||
|
*
|
||||||
|
* By default, this module creates a cat ear.
|
||||||
|
*
|
||||||
|
* I don't remember the original author of this module. I refactored it and improved it a bit. Documentation is from me.
|
||||||
|
*/
|
||||||
|
module ear(depth, thickness, side_len=30, bend_factor=0.5, stretch_factor=1.2, chamfer=1, chamfer_shape="curve", details=true) {
|
||||||
|
depth = depth == undef ? 20 : depth ;
|
||||||
|
thickness = thickness == undef ? 3 : thickness ;
|
||||||
|
|
||||||
|
// $A and $B are the end of the ear
|
||||||
|
// $C is the higher end point.
|
||||||
|
$A=[0, side_len/2];
|
||||||
|
$B=[0,-side_len/2];
|
||||||
|
// From the front, an ear looks like:
|
||||||
|
//
|
||||||
|
// $C
|
||||||
|
// /|\
|
||||||
|
// / | \
|
||||||
|
// / | \
|
||||||
|
// /---+---\
|
||||||
|
// $B c $A
|
||||||
|
//
|
||||||
|
// c is the origin of the ear.
|
||||||
|
// $Bc$C and $Ac$C are 90deg angles.
|
||||||
|
//
|
||||||
|
// The length [$B $A] is `side_len`
|
||||||
|
// Thus, [$B c] == [c $A] == side_len/2
|
||||||
|
//
|
||||||
|
// Since SOH, sin(angle) = Opposed / Hypotenuse
|
||||||
|
// sin(angle) = Opposed / Hypotenuse
|
||||||
|
// sin(angle) * Hypotenuse = Opposed
|
||||||
|
// Hypotenuse = Opposed / sin(angle)
|
||||||
|
//
|
||||||
|
// Thus, the `(side_len/2/sin(120))` implies that "The opposed side of the 120 angle is `(side_len/2)` length" and is the formula to know the size of the hypotenuse.
|
||||||
|
// Moreover, a 120deg angle in a right rectangle does not exists: the sum of all the angles of a triangle needs to be 180deg. I think the author tried, instead, to use the 60 as an angle, since the sinus is the same.
|
||||||
|
//
|
||||||
|
// The correct formula should be `((side_len/2)*tan(60))`: since $C$B$A should a 60deg angle to have an equilateral `$A$B$C` triangle, the product of the tangent ("TOA") of this angle and the adjacent segment [$B c] will give us the size of length of the opposed segment [$C c].
|
||||||
|
//
|
||||||
|
// MOREOVER, the product of the magic number `1.5` with the divisor `sin(120)`... is actually the result of the `tan(60)`!
|
||||||
|
//
|
||||||
|
// The original formula was:
|
||||||
|
// $C=[-(side_len/2/sin(120))*1.5*stretch_factor, 0];
|
||||||
|
$C=[-((side_len/2)*tan(60))*stretch_factor, 0];
|
||||||
|
|
||||||
|
// $a, $b and $c are the distance between the different points of the triangle.
|
||||||
|
$c=sqrt(pow($A.x-$B.x, 2)+pow($A.y-$B.y, 2));
|
||||||
|
$b=sqrt(pow($A.x-$C.x, 2)+pow($A.y-$C.y, 2));
|
||||||
|
$a=sqrt(pow($C.x-$B.x, 2)+pow($C.y-$B.y, 2));
|
||||||
|
|
||||||
|
// $hc is the height of $C.
|
||||||
|
$hc=-$C.x;
|
||||||
|
|
||||||
|
// $alpha should be the angle of the $B$A$C. This should is 60deg if `stretch_factor` is `1`, but this angle change with this factor.
|
||||||
|
$alpha=asin($hc/$b);
|
||||||
|
$beta=$alpha;
|
||||||
|
// $gamma is the $A$C$B angle.
|
||||||
|
$gamma=180-$alpha-$beta;
|
||||||
|
$delta=180*bend_factor;
|
||||||
|
$bend_radius=$a/(2*cos(90-$delta/2));
|
||||||
|
$bend_offset=$bend_radius*sin(90-$delta/2);
|
||||||
|
|
||||||
|
translate([0, -$c/2, 0])
|
||||||
|
rotate($beta, [0, 0, 1])
|
||||||
|
translate([0, $a/2, 0])
|
||||||
|
translate([$bend_offset, 0, 0])
|
||||||
|
color("#00ffff")
|
||||||
|
chamfer(size=(details)?chamfer:0, child_h=depth, child_bot=-depth/2, shape=chamfer_shape)
|
||||||
|
partial_ring(
|
||||||
|
part=$delta/360,
|
||||||
|
radius=$bend_radius,
|
||||||
|
thickness=thickness,
|
||||||
|
height=depth
|
||||||
|
);
|
||||||
|
translate([0, $c/2, 0])
|
||||||
|
rotate(-$alpha, [0, 0, 1])
|
||||||
|
translate([0, -$b/2, 0])
|
||||||
|
translate([$bend_offset, 0, 0])
|
||||||
|
color("#ff00ff")
|
||||||
|
chamfer(size=(details)?chamfer:0, child_h=depth, child_bot=-depth/2, shape=chamfer_shape)
|
||||||
|
partial_ring(
|
||||||
|
part=$delta/360,
|
||||||
|
radius=$bend_radius,
|
||||||
|
thickness=thickness,
|
||||||
|
height=depth
|
||||||
|
);
|
||||||
|
translate($A) color("#aaaaaa")
|
||||||
|
chamfer(size=chamfer, child_h=depth, child_bot=-depth/2, shape=chamfer_shape)
|
||||||
|
cylinder(h=depth, d=thickness, center=true);
|
||||||
|
translate($B) color("#bbbbbb")
|
||||||
|
chamfer(size=chamfer, child_h=depth, child_bot=-depth/2, shape=chamfer_shape)
|
||||||
|
cylinder(h=depth, d=thickness, center=true);
|
||||||
|
translate($C) color("#cccccc")
|
||||||
|
chamfer(size=chamfer, child_h=depth, child_bot=-depth/2, shape=chamfer_shape)
|
||||||
|
cylinder(h=depth, d=thickness, center=true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Steinie-Tag has been removed since it does not support logos.
|
* This module is not mine.
|
||||||
**/
|
*/
|
||||||
|
module partial_ring(part, radius, thickness, height) {
|
||||||
|
rotate(180-180*part, [0, 0, 1])
|
||||||
|
rotate_extrude(angle=360*part)
|
||||||
|
translate([radius, 0])
|
||||||
|
square([thickness, height], center=true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module is not mine.
|
||||||
|
*/
|
||||||
|
module chamfer(size=2, child_h=5, child_bot=0, shape="curve") {
|
||||||
|
chamfer_size=size;
|
||||||
|
|
||||||
|
module chamfer_shape() {
|
||||||
|
if (shape == "cone") {
|
||||||
|
$fn=16;
|
||||||
|
cylinder(chamfer_size/2,chamfer_size/2,0);
|
||||||
|
} else if (shape == "curve") {
|
||||||
|
$fn=4;
|
||||||
|
for( y = [0:1/$fn:1]) {
|
||||||
|
cylinder(chamfer_size/2*(1-y),chamfer_size/2/cos(180/$fn)*y,0);
|
||||||
|
}
|
||||||
|
} else if (shape == "curve-in") {
|
||||||
|
$fn=16;
|
||||||
|
intersection() {
|
||||||
|
sphere(chamfer_size/2/cos(180/$fn));
|
||||||
|
translate([0,0,chamfer_size/2])
|
||||||
|
cube(chamfer_size, center=true);
|
||||||
|
}
|
||||||
|
} else if (shape == "pyramid") {
|
||||||
|
$fn=4;
|
||||||
|
cylinder(chamfer_size/2/cos(180/$fn),chamfer_size/2,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module lower_chamfer() {
|
||||||
|
minkowski()
|
||||||
|
{
|
||||||
|
linear_extrude(0.0001) difference() {
|
||||||
|
square([1000,1000],center=true);
|
||||||
|
projection()children(0);
|
||||||
|
}
|
||||||
|
chamfer_shape();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module upper_chamfer() {
|
||||||
|
scale([1,1,-1])lower_chamfer()children();
|
||||||
|
}
|
||||||
|
|
||||||
|
render()difference() {
|
||||||
|
children();
|
||||||
|
translate([0,0,child_bot])lower_chamfer()children();
|
||||||
|
translate([0,0,child_bot+child_h])upper_chamfer()children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,37 @@ set -u
|
||||||
|
|
||||||
VERSION=2.2
|
VERSION=2.2
|
||||||
LOGO_FILE='""'
|
LOGO_FILE='""'
|
||||||
TINY_EARS=false
|
|
||||||
FN=90
|
FN=90
|
||||||
|
EARS_STYLE=1
|
||||||
|
|
||||||
NAME="\"$1\""
|
NAME="\"$1\""
|
||||||
|
|
||||||
# usage: render NAME PART
|
# usage: render NAME PART [BOTTLE_FORMAT]
|
||||||
render() {
|
render() {
|
||||||
case "$2" in
|
case "$2" in
|
||||||
body)
|
body)
|
||||||
ONE=true
|
CLIP=true
|
||||||
TWO=false
|
TEXT=false
|
||||||
THREE=false
|
LOGO=false
|
||||||
|
EARS=false
|
||||||
;;
|
;;
|
||||||
name)
|
name)
|
||||||
ONE=false
|
CLIP=false
|
||||||
TWO=true
|
TEXT=true
|
||||||
THREE=false
|
LOGO=false
|
||||||
|
EARS=false
|
||||||
;;
|
;;
|
||||||
logo)
|
logo)
|
||||||
ONE=false
|
CLIP=false
|
||||||
TWO=false
|
TEXT=false
|
||||||
THREE=true
|
LOGO=true
|
||||||
|
EARS=false
|
||||||
|
;;
|
||||||
|
ears)
|
||||||
|
CLIP=false
|
||||||
|
TEXT=false
|
||||||
|
LOGO=false
|
||||||
|
EARS=true
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo 'fatal: invalid part' >&2
|
echo 'fatal: invalid part' >&2
|
||||||
|
|
@ -35,23 +44,34 @@ render() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if [ $# -lt 3 ]; then
|
||||||
|
BOTTLE_FORMAT="0"
|
||||||
|
else
|
||||||
|
BOTTLE_FORMAT="$3"
|
||||||
|
fi
|
||||||
|
|
||||||
echo rendering "$1" "$2"
|
echo rendering "$1" "$2"
|
||||||
openscad \
|
openscad \
|
||||||
-D "\$fn=${FN}" \
|
-D "\$fn=${FN}" \
|
||||||
-D "USE_TINY_EARS=${TINY_EARS}" \
|
-D "EARS_STYLE=${EARS_STYLE}" \
|
||||||
-D "LOGO_FILE=${LOGO_FILE}" \
|
-D "LOGO_FILE=${LOGO_FILE}" \
|
||||||
-D "NAME=${NAME}" \
|
-D "NAME=${NAME}" \
|
||||||
-D "RENDER_COLOR_ONE=${ONE}" \
|
-D "RENDER_COLOR_CLIP=${CLIP}" \
|
||||||
-D "RENDER_COLOR_TWO=${TWO}" \
|
-D "RENDER_COLOR_TEXT=${TEXT}" \
|
||||||
-D "RENDER_COLOR_THREE=${THREE}" \
|
-D "RENDER_COLOR_LOGO=${LOGO}" \
|
||||||
-o "stls/c3cat-bottle-clip-v${VERSION}_${NAME}_${PART}.stl" \
|
-D "RENDER_COLOR_EARS=${EARS}" \
|
||||||
|
-o "stls/c3cat-bottle-clip-v${VERSION}_BOTTLE${BOTTLE_FORMAT}_${NAME}_${PART}.stl" \
|
||||||
c3cat-bottle-clip/c3cat-bottle-clip.scad
|
c3cat-bottle-clip/c3cat-bottle-clip.scad
|
||||||
}
|
}
|
||||||
|
|
||||||
cd "$(dirname $0)"
|
cd "$(dirname $0)"
|
||||||
|
|
||||||
for PART in body logo name
|
for BOTTLE_FORMAT in 0 1 2
|
||||||
do
|
do
|
||||||
render "$NAME" "$PART"
|
echo "Generating bottle format ${BOTTLE_FORMAT}"
|
||||||
sleep 1
|
for PART in body logo name ears
|
||||||
|
do
|
||||||
|
render "$NAME" "$PART" "$BOTTLE_FORMAT"
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
done
|
done
|
||||||
|
|
|
||||||
1
thing-logos
Submodule
1
thing-logos
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2ac5bec02e5015918dff95b6c12ba890ef1ea95a
|
||||||
Loading…
Add table
Add a link
Reference in a new issue