Merge a4e08283cc
into 89489c2e41
This commit is contained in:
commit
3a588a1395
8 changed files with 53176 additions and 17168 deletions
9
README.md
Normal file → Executable file
9
README.md
Normal file → Executable file
|
@ -12,7 +12,7 @@ The clip is customizable and you can tweak the following parameters:
|
|||
similar) bottles as well as 0.33l longneck bottles and German 0.33l DIN 6199
|
||||
(“Steinie”) beer bottles.
|
||||
* wall thickness (though the default should be okay for easy clipping)
|
||||
|
||||
|
||||
|
||||
Instructions
|
||||
------------
|
||||
|
@ -21,8 +21,6 @@ First, get all prerequisites. If you cloned this repository with Git, all you
|
|||
have to do is `cd` into the repository and do a `git submodule init && git
|
||||
submodule update`. Otherwise, you need the following:
|
||||
|
||||
* [Write.scad][thing16193] and at least one font, put it into the `write/`
|
||||
subfolder
|
||||
* If you want a logo on your name tag, draw a DXF file by yourself, or choose
|
||||
one out of my collection at rohieb/thing-logos. Your own logos should be no
|
||||
more than 50mm in height, and centered on point (25,25) for optimal results.
|
||||
|
@ -32,7 +30,6 @@ your expectations, comment it out (remove the `//` on the beginning of the
|
|||
line) and adapt it to your needs, or create your own. The code itself resides
|
||||
in `bottle-clip.scad` and should be documented sufficiently.
|
||||
|
||||
[thing16193]: http://thingiverse.com/thing:16193
|
||||
|
||||
Ancestry and Licence
|
||||
---------------
|
||||
|
@ -42,6 +39,7 @@ The [original design][thing888] was made by Thingiverse user
|
|||
the [text][thing18978] and then the [logo][thing23817] on it, both his designs
|
||||
were [CC-BY-SA-3.0][ccbysa30]. In the direct consequence, the design in this
|
||||
repo is also [CC-BY-SA-3.0][ccbysa30].
|
||||
The the [text][textonscad] was replaced by fototeddy
|
||||
|
||||
[thing888]: http://www.thingiverse.com/thing:888
|
||||
[wizard23]: http://www.thingiverse.com/wizard23
|
||||
|
@ -50,5 +48,4 @@ repo is also [CC-BY-SA-3.0][ccbysa30].
|
|||
[thing23817]: http://www.thingiverse.com/thing:23817
|
||||
[ccbync30]: https://creativecommons.org/licenses/by-nc/3.0/
|
||||
[ccbysa30]: https://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
// vim: set et ts=2 sw=2 tw=0:
|
||||
[textonscad]: https://github.com/brodykenrick/text_on_OpenSCAD
|
||||
|
|
File diff suppressed because it is too large
Load diff
31
bottle-clip.scad
Normal file → Executable file
31
bottle-clip.scad
Normal file → Executable file
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* A name tag that can easily be clipped to the neck of your bottle.
|
||||
* Copyright (C) 2013 Roland Hieber <rohieb+bottleclip@rohieb.name>
|
||||
* forked an extenden by fototeddy 2017
|
||||
*
|
||||
* See examples.scad for examples on how to use this module.
|
||||
*
|
||||
|
@ -9,7 +10,7 @@
|
|||
* licensing terms.
|
||||
*/
|
||||
|
||||
include <write/Write.scad>
|
||||
include <text_on.scad>
|
||||
|
||||
/**
|
||||
* Creates one instance of a bottle clip name tag. The default values are
|
||||
|
@ -29,29 +30,28 @@ include <write/Write.scad>
|
|||
* be centered on the point (25,25). Also all units in the DXF file should be
|
||||
* in mm. This parameter can be empty; in this case, the text uses the total
|
||||
* height of the name tag.
|
||||
* font: the path to a font for Write.scad.
|
||||
* font: the name of a system font or path to a seperate fontfile
|
||||
* ew: eastwest orientation of the name to center it
|
||||
*/
|
||||
module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="",
|
||||
logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") {
|
||||
logo="", ew=-90, resize=50, font="") {
|
||||
|
||||
e=100; // should be big enough, used for the outer boundary of the text/logo
|
||||
|
||||
difference() {
|
||||
rotate([0,0,-45]) union() {
|
||||
// main cylinder
|
||||
cylinder(r1=rl+width, r2=ru+width, h=ht);
|
||||
// text and logo
|
||||
if(logo == "") {
|
||||
writecylinder(name, [0,0,3], rl+0.5, ht/13*7, h=ht/13*8, t=max(rl,ru),
|
||||
font=font);
|
||||
text_on_cylinder(name, [0,0,3], r1=rl+width, r2=ru+width, h=ht, eastwest=ew,size=9, updown=-10, font=font);
|
||||
} else {
|
||||
writecylinder(name, [0,0,0], rl+0.5, ht/13*7, h=ht/13*4, t=max(rl,ru),
|
||||
font=font);
|
||||
text_on_cylinder(name, [0,0,0], r1=rl+width, r2=ru+width, h=ht, eastwest=ew, size=9, updown=-10, font=font);
|
||||
translate([0,0,ht*3/4-0.1])
|
||||
rotate([90,0,0])
|
||||
scale([ht/100,ht/100,1])
|
||||
translate([-25,-25,0.5])
|
||||
linear_extrude(height=max(ru,rl)*2)
|
||||
resize([resize,0,0], auto=[true,true,false])
|
||||
import(logo);
|
||||
}
|
||||
}
|
||||
|
@ -78,9 +78,8 @@ module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="",
|
|||
* bottle_clip(), see there for their documentation.
|
||||
*/
|
||||
module bottle_clip_longneck(name="", width=2.5,
|
||||
logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") {
|
||||
bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, logo=logo,
|
||||
font=font);
|
||||
logo="", ew="", font="", resize=50) {
|
||||
bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, logo=logo, ew=ew, font=font, resize=resize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,9 +88,8 @@ module bottle_clip_longneck(name="", width=2.5,
|
|||
* reasons, there is no logo, but all other parameters are passed to the module
|
||||
* bottle_clip(), see there for their documentation.
|
||||
*/
|
||||
module bottle_clip_steinie(name="", width=2.5, font="write/orbitron.dxf") {
|
||||
bottle_clip(name=name, ru=13, rl=17.5, ht=13, width=width, logo="",
|
||||
font=font);
|
||||
module bottle_clip_steinie(name="", width=2.5) {
|
||||
bottle_clip(name=name, ru=13, rl=17.5, ht=13, width=width, logo="");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -100,9 +98,8 @@ module bottle_clip_steinie(name="", width=2.5, font="write/orbitron.dxf") {
|
|||
* passed to the module bottle_clip(), see there for their documentation.
|
||||
*/
|
||||
module bottle_clip_euro2(name="", width=2.5,
|
||||
logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") {
|
||||
bottle_clip(name=name, ru=13, rl=22.5, ht=26, width=width, logo=logo,
|
||||
font=font);
|
||||
logo="") {
|
||||
bottle_clip(name=name, ru=13, rl=22.5, ht=26, width=width, logo=logo);
|
||||
}
|
||||
|
||||
// vim: set noet ts=2 sw=2 tw=80:
|
||||
|
|
BIN
example.png
Normal file
BIN
example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
16
examples.scad
Normal file → Executable file
16
examples.scad
Normal file → Executable file
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Examples for bottle clip name tags.
|
||||
* Copyright (C) 2013 Roland Hieber <rohieb+bottleclip@rohieb.name>
|
||||
* forkend and exteden by fototeddy 2017
|
||||
*
|
||||
* You can simply comment out one of the examples, adapt it to your needs and
|
||||
* render it, or use it to build your own variant.
|
||||
|
@ -15,26 +16,29 @@ use <bottle-clip.scad>
|
|||
$fn=50; // approximation steps for the cylinders
|
||||
|
||||
// one name tag for 0.5l Club Mate and similar bottles
|
||||
bottle_clip(name="Zero Cool");
|
||||
//bottle_clip(name="Your Name", ew=-90);
|
||||
|
||||
// one default name tag with a different logo.
|
||||
//bottle_clip(name="Acid Burn", logo="thing-logos/glider.dxf");
|
||||
bottle_clip(name="Club Mate", logo="thing-logos/Club_mate_logo.dxf", ew=-90);
|
||||
|
||||
// one default name tag with a smaller logo.
|
||||
//bottle_clip(name="Name here", logo="Club_mate_logo.dxf", ew=-90, resize=40);
|
||||
|
||||
// ...or with a different font:
|
||||
//bottle_clip(name="Acid Burn", font="write/Letters.dxf");
|
||||
//bottle_clip(name="Name", logo="Club_mate_logo.dxf", ew=-90, font="ComicSansMS");
|
||||
// ...or with a differnet logo and a different font... you get it.
|
||||
|
||||
// Now for something completely different: Longneck bottles.
|
||||
//bottle_clip_longneck(name="Tom Anderson", logo="thing-logos/glider.dxf");
|
||||
//bottle_clip_longneck(name="Your Name", ew=-125, logo="Club_mate_logo.dxf", resize=54, font="ComicSansMS");
|
||||
|
||||
// ...or DIN 6199 ("Steinie") beer bottles. Note that these have no logo.
|
||||
//bottle_clip_steinie(name="ohbier");
|
||||
//bottle_clip_steinie(name="Bier name");
|
||||
|
||||
// ...or just do your own variant: Measure the diameter of your bottle at two
|
||||
// different heights, and pass those as parameters rl (lower diameter), ru
|
||||
// (upper diameter) and ht (height) to the bottle_clip() module. You can also
|
||||
// use the other parameters from above, if you set logo="", then only the text
|
||||
// is rendered.
|
||||
//bottle_clip(name="Niobe", rl=15, ru=12, ht=16, logo="");
|
||||
//bottle_clip(name="name here", rl=15, ru=12, ht=16, logo="");
|
||||
|
||||
// vim: set noet ts=2 sw=2 tw=80:
|
||||
|
|
52502
examples.stl
Normal file
52502
examples.stl
Normal file
File diff suppressed because it is too large
Load diff
647
text_on.scad
Executable file
647
text_on.scad
Executable file
|
@ -0,0 +1,647 @@
|
|||
/* text on ....
|
||||
This is a rework of version 3 of write.scad to use the new OpenSCAD internal text() primitive.
|
||||
All credit to Harlan Martin (harlan@sutlog.com) for his great effort on the original.
|
||||
Great thanks to t-paul (and the OpenSCAD dev team) on adding the new text() primitive.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
The arguments to be provided for each function are explictly in the modules.
|
||||
|
||||
All modules take close to all the arguments to text() [Not all features are supported in all text_on_object() modules though -- try them out warnings will be given if it is not supported]
|
||||
|
||||
text() params:
|
||||
t
|
||||
size
|
||||
spacing
|
||||
font
|
||||
direction -- ltr, ttb, btt or rtl
|
||||
language
|
||||
script
|
||||
halign -- left, right or center
|
||||
valign -- baseline, bottom, top or center
|
||||
|
||||
All modules also take the additional arguments:
|
||||
extrusion_height = depth of the letter, i.e. how far it sits proud
|
||||
rotate
|
||||
center //center the text at the location it is being written (NOT that the object is centered)
|
||||
|
||||
ALL faux-objects that the text is applied to have center=true
|
||||
TODO: object_center=true/false (already done for cylinder)
|
||||
|
||||
The above arguemnts can be seen in text_extrude() as all modules call that module evetually (often multiple times).
|
||||
|
||||
locn_vector -- Where the faux-object has been translated to. TODO: Rename object to translate_vector?
|
||||
|
||||
Additional arguments for text_on_cube():
|
||||
|
||||
Additional arguments for text_on_cylinder():
|
||||
|
||||
Additional arguments for text_on_circle():
|
||||
|
||||
Additional arguments for text_on_sphere():
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// These control the default values for text_extrude(), text_on_sphere(), text_on_cube(), text_on_cylinder(), text_on_circle()
|
||||
// if the arguments are not included in the call to the module.
|
||||
|
||||
// Defaults
|
||||
// Defaults for all modules
|
||||
default_t="text_on";
|
||||
default_size = 4; //TODO - Can we make this 10?? To match internal size? There is an underlying value in text() -- This masks that.
|
||||
default_font = "Liberation Mono";
|
||||
default_spacing = 1; //Spacing between characters. There is an underlying value in text() -- This masks that. We try and match it here.
|
||||
default_rotate = 0; // text rotation (clockwise)
|
||||
default_center = true; //Text-centering
|
||||
default_scale = [1,1,1];
|
||||
default_extrusion_height = 2; //mm letter extrusion height
|
||||
|
||||
//Defaults for Cube
|
||||
default_cube_face = "front"; // default face (top,bottom,left,right,back,front)
|
||||
default_sphere_rounded = false; //default for rounded letters on text_on_sphere
|
||||
default_cube_updown = 0; //mm up (-down) from center on face of cube
|
||||
default_cube_rightleft = 0; //mm right(-left) from center on face of cube
|
||||
|
||||
//Defaults for Sphere
|
||||
default_sphere_northsouth= 0;
|
||||
default_sphere_eastwest = 0;
|
||||
default_sphere_spin = 0; //TODO:Different to rotate? or up/down. Better name?
|
||||
|
||||
//Defaults for Cylinder (including circle as it is on top/bottom)
|
||||
default_circle_middle = 0; //(mm toward middle of circle)
|
||||
default_circle_ccw = false; //write on top or bottom in a ccw direction
|
||||
default_circle_eastwest = 0;
|
||||
default_cylinder_face = "side";
|
||||
default_cylinder_updown = 0;
|
||||
|
||||
//Internal values - don't play with these :)
|
||||
//This is much more accurate than the PI constant internal to Openscad.
|
||||
internal_pi=3.1415926535897932384626433832795028841971693993751058209;
|
||||
internal_pi2=internal_pi*2;
|
||||
|
||||
//Internal values - You might want to play with these if you are using a proportional font
|
||||
internal_space_fudge = 0.80; //Fudge for working out lengths (widths) of strings
|
||||
|
||||
debug = true;
|
||||
|
||||
//---- Helper Functions ----
|
||||
//String width (length from left to right or RTL) in OpenSCAD units
|
||||
//NOTE: These are innacurate because we don't know the real spacing of the chars and so have to approximate
|
||||
//They work for monospaced (fixed-width) fonts well
|
||||
function width_of_text_char( size, spacing ) = (size * internal_space_fudge * spacing);
|
||||
function width_of_text_string_num_length(length, size, spacing) = ( width_of_text_char( size, spacing ) * (length));
|
||||
function width_of_text_string( t, size, spacing ) = ( width_of_text_string_num_length(len(t), size, spacing) );
|
||||
|
||||
function cylinder_center_adjusted_top( height, center ) = (center==true) ? height/2 : height ;
|
||||
function cylinder_center_adjusted_bottom( height, center ) = (center==true) ? height/2 : 0 ;
|
||||
|
||||
|
||||
//Angle that measures width of letters on perimeter of a circle (and sphere and cylinder)
|
||||
function rotation_for_character(size, spacing, r, rotate = 0)
|
||||
= ( width_of_text_char( size, spacing ) /(internal_pi2*r))*360*(1-abs(rotate)/90);
|
||||
|
||||
|
||||
//Rotate 1/2 width of text if centering
|
||||
//One less -- if we have a single char we are already centred..
|
||||
function rotation_for_center_text_string( t, size, spacing,r,rotate,center)
|
||||
= (center) ? (width_of_text_string_num_length( len(t)-1, size, spacing )/2/(internal_pi2*r)*360) : 0 ;
|
||||
|
||||
//Rotate according to rotate and if centred text also 1/2 width of text
|
||||
function rotation_for_center_text_string_and_rotate( t, size, spacing,r,rotate,center)
|
||||
= ((center) ? (width_of_text_string( t, size, spacing )/2/(internal_pi2*r)*360) : 1) * (1-abs(rotate)/90);
|
||||
|
||||
|
||||
//---- Text on Object Functions ----
|
||||
//Text on the top or side of a cylinder.
|
||||
//Supports writing on normal and slanty cylinders
|
||||
//cylinder(h,r,center)
|
||||
//cylinder(h,r1,r2,center)
|
||||
module text_on_cylinder(t=default_t,
|
||||
//Object-specific
|
||||
locn_vec = [0,0,0],
|
||||
r,r1,r2,h,
|
||||
face = default_cylinder_face,
|
||||
updown = default_cylinder_updown,
|
||||
rotate = default_rotate,
|
||||
eastwest = default_circle_eastwest,
|
||||
middle = default_circle_middle,
|
||||
ccw = default_circle_ccw,
|
||||
cylinder_center = false, //if the cylinder object we are writing on is center==true
|
||||
//TODO: add rounded
|
||||
|
||||
//All objects
|
||||
extrusion_height = default_extrusion_height,
|
||||
center = default_center,
|
||||
//All objects -- arguments as for text()
|
||||
font = undef,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
halign = undef,
|
||||
valign = undef,
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
){
|
||||
// echo (str("text_on_cylinder:There are " ,len(t) ," letters in t" , t));
|
||||
// echo (str("text_on_cylinder:","h" , h));
|
||||
// echo (str("text_on_cylinder:","r=" , r));
|
||||
// echo (str("text_on_cylinder:","r1=" , r1));
|
||||
// echo (str("text_on_cylinder:","r2=" , r2));
|
||||
|
||||
if((halign!=undef) || (halign!=undef))
|
||||
{
|
||||
echo (str("text_on_cylinder:","WARNING " , "halign and valign are NOT supported."));
|
||||
}
|
||||
|
||||
rtl_sign = (direction=="rtl") ? -1 : 1;
|
||||
if ((face=="top")||(face=="bottom") ){
|
||||
//Work on a circle
|
||||
locn_offset_vec = (face=="top" ) ? [0,0,cylinder_center_adjusted_top(h,cylinder_center)] : [0,0,cylinder_center_adjusted_bottom(h,cylinder_center)] ;
|
||||
rotation_angle = (face=="top" ) ? 0 : 180 ;
|
||||
int_radius = (r==undef) ? ((face=="top" ) ? r2 : r1 ) : r; //Use the top/bottom radius for slanty-cylinders
|
||||
rotate(rotation_angle,[1,0,0])
|
||||
text_on_circle(t,locn_vec+locn_offset_vec,r=int_radius-size,
|
||||
font=font,size=size,
|
||||
spacing=spacing,direction=direction,language=language,script=script,halign=halign,valign=valign,
|
||||
extrusion_height=extrusion_height,
|
||||
rotate=rotate,
|
||||
eastwest=eastwest,middle=middle,ccw=ccw);
|
||||
}else{
|
||||
if((middle!=undef) && (middle!=default_circle_middle))
|
||||
{
|
||||
//TODO: Which others?
|
||||
//TODO: Which side things aren't supported on the circle
|
||||
echo (str("text_on_cylinder:","WARNING " , "middle NOT supported for the SIDE of a cylinder."));
|
||||
}
|
||||
//Work on the side
|
||||
locn_offset_vec = (cylinder_center==true) ? [0,0,0] : [0,0,h/2];
|
||||
rotate(-rtl_sign * rotation_for_center_text_string_and_rotate(t, size, spacing,r,rotate,center), [0,0,1])
|
||||
translate(locn_vec+locn_offset_vec)
|
||||
__internal_text_on_cylinder_side(t,locn_vec,r=r,h=h,r1=r1,r2=r2,
|
||||
cylinder_center=cylinder_center,
|
||||
center=center,
|
||||
font=font,size=size,
|
||||
spacing=spacing,direction=direction,language=language,script=script,halign=halign,valign=valign,
|
||||
extrusion_height=extrusion_height,
|
||||
rotate=rotate,face=face,updown=updown,
|
||||
eastwest=eastwest);
|
||||
}
|
||||
}
|
||||
|
||||
//circle(r)
|
||||
module text_on_circle(t=default_t,
|
||||
//Object-specific
|
||||
locn_vec = [0,0,0],
|
||||
r,
|
||||
eastwest = default_circle_eastwest,
|
||||
middle = default_circle_middle,
|
||||
ccw = default_circle_ccw,
|
||||
|
||||
//All objects
|
||||
extrusion_height = default_extrusion_height,
|
||||
rotate = default_rotate,
|
||||
center = default_center,
|
||||
|
||||
//All objects -- arguments as for text()
|
||||
font = undef,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
halign = undef,
|
||||
valign = undef,
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
){
|
||||
// echo (str("text_on_circle:","There are " ,len(t) ," letters in t" , t));
|
||||
// echo (str("text_on_circle:","rotate=" , rotate));
|
||||
// echo (str("text_on_circle:","eastwest=" , eastwest));
|
||||
|
||||
if((halign!=undef) || (halign!=undef))
|
||||
{
|
||||
echo (str("text_on_circle:","WARNING " , "halign and valign are NOT supported."));
|
||||
}
|
||||
|
||||
ccw_sign = (ccw==true) ? 1 : -1;
|
||||
rtl_sign = (direction=="rtl") ? -1 : 1;
|
||||
ttb_btt_inaction = (direction=="ttb" || direction=="btt") ? 0 : 1;
|
||||
rotate_z_outer = -rotate + ccw_sign*eastwest;
|
||||
rotate_z_inner = -rtl_sign * ccw_sign * ttb_btt_inaction * rotation_for_center_text_string( t, size, spacing, r-middle, rotate, center);
|
||||
rotate( rotate_z_outer, [0,0,1] )
|
||||
rotate( rotate_z_inner, [0,0,1] )
|
||||
translate(locn_vec)
|
||||
for (l=[0:len(t)-1]){
|
||||
//TTB/BTT means no per letter rotation
|
||||
rotate_z_inner2 = -ccw_sign * 90 + ttb_btt_inaction*rtl_sign*ccw_sign*l*rotation_for_character(size, spacing, r-middle, rotate=0); //Bottom out=-270+r
|
||||
//TTB means we go toward center, BTT means away
|
||||
vert_x_offset = (direction=="ttb" || direction=="btt") ? (l * size * ((direction=="btt") ? -1 : 1)) : 0;
|
||||
rotate( rotate_z_inner2, [0,0,1] )
|
||||
translate([r - middle - vert_x_offset,0,0])
|
||||
rotate(-ccw_sign*270,[0,0,1]) // flip text (botom out = -270)
|
||||
text_extrude(t[l],center=true,
|
||||
font=font,size=size,
|
||||
rotate=undef,
|
||||
spacing=spacing,
|
||||
direction=undef, //We don't pass direction ( misaligns inside text() ). TODO: Investigate why
|
||||
language=language,script=script,halign=halign,valign=valign,
|
||||
extrusion_height=extrusion_height );
|
||||
}
|
||||
}
|
||||
|
||||
//Only expected to be called from another function. No defaults as expected to be done in parent.
|
||||
//NOTE: This is hacked. Requires more mathematics than I feel like to do properly today....
|
||||
//TODO: Refactor the two operations - side of normal and slanty
|
||||
//No default checks in this funciton -- done in parent
|
||||
module __internal_text_on_cylinder_side(t=default_t,
|
||||
//Object-specific
|
||||
locn_vec = [0,0,0],
|
||||
r,r1,r2,h,
|
||||
cylinder_center,
|
||||
|
||||
//All objects
|
||||
extrusion_height = default_extrusion_height,
|
||||
center = undef,
|
||||
rotate = default_rotate,
|
||||
|
||||
//All objects -- arguments as for text()
|
||||
font = undef,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
halign = undef, //Overridden
|
||||
valign = undef,
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
)
|
||||
{
|
||||
// echo (str("__internal_text_on_cylinder_side:There are " ,len(t) ," letters in t" , t));
|
||||
// echo (str("__internal_text_on_cylinder_side:","h=" , h));
|
||||
// echo (str("__internal_text_on_cylinder_side:","r=" , r));
|
||||
// echo (str("__internal_text_on_cylinder_side:","r1=" , r1));
|
||||
// echo (str("__internal_text_on_cylinder_side:","r2=" , r2));
|
||||
// echo (str("__internal_text_on_cylinder_side:","direction=" , direction));
|
||||
|
||||
if((halign!=undef) || (halign!=undef))
|
||||
{
|
||||
echo (str("text_on_cylinder:","WARNING " , "halign and valign are NOT supported."));
|
||||
}
|
||||
|
||||
wid = width_of_text_char( size, spacing ); //TODO: refactor this out?
|
||||
|
||||
function calc_radius_at_height_offset(r1,r2,h_total,h_offset) = ( r1 + ((r2-r1) * (h_total-h_offset)/h_total) );
|
||||
|
||||
//Has to factor in up/downedness
|
||||
//Starts at middle height then height displacement is reduced under rotation and by the slope of the uneven radii
|
||||
function calc_height_offset_at_length(r1,r2,h,length,rotate, updown) = ( h/2 - updown + length * rotate/90 * cos( atan( (r2-r1)/h ) ) );
|
||||
|
||||
function calc_radius_at_length(r1,r2,h,length,rotate,updown) = ( calc_radius_at_height_offset(r1,r2,h,calc_height_offset_at_length(r1,r2,h,length,rotate,updown)));
|
||||
|
||||
if(r==undef)
|
||||
{
|
||||
//Slanty-cylinder (truncated cone) warnings
|
||||
if((direction=="btt") || (direction=="ttb"))
|
||||
{
|
||||
//TODO: After the issues are resolved refactoring should give this pretty easily
|
||||
echo (str("text_on_cylinder:","WARNING" , " - Slanty-cylinders definitely don't directions TTB or BTT on sides yet. Setting direction to ltr."));
|
||||
}
|
||||
if(center==true)
|
||||
{
|
||||
echo (str("text_on_cylinder:","WARNING" , " - Slanty-cylinders don't support centering yet. Setting center to false. You can adjust updown and eastwest and achieve most of what you are after...."));
|
||||
}
|
||||
}
|
||||
|
||||
r1 = (r1!=undef) ? r1 : r;
|
||||
r2 = (r2!=undef) ? r2 : r;
|
||||
//NOTE: r is not used after here. We operate on generalised slanty cone (r1 and r2)
|
||||
|
||||
//TODO: Look at changing this to extrusion_height_center
|
||||
//and renaming the other as text_center
|
||||
rr1 = (center) ? r1-extrusion_height/2 : r1;
|
||||
rr2 = (center) ? r2-extrusion_height/2 : r2;
|
||||
|
||||
ccenter = (r!=undef) ? center : false; //We don't do (text) centering for the slanty cones/helical paths (yet? ever?). Needs to do quite a few offset calcs.
|
||||
ddirection = ((r==undef) && ((direction=="ttb")||(direction=="btt"))) ? "ltr" : direction; //We don't do ttb or btt directions on slanty
|
||||
rtl_sign = (ddirection=="rtl") ? -1 : 1;
|
||||
|
||||
//This code takes care of slanty cylinders and "normal" cylinders
|
||||
translate([0,0,updown])
|
||||
rotate(eastwest,[0,0,1])
|
||||
for (l=[0:len(t)-1]){
|
||||
//TODO: TTB and BTT need to have a different concept of path/length than this for RTL/LTR
|
||||
//width_of_... is half a char too long -- add 0.5 (counting from zero)
|
||||
length_to_center_of_char = width_of_text_string_num_length(l+0.5,size,spacing);
|
||||
radius_here = calc_radius_at_length(rr1,rr2,h, length_to_center_of_char, rotate, updown);
|
||||
//Rotating into position and tangentially to surface -- Don't rotate per character for ttb/btt
|
||||
//-90 is to get centering at origin
|
||||
rotate_z_inner = -90 + rtl_sign * rotation_for_character(size, spacing, ( radius_here ), rotate) * ((ddirection=="ttb" || ddirection=="btt") ? 0 : l);
|
||||
rotate(rotate_z_inner,[0,0,1])
|
||||
{
|
||||
//Positioning - based on (somewhat innacurate) string length
|
||||
//Offset per character to go up/down the side in ttb/btt -- TTB down, BTT up
|
||||
vert_z_char_offset = (ddirection=="ttb" || ddirection=="btt") ? (l * size * ((ddirection=="ttb") ? -1 : 1 )) : 0 ;
|
||||
//Only if RTL/LTR and if center -- center the text (starts off in a more visually appealing location)
|
||||
vert_z_half_text_offset_tmp = (len(t)-1)/2 * (rotate/90*wid);
|
||||
vert_z_half_text_offset = ((ddirection=="ttb" || ddirection=="btt") || (ccenter==false)) ? 0 : vert_z_half_text_offset_tmp;
|
||||
translate([ radius_here , 0, vert_z_char_offset - l * ((rotate)/90*wid) + vert_z_half_text_offset])
|
||||
|
||||
//Flip to tangent on the sloping side (without respecting rotation impact on the tangent -- rotate seems a little off. TODO: Investigate).
|
||||
rotate( atan( (rr2-rr1)/h ) , [0,1,0])
|
||||
//Flip onto face of "normal" cylinder
|
||||
rotate(90,[1,0,0])
|
||||
rotate(90,[0,1,0])
|
||||
|
||||
//Modify the offset of the baselined text to center
|
||||
translate([0,(ccenter) ? -size/2 : 0,0])
|
||||
|
||||
text_extrude(t[l],
|
||||
center=false,
|
||||
rotate=rotate,
|
||||
font=font,size=size,
|
||||
spacing=spacing,
|
||||
direction=undef, //We don't pass direction ( misaligns inside text() ). TODO: Investigate why
|
||||
language=language,script=script,
|
||||
halign="center", //This can be relaxed eventually
|
||||
valign="baseline", //Need this to keep all letters on the same line (could also support top -- otherw will make
|
||||
extrusion_height=extrusion_height
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//sphere(r)
|
||||
//NB: Iterates through characters/glyphs and presents them individually (but supports actions across the entire string still)
|
||||
//supports all features of text() except: halign and valign
|
||||
module text_on_sphere(t=default_t,
|
||||
//Object-specific
|
||||
locn_vec = [0,0,0],
|
||||
r,
|
||||
eastwest = default_sphere_eastwest,
|
||||
northsouth = default_sphere_northsouth,
|
||||
rotate = default_rotate,
|
||||
spin = default_sphere_spin,
|
||||
rounded = default_sphere_rounded,
|
||||
//All objects
|
||||
extrusion_height = default_extrusion_height,
|
||||
center = default_center, //center = false doesn't really even make sense to do (IMHO)
|
||||
scale = default_scale,
|
||||
//All objects -- arguments as for text()
|
||||
font = undef,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
halign = undef, //Not supported - only here to enable a warning
|
||||
valign = undef, //Not supported - only here to enable a warning
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
){
|
||||
//echo ("text_on_sphere:There are " ,len(t) ," letters in t" , t);
|
||||
|
||||
if((halign!=undef) || (halign!=undef))
|
||||
{
|
||||
echo (str("text_on_sphere:","WARNING " , "halign and valign are NOT supported (functionality used in centering)."));
|
||||
}
|
||||
|
||||
//TODO: refactor this?
|
||||
rtl_sign = (direction=="rtl") ? -1 : 1;
|
||||
|
||||
//TODO: Look at changing this to extrusion_height_center
|
||||
//and renaming the other as text_center
|
||||
//If we are centered - we sink the radius by half the
|
||||
//extrusion height to draw "just below the surface"
|
||||
rr = (center) ? r-extrusion_height/2 : r ;
|
||||
|
||||
rotate(eastwest,[0,0,1])
|
||||
rotate(-northsouth,[1,0,0])
|
||||
rotate(spin,[0,1,0])
|
||||
{
|
||||
//This tries to center the text (for RTL text).
|
||||
ttb_btt_inaction = (direction=="ttb" || direction=="btt") ? 0 : 1;
|
||||
rotate( -rtl_sign * ttb_btt_inaction * rotation_for_center_text_string(t, size, spacing, rr, rotate, center), [0,0,1])
|
||||
{
|
||||
translate(locn_vec)
|
||||
if ( rounded == false ){
|
||||
__internal_text_on_sphere_helper(t=t,r=rr,
|
||||
rotate=rotate,
|
||||
center=center,
|
||||
scale=scale,
|
||||
font=font,size=size,
|
||||
spacing=spacing,
|
||||
direction=direction,
|
||||
language=language,script=script,halign=halign,valign=valign,
|
||||
extrusion_height=extrusion_height
|
||||
);
|
||||
}else{
|
||||
//If rounding then clip the text inside an inner sphere and outer sphere
|
||||
intersection()
|
||||
{
|
||||
__internal_text_on_sphere_helper(t=t,r=rr,
|
||||
rotate=rotate,
|
||||
center=center,
|
||||
scale=scale,
|
||||
font=font,size=size,
|
||||
spacing=spacing,
|
||||
direction=direction,
|
||||
language=language,script=script,halign=halign,valign=valign,
|
||||
extrusion_height=extrusion_height*2 //Make it proud to clip it off.
|
||||
);
|
||||
|
||||
//Shell - bounding inner and outer
|
||||
difference()
|
||||
{ //rounded outside
|
||||
sphere(rr+extrusion_height);
|
||||
// rounded inside for indented text
|
||||
sphere( rr );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//internal function -- don't call directly
|
||||
//No default checks in this funciton -- done in parent
|
||||
module __internal_text_on_sphere_helper(t=default_t,
|
||||
//Object-specific
|
||||
r,
|
||||
//All objects
|
||||
extrusion_height = default_extrusion_height,
|
||||
center = default_center,
|
||||
scale = default_scale,
|
||||
//All objects -- arguments as for text()
|
||||
font = undef,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
//halign = undef,
|
||||
//valign = undef,
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
)
|
||||
{
|
||||
rtl_sign = (direction=="rtl") ? -1 : 1;
|
||||
ttb_btt_inaction = (direction=="ttb" || direction=="btt") ? 0 : 1;
|
||||
ttb_btt_action = (direction=="ttb" || direction=="btt") ? 1 : 0;
|
||||
|
||||
for (l=[0:len(t)-1]){
|
||||
rotate_z_inner = -90 + rtl_sign * ttb_btt_inaction * l * rotation_for_character(size, spacing, r, 0);
|
||||
|
||||
rotate( rotate_z_inner, [0,0,1] )
|
||||
{
|
||||
translate_sign = (direction=="ttb" || direction=="btt") ? ((direction=="btt") ? 1 : -1) : 0 ;
|
||||
//translate_effect = (direction=="ttb" || direction=="btt") ? 1 : 0 ;
|
||||
//Translate letter to be located on the sphere in up/down direction when we are doing TTB and BTT
|
||||
translate(r * [cos(0 + ttb_btt_action * rotation_for_character(size, spacing, r, rotate) * l ), 0, translate_sign * ttb_btt_action * sin(0 + rotation_for_character(size, spacing, r, rotate) * l ) ])
|
||||
//Rotate letter to be tangential to the new part of the sphere when we are doing TTB and BTT
|
||||
rotate(-90 * translate_sign * (0 + ttb_btt_action * rotation_for_character(size, spacing, r, rotate) * l )/90 , [0,1,0])
|
||||
//Flip character into position to be flush against sphere
|
||||
rotate(90,[1,0,0])
|
||||
rotate(90,[0,1,0])
|
||||
|
||||
//Modify the offset of the baselined text to center
|
||||
translate([0,(center) ? -size/2 : 0 ,0])
|
||||
|
||||
text_extrude(t[l],
|
||||
center=false,
|
||||
rotate=rotate,
|
||||
scale=scale,
|
||||
font=font,
|
||||
size=size,
|
||||
spacing=spacing,
|
||||
direction=undef, //We don't pass direction ( misaligns inside text() ). TODO: Investigate why
|
||||
language=language,script=script,
|
||||
halign="center", //This can be relaxed eventually
|
||||
valign="baseline", //Need this to keep all letters on the same line (could also support top -- otherw will make wonky letters)
|
||||
extrusion_height=extrusion_height );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//cube(size)
|
||||
//cube([width,h,depth])
|
||||
//NB: cube_size is used instead of size (the name size is used in the text module)
|
||||
//NB: Passes through text as strings -- supports all features of text()
|
||||
module text_on_cube( t=default_t,
|
||||
//Object-specific
|
||||
cube_size, //number or 3-vector
|
||||
face = default_cube_face,
|
||||
rightleft = default_cube_rightleft,
|
||||
updown = default_cube_updown,
|
||||
//All objects
|
||||
locn_vec = [0,0,0],
|
||||
extrusion_height = default_extrusion_height,
|
||||
center = undef,
|
||||
rotate = default_rotate,
|
||||
scale = default_scale,
|
||||
//All objects -- arguments as for text()
|
||||
font = undef,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
halign = undef,
|
||||
valign = undef,
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
){
|
||||
//echo (str("text_on_cube:","There are " ,len(t) ," letters in t" , t));
|
||||
//echo (str("text_on_cube:","cube_size" , cube_size));
|
||||
|
||||
if((halign!=undef) || (halign!=undef))
|
||||
{
|
||||
echo (str("text_on_cube:","WARNING " , "halign and valign are NOT supported."));
|
||||
}
|
||||
|
||||
int_cube_size = (str(cube_size)[0] != "[") ? [cube_size,cube_size,cube_size] : cube_size;
|
||||
rotate_x = ( (face=="front") || (face=="back") || (face=="left") || (face=="right") ) ? 90
|
||||
: ((face=="bottom") ? 180 : 0) ; //Top is zero
|
||||
rotate_y = ( (face=="back") || (face=="left") || (face=="right") ) ? (face=="back") ? 180 : ((face=="left") ? -90 : 90) //Right is 90
|
||||
: 0 ; //Top, bottom, front are zero
|
||||
locn_vec_offset =
|
||||
(face=="front") ? [+rightleft, -int_cube_size[1]/2, +updown]
|
||||
:((face=="back")? [+rightleft, +int_cube_size[1]/2, +updown]
|
||||
: ((face=="left")? [-int_cube_size[0]/2, +rightleft, +updown]
|
||||
: ((face=="right")? [+int_cube_size[0]/2, +rightleft, +updown]
|
||||
: ((face=="top")? [+rightleft, +updown, +int_cube_size[2]/2]
|
||||
: [+rightleft, -updown, -int_cube_size[2]/2]
|
||||
)))); //bottom
|
||||
|
||||
translate(locn_vec + locn_vec_offset)
|
||||
rotate(rotate_x,[1,0,0])
|
||||
rotate(rotate_y,[0,1,0]) // rotate around the y axis (z before rotation)
|
||||
text_extrude(t,
|
||||
center=center,
|
||||
rotate=rotate,
|
||||
scale=scale,
|
||||
font=font,
|
||||
size=size,
|
||||
spacing=spacing,
|
||||
direction=direction, //Does this misalign inside text()? the individual character modules do.
|
||||
language=language,
|
||||
script=script,
|
||||
halign=halign,
|
||||
valign=valign,
|
||||
extrusion_height=extrusion_height );
|
||||
}
|
||||
|
||||
function default_if_undef(val, default_val) = (val!=undef) ? val : default_val ;
|
||||
|
||||
//Print a single character or a string at the desired extrusion height
|
||||
//Passes on values to text() that are passed in
|
||||
//TODO: Add x,y,z rotations get text facing the right way from the start)
|
||||
module text_extrude( t=default_t,
|
||||
extrusion_height = default_extrusion_height,
|
||||
center = default_center, //Fudgy. YMMV. //TODO:center_extrusion, or extrusion offset??
|
||||
rotate = default_rotate,
|
||||
scale = default_scale, //For scaling by different on axes (for widening etc)
|
||||
//Following are test() params (in addition to t=)
|
||||
font = default_font,
|
||||
size = default_size,
|
||||
direction = undef,
|
||||
halign = undef,
|
||||
valign = undef,
|
||||
language = undef,
|
||||
script = undef,
|
||||
spacing = default_spacing
|
||||
)
|
||||
{
|
||||
//echo (str("text_extrude:","There are " ,len(t) ," letters in text" , t));
|
||||
//echo (str("text_extrude:","extrusion_height=" , extrusion_height));
|
||||
|
||||
if(center==true)
|
||||
{
|
||||
if((halign!=undef) || (valign!=undef))
|
||||
{
|
||||
echo (str("text_extrude:","WARNING " , "When center is true, then halign and valign are NOT supported."));
|
||||
}
|
||||
}
|
||||
|
||||
//As arguments are explicitly set as undef (from higher functions) as they come down (they don't get defaults in this function as they are set as something)
|
||||
//we need to check and replace any that we don't want to be undef
|
||||
t = default_if_undef(t,default_t);
|
||||
font = default_if_undef(font,default_font);
|
||||
extrusion_height = default_if_undef(extrusion_height,default_extrusion_height);
|
||||
center = default_if_undef(center,default_center);
|
||||
rotate = default_if_undef(rotate,default_rotate);
|
||||
spacing = default_if_undef(spacing,default_spacing);
|
||||
size = default_if_undef(size,default_size);
|
||||
|
||||
halign = (center) ? "center" : halign ;
|
||||
valign = (center) ? "center" : valign ;
|
||||
extrusion_center = (center) ? true : false ;
|
||||
|
||||
scale( scale )
|
||||
rotate(rotate,[0,0,-1]) //TODO: Do we want to make this so that the entire vector can be set?
|
||||
{
|
||||
linear_extrude(height=extrusion_height,convexity=10,center=extrusion_center)
|
||||
text(text=t, size = size,
|
||||
$fn = 40,
|
||||
font = font, direction = direction, spacing = spacing,
|
||||
halign = halign,
|
||||
valign = valign,
|
||||
language=language, script=script);
|
||||
}
|
||||
}
|
||||
|
1
write
1
write
|
@ -1 +0,0 @@
|
|||
Subproject commit cc949a2ed0962ce81876f0fd5f58cd7f1128a56e
|
Loading…
Add table
Add a link
Reference in a new issue