/* Customizable rotating rings keychain V5
Based on Customizable Rotating Rings by Blueteeth
https://www.thingiverse.com/thing:276248
which in turn was based on Rotating Rings Toy by RarelyEvil
Based on text_on.scad by Brody Kenrick
https://github.com/brodykenrick/text_on_OpenSCAD
Remix Author: Daniel K. Schneider, TECFA, University of Geneva, Nov 28, 2018
Instructions:
If you want a smooth experience:
- Use a low OpenSCAD resolution, e.g. $fs=0.05 for the circles, text can be much less. However if you do not want to wait, a high resolution also can do
- Use small 0.15mm layers, but 0.2mm also can do.
- Number of rings means number of equal segments, but if the inner ones are too small they will not be generated.
- Adjust spacing between letters if needed.
- Make sure that the rings include some curvature, else the thing falls apart. Height should be half of radius, e.g. set height to 10 if radius = 20.
- To see if a text fits on an inner ring look at the output in the console. There will be a red warning if we think it to be too big (but it is only an estimation). You also could test using the inner message on the outside of redimensionned ring.
- You can skip generating rings for debugging/looking at embedd text, etc.
- You can only print the first ring for checking the eyelet and lettering
- There are 2 types of eyelets. Default is the easier to print "square". Type "round" (default=false) is prettier, in principle.
- Text embedding is difficult to manage since it also depends on the text_on.scad library. Some day I will have to fix this.
- Make sure to remove any support. Else you will spend time scratching out letters...
Disclaimer:
- There may be some wrong calculations. I did not take time to carefully examine each function.
Changelog for this derivative
v1.4
Changed: Text is now embedded and curved
Removed: Support for dual extruders
Added: Key ring holder
Changed: replaced write.scad library by text_on_OpenSCAD
V5
Fixed: some positioning
Added: Rounded corners
Added: Debugging rings
Removed: Extra functions from text_on_scad
V6 Fixed: Ten commandments example
Added/fixed: Circle resolution parameter is now min angle. Font default made higher.
ToDo:
Adapt for dual extruders (maybe)
Verify all dimensions
Manage numberOfRings a bit better. Right now: If height > radius the inner ring will merge or if height > 0.66*radius, there will be ahole.
*/
/* [Rings Parameters] */
// Radius in mm of final shape
radiusShape = 23;
// Height in mm (no bigger than 20 or so)
heightShape = 14;
// Spacing between rings. Try double width for medium quality and medium resolution. E.g. 0.7 for a 0.35 nozzle at 0.2mm layer height. Minimum is extrusion width.
spacingRings = 0.6;
// Number of rings to print. Rings will be lost if their radius is less than the height and you even might get a hole.
numberOfRings = 5;
/* [Text Parameters] */
// Text. Must be an array of strings. First is outside
textList = ["MY THINGS IN THE UNIVERSE", "ARE ON THINGIVERSE"];
// It is recommended to select a fixed font
fontFamily = "Liberation Mono:style=Bold";
// Text distance should be zero or a bit positive, negative for large letters in small pieces
textDist= 0;
// Vertical height of the text(s)
letterHeight = 6;
// Thickness of partily embedded subtracted letters
letterThickness = 2;
// Multiply spacing between letters, e.g. 1.1
letterSpacing = 1;
/* [Eyelet Parameters] */
// Choose between round or square.
eyeletDefaultType = false;
// Distance of eyelet from outer ring
eyeletDistance = -2;
// Wall width multiplier (horizontal)
eyeletWidth = 1.3;
// Wall length multiplier (horizontal)
eyeletLength = 1.05;
// WallWidth (vertical) of eyeLet
eyeletWallWidth = 5;
// Width of the hole. Make sure that some on top/bottom is shaved off.
eyeletHoleWidth = 5.2;
/* [Various] */
// Skip N rings for debugging purposes (0 means none)
skipRings = 0;
// Only print first ring
firstRingOnly = false;
// Decide what to do with small center pieces. I like holes.
middleHole = 0.66;
// Circle resolution (minimal angle), high to make it smooth. If you cannot wait, set to 10
circleResolution = 1;
// Font resolution, high to make it pretty. Low is OK.
fontResolution = 20;
/* [Hidden] */
// Default
$fa = 10;
// You can override $fa and $fs values with $fn (not recommended)
// $fn = 30;
// Color list (just for display)
colorList = ["lightblue","red","purple","green","pink","yellow","magenta","red","blue","purple","green","pink","yellow","magenta"];
// ------------------------------------- Generate --------------------------------------
/*
Please scroll down to the end to replace see how to replace using global variables with a more pratical function call. I moved this section to test if thingiverse might like my code better that way.
*/
// --------------------- Rings code ---------------------------------------
// Adapted from Customizable Rotating Rings by Blueteeth
module print_part (
radius = radiusShape,
height = heightShape,
spacing = spacingRings,
rings_n = numberOfRings,
middle_hole_ratio = middleHole,
eyelet_default_type = eyeletDefaultType,
eyelet_hole_w =eyeletHoleWidth,
eyelet_w =eyeletWidth,
eyelet_l =eyeletLength,
eyelet_wall_w =eyeletWallWidth,
eyelet_d = eyeletDistance,
text = textList,
text_d = textDist,
letter_h = letterHeight,
letter_t = letterThickness,
font_s = letterSpacing,
font_f = fontFamily,
circle_resolution = circleResolution,
font_res = fontResolution,
skip_rings = skipRings,
first_ring_only = firstRingOnly
)
{
ringWall = radius / (rings_n) - spacing;
echo (str ("--- Parameters: ",
", radius=", radius,
", height=", height,
", spacing=", spacing,
", rings_n=", rings_n,
", computed ring wall size=", ringWall,
", middle_hole_ratio=", middle_hole_ratio,
", eyelet_default_type=", eyelet_default_type,
", eyelet_hole_w=", eyelet_hole_w,
", eyelet_w=", eyelet_w,
", eyelet_l=", eyelet_l,
", eyelet_wall_w=", eyelet_wall_w,
", eyelet_d=", eyelet_d,
", text=", text,
", text_d=", text_d,
", letter_h=", letter_h,
", letter_t=", letter_t,
", font_s=", font_s,
", font_f=", font_f,
", skip_rings=", skip_rings,
", font_res=", font_res,
", circle_resolution=", circle_resolution
));
module sphereShell(text, radius, wallThickness) {
// circles should be really round
if (text) {
text_radius = radius+text_d;
echo (str("____Text radius is ", text_radius, ", text distance extra is ", text_d, ", letter height= ", letter_h, ", letter_t= ", letter_t));
difference () {
sphere(r=radius, $fa=circle_resolution);
union() {
text_on_sphere (t=text, locn_vec=[0,0,0], r=text_radius, rounded=true, size=letter_h, extrusion_height=letter_t, font=font_f, spacing=font_s, font_res=font_res);
sphere(r=radius-wallThickness, $fa=circle_resolution);
}
}
} else {
difference() {
sphere(radius);
sphere(radius-wallThickness);
}
}
if (radius-wallThickness < wallThickness) echo (str (" Ball radius ", radius, " minus ", wallThickness, " wall thickness is too small, there will be no circle" ) );
}
/* We iterate from the outside to the inside
text, as well as color is number of rings - current iteration)
*/
module spheres() {
for (i = [rings_n: -1: 1]) {
ring_to_skip = rings_n+1 - skip_rings;
text_el = text [rings_n-i];
radius_ball_i = (ringWall + spacing) * i;
echo (str ("Processing sphere ", rings_n-i+1, ". Radius is ", radius_ball_i, ". Circumference is ", 2*radius_ball_i * PI));
// if the ring is too small in the middle, leave a hole
if (radius_ball_i > height * middle_hole_ratio) {
if ( (first_ring_only==true) && (rings_n-i+1 != 1) ) {
// only print first ring, allows checking eyelet and letter thickness
}
else if (ring_to_skip <= i) {
// skip the rings from now on, allows checking lettering length
} else {
color (colorList[rings_n - i]) sphereShell(text_el, radius_ball_i, ringWall);
}
} else {
echo (str (" Ball radius ", radius_ball_i, " is smaller than ", height * middle_hole_ratio, " (height * middleHole) and replaced by nothingness" ) );
}
}
}
// create the spheres, and cut out the horizontal slice
difference() {
union () {
spheres();
eyeLet (eyelet_default_type, radius,eyelet_d,eyelet_hole_w, eyelet_w, eyelet_l, eyelet_wall_w, height);
}
translate([0, 0, 100 + height/2]) cube([radius*4, radius*4, 200], center=true);
translate([0, 0, -100 - height/2]) cube([radius*4, radius*4, 200], center=true);
}
}
module eyeLet (eyelet_default_type, radius,eyelet_d, eyelet_hole_w, eyelet_w, eyelet_l, eyelet_wall_w, height) {
$fn = 30;
if (eyelet_default_type) {
eyelet_length = (eyelet_wall_w+eyelet_hole_w) * eyelet_l;
translate ([0,radius+eyelet_length/2+eyelet_d,0]) {
difference () {
cube (size=[eyelet_wall_w*eyelet_w,eyelet_length,height], center=true);
translate ([0,(eyelet_length/2)-eyelet_hole_w,0])
rotate ([0,90,0])
cylinder (h=6*eyelet_hole_w, r=eyelet_hole_w/2, center=true);
}
}
} else {
difference () {
// make this the height of the module + a little something
scale ([1, eyelet_l]) {
translate ([0,radius + eyelet_d]) {
rotate ([0,90,0]) {
rotate_extrude()
{
translate([eyelet_hole_w, 0]) // center of rotation
scale ([1,eyelet_w])
circle(r = eyelet_wall_w/2); // radius of rotated circle
}
}
}}
sphere (r=radius-0.01,center=true);
}
}
}
// --------------------- text on scad library ---------------------------------------
/* Functions from this library were used almost "as is" except:
- font_resolution (added a parameter) and user messages
- removed unused functions (because I tried to narrow down loading problems)
Retrieved on Nov 30 2018 from https://github.com/brodykenrick/text_on_OpenSCAD
text on scad
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?
*/
// 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 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
default_buffer_width = 0; //mm of buffer (thickening in all directions) to add to each letter
//Defaults for Sphere
default_sphere_northsouth = 0;
default_sphere_eastwest = 0;
default_sphere_spin = 0; // TODO:Different to rotate? or up/down. Better name?
default_sphere_rounded = false; // default for rounded letters on text_on_sphere
font_resolution = undef;
// Internal values - do not play with these :)
// This is much more accurate than the PI constant internal to Openscad.
// internal_pi = 3.1415926535897932384626433832795028841971693993751058209;
// DKS
internal_pi = 3.1416;
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 do not 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 ----
// module text_on_cylinder REMOVED BY DKS
//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 does not really even make sense to do (IMHO)
scale = default_scale,
font_res = font_resolution,
//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) {
// Modified to improve user experience in our case - DKS 11/2018
// Estimation of length was wrong for bold fonts (added 1.25)
$fn = font_res;
guess_length = width_of_text_string (t, size, spacing) * 1.25;
echo (str ("____There are " ,len(t) ," letters in " , t, ". Estimation of text length = ", guess_length, ". Font resolution = ", font_res)) ;
if (r*2*PI < guess_length) echo (str ("____ WARNING: your text may not fit ", ". Available circumference for text could be ", r*2*PI, ". Set skip_rings ring number-1 to check."));
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 -- do not 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,
buffer_width = default_buffer_width) {
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);
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
rotate(rotate_z_inner, [0, 0, 1])
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 do not 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,
buffer_width = buffer_width);
}
}
// module text_on_cube REMOVED by DKS
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,
buffer_width = default_buffer_width) {
//echo (str("text_extrude:","There are " ,len(t) ," letters in text" , t));
//echo (str("text_extrude:","extrusion_height=" , extrusion_height));
//echo (str("text_extrude:","$fn=" , $fn));
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 do not get defaults in this function as they are set as something)
// we need to check and replace any that we do not 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)
offset(delta = buffer_width)
text(text = t,
size = size,
font = font,
direction = direction,
spacing = spacing,
halign = halign,
valign = valign,
language = language,
script = script);
}
/* ------------------------------------ Generate ---------------------------------
Either change global parameters in the beginning of the file or comment "print_part()" just below, then adapt function calls below or create yours from scratch
*/
// Using default global variables
print_part();
/*
Below are various examples. Most have been test printed. Please be aware that OpenSCAD settings must be adapted to slicer settings or the other way round. This concerns in particular the spacing parameter
*/
// high resolution example calibration
// test printed at 0.15 layer and 90mm/s in 15 minutes
// print_part ( radius = 10, height = 6, spacing = 0.3, rings_n = 4, eyelet_default_type=false, eyelet_wall_w = 2.5, eyelet_hole_w = 2.5, eyelet_d = -1.3, text = ["WORK AND LIFE", "ARE", "good", ], text_d = 1.5, letter_h = 4, letter_t = 5, font_s = 1, skip_rings = 0, circle_resolution=1, middle_hole_ratio=0.8);
// print_part ( radius = 35, height = 14, spacing = 0.7, rings_n = 5, eyelet_default_type=true, eyelet_w=1.5, eyelet_wall_w = 5, eyelet_hole_w = 5 ,eyelet_d = -2, text = ["http://www.thingiverse.com/thing:3256469", "CREATE YOUR OWN", "on thingiverse"], text_d = 0, letter_h = 6, letter_t = 5, font_s = 1, skip_rings = 0);
// print_part ( radius = 30, height = 14, spacing = 0.7, rings_n = 5, eyelet_default_type=true, eyelet_wall_w = 5, eyelet_hole_w = 5 ,eyelet_d = -2, text = ["MAKE PRINTS NOT LOVE","CREATE PLASTIC"], text_d = 0, letter_h = 9, letter_t = 5, font_s = 1 );
// print_part ( radius = 20, height = 15, spacing = 0.7, rings_n = 5, eyelet_default_type=false, eyelet_wall_w = 4, eyelet_hole_w = 6,eyelet_d = -2, text = ["CREATE ON", "Thingiverse"], text_d = -0.5, letter_h = 9, letter_t = 5, font_s = 1 );
// print this with low resolution
// print_part ( radius = 30, height = 13, spacing = 0.5, rings_n = 6, eyelet_default_type=false, eyelet_wall_w = 4, eyelet_hole_w = 4.8, eyelet_d = -1.3, text = ["DANIEL K. SCHNEIDER, Associate professor", "daniel.schneider@unige.ch", "http://tecfa.unige.ch/DKS", "Geneva university", "Maker"], text_d = 1, letter_h = 5, letter_t = 5, font_s = 0.95, skip_rings = 0);
// print this with low resolution
// print_part ( radius = 20, height = 12, spacing = 0.6, rings_n = 4, eyelet_wall_w = 4, eyelet_hole_w = 4.4, eyelet_d = -1.5, text = ["CREATIVE COMMONS", "I LIKE TO", "SHARE"], text_d = -0.5, letter_h = 8, letter_t = 5, font_s = 0.95, eyelet_default_type=false );
// print_part ( radius = 28, height = 13, spacing = 0.5, rings_n = 6, eyelet_default_type=false, eyelet_wall_w = 4, eyelet_hole_w = 4.8, eyelet_d = -1.3, text = ["According to a recent study", "long term effects of 3D printing", "are better than alcohol,", "marihuana", "and sex", ], text_d = 1, letter_h = 5, letter_t = 5, font_s = 1, skip_rings = 0, circle_resolution=1);
// low poly version of 10 commandments
// print_part ( radius = 51, height = 20.5, spacing = 0.7, rings_n = 13, eyelet_default_type=true, eyelet_wall_w = 12, eyelet_hole_w = 6, eyelet_d = -3, eyelet_l=0.7,text = ["TEN COMMANDMENTS AND PRINCIPLES OF 3D PRINTING", "Calibrate well for the first layer", "Keep an open mind, be creative.", "Create supportless models", "Honor other ideas and designs", "Create assembly free", "Learn from others", "Make customizables", "share objects", "share code"], text_d = 1, letter_h = 8, letter_t = 5, font_s = 0.99, skip_rings = 0, first_ring_only = false, circle_resolution=10, font_resolution=10);
// medium size, medium poly version of 10 commandments
// print_part ( radius = 40, height = 20.5, spacing = 0.4, rings_n = 13, eyelet_default_type=true, eyelet_wall_w = 12, eyelet_hole_w = 6, eyelet_d = -3, eyelet_l=0.7,text = ["TEN COMMANDMENTS AND PRINCIPLES OF 3D PRINTING", "Calibrate well for the first layer", "Keep an open mind, be creative.", "Create supportless models", "Honor other designs", "Create assembly free", "Learn from others", "Customizables !", "share objects", "share code"], text_d = 1, letter_h = 8, letter_t = 5, font_s = 0.99, skip_rings = 0, first_ring_only = false, circle_resolution=5, font_resolution=20, middle_hole_ratio=0.3);
// requires low resolution slicing and OpenScad settings
// Takes ages to compile (15 min or more), print time = 10-15 hours. For testing lettering on screen, just set resolution to 20 or so. One test print (medium speed) at 0.15mm took 14h30.
// print_part ( radius = 51, height = 20.5, spacing = 0.4, rings_n = 13, eyelet_default_type=true, eyelet_wall_w = 12, eyelet_hole_w = 6, eyelet_d = -3, eyelet_l=0.7,text = ["TEN COMMANDMENTS AND PRINCIPLES OF 3D PRINTING", "Calibrate well for the first layer", "Keep an open mind, be creative.", "Create supportless models", "Honor other ideas and designs", "Create assembly free", "Learn from others", "Make customizables", "share objects", "share code"], text_d = 1.5, letter_h = 8, letter_t = 5, font_s = 0.99, skip_rings = 0, first_ring_only = false, circle_resolution=1);