Trying out Cadhub.xyz
cadhub.xyz/u/TLC123/unionRoundMask-scad
ComplementryRGBColor calculates the opposite point of the
color wheel to resolve the complementary color
for(i=[0:360/20:180]){
c=rands(0,1,3,i);
rotate(i,[0,.1,1])
{
color(c)render()translate([5,5])square(10);
color(complementryRGBColor(c))render()translate([13,13])square(10);
}
echo(c,complementryRGBColor(c));
}
function complementryRGBColor(c) =
let (r = c[0], g = c[1], b = c[2])
(max(r, g, b) == min(r, g, b)) ?
[1 - r, 1 - g, 1 - b] :
let (mx = max(r, g, b),
mn = min(r, g, b),
h = (mx + mn) / 2,
s = (mx + mn) / 2,
l = (mx + mn) / 2,
d = mx - mn)
let (s = l > 0.5 ? d / (2 - mx - mn) : d / (mx + mn),
h = mx == r ? (g - b) / d + (g < b ? 6 : 0) :
mx == g ? (b - r) / d + 2 :
/*mx== b?*/ (r - g) / d + 4)
let (h = round((h * 60) + 180) % 360)
let (h = h / 360)
let (hue2rgb = function(p, q, t)
let (t = t - floor(t))
(t < 1 / 6) ? p + (q - p) * 6 * t :
(t < 1 / 2) ? q :
(t < 2 / 3) ? p + (q - p) * (2 / 3 - t) * 6 :
p)
let (q = l < 0.5 ? l * (1 + s) : l + s - l * s)
let (p = 2 * l - q)
let (r = hue2rgb(p, q, h + 1 / 3))
let (g = hue2rgb(p, q, h))
let (b = hue2rgb(p, q, h - 1 / 3))[r, g, b];
For non convex operands, a simple masking system enable us to isolate out only local convex areas to process.Masks are in practice a common volume that both operands are first intersected by.
//////////////////////////////////////////////////////// /* unionRound() 1.0 Module by Torleif Ceder - TLC123 late summer 2021 Pretty fast Union with radius, But limited to a subset of cases Usage unionRound( radius , detail ) { YourObject1(); YourObject2(); } unionRoundMask (r, detail , epsilon ,showMask ) { YourObject1(); YourObject2(); YourMask(); YourMask(); // ... // ... // ... } limitations: 0. Only really fast when boolean operands are convex, Minkowski is fast in that case. 1. Boolean operands may be concave but can only touch in a single convex area 2. Radius is of elliptic type and is only approximate r were operand intersect at perpendicular angle. */ //////////////////////////////////////////////////////// // Demo code demo= false; if (demo) unionRoundMask( r=1.5 , detail= 5 , q=70 , includeOperands = true) { cube([10,10,2],true); rotate([20,-10,0])cylinder(5,1,1,$fn=12); translate([0,0,1.5])cube([1.5,10,3],center=true); //mask rotate(90) translate([0,0,1.5])cube([3,10,3],center=true); //mask } // end of demo code // module unionRoundMask(r=1, detail = 5,q=70, epsilon = 1e-6 , showMask = true, includeOperands = true) { //automask if none if($children <=2){ unionRoundMask(r,detail,q,epsilon,showMask, includeOperands) { children(0); children(1); clad(r,q) intersection(){ children(0); children(1); } } } else { union() { if(includeOperands){ children(0); children(1); } if (showMask && $children > 2) % for (i = [2: max(2, $children - 1)]) children(i); if ($children > 2) for (i = [2: max(2, $children - 1)]) { intersection() { children(i); unionRound(r, detail,q, epsilon ,includeOperands) { intersection() { children(0); children(i); // mask } intersection() { children(1); children(i); // mask } } } } } } } module unionRound(r=1, detail = 5,q=70, epsilon = 1e-6 , includeOperands=true) { if(includeOperands){ children(0); children(1); } step = 90 / detail; union()for (i = [0: detail-1]) { { x = r - sin(i * step ) * r; y = r - cos(i * step ) * r; xi = r - sin((i * step + step) ) * r; yi = r - cos((i * step + step) ) * r; color(rands(0, 1, 3, i)) hull() { intersection() { // shell(epsilon) clad(x,q) children(0); // shell(epsilon) clad(y,q) children(1); } intersection() { // shell(epsilon) clad(xi,q) children(0); // shell(epsilon) clad(yi,q) children(1); } } } } } // prototype module slow maybe on concave feature module intersectionRound(r, q=70, epsilon = 1e-6
,showOperands = true) {
%if (showOperands){children(0);
children(1);}
clad(r,q) inset(r,q)
hull()intersection() {
children(0);
children(1);
}
}
// unionRound helper expand by r
module clad(r,q=70) {
minkowski() {
children();
// icosphere(r,2);
isosphere(r,q);
}
}
// unionRound helper
module shell(r,q=70) {
difference() {
clad(r,q) children();
children();
}
}
// inset 3d "negative offset", optimally on convex hull
// else jagged inner corners by q quality factor
module inset(r,q=20){
a= generatepoints(q)*r;
//#children();
intersection_for(t=a){
translate(t ) children();
}
}
/*
// The following is a sphere with some equidistant properties.
// Not strictly necessary
Kogan, Jonathan (2017)
"A New Computationally Efficient Method for
Spacing n Points on a Sphere,"
Rose-Hulman Undergraduate Mathematics Journal:
Vol. 18 : Iss. 2 , Article 5.
Available at:
https://scholar.rose-hulman.edu/rhumj/vol18/iss2/5 */
function sphericalcoordinate(x,y)=[cos(x)*cos(y),sin(x)*cos(y),sin(y)];
function NX(n=70,x)=
let(toDeg=57.2958,PI=acos(-1)/toDeg,
start=(-1.+1./(n-1.)),increment=(2.-2./(n-1.))/(n-1.) )
[ for (j= [0:n-1])let (s=start+j*increment )
sphericalcoordinate(s*x*toDeg,PI/2.*sign(s)*(1.-sqrt(1.-abs(s)))*toDeg)];
function generatepoints(n=70)= NX(n,0.1+1.2*n);
module isosphere(r,q=70){
a= generatepoints(q);
scale(r)hull()polyhedron(a,[[for(i=[0:len(a)-1])i]]);
}
Language:
- Reference image import - based on surface() just zero height and a texture.
OpenCSG very much support this out of the box.
- Native function import .scad file as pre render in [ points , faces ].
this closes the loop a bit. At least save current mesh result as a
polyhedron([ points , faces ]) .dot scad file.
- Auto crop shape when:
ERROR: all points for rotate_extrude() must have the same X coordinate sign
- importMetrics catching information about imported files similar to textmetrics()
Gui:
- Save/display depth map and normal map from render pipeline to png.
- Animation play- pause
- Ambient SSAO
The Five steps.
Elon Musk, in an interview with Tim Dodd, outlined five essential steps of manufacture design.
The two met at starbase late summer of 2021 for a tour. At the meeting Elon stressed that designing a prototype is very simple when compared to the complexity of designing volume production. Something that Elon Musk earlier has called "the machine that makes the machine". The full interview series are available on Tim Dodd's Youtube channel - The Everyday Astronaut,
The five steps were as mentioned:
1. Make requermens less dumb.
2. Try really hard to delete the part or delete the process.
3 Simplify or optimize.
4. Accelerate cycle time.
5. Automate.
notes:
step 1
/ your requirements are likely dumb.
Especially if they come from a really smart person.
step 2
/ Put persons name on requirement not department.
/ “If you’re not adding things back in 10% of the time,
you’re clearly not deleting enough from your design.”
step 3
/ First begin when 1. and 2. is exhausted
step 4
/ "cycle" Assumed to be iterations of innovations in contrast to 5.
Mastering OpenSCAD within 10 projects by Jochen Kerdels
Dielectric High Temp Seal .
A non conduction high temperature seal can be achieved by separating the two functions of elasticity and isolation. Such that the insulation flange (Ceramic) only see compression.
tag: Donald Sadoway, Ambri , battery antimony, salt, seal, insulator, dielectric
Calculates the volume of a point-face triangel mesh.
points=[[0,0,0], ... ]
faces=[[0,1,2],[0,2,3],[4,6,5],[4,7,6], [0,4,5],[1,0,5],[1,5,6],[2,1,6], [2,6,7],[2,7,3],[3,7,4],[3,0,4]]
function meshVolume(points,faces)=
let(
sum=[for(faces)-1]*[for(f=faces)
SignedVolumeOfTriangle(points[f[0]],points[f[1]],points[f[2]])])
sum
;
function SignedVolumeOfTriangle( p1, p2, p3) =
let(
v321 = p3.x*p2.y*p1.z,
v231 = p2.x*p3.y*p1.z,
v312 = p3.x*p1.y*p2.z,
v132 = p1.x*p3.y*p2.z,
v213 = p2.x*p1.y*p3.z,
v123 = p1.x*p2.y*p3.z
) (1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123);
// MarchingCubes for function literals v0.1 - Torleif Ceder 2020
// With function literals of bounded closed isosufaces
// in the form f([x,y,z])
// Signed distans function can be output as polyhedron.
// Quality and problens is as expected with MarchingCubes
////////////// DEMO ////////////////////////////////////////////////////////////
sdScene = function(p) min(
max(abs(p.x)-6.5,abs(p.y+3)-4.5,abs(p.z*.7-p.x*.7)-0.5) ,
max(abs(p.x)-6.5,abs(p.y-3)-4.5,abs(p.z*.7+p.x*.7)-0.5) ,
norm(p )-5.5 ); // function literal of our Signed distance function
// learn more at https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
sdDemo= true;
if(sdDemo) sdMarchingCubes(sdScene,sub=5);
/////////////////////////////////////////////////////////////////////////////////////
//sdMC is a Octree subdivision MarchingCubes with direct gemoetry output
module sdMarchingCubes(sdScene, cell=[],sub){
assert(!is_undef(sub)&&!is_undef(sdScene),
" sdMarchingCubes() Usage: sdMarchingCubes( sdScene = f([ x , y , z ]) , sub = subdivisions ) ")
if (cell==[]) sdMarchingCubes(sdScene,autoBound(sdScene,cubic=true,pad=0.5 ),sub); else{
O = cell[0]; S = cell[1]; C = (O + S) / 2; D = S - O;
maxD = max( abs (D.x),abs (D.y),abs (D.z));
if (abs(sdScene(C))<=maxD )//ignore completly empty or full cells
{ p=vertFromCell (cell) ;
evals=[for(p=p)eval(p,sdScene)];
case=bitMaskToValue(evals);
if (sub>0){ // subdivide cell into eight smaller if subdivisions left
pxxx=[O+[0,0,0],O+[D.x,0,0],O+[0,D.y,0],O+[0,D.y,D.z],
O+[0,0,D.z],O+[D.x,D.y,0],O+[D.x,0,D.z],O+[D.x,D.y,D.z]];
for(i=[0:7]){sdMarchingCubes(sdScene,([C,pxxx[i]]),sub-1 ); } }
else { // Make polyhedron of this cell
faces=(CASES()[ (case)]); // Use MC 256 table to find conectivity
edgepoints=[for(e=EDGES()) // intersecion points along edges
lerp(p[e[0]],p[e[1]], findZero(evals[e[0]],evals[e[1]]) )];
polyhedron(edgepoints,faces); } } } } // Showtime
/////////////////////////////////////////////////////////////////////////////////////
// tiny utils fuctions
function vertFromCell(cell)= [for(c=VERTICES())[cell[c.x].x,cell[c.y].y,cell[c.z].z ]];
function findZero(e1,e2)=sign(e1)==sign(e2)||e1+e2==0?0.5: (abs(e1)/(abs(e1)+abs(e2)) );
function lerp(start,end,bias) = (end * bias + start * (1 - bias));
function un(v) = v / max(norm(v), 0.000001) * 1; // div by zero safe unit normal
function clamp(a,b=0,c=1) = min(max(a,min(b,c)),max(b,c));
/////////////////////////////////////////////////////////////////////////////////////
function eval(p,sdScene)=sdScene(p);// For legacy
//////////////////////////////////////////////////////////////////////////////////////
function evalnorm(q,sdScene) =
let (tiny = -1e16, e = eval(q,sdScene))[
eval([q.x + tiny,q.y,q.z],sdScene) - eval([q.x - tiny,q.y,q.z],sdScene),
eval([q.x,q.y + tiny,q.z],sdScene) - eval([q.x,q.y - tiny,q.z],sdScene),
eval([q.x,q.y,q.z + tiny],sdScene) - eval([q.x,q.y,q.z - tiny],sdScene), e];
//////////////////////////////////////////////////////////////////////////////////////
// Takes a vector. Any number >0 is 1 rest 0. use binary to build a number
function bitMaskToValue(v=[0])= is_undef(v[0])?0:
[for(j=v)1]* [for (i=[0:max(0,len(v)-1)]) max(0,sign(v[i]))*pow(2,i)] ;
//////////////////////////////////////////////////////////////////////////////////////
// arrange bundary box from sloppy to proper orientation of minor corner and major corner
function bflip(a,b) = is_undef(b)&&len(a)==2?bflip(a[0],a[1]):[ [min(a.x,b.x),min(a.y,b.y),min(a.z,b.z)], [max(a.x,b.x),max(a.y,b.y),max(a.z,b.z)] ];
//////////////////////////////////////////////////////////////////////////////////////
function autoBound(sdScene,cubic = (false),pad = 1) = let (
up = findBound([0,0,1],sdScene), down = -findBound([0,0,-1],sdScene),
north = findBound([0,1,0],sdScene), south = -findBound([ 0,-1,0],sdScene),
west = findBound([1,0,0],sdScene), east = -findBound([- 1,0,0],sdScene),
esd = min(east,south,down),wnu = max(west,north,up) )
cubic == true ?
let(scenecenter=[(east+west)/2,(south+north)/2,(up+down)/2],
scenemax=max(abs(east-west),abs(south-north),abs(up+down))/2,
d = [scenemax,scenemax,scenemax] )
[scenecenter - (d * (1+pad)),scenecenter + d * (1+pad)] :
let (d = [west,north,up ] - [east,south,down])
[[east,south,down ] - d * pad,[west,north,up] + d * pad];
//////////////////////////////////////////////////////////////////////////////////////
function findBound(vec,sdScene) =
let (VeryFar = 10e6, p1 = vec * VeryFar, p2 = p1 + un(vec ),
e1 = abs(eval(p1,sdScene)), e2 = abs(eval(p2,sdScene)),
scale = abs(e2 - e1),// Account for non unit_for_unit field.
corrected = (e1 / scale), distance = VeryFar - e1/scale //distance= VeryFar-corrected
)/*[p1,p2,e1,e2,scale,corrected,distance ]*/ distance ;
//////////////////////////////////////////////////////////////////////////////////////
////// MC Tables by BorisTheBrav /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
function VERTICES ()= [
[0,0,0], [1,0,0],
[1,1,0], [0,1,0],
[0,0,1], [1,0,1],
[1,1,1], [0,1,1], ];
//# BorisTheBrave convention for the edges
function EDGES() = [
[0,1], [1,2], [2,3],
[3,0], [4,5], [5,6],
[6,7], [7,4], [0,4],
[1,5], [2,6], [3,7] ];
//BorisTheBrave # Table driven approach to the 256 combinations. Pro-tip,don't write this by hand,copy mine!
//BorisTheBrave# See marching_cubes_gen.py for how I generated these.
//BorisTheBrave# Each index is the bitwise representation of what is solid.
//BorisTheBrave# Each value is a list of triples indicating what edges are used for that triangle
//BorisTheBrave# (Recall each edge of the cell may become a vertex in the output boundary)
function CASES() = [[],[[8,0,3]],[[1,0,9]],[[8,1,3],[8,9,1]],[[10,2,1]],[[8,0,3],[1,10,2]],[[9,2,0],[9,10,2]],[[3,8,2],[2,8,10],[10,8,9]],[[3,2,11]],[[0,2,8],[2,11,8]],[[1,0,9],[2,11,3]],[[2,9,1],[11,9,2],[8,9,11]],[[3,10,11],[3,1,10]],[[1,10,0],[0,10,8],[8,10,11]],[[0,11,3],[9,11,0],[10,11,9]],[[8,9,11],[11,9,10]],[[7,4,8]],[[3,7,0],[7,4,0]],[[7,4,8],[9,1,0]],[[9,1,4],[4,1,7],[7,1,3]],[[7,4,8],[2,1,10]],[[4,3,7],[4,0,3],[2,1,10]],[[2,0,10],[0,9,10],[7,4,8]],[[9,10,4],[4,10,3],[3,10,2],[4,3,7]],[[4,8,7],[3,2,11]],[[7,4,11],[11,4,2],[2,4,0]],[[1,0,9],[2,11,3],[8,7,4]],[[2,11,1],[1,11,9],[9,11,7],[9,7,4]],[[10,11,1],[11,3,1],[4,8,7]],[[4,0,7],[7,0,10],[0,1,10],[7,10,11]],[[7,4,8],[0,11,3],[9,11,0],[10,11,9]],[[4,11,7],[9,11,4],[10,11,9]],[[9,4,5]],[[9,4,5],[0,3,8]],[[0,5,1],[0,4,5]],[[4,3,8],[5,3,4],[1,3,5]],[[5,9,4],[10,2,1]],[[8,0,3],[1,10,2],[4,5,9]],[[10,4,5],[2,4,10],[0,4,2]],[[3,10,2],[8,10,3],[5,10,8],[4,5,8]],[[9,4,5],[11,3,2]],[[11,0,2],[11,8,0],[9,4,5]],[[5,1,4],[1,0,4],[11,3,2]],[[5,1,4],[4,1,11],[1,2,11],[4,11,8]],[[3,10,11],[3,1,10],[5,9,4]],[[9,4,5],[1,10,0],[0,10,8],[8,10,11]],[[5,0,4],[11,0,5],[11,3,0],[10,11,5]],[[5,10,4],[4,10,8],[8,10,11]],[[9,7,5],[9,8,7]],[[0,5,9],[3,5,0],[7,5,3]],[[8,7,0],[0,7,1],[1,7,5]],[[7,5,3],[3,5,1]],[[7,5,8],[5,9,8],[2,1,10]],[[10,2,1],[0,5,9],[3,5,0],[7,5,3]],[[8,2,0],[5,2,8],[10,2,5],[7,5,8]],[[2,3,10],[10,3,5],[5,3,7]],[[9,7,5],[9,8,7],[11,3,2]],[[0,2,9],[9,2,7],[7,2,11],[9,7,5]],
[[3,2,11],[8,7,0],[0,7,1],[1,7,5]],[[11,1,2],[7,1,11],[5,1,7]],[[3,1,11],[11,1,10],[8,7,9],[9,7,5]],[[11,7,0],[7,5,0],[5,9,0],[10,11,0],[1,10,0]],[[0,5,10],[0,7,5],[0,8,7],[0,10,11],[0,11,3]],[[10,11,5],[11,7,5]],[[5,6,10]],[[8,0,3],[10,5,6]],[[0,9,1],[5,6,10]],[[8,1,3],[8,9,1],[10,5,6]],[[1,6,2],[1,5,6]],[[6,2,5],[2,1,5],[8,0,3]],[[5,6,9],[9,6,0],[0,6,2]],[[5,8,9],[2,8,5],[3,8,2],[6,2,5]],[[3,2,11],[10,5,6]],[[0,2,8],[2,11,8],[5,6,10]],[[3,2,11],[0,9,1],[10,5,6]],[[5,6,10],[2,9,1],[11,9,2],[8,9,11]],[[11,3,6],[6,3,5],[5,3,1]],[[11,8,6],[6,8,1],[1,8,0],[6,1,5]],[[5,0,9],[6,0,5],[3,0,6],[11,3,6]],[[6,9,5],[11,9,6],[8,9,11]],[[7,4,8],[6,10,5]],[[3,7,0],[7,4,0],[10,5,6]],[[7,4,8],[6,10,5],[9,1,0]],[[5,6,10],[9,1,4],[4,1,7],[7,1,3]],[[1,6,2],[1,5,6],[7,4,8]],[[6,1,5],[2,1,6],[0,7,4],[3,7,0]],[[4,8,7],[5,6,9],[9,6,0],[0,6,2]],[[2,3,9],[3,7,9],[7,4,9],[6,2,9],[5,6,9]],[[2,11,3],[7,4,8],[10,5,6]],[[6,10,5],[7,4,11],[11,4,2],[2,4,0]],[[1,0,9],[8,7,4],[3,2,11],[5,6,10]],[[1,2,9],[9,2,11],[9,11,4],[4,11,7],[5,6,10]],
[[7,4,8],[11,3,6],[6,3,5],[5,3,1]],[[11,0,1],[11,4,0],[11,7,4],[11,1,5],[11,5,6]],[[6,9,5],[0,9,6],[11,0,6],[3,0,11],[4,8,7]],[[5,6,9],[9,6,11],[9,11,7],[9,7,4]],[[4,10,9],[4,6,10]],[[10,4,6],[10,9,4],[8,0,3]],[[1,0,10],[10,0,6],[6,0,4]],[[8,1,3],[6,1,8],[6,10,1],[4,6,8]],[[9,2,1],[4,2,9],[6,2,4]],[[3,8,0],[9,2,1],[4,2,9],[6,2,4]],[[0,4,2],[2,4,6]],[[8,2,3],[4,2,8],[6,2,4]],[[4,10,9],[4,6,10],[2,11,3]],[[11,8,2],[2,8,0],[6,10,4],[4,10,9]],[[2,11,3],[1,0,10],[10,0,6],[6,0,4]],[[8,4,1],[4,6,1],[6,10,1],[11,8,1],[2,11,1]],[[3,1,11],[11,1,4],[1,9,4],[11,4,6]],[[6,11,1],[11,8,1],[8,0,1],[4,6,1],[9,4,1]],[[3,0,11],[11,0,6],[6,0,4]],[[4,11,8],[4,6,11]],[[6,8,7],[10,8,6],[9,8,10]],[[3,7,0],[0,7,10],[7,6,10],[0,10,9]],[[1,6,10],[0,6,1],[7,6,0],[8,7,0]],[[10,1,6],[6,1,7],[7,1,3]],[[9,8,1],[1,8,6],[6,8,7],[1,6,2]],[[9,7,6],[9,3,7],[9,0,3],[9,6,2],[9,2,1]],[[7,6,8],[8,6,0],[0,6,2]],[[3,6,2],[3,7,6]],[[3,2,11],[6,8,7],[10,8,6],[9,8,10]],[[7,9,0],[7,10,9],[7,6,10],[7,0,2],[7,2,11]],[[0,10,1],[6,10,0],[8,6,0],[7,6,8],[2,11,3]],[[1,6,10],[7,6,1],[11,7,1],[2,11,1]],[[1,9,6],[9,8,6],[8,7,6],[3,1,6],[11,3,6]],
[[9,0,1],[11,7,6]],[[0,11,3],[6,11,0],[7,6,0],[8,7,0]],[[7,6,11]],[[11,6,7]],[[3,8,0],[11,6,7]],[[1,0,9],[6,7,11]],[[1,3,9],[3,8,9],[6,7,11]],[[10,2,1],[6,7,11]],[[10,2,1],[3,8,0],[6,7,11]],[[9,2,0],[9,10,2],[11,6,7]],[[11,6,7],[3,8,2],[2,8,10],[10,8,9]],[[2,6,3],[6,7,3]],[[8,6,7],[0,6,8],[2,6,0]],[[7,2,6],[7,3,2],[1,0,9]],[[8,9,7],[7,9,2],[2,9,1],[7,2,6]],[[6,1,10],[7,1,6],[3,1,7]],[[8,0,7],[7,0,6],[6,0,1],[6,1,10]],[[7,3,6],[6,3,9],[3,0,9],[6,9,10]],[[7,8,6],[6,8,10],[10,8,9]],[[8,11,4],[11,6,4]],[[11,0,3],[6,0,11],[4,0,6]],[[6,4,11],[4,8,11],[1,0,9]],[[1,3,9],[9,3,6],[3,11,6],[9,6,4]],[[8,11,4],[11,6,4],[1,10,2]],[[1,10,2],[11,0,3],[6,0,11],[4,0,6]],[[2,9,10],[0,9,2],[4,11,6],[8,11,4]],[[3,4,9],[3,6,4],[3,11,6],[3,9,10],[3,10,2]],[[3,2,8],[8,2,4],[4,2,6]],[[2,4,0],[6,4,2]],[[0,9,1],[3,2,8],[8,2,4],[4,2,6]],[[1,2,9],[9,2,4],[4,2,6]],[[10,3,1],[4,3,10],[4,8,3],[6,4,10]],[[10,0,1],[6,0,10],[4,0,6]],[[3,10,6],[3,9,10],[3,0,9],[3,6,4],[3,4,8]],[[9,10,4],[10,6,4]],[[9,4,5],[7,11,6]],[[9,4,5],[7,11,6],[0,3,8]],[[0,5,1],[0,4,5],[6,7,11]],[[11,6,7],[4,3,8],[5,3,4],[1,3,5]],[[1,10,2],[9,4,5],[6,7,11]],
[[8,0,3],[4,5,9],[10,2,1],[11,6,7]],[[7,11,6],[10,4,5],[2,4,10],[0,4,2]],[[8,2,3],[10,2,8],[4,10,8],[5,10,4],[11,6,7]],[[2,6,3],[6,7,3],[9,4,5]],[[5,9,4],[8,6,7],[0,6,8],[2,6,0]],[[7,3,6],[6,3,2],[4,5,0],[0,5,1]],[[8,1,2],[8,5,1],[8,4,5],[8,2,6],[8,6,7]],[[9,4,5],[6,1,10],[7,1,6],[3,1,7]],[[7,8,6],[6,8,0],[6,0,10],[10,0,1],[5,9,4]],[[3,0,10],[0,4,10],[4,5,10],[7,3,10],[6,7,10]],[[8,6,7],[10,6,8],[5,10,8],[4,5,8]],[[5,9,6],[6,9,11],[11,9,8]],[[11,6,3],[3,6,0],[0,6,5],[0,5,9]],[[8,11,0],[0,11,5],[5,11,6],[0,5,1]],[[6,3,11],[5,3,6],[1,3,5]],[[10,2,1],[5,9,6],[6,9,11],[11,9,8]],[[3,11,0],[0,11,6],[0,6,9],[9,6,5],[1,10,2]],[[0,8,5],[8,11,5],[11,6,5],[2,0,5],[10,2,5]],[[11,6,3],[3,6,5],[3,5,10],[3,10,2]],[[3,9,8],[6,9,3],[5,9,6],[2,6,3]],[[9,6,5],[0,6,9],[2,6,0]],[[6,5,8],[5,1,8],[1,0,8],[2,6,8],[3,2,8]],[[2,6,1],[6,5,1]],[[6,8,3],[6,9,8],[6,5,9],[6,3,1],[6,1,10]],[[1,10,0],[0,10,6],[0,6,5],[0,5,9]],[[3,0,8],[6,5,10]],[[10,6,5]],[[5,11,10],[5,7,11]],[[5,11,10],[5,7,11],[3,8,0]],[[11,10,7],[10,5,7],[0,9,1]],[[5,7,10],[10,7,11],[9,1,8],[8,1,3]],[[2,1,11],[11,1,7],[7,1,5]],[[3,8,0],[2,1,11],[11,1,7],[7,1,5]],[[2,0,11],[11,0,5],[5,0,9],[11,5,7]],[[2,9,5],[2,8,9],[2,3,8],[2,5,7],[2,7,11]],[[10,3,2],[5,3,10],[7,3,5]],[[10,0,2],[7,0,10],[8,0,7],[5,7,10]],[[0,9,1],[10,3,2],[5,3,10],[7,3,5]],[[7,8,2],[8,9,2],[9,1,2],[5,7,2],[10,5,2]],[[3,1,7],[7,1,5]],[[0,7,8],[1,7,0],[5,7,1]],[[9,5,0],[0,5,3],[3,5,7]],[[5,7,9],[7,8,9]],[[4,10,5],[8,10,4],[11,10,8]],[[3,4,0],[10,4,3],[10,5,4],[11,10,3]],[[1,0,9],[4,10,5],[8,10,4],[11,10,8]],
[[4,3,11],[4,1,3],[4,9,1],[4,11,10],[4,10,5]],[[1,5,2],[2,5,8],[5,4,8],[2,8,11]],[[5,4,11],[4,0,11],[0,3,11],[1,5,11],[2,1,11]],[[5,11,2],[5,8,11],[5,4,8],[5,2,0],[5,0,9]],[[5,4,9],[2,3,11]],[[3,4,8],[2,4,3],[5,4,2],[10,5,2]],[[5,4,10],[10,4,2],[2,4,0]],[[2,8,3],[4,8,2],[10,4,2],[5,4,10],[0,9,1]],[[4,10,5],[2,10,4],[1,2,4],[9,1,4]],[[8,3,4],[4,3,5],[5,3,1]],[[1,5,0],[5,4,0]],[[5,0,9],[3,0,5],[8,3,5],[4,8,5]],[[5,4,9]],[[7,11,4],[4,11,9],[9,11,10]],[[8,0,3],[7,11,4],[4,11,9],[9,11,10]],[[0,4,1],[1,4,11],[4,7,11],[1,11,10]],[[10,1,4],[1,3,4],[3,8,4],[11,10,4],[7,11,4]],[[9,4,1],[1,4,2],[2,4,7],[2,7,11]],[[1,9,2],[2,9,4],[2,4,11],[11,4,7],[3,8,0]],[[11,4,7],[2,4,11],[0,4,2]],[[7,11,4],[4,11,2],[4,2,3],[4,3,8]],[[10,9,2],[2,9,7],[7,9,4],[2,7,3]],[[2,10,7],[10,9,7],[9,4,7],[0,2,7],[8,0,7]],[[10,4,7],[10,0,4],[10,1,0],[10,7,3],[10,3,2]],[[8,4,7],[10,1,2]],[[4,1,9],[7,1,4],[3,1,7]],[[8,0,7],[7,0,1],[7,1,9],[7,9,4]],[[0,7,3],[0,4,7]],[[8,4,7]],[[9,8,10],[10,8,11]],[[3,11,0],[0,11,9],[9,11,10]],[[0,10,1],[8,10,0],[11,10,8]],[[11,10,3],[10,1,3]],[[1,9,2],[2,9,11],[11,9,8]],[[9,2,1],[11,2,9],[3,11,9],[0,3,9]],[[8,2,0],[8,11,2]],[[11,2,3]],[[2,8,3],[10,8,2],[9,8,10]],[[0,2,9],[2,10,9]],[[3,2,8],[8,2,10],[8,10,1],[8,1,0]],[[1,2,10]],[[3,1,8],[1,9,8]],[[9,0,1]],[[3,0,8]],[]];
{
//
for (i = [-1: 0.01: 3])
color("gray") hull() {
translate([jsin(10 * i * 360) * 0.1, 0, 0])
translate([i * 2, min(i, 0) * -12, 0]) rotate([max(i, 0) * 360, 0, 0])
translate([0, 0, 2]) cube([2 - 0.1, 0.01, 0.001], center = true);
j = i + 0.01;
translate([jsin(10 * j * 360) * 0.1, 0, 0])
translate([j * 2, min(j, 0) * -12, 0]) rotate([max(j, 0) * 360, 0, 0])
translate([0, 0, 2]) cube([2 - .1, 0.01, 0.001], center = true);
}
// uncut stainless
color("gray") translate([-0.17, 1, 0] * 0.22)
translate([0, 0, 2])
linear_extrude(0.002)
polygon([
[-3, 12],
[-1, 12],
[0, 6],
[-2, 6]
]);
// final rocket trunk
translate([4, 0, 0]) color([0.6, 0.6, 0.6]) rotate([0, 90, 0])
linear_extrude(13) difference() {
$fn = 120;
circle(2 - 0.001);
circle(2 - 0.002);
}
$fn = 120;
// laser cutter profile edges
color([0.4, 0.5, 0.7]) translate([-1.8, 12] * 0.5) translate([0, 0, 2])
cube([2.4, 0.5, 1], center = true);
// coil
color([0.6, 0.6, 0.6]) translate([-2, 12] * 1.025) translate([0, 0, 1])
rotate([0, 0, 7]) rotate([0, 90, 0]) cylinder(2, 1, 1, center = true);
// xray and heat treat
color("red") rotate([30, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("orange") rotate([50, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("gold") rotate([60, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
color("blue") rotate([90, 0, 0]) translate([1, 0, 2]) cube([.5, 0.25, 1], center = true);
//welder
color("yellow") rotate([1, 0, 0]) translate([1, 0, 2]) cube([.125, 0.125, 1.5], center = true);
color([1, .8, .3]) rotate([1, 0, 0]) translate([1, 0, 2]) cube([.4, 0.4, .25], center = true);
}
function jsin(s) =
max(clamp(sin(s + 60) * 3, -0.5, 0.5), clamp(sin(s) * 3, -0.5, 0.5));
function clamp(a, b, c) = min(max(a, min(b, c)), max(b, c));
