Files
SyncHome/trunk/workspace/09_3D-Draws/Lego Customizable Brick/files/LEGOTextBrick-v1p8.scad
paolo.iocco 74a1ae0e89
2023-03-09 13:37:43 +00:00

244 lines
11 KiB
OpenSCAD

/* LEGO Text Bricks
by Lyl3
Create LEGO compatible bricks with text engraved on the sides
This code is published at:
https://www.thingiverse.com/thing:3867358
licensed under the Creative Commons - Attribution - Share Alike license (CC BY-SA 3.0)
V0.1 - working code
V0.2 - corrected brick dimensions to have 0.1 mm play on each side
corrected stud height to be 1.8 mm instead of 1.6 mm
corrected roof thickness to be 1.0 mm instead of 1.6 mm
V0.3 - cleaned the code
V0.4 - adjusted wall thickness from 1.6 mm to 1.4 mm
fixed math for stud positions
fixed math for play so that it's split between sides instead of on just one side
V0.5 - added tolerance parameter
V0.6 - corrected position of text to account for play and tolerance
V0.7 - set sane ranges for all parameters
V1.0 - adjusted diameter of under-stud from 6.51 to 6.41
adjusted width of walls from 1.4 mm to 1.5 mm
ready for release
V1.1 - changed boolean parameters to yes/no parameters to make them Thingiverse Customizer-friendly
V1.2 - allowed $fn to be adjusted from previous hard-coded value of 100
V1.3 - allow text Z shift to be negative
V1.4 - added parameter for spacing between letters
V1.5 - moved studs down 0.00001 mm so that the brick and studs are a single mesh
V1.6 - bug fix: parameter for spacing between letters now applied to text on back,left and right sides
- allowed LEGO dimensions to be overridden
V1.7 - modified font selection method to work around bug that Thingiverse customizer recently introduced
that prevents direct selection of fonts with a style specified
added capability to select any font
V1.8 - added capability to have raised text instead of embossed text
*/
/*
Set default brick to be #2456 6x2
*/
/* [Brick Parameters] */
// Brick length (specified in number of studs).
brickLength = 6; // [1:1:48]
// Brick width (specified in number of studs).
brickWidth = 2; // [1:1:48]
// Brick height (specified in LEGO height units: 3 is normal brick height, 1 is plate height).
brickHeight = 3; // [1:1:18]
// Studs on top of the brick?
withStuds = "yes"; // [yes,no]
createStuds = (withStuds=="yes") ? true : false;
// Under-studs on underneath of skinny bricks? Skinny bricks that are only one unit wide have smaller solid cylinders (under-studs) underneath instead of the usual hollow cylinders. These have a tiny footprint and may not stick to the build-plate, so you may want to avoid printing them.
withUnderStuds = "no"; // [yes,no]
createUnderStuds = (withUnderStuds=="yes") ? true : false;
/* [Text Parameters] */
// Raised text instead of embossed text?
raisedText = "no"; // [yes,no]
textRaised = (raisedText=="yes") ? true : false;
frontText = "Text Bricks";
frontTextScale = 1.0; // [0:0.01:1]
backText = "";
backTextScale = 1.0; // [0:0.01:1]
leftText = "";
leftTextScale = 1.0; // [0:0.01:1]
rightText = "";
rightTextScale = 1.0; // [0:0.01:1]
/* [Advanced parameters] */
// Tolerance to account for 3D printing inaccuracies (mm). This decreases the sizes of all vertical surfaces (brick walls, studs, under-tubes, and under-studs) to provide a better fit. It is equivalent to a negative horizontal expansion setting in the Cura slicer. You might want to decrease this for bricks that are only 1 unit wide without under-studs as they will be naturally looser fitting than other bricks. The best setting is printer/filament dependent so I've set the default for my printer on the assumption that it's average.
tolerance = 0.05; // [0:0.01:0.1]
// Some suitable fonts
//fontName = "Arial Black:style=Regular"; // Not available on Thingiverse customizer
//fontName = "Biryani:style=Black"; // Has short numbers
//fontName = "Heebo:style=Black"; // Has tight kerning
//fontName = "Maven Pro:style=Black"; // Has tight spacing on "g"
//fontName = "Nunito Sans:style=Black"; // Has tight kerning
//fontName = "Orbitron:style=Black"; // Has blocky letters
//fontName = "Palanquin Dark:style=Bold"; // Has descended numbers
//fontName = "Raleway:style=Black"; // Has descended numbers
//fontName = "Roboto:style=Black"; // No issues
//fontName = "Yantramanav:style=Black"; // No issues
// Choose from a small selection of similar fonts that should work well in this application (NOTE: Arial is not available on Thingiverse).
fontName = 9; // [2:Biryani Black, 3:Heebo Black, 4:Maven Pro Black, 5:Nunito Sans Black, 6:Orbitron Black, 7:Palanquin Dark Bold, 8:Raleway Black, 9:Roboto Black, 10:Yantramanav Black, 0:other, 1:Arial Black]
// If "other" is selected above, you can specify any font available from the Google fonts repository . See https://fonts.google.com/ for available fonts. For example, specify "Overpass Mono:style=Bold" to allow entering some special symbols like heart, club, etc.
otherFont = "Overpass Mono";
// The base size of the text on all sides (can be scaled down in the text parameters section).
textSize = 5.5; // [1:0.1:10]
// Spacing between letters. (ratio: 1 is normal spacing of the font) It's better to have this a little higher for this application.
letterSpacing = 1.05; // [0.9:0.01:2.0]
// How much to shift the text in the Z dimension (mm).
textZShift = 2.0; // [-5:0.1:8]
// The depth of the text (mm). You should probably decrease this from the default of 0.8 if you plan on scaling the model up in your slicer.
textDepth = 0.8; // [0.2:0.01:1.0]
// Resolution of circles. 50 fragments is more than enough for such a small cylinders unless the model will be later scaled up
numberFragments = 50; // [6:1:100]
$fn = numberFragments;
/* [Advanced parameters: Override LEGO dimensions] */
// X and Y dimension of one brick unit (mm)
UNIT_LENGTH = 8; // [0.8:0.01:80]
// plate height (a standard brick is 3 times this height) (mm)
PLATE_HEIGHT = 3.2; // [0.32:0.01:32]
// thickness of brick roof (mm)
ROOF_THICKNESS = 1; // [0.1:0.01:10]
// thickness of brick outer wall as in the original 1.5 mm wall without nubs (mm)
WALL_THICKNESS = 1.5; // [0.15:0.01:15]
// diameter of the studs (solid cylinders) on top of a brick (mm)
STUD_DIAMETER = 4.8; // [0.48:0.01:48]
// height of the studs (solid cylinders) on top of a brick (mm)
STUD_HEIGHT = 1.8; // [0.18:0.01:18]
// outer diameter of the under-tubes (hollow cylinders) on the underside of bricks with length > 1 and width > 1 (mm)
UNDERTUBE_OUTER_DIAMETER = 6.41; // [0.64:0.01:64.1]
// inner diameter of the under-tubes (hollow cylinders) on the underside of bricks with length > 1 and width > 1 (mm)
UNDERTUBE_INNER_DIAMETER = 4.8; // [0.48:0.01:48]
// diameter of the under-studs (solid cylinders) on the underside of bricks with length = 1 or width = 1 (mm)
UNDERSTUD_DIAMETER = 1.6; // [0.16:0.01:16]
// the necessary play between bricks so that they fit together
PLAY = 0.2; // [0.02:0.01:2]
/* [Hidden] */
fudge = 0.01; // Amount to expand some dimensions to ensure manifold model
// This convoluted way of selecting the font from an array was a requirement introduced by a change
// on the Thingiverse customizer that broke the ability to directly select fonts with a style specified.
// This issue was first noticed 2010-02-26 and probably happened within the two months prior to that date.
fontNames = ["other", "Arial Black:style=Regular", "Biryani:style=Black", "Heebo:style=Black", "Maven Pro:style=Black", "Nunito Sans:style=Black", "Orbitron:style=Black", "Palanquin Dark:style=Bold", "Raleway:style=Black", "Roboto:style=Black", "Yantramanav:style=Black"];
selectedFont = (fontName==0) ? otherFont : fontNames[fontName];
textBack = textRaised ? 0 : textDepth;
if(textRaised) {
union() {
translate([-brickLength/2*UNIT_LENGTH, -brickWidth/2*UNIT_LENGTH, 0])
brick (brickLength, brickWidth, brickHeight);
makeText();
}
} else {
difference() {
translate([-brickLength/2*UNIT_LENGTH, -brickWidth/2*UNIT_LENGTH, 0])
brick (brickLength, brickWidth, brickHeight);
makeText();
}
}
/*
Module to make a simple rectangular LEGO compatible brick
Makes a #3001 4x2 brick by default
*/
module brick(length=4, width=2, height=3) {
// The brick
translate([PLAY/2+tolerance, PLAY/2+tolerance, 0])
difference() {
cube([length*UNIT_LENGTH-PLAY-2*tolerance, width*UNIT_LENGTH-PLAY-2*tolerance, height*PLATE_HEIGHT]);
translate([WALL_THICKNESS-2*tolerance, WALL_THICKNESS-2*tolerance, -ROOF_THICKNESS])
cube([length*UNIT_LENGTH-2*WALL_THICKNESS-PLAY+2*tolerance, width*UNIT_LENGTH-2*WALL_THICKNESS-PLAY+2*tolerance, height*PLATE_HEIGHT]);
}
// The studs
if(createStuds) {
translate([0,0, height*PLATE_HEIGHT-0.00001])
for (y = [0:width-1]) {
for (x = [0:length-1]) {
translate([(x+0.5)*UNIT_LENGTH, (y+0.5)*UNIT_LENGTH, 0])
cylinder(h=STUD_HEIGHT, d=STUD_DIAMETER-2*tolerance);
}
}
}
// The under-tubes (hollow cylinders)
if (width > 1 && length > 1) {
for (y = [1:width-1]) {
for (x = [1:length-1]) {
difference() {
translate([x*UNIT_LENGTH, y*UNIT_LENGTH, 0])
cylinder(h=height*PLATE_HEIGHT-ROOF_THICKNESS+fudge, d = UNDERTUBE_OUTER_DIAMETER-2*tolerance);
translate([x*UNIT_LENGTH, y*UNIT_LENGTH, -fudge])
cylinder(h=height*PLATE_HEIGHT-ROOF_THICKNESS+fudge, d = UNDERTUBE_INNER_DIAMETER+2*tolerance);
}
}
}
}
// The under-studs (smaller solid cylinders) along the length
if (width == 1 && length > 1 && createUnderStuds) {
for (x = [1:length-1]) {
translate([x*UNIT_LENGTH, 0.5*UNIT_LENGTH, 0])
cylinder(h=height*PLATE_HEIGHT-WALL_THICKNESS, d=UNDERSTUD_DIAMETER-2*tolerance);
}
}
// The under-studs (smaller solid cylinders) along the width
if (length == 1 && width > 1 && createUnderStuds) {
for (y = [1:width-1]) {
translate([0.5*UNIT_LENGTH, y*UNIT_LENGTH, 0])
cylinder(h=height*PLATE_HEIGHT-WALL_THICKNESS, d=UNDERSTUD_DIAMETER-2*tolerance);
}
}
}
module makeText () {
translate([0, -brickWidth/2*UNIT_LENGTH+textBack+PLAY/2+tolerance, textZShift]) rotate([90, 0, 0])
linear_extrude(textDepth+fudge) text(frontText, font=selectedFont, size=textSize*frontTextScale, halign="center", spacing=letterSpacing);
translate([0, brickWidth/2*UNIT_LENGTH-textBack-PLAY/2-tolerance, textZShift]) rotate([90, 0, 180])
linear_extrude(textDepth+fudge) text(backText, font=selectedFont, size=textSize*backTextScale, halign="center", spacing=letterSpacing);
translate([-brickLength/2*UNIT_LENGTH+textBack+PLAY/2+tolerance, 0, textZShift]) rotate([90, 0, 270])
linear_extrude(textDepth+fudge) text(leftText, font=selectedFont, size=textSize*leftTextScale, halign="center", spacing=letterSpacing);
translate([brickLength/2*UNIT_LENGTH-textBack-PLAY/2-tolerance, 0, textZShift]) rotate([90, 0, 90])
linear_extrude(textDepth+fudge) text(rightText, font=selectedFont, size=textSize*rightTextScale, halign="center", spacing=letterSpacing);
}