[User]
I'd like to design a parametric slew bearing in OpenSCAD. I have some ideas based on an existing design but I'd prefer a fresh implementation.

Here's what I need:

**Basic Geometry:**

*   The bearing should have an outer diameter, an inner diameter, and a gap diameter where the balls will run. These should all be configurable parameters.
*   I need to control the overall height of the bearing, and the diameter of the balls used in the bearing.

**Races:**

*   The bearing will consist of an outer race and two inner races (A and B). I want to be able to turn each of these races on or off using parameters.
*   I need to also be able to turn on or off pins in the ball track, in case I want to use the bearing without them.
*   It would be helpful to see a cross-section of the design to confirm correct dimensions. This should be toggleable with a parameter as well.

**Holes:**

*   The inner races need screw holes to attach it to a surface. I need to be able to set:
    *   The number of screw holes
    *   The diameter of the screw holes.
    *   The depth of the screw cap hole (countersink/counterbore).
    *   The diameter of the screw cap hole.
    *   The diameter of the circle where these screw holes are located.
*   I also need a similar set of parameters for screw holes on the outer race, but only if there is a flange.
*   I'd like an option for an outer flange. I need to be able to specify the size and height of this flange.

**Advanced Parameters:**

*   I want to add a "slew gap," which is a Z-axis offset between the two inner races. I would like to be able to control the value of this gap
*   I also need to add a tolerance between the ball and the race to allow for smooth operation. This should be adjustable via a parameter.
*   To parameterize the distance between the balls and the races I'd like a "gap factor" based on ball diameter (so it's a multiplier of ball radius).
*   Finally, the resolution of the model should be configurable with a `$fn` parameter.

I'm not worried about the visual appearance of the model, beyond the ability to toggle various elements on or off. I’m fine with basic cylinder shapes, spheres etc.

I don't have a preference for any particular libraries or anything like that, you can choose what makes the most sense.

[Assistant]
slew_bearing-201508.scad:
```

/* [Basics] */

outer_diameter = 110;
inner_diameter = 70;
gap_diameter = 95;
bearing_height=12;
ball_diameter=6;

show_outer_race = "yes"; // [yes,no]
show_inner_race_a= "yes"; // [yes,no]
show_inner_race_b= "yes"; // [yes,no]
show_pins = "yes"; // [yes,no]

show_crossection="yes"; // [yes,no]

/* [Holes] */

// You may need to screw the inner races...
inner_race_screw_holes = 4;
inner_race_screw_hole_diameter = 3;
inner_race_screw_cap_depth = 3;
inner_race_screw_cap_diameter = 6;
inner_race_screw_diameter = 40;

// You could use a flange. Flange parameter is added to outer diameter.
flange=0;
flange_height=8;

outer_race_screw_holes = 4;
outer_race_screw_hole_diameter = 3;
outer_race_screw_cap_depth = 3;
outer_race_screw_cap_diameter = 6;
outer_race_screw_diameter = 60;

/* [Advanced] */

// The difference between Inner and Outer races on Z axis. This will increase the total height of the bearing
slew_gap = 1;

// The tolerance applied on ball diameter to let them run
tolerance=0.24;

// A factor the gap between races relative to ball diameter
gap_factor=0.1;

// Resolution
fn=100;

/* [Hidden] */
flange_params=(flange)? [flange,flange_height] : 0;

function radius_to_balls(r_ball, r) = 180 / asin(r_ball / r);
function ball_to_radius(n, r) = r * sin(180 / n);

module Bearing(outer, inner, ball_radius, gap, hole, height, outer_flange=0, slew=0, pr=0.5) {
	echo(radius_to_balls(ball_radius, inner));
	n = round(radius_to_balls(ball_radius, inner));
	r = ball_to_radius(n, inner);
	theta = 360 / n;
	pinRadius = pr * r;

	height1 = (len(height)==2) ? height[0]:height;
	height2 = (len(height)==2) ? height[1]:height;

// The pins:
	if (show_pins=="yes"){
	for(i = [0 : n])
		rotate(a = [0, 0, theta * i])
			translate([inner, 0, 0])
				union() {
					color("red")
						sphere(r = r - 0.5*gap, center = true, $fn = 45);
					assign(rad = pinRadius - gap)
						color("red")
							cylinder(r1 = rad, r2 = rad, h = height, center = true, $fn = 45);
				}
	}

// The inner race:
	if (show_inner_race_a=="yes"){
		difference() {
			assign(rad = inner - pinRadius - gap)
				translate([0,0,-slew-(height1/4)])
					cylinder(r1 = rad, r2 = rad, h = height1/2, center = true, $fn = fn);
			rotate_extrude(convexity = 10,$fn=fn)
				translate([inner, 0, 0])
					circle(r = r + gap, $fn = fn);
			cylinder(r1 = hole, r2 = hole, h = height1 + 5, center = true, $fn = fn);

		}
	}
	if (show_inner_race_b=="yes"){
		translate([0,0,1])
		difference() {
			assign(rad = inner - pinRadius - gap)
				translate([0,0,-slew+(height1/4)])
					cylinder(r1 = rad, r2 = rad, h = height1/2, center = true, $fn = fn);
			rotate_extrude(convexity = 10,$fn=fn)
				translate([inner, 0, 0])
					circle(r = r + gap, $fn = fn);
			cylinder(r1 = hole, r2 = hole, h = height1 + 5, center = true, $fn = fn);

		}
	}
// The outer race:
	if (show_outer_race=="yes"){
	union(){
		difference() {
			cylinder(r1 = outer, r2 = outer, h = height2, center = true, $fn = fn);
			assign(rad = inner + pinRadius + gap)
				cylinder(r1 = rad, r2 = rad, h = height2 + 5, center = true, $fn = fn);
			rotate_extrude(convexity = 10,$fn = fn)
				translate([inner, 0, 0])
					circle(r = r + gap, $fn = fn);
		}

		if (len(outer_flange)==2) {
			translate([0,0,height2/2-outer_flange[1]/2])
			color("green")
				difference(){
					cylinder(r1 = outer+outer_flange[0], r2 = outer+outer_flange[0], h = outer_flange[1], center = true, $fn = fn);
//					translate([0,0,-0.5])
						cylinder(r1 = outer-((outer-inner)/2), r2 = outer-((outer-inner)/2), h = outer_flange[1]+1, center = true, $fn = fn);
				}
		}
	}
	}
}

module crown(inner,elements, height, r,center=true){
	theta = 360/elements;
	for(i = [0 : elements])
		rotate(a = [0, 0, theta * i])
			translate([inner, 0, 0])
				assign(rad = r)
					cylinder(r1 = rad, r2 = rad, h = height, center = center, $fn = 45);

}

difference(){
	Bearing(outer = outer_diameter/2, inner = gap_diameter/2, ball_radius = ball_diameter/2, gap = tolerance, height = bearing_height, hole = inner_diameter/2,outer_flange=flange_params,slew=slew_gap,pr=gap_factor);
	// inner holes
		crown(inner_race_screw_diameter,inner_race_screw_holes,bearing_height+slew_gap+2,inner_race_screw_hole_diameter/2);
	// inner hole caps
		translate([0,0,bearing_height/2-inner_race_screw_cap_depth])
			crown(inner_race_screw_diameter,inner_race_screw_holes,inner_race_screw_cap_depth+1,inner_race_screw_cap_diameter/2,false);
		translate([0,0,-bearing_height/2-inner_race_screw_cap_depth+1])
			crown(inner_race_screw_diameter,inner_race_screw_holes,inner_race_screw_cap_depth+1,inner_race_screw_cap_diameter/2,false);
	if (flange){
		// outer holes
			translate([0,0,bearing_height/2-flange_height-1])
				crown(outer_race_screw_diameter,outer_race_screw_holes,flange_height+2,outer_race_screw_hole_diameter/2,false);

			translate([0,0,bearing_height/2-outer_race_screw_cap_depth])
				crown(outer_race_screw_diameter,outer_race_screw_holes,flange_height+2,outer_race_screw_cap_diameter/2,false);
	}

	if (show_crossection=="yes")	{
		translate([0,0,-bearing_height])
			cube([outer_diameter,outer_diameter,bearing_height*2]);
	}
}

```


[User]
Hey there, I'm looking to get some custom bottle clips designed in OpenSCAD. I want to be able to attach them to different bottle necks. I'd like them to have a name printed on them and a logo of a stylized "31C3" with a gap in the "C".

Here's the general idea: the clip will be a cylinder with different radii at the top and bottom, creating a slightly tapered shape. This cylinder has a section removed, creating a gap that allows you to clip it onto a bottle neck. I need to be able to adjust the top and bottom radii, the total height of the clip, and the wall thickness. Also, the text and logo need to be embedded in the clip's outer surface.

For the text, I'd like to be able to specify the name and choose from a few different fonts. I think I'd need the Write library for that. Let's say the supported fonts will be "Letters", "BlackRose", "Orbitron", "Knewave", and "Braille" (just like in the example). I'll need to pass in the desired font for each tag when calling the module.

The logo should be a stylized "31C3", with the "3"s being curved, the "1" straight, and the "C" an open ring, just like in the included example code. I need the logo's position to be adjustable and it needs to have a small gap, too, as you'll see in the example. I want to specify the overall size of the logo and the wall thickness and depth of the logo extrusion.

I think it would also be really helpful if I could specify the type of bottle so that the radii are set automatically, that would help a lot in generating them quickly. I'm primarily working with standard "Club Mate" bottles and "longneck" bottles. If I select the "mate" type, it should use a radius of 13 for the top, 17.5 for the bottom, and a height of 26. If I select "longneck", it should use a radius of 13 for the top, 15 for the bottom, and a height of 26. The wall thickness should always be configurable by parameter.

Finally, I need to be able to generate two tags at the same time using the same function, and rotate and translate the second tag to align it in the build plate.

So, in short, I'm thinking I need a main module like 'bottle_clip' that I can use to make each bottle clip and a module to create the stylized "31C3" logo and one for the name. I need to be able to specify names for each of the two potential tags as well as the bottle type. I'd like to be able to define parameters for the name of each clip, the font, and the bottle type for each tag. Could you help me out with that?

[Assistant]
31C3-bottle-clip.scad:
```
include <write/Write.scad>

/**
 * A name tag that can easily be clipped to the neck of your bottle.
 * Copyright (C) 2013 Roland Hieber <rohieb+bottleclip@rohieb.name>
 *
 * This file was modified by obelix <christian@loelkes.com> for the
 * OHM2013-Logo. If you wish to use other logos please use the original
 * file. All other parameters were not modified.
 *
 * Version of the modification: 1.0
 *
 * See examples.scad for examples on how to use this module.
 *
 * The contents of this file are licenced under CC-BY-SA 3.0 Unported.
 * See https://creativecommons.org/licenses/by-sa/3.0/deed for the
 * licensing terms.
 */

/**
 * Creates one instance of a bottle clip name tag. The default values are
 * suitable for 0.5l Club Mate bottles (and similar bottles). By default, logo
 * and text are placed on the name tag so they both share half the height. In this
 * version the logo is fixed.
 *
 * Parameters:
 * ru: the radius on the upper side of the clip
 * rl: the radius on the lower side of the clip
 * ht: the height of the clip
 * width: the thickness of the wall. Values near 2.5 usually result in a good
 *	clippiness for PLA prints.
 * name: the name that is printed on your name tag. For the default ru/rt/ht
 *	values, this string should not exceed 18 characters to fit on the name tag.
 * font: the path to a font for Write.scad.
 */

/* [Global] */

// Name on the first tag
name1 = "Foo"; // Name

// Name on the second tag
name2 = ""; // Name

// Size first tag
type1 = "mate"; // [mate:Club-Mate,longneck:Longneck]

// Size second tag
type2 = "mate"; // [mate:Club-Mate,longneck:Longneck]

// Font
font = 3; // [1:Letters,2:BlackRose,3:Orbitron,4:Knewave,5:Braille]

/* [Hidden] */

$fn = 100;
if(font == 1) { generate("write/Letters.dxf");}
if(font == 2) { generate("write/BlackRose.dxf");}
if(font == 3) { generate("write/orbitron.dxf");}
if(font == 4) { generate("write/knewave.dxf");}
if(font == 5) { generate("write/braille.dxf");}

module generate(font) {
	if( name1 != "") {
		if(type1 == "mate") {
			echo("Creating normal mate tag with nick: ", name1);
			bottle_clip(13,17.5,26,2.5,name1,font);
		}
		if(type1 == "longneck") {
			bottle_clip(13,15,26,2.5,name1, font);
			echo("Creating longneck tag with nick: ", name1);

		}
	}
	if( name2 != "") {
		if(type2 == "mate") {
			rotate([0,0,180])translate([-15,0,0])bottle_clip(13,17.5,26,2.5,name2,font);
			echo("Creating normal mate tag with nick: ", name2);
		}
		if(type2 == "longneck") {
			rotate([0,0,180])translate([-15,0,0])bottle_clip(13,15,26,2.5,name2, font);
			echo("Creating longneck tag with nick: ", name2);
		}
	}
}

module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name=name1, font="write/orbitron.dxf") {

	e=100;  // should be big enough, used for the outer boundary of the text/logo
	r_diff = rl-ru;
	text_pos = 18;

	difference() {
		rotate([0,0,-45])
			union() {
				cylinder(r1=rl+width, r2=ru+width, h=ht);
				writecylinder(name, [0,0,0], rl+0.5, ht/13*7, h=ht/13*4, t=max(rl,ru), font=font);
				translate([0,0,text_pos])
					rotate([0,-90,90])
						31C3_mate(10,0.6,1.5+ru+text_pos*(r_diff)/ht,7,asin(r_diff/ht));
			}
		// inner cylinder which is substracted
		translate([0,0,-1])
			cylinder(r1=rl, r2=ru, h=ht+2);
		// outer cylinder which is substracted, so the text and the logo end
		// somewhere on the outside ;-)
		difference () {
			cylinder(r1=rl+e, r2=ru+e, h=ht);
			translate([0,0,-1])
				// Note: bottom edges of characters are hard to print when character
				// depth is > 0.7
				cylinder(r1=rl+width+0.7, r2=ru+width+0.7, h=ht+2);
		}
		// finally, substract a cube as a gap so we can clip it to the bottle
		translate([0,0,-1]) cube([50,50,50]);
	}
}

/**
 * Creates one instance of a bottle clip name tag suitable for 0.33l longneck
 * bottles (like fritz cola, etc.). All parameters are passed to the module
 * bottle_clip(), see there for their documentation.
 */
//module bottle_clip_longneck(name="", width=2.5, font="write/orbitron.dxf") {
//	bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, font=font);
//}

/**
 * The Steinie-Tag has been removed since it does not support logos.
**/

// Generate the 31C3 Logo

rad=20;
thick = 2;

//31C3_cylinder(100,5,200,50);

module 31C3_mate(height, wall, rad, extrude=2, incl=10) {
	length = (height+wall) * 2.4 ;

	angle = asin(0.5*(height+wall)/rad);
	//echo(angle);

	translate([0,0,0])rotate([0,0,0]) {
		rotate([-angle*2.4,0,0])translate([0,0,rad-extrude/2])rotate([0,incl,0])31C3_3(height, wall, extrude);
		rotate([-angle,0,0])translate([0,0,rad-extrude/2])rotate([0,incl,0])31C3_1(height, wall, extrude);
		rotate([angle*0.4,0,0])translate([0,0,rad-extrude/2])rotate([0,incl,0])31C3_C(height, wall, extrude);
		rotate([angle*2.4,0,0])translate([0,0,rad-extrude/2])rotate([0,incl,0])31C3_3(height, wall, extrude);
	}
}

module 31C3(height, wall, extrude=2) {
	translate([0,(height+wall)*2.4,0])31C3_3(height, wall, extrude);
	translate([0,(height+wall)*1.7,0])31C3_1(height, wall, extrude);
	translate([0,height+wall,0])31C3_C(height, wall, extrude);
	31C3_3(height, wall, extrude);
}

module 31C3_logo (size, wall, extrude) {
	open_ring(size,wall*2,size*0.75, extrude);
	translate([-wall,wall*2,0])cube([wall*2,size*1.2,extrude]);
}

module 31C3_3(height, wall, extrude) {
	open_ring(height/2,wall*2,height*0.5*0.75, extrude);
	translate([-wall,-height/4,0])cube([wall*2,height*0.75,extrude]);
}

module 31C3_1(height, wall, extrude) {
	rotate([0,0,90])translate([0,0,extrude/2])cube([wall*2,height,extrude], center=true);
}

module 31C3_C(height, wall, extrude) {
	rotate([0,0,180])open_ring(height/2,wall*2,height*0.5*0.75, extrude);
}

module open_ring(rad, wall, gap, extrude=2) {
	difference() {
		ring(rad,wall, extrude);
		translate([-gap/2,0,-1])cube([gap,rad+1,extrude+2]);
	}
}

module ring(rad, wall, extrude=2) {
	difference() {
		cylinder(r=rad,h=extrude);
		translate([0,0,-1])cylinder(r=rad-wall,h=extrude+2);
	}
}

/*
Size Mate 13 17.5
Size Longneck 13 15
Size Cola Cola 1L 15 25
*/

```


[User]
I'm trying to design a cupola with supporting columns, and I'd like to have it be parametric so I can easily adjust its dimensions. I envision a cylindrical base, a number of columns evenly spaced around that base, and then a dome-like structure on top.

Here are the specific features I need:

*   **Base:** A cylinder with adjustable diameter and height. The height should be slightly larger than just a base and should scale a bit with the overall height of the cupola.
*   **Columns:** A set of equally spaced cylindrical columns around the base. The number of columns, their diameter, and their height should all be adjustable. These columns need to start at the top of the base cylinder and extend upwards. The diameter of the columns should also scale a bit with the overall diameter.
*   **Dome:** A dome shape on top, achieved by taking the difference of two spheres and then cutting off the bottom to make the dome shape. The inner sphere should be subtracted from the outer sphere, leaving a shell with an adjustable thickness. The diameter of the sphere should be derived from the base cylinder's diameter, and the base should be directly on the top of the columns.

I'd like to be able to control the following parameters:

*   `diameter`: The diameter of the base cylinder and the dome.
*   `hight`: The height of the cylindrical columns.
*   `column_number`: The number of columns.

I'm not very experienced with OpenSCAD, and I'm struggling a little bit. Could you help me create a fully parametric OpenSCAD file for this cupola, including all the features I’ve mentioned? I don't need any special libraries at this time. I'd just like the core design in a single .scad file. Thanks!

[Assistant]
cupola_Custom.scad:
```

diameter=60; //[5:100]
hight=20;	//[0:100]
column_number=8; //[0:36]

$fn=30;

base_hight=2+hight/10;
column_diameter=1+diameter/8;
radius=diameter/2;

translate([0,0,base_hight/2])
cylinder(h=base_hight, r=radius, center=true);

column_z=base_hight+hight/2;

for ( i = [0 : column_number-1] )
{
    rotate( i * 360 / column_number, [0, 0, 1])
    translate([0, (diameter-column_diameter)/2, base_hight+hight/2])
  		cylinder(h=hight, r=column_diameter/2, center=true);
}

cupola();

module cupola()
{
	translate([0,0,base_hight+hight])
	difference()
	{

		sphere(r=radius, center=true);
		sphere(r=radius-column_diameter, center=true);
		translate([0,0,-diameter/2])
		cube(diameter, center=true);
	}

}

```


[User]
Hey, I'm looking for some help designing a bed leveling aid for my 3D printer. I've got a round bed and I want a disc with concentric rings and some visual indicators along the edge. I've kinda got something hacked together, but it's not very flexible.

Here's what I need:

*   **Overall Shape:** A flat disc.
*   **Outer Diameter:** Should be a parameter I can change. Let's call it `bed_diameter`.
*   **Ring Thickness:**  Each ring should be a certain width based on my extrusion width and how many perimeters I want. Let's call the extrusion width `extrusion_width` and the number of perimeters `ring_perimeters`. The actual ring thickness will be `extrusion_width` * `ring_perimeters`.
*   **Ring Height:** Should also be a parameter (`ring_height`).  All rings and the overall disc should be the same height.
*  **Number of Rings:** Should be a parameter (`num_inner_rings`) that controls how many inner concentric rings are created. Each ring should be spaced evenly between the edge of the disc and the center.
*  **Center Circle:** I want a small circle in the very center, also with a parameter to control its diameter (`center_diameter`). It will have the same height as the rings and main disc.
*   **Axis Markers:** I need 3 equally spaced "axis" markers along the outer edge of the disc. These should extend inwards toward the center.
*   **Axis Marker Shapes:** Each axis marker should have a different shape. I was thinking X, Y and Z for the 3 markers.  The "X" should be two crossed lines, "Y" should be two angled lines with a vertical line connecting them, and "Z" should be two vertical lines and a angled line.
* **Axis Marker Depth:** The axis markers should also have a depth ( `axis_marker_depth`) equal to `ring_height`. They should be a full "cube" like extrusion.
*   **Parametric:** I need all these things to be defined as parameters that I can change in the OpenSCAD customizer.

I would like this to all be in one .scad file. Can you help me with that? I'm not worried about it being perfect - just functional is great. Thanks!

[Assistant]
bedLevelAid.scad:
```
// bed diameter (mm)
d=127;
// extrusion width
ed=0.55;
// ring perimeters
rp=2;
// thickness
h=0.4;
// center diameter
cd=8;
// # of inner rings
ir=1;

$fn=150;
union() {
difference() {
	cylinder(d=d,h=h, center=true);
	cylinder(d=d-(rp*ed)*2, h=h+1, center=true);
}

for(y=[1:ir]) {
	innerRing(ir, y);
}

cylinder(d=cd,h=h,center=true);

for(x=[1:3]) {
	axis(360/3*x, x);
}
}

module innerRing(rings, ring) {
	difference() {
		cylinder(d=d/(rings+1)*ring,h=h, center=true);
		cylinder(d=d/(rings+1)*ring-(rp*ed)*2, h=h+1, center=true);
	}
}

module axis(r, axis) {
	rotate([0,0,r])
	union(){
		translate([0,d/4,0])
		cube([ed*rp,d/2,h], center=true);

		if(axis==1) x();
		if(axis==2) y();
		if(axis==3) z();
	}
}

module x() {
	translate([0,d/2/4*3,0])
	union() {
		rotate([0,0,45])
		cube([8,ed*rp,h], center=true);
		rotate([0,0,-45])
		cube([8,ed*rp,h], center=true);
	}
}

module y() {
	translate([0,d/2/4*3,0])
	union() {
		translate([-1.5,-1,0])
		rotate([0,0,45])
		cube([4,ed*rp,h], center=true);
		translate([-1.5,1,0])
		rotate([0,0,-45])
		cube([4,ed*rp,h], center=true);
		translate([1.5,0,0])
		cube([4,ed*rp,h], center=true);
	}
}

module z() {
	translate([0,d/2/4*3,0])
	union() {
		translate([-2.7,.15,0])
		rotate([0,0,90])
		cube([4,ed*rp,h], center=true);
		translate([2.7,-.15,0])
		rotate([0,0,-90])
		cube([4,ed*rp,h], center=true);
		rotate([0,0,-35])
		cube([6,ed*rp,h], center=true);
	}
}

```


[User]
Okay, so I need to create a Bahtinov mask for my telescope, but it's too big to print in one piece. I've found this OpenSCAD code that splits the mask into sections, and I'd like to have an AI assistant build the design for me using parametric OpenSCAD code.

Here's the breakdown:

**Overall Goal:** Generate a parametric Bahtinov mask design that can be split into sections for printing on smaller printers.

**Key Features and Parameters:**

*   **Sections:** The mask should be able to be split into 1, 2, or 4 sections. This is controlled by the `sections` variable.
*   **Section:** The `section` variable controls which section is rendered (0 to sections-1).
*   **Outer Diameter:** The overall diameter of the mask, controlled by `outerDiameter`.
*   **Aperture:** The light path diameter of the telescope, controlled by `aperture`. This should always be smaller than `outerDiameter`.
*   **Center Hole Diameter:** The diameter of the secondary mirror holder or an equivalent center hole, controlled by `centerHoleDiameter`.  Set to 0 if there's no center obstruction.
*   **Gap:** The width of the gaps in the Bahtinov pattern, controlled by `gap`.
*   **Angle:** The angle of the bars in the pattern, controlled by `angle`.
*   **Max Bars:** The maximum number of bars in the pattern, controlled by `maxBars`.
*   **Bar:** The width of the strengthening bars on the mask, controlled by `bar`.
*   **mHeight:** The height of the main part of the mask, controlled by `mHeight`.
*   **bHeight:** The height of the strengthening bars, controlled by `bHeight`.
*   **Tol:** Extra space between sections for printing, controlled by `tol`.

**Detailed Description:**

1.  **Bahtinov Pattern:** The core of the design is the Bahtinov pattern, which consists of three sets of angled bars.  Two sets are angled at `angle` and `-angle` respectively, and the third set is a set of vertical bars in the center. The number of bars is derived from `aperture` and `gap`, but capped by `maxBars`.
2.  **Mask Shape:** The mask should be a circle with the diameter defined by `outerDiameter`.  It should have a circular hole in the center defined by `aperture`, and if necessary, a center hole defined by `centerHoleDiameter`.
3.  **Strengthening:** The mask has some strengthening bars: a horizontal and a vertical bar. The vertical bar will always extend across the diameter; the horizontal bar's length depends on the number of sections; for 4 sections, it goes across the diameter but for 1 or 2 it should be reduced.
4.  **Sectioning:** When `sections` is set to 2 or 4, the mask should be split into corresponding sections.  The `section` parameter should select the appropriate part for printing. The splitting should be done so the pieces can be joined easily after printing; some additional material (controlled by `tol`) needs to be included between sections. The edge of the sections are not straight lines, but rather a combination of straight edges with cylinder cutouts.
5. **Handle** At the outer edge, add a small handle, a semi-cylinder.

**Libraries:**

No external libraries should be needed for this design as far as I can tell.

**Output:**

I would like parametric OpenSCAD code that achieves all of the above. The code should be well-commented and follow good coding practices.  I want to be able to adjust all the parameters easily.

Let me know if you need any clarification.

[Assistant]
bahtinov.scad:
```
/*                                                 -*- c++ -*-
 * A Bahtinov mask generator.
 * Units in mm, default values are for
 * an 8 inch Newtonian
 *
 * Copyright 2013-2014, Brent Burton
 * License: CC-BY-SA
 *
 * Based on version updated: 2014-06-23
 *
 * Further modifications by Egil Kvaleberg
 * Latest update: 2014-01-26
 */

// Number of sections to split the mask in
sections = 0; // [1,2,4]

// Print which section, max is sections-1
section = 0; // [0,1,2,3]

// The overall diameter of the mask.
outerDiameter = 224.0; //

// The telescope light path diameter.
aperture = 212.0; // should be less than outerDiameter

// Diameter of secondary mirror holder. If no secondary, set to 0.
centerHoleDiameter = 0; //

// Width of the bars.
gap = 3.3; // 3.3 is for 1000mm focal length; 4.0 for 1200mm; 6.0 for 2000mm

// Angle of bars
angle = 20; // 20 degrees is the standard value

// Maximum number of bars
maxBars = 10; //

// Width of the strengthening bars.
bar = 10.0;

// Height of gap mask
mHeight = 2.0;  //

// Height of strengthening bars
bHeight = 6.0; //

// Extra air needed between sections (times two)
tol = 0.25; // Depends on the accuracy of your printer

d = 1 * 0.01;

/* create a series of bars covering roughly one half of the
 * scope aperture. Located in the +X side.
 */
module bars(gap, width, num=5) {
    num = round(num);
    for (i=[-num:num]) {
        translate([width/2,i*2*gap]) square([width,gap], center=true);
    }
}

module bahtinovBars(gap,width) {
    numBars = min(maxBars-1, aperture/2 / gap / 2 -1);
    // +X +Y bars
    intersection() {
        translate([0, outerDiameter*.08, 0]) rotate([0,0,angle]) bars(gap, width, numBars/2);
        square([outerDiameter/2, outerDiameter/2], center=false);
    }
    // +X -Y bars
    intersection() {
        translate([0, -outerDiameter*.08, 0]) rotate([0,0,-angle]) bars(gap, width, numBars/2);
        translate([0,-outerDiameter/2]) square([outerDiameter/2, outerDiameter/2], center=false);
    }
    // -X bars
    rotate([0,0,180]) {
		if (sections<=2) bars(gap, width, numBars);
		else translate([0,gap,0]) bars(gap, width, numBars+1); 	 // offset so there is a solid bar in the middle
	}
}

$fn=72;
module bahtinov2D() {
    width = aperture/2;

    union() {
        difference() {                  // trims the mask to aperture size
            circle(r=aperture/2+1);
            bahtinovBars(gap,width);
        }
        difference() {                  // makes the outer margin
            circle(r=outerDiameter/2-1);
            circle(r=aperture/2);
        }
        // Add horizontal and vertical structural bars:
		  square([bar,2*(aperture/2+1)], center=true);

        if (sections==4) square([2*(aperture/2+1),bar], center=true);
		  else translate([aperture/4,0]) square([aperture/2+1,bar], center=true);
        // Add center hole margin if needed:
        if (centerHoleDiameter > 0 && centerHoleDiameter < outerDiameter) {
            circle(r=(centerHoleDiameter)/2+gap);
        }
    }
}

module bahtinov() {
   difference() {                          // overall plate minus center hole
		union() {
	   		linear_extrude(height=mHeight) bahtinov2D();
			// Add strengthening bars
	       difference() {
	          cylinder(r=outerDiameter/2, h=bHeight);
	          translate([0,0,-d]) cylinder(r=aperture/2+1, h=bHeight+2*d);
	       }
	       // Add horizontal and vertical structural bars:
	       translate([0,0,bHeight/2])
				cube([bar*.75,2*(aperture/2+1),bHeight], center=true);
	       if (sections==4) translate([0,0,bHeight/2])
				cube([2*(aperture/2+1),bar*.75,bHeight], center=true);
			else translate([aperture/4,0,bHeight/2])
				cube([aperture/2+1,bar*.75,bHeight], center=true);

	  		// Add a little handle
	    	translate([outerDiameter/2-bar,0,0]) hull () {
				cylinder(r=bar*.4, h=12);
				translate([-12,0,0]) cylinder(r=bar*.4, h=12);
			}
		}
      // subtract center hole if needed
      if (centerHoleDiameter > 0 && centerHoleDiameter < outerDiameter) {
          translate([0,0,-0.1]) cylinder(r=centerHoleDiameter/2+1, h=bHeight+0.2);
      }
   }
}

// create the outline that defines the cut between sections
module section() {
 	// the factor 20 can be tuned
	step = (outerDiameter-centerHoleDiameter-bar)/20;

	if (sections==2) translate([bar/4+tol, -outerDiameter/2, 0])
		cube([outerDiameter/2, outerDiameter, mHeight+12]);
	else translate([bar/4+tol, bar/4+tol, 0])
		cube([outerDiameter/2, outerDiameter/2, mHeight+12]);
	rotate ([0,0,(sections==2)?-90:0]) {
		for (x=[centerHoleDiameter/2+bar/2:2*step:outerDiameter/2-step]) {
			translate([x,-bar/8,0])
				hull () {
					cylinder(r=bar/8-tol, h=mHeight+12);
					translate([step,0,0]) cylinder(r=bar/8-tol, h=mHeight+12);
				}
			difference () {
				translate([x,-tol,0]) cube([step, bar/4+2*tol, mHeight+12]);
				translate([x,bar/8,-d]) {
					cylinder(r=bar/8+tol, h=mHeight+12+2*d);
	 				translate([step,0,0]) cylinder(r=bar/8+tol, h=mHeight+12+2*d);
				}
			}
		}
		// filler at start
		translate([centerHoleDiameter/2+tol+((centerHoleDiameter>0 || sections==2 || section==0 || section==2)? 0: bar/4),-bar/4+tol,0]) cube([step, bar/2, mHeight+12]);
	}

	for (y=[centerHoleDiameter/2+bar/2+step:2*step:outerDiameter/2-step]) {
		translate([-bar/8,y,0])
			hull () {
				cylinder(r=bar/8-tol, h=mHeight+12);
				translate([0,step,0]) cylinder(r=bar/8-tol, h=mHeight+12);
			}
		difference () {
			translate([-tol,y,0]) cube([bar/4+2*tol, step, mHeight+12]);
			translate([bar/8,y,-d]) {
				cylinder(r=bar/8+tol, h=mHeight+12+2*d);
 				translate([0,step,0]) cylinder(r=bar/8+tol, h=mHeight+12+2*d);
			}
		}
	}
	// filler at end
	translate([-bar/4+tol,outerDiameter/2-bar/2,0]) cube([bar/2, step, mHeight+12]);
}

px = (360 / sections) * section;
qx = (sections == 2) ? 90 + 45 : 0;

if (sections > 1) {
	rotate([0, 0, qx]) intersection () {
		bahtinov();
		rotate([0, 0, px]) section();
	}
} else {
	bahtinov();
}
```


[User]
I'm looking for an OpenSCAD design for a mounting bracket for a GoPro Hero camera (with its housing) to attach to a HobbyKing Brushless ActionCam Gimbal. I've seen a design for it, but I need something parametric so I can adjust it easily.

The gimbal itself is this one: http://hobbyking.com/hobbyking/store/__51184__HobbyKing_Brushless_ActionCam_Gimbal_With_2208_Motors_and_3K_Carbon_Construction.html

Basically, the bracket needs to have a couple of flat tabs that the camera will mount to, and also a support piece with holes for screws to attach the bracket to the gimbal. The design I saw also had some strengthening bars along the edges of the tabs, and some extra space to accommodate an accelerometer board.

I need the design to be parametric so I can adjust the balance. Specifically I'd like to be able to control the `camera_yoffs` (the distance from the first tab to the camera mount points) and `camera_zoffs` (the offset between the bracket plane and the camera mount points).

Here are the parameters from the existing design, though you should make your own design from scratch:

*   `camera_yoffs`: Distance from the first tab to the nearest camera tab.
*   `camera_zoffs`: Distance from the bracket plane.
*   `cbracket_screw`: Diameter of the mounting screw (with some margin).
*   `cbracket_circ`: Circumference around the screw for clearance.
*   `cbracket_circ2`: Clearance for the screw head.
*   `cbracket_suppw`: Width of the support piece.
*   `cbracket_wall`: Wall thickness of the support piece.
*   `cbracket_dist`: Distance between the mounting holes.
*   `nut_height`: Height of the nut.
*   `nut_af`: Across-flats of the nut.
*   `thickness`: Thickness of the mounting tabs.
*   `wall`: Thickness of the edge bars.
*   `inner_width`: Inner width of the main body.
*   `outer_width`: Outer width of the main body.
*   `tabs`: Depth of the tabs on each side of the main body.
*   `board_extra`: Extra space for the accelerometer board.
*   `tab1`: Length of the first mounting tab.
*   `tabd`: Distance between the two mounting tabs.
*   `tab2`: Length of the second mounting tab.

I don't need the exact same approach as the linked SCAD code - just an equivalent, parameterizable, design. I'm not sure if it's important, but I don't use any external OpenSCAD libraries.

[Assistant]
gopro_hk_gimbal_bracket.scad:
```
//
// mounting bracket for GoPro Hero with housing
// for use on the HobbyKing Brushless ActionCam Gimbal
// http://hobbyking.com/hobbyking/store/__51184__HobbyKing_Brushless_ActionCam_Gimbal_With_2208_Motors_and_3K_Carbon_Construction.html
//
// Design by Egil Kvaleberg, Jan 2015
//

// adjust for best balance:
camera_yoffs = 28.0; // measured from tab1 to nearest camera tab
// adjust for best balance:
camera_zoffs = 2.0; // measured from bracket plane

cbracket_screw = 1*5.3; // M5 with margin
cbracket_circ = 1*4.5; // circumference round screw (5.0)
cbracket_circ2 = 1*6.5; // clearance with margin
cbracket_suppw = 1*12.0; // width of support piece
cbracket_wall = 1*3.1; // 3.0 with clearance
cbracket_dist = 1*3.3; // with clearance
nut_height = 3.5;
nut_af = 1*8.6; // 8mm plus margin

thickness = 1*1.90; // of tabs
wall = 1*2.5;
inner_width = 1*21.7;
outer_width = 1*26.0;
tabs = 1*2.0;
board_extra = 9.0; // extra space for accelerometer board
tab1 = 1*10.25;
tabd = 1*28.9;
tab2 = 1*5.25;
d = 1*0.01;

module add_this()
{
	// middle section, two parts
	translate([-inner_width/2, -board_extra, -thickness/2]) cube([inner_width, board_extra+tabs+camera_yoffs-cbracket_wall-2*nut_height, thickness]);
	translate([-inner_width/2, tabs+tab1+tabd, -thickness/2]) cube([inner_width, tab2+tabs, thickness]);

	// strengthening bars along edge
	translate([-inner_width/2, tabs+3.0, -thickness/2]) cube([wall, tab1-3.0+tabd+tab2+tabs, wall+thickness]);
	translate([inner_width/2-wall, tabs+3.0, -thickness/2]) cube([wall, tab1-3.0+tabd+tab2+tabs, wall+thickness]);

	// two tabs
	translate([-outer_width/2, tabs, -thickness/2]) cube([outer_width, tab1, thickness]);
	translate([-outer_width/2, tabs+tab1+tabd, -thickness/2]) cube([outer_width, tab2, thickness]);

	// bottom support
	translate([0, tabs+camera_yoffs-cbracket_wall-2*nut_height, camera_zoffs]) difference() {
		translate([-cbracket_suppw/2, -wall, -(cbracket_screw/2 + cbracket_circ2 + wall)]) cube([cbracket_suppw, wall+15.0, wall+cbracket_circ2+cbracket_screw/2-camera_zoffs]);
		rotate([-90, 0, 0]) cylinder(r = cbracket_screw/2 + cbracket_circ2, h=15.0+d);
	}
	translate([-cbracket_suppw/2, tabs+camera_yoffs-cbracket_wall, -(cbracket_screw/2 + cbracket_circ2 + wall)+camera_zoffs]) cube([cbracket_suppw, cbracket_wall+cbracket_wall+cbracket_dist+cbracket_wall+cbracket_wall, wall+ cbracket_circ2]);

	translate([0, tabs+camera_yoffs-cbracket_wall, camera_zoffs]) rotate([-90, 0, 0]) {
		// cage for nut
		translate([0, 0, -nut_height]) {
			cylinder(r1 = (nut_af/2)/cos(30), r2 = cbracket_screw/2 + cbracket_circ, h=nut_height);
		}
		cylinder(r = cbracket_screw/2 + cbracket_circ, h=cbracket_wall+cbracket_wall+cbracket_dist+cbracket_wall+cbracket_wall);
		translate([0, 0, cbracket_wall+cbracket_wall+cbracket_dist+cbracket_wall+cbracket_wall]) cylinder(r = cbracket_screw/2 + wall, h=2*cbracket_wall);
	}
}

module sub_this()
{
	translate([0, tabs+camera_yoffs-cbracket_wall, camera_zoffs]) rotate([-90, 0, 0]) {
		translate([0, 0, -nut_height]) {
			rotate([0, 0, 30]) translate([0, 0, -nut_height]) cylinder(r = (nut_af/2)/cos(30), h=nut_height*2, $fn=6);
			cylinder(r = cbracket_screw/2, h=50.0, $fn=30);
		}
		translate([0, 0, cbracket_wall]) cylinder(r = cbracket_screw/2 + cbracket_circ2, h=cbracket_wall);
		translate([0, 0, cbracket_wall+cbracket_wall+cbracket_dist]) cylinder(r = cbracket_screw/2 + cbracket_circ2, h=cbracket_wall);
		translate([0, 0, cbracket_wall+cbracket_wall+cbracket_dist+cbracket_wall+cbracket_wall+3*cbracket_wall]) cylinder(r = cbracket_screw/2 + wall + 0.5, h=cbracket_wall);
	}
}

difference() {
	add_this();
	sub_this();
}

```


[User]
I need a custom place card generator in OpenSCAD. I'd like it to create a design that can be folded into a hollow triangular prism, with the guest's name printed on two opposite sides. I'm imagining something similar to the existing "PlaceCard.scad" I found online but I need it made from scratch.

Here are the specific parameters I need control over:

*   **Text:** Obviously, the guest's name needs to be configurable as a text string.
*   **Font:** I need to be able to specify the font to use. I'd like to use a font from the included Write.scad library.
*   **Font Size and Height:** I need to control both the overall font size and the extrusion height of the text.
*   **Text Offset:** I'll need to shift the text horizontally and vertically.
*   **Overall Dimensions:**  I need parameters for the width and height of the place card, specifically the unfolded rectangle.
*   **Thickness:** The total thickness of the material, excluding the text.
*   **Hinge Layer Thickness:** The thickness of the layer used for the hinge, which will be thinner than the rest to allow folding.
*   **Angle:** The angle of the triangular prism, which will affect the shape of the sides.
*   **Band:** I would like to use bands on each end to hold the folded place card in its triangular prism shape. I'll need parameters to define the radius, width and distance from the ends.
*   **Manifold Fix:** The file I included has this as 0.01, and I assume its for a slight correction. This is probably not needed but please include it.

The design should consist of three identical rectangular sections, with the middle one having a hinge created by a reduced-thickness section. The guest's name should be printed on the first and third sections, rotated 180 degrees from each other, with the text raised. The bands should be extruded and centered on each end.

Please use the `Write.scad` library. I need the design to be parametric so that I can adjust these variables to fit my needs. I want the scad to be made from scratch.

[Assistant]
PlaceCard.scad:
```
// ************* Credits part *************

// Programmed by Fryns - January 2015

// Optimized for Customizer

// Uses Write.scad by HarlanDMii, published on Thingiverse 18-Jan-2012 (thing:16193)

// ************* Declaration part *************

/* [Text] */
text="Guest Name";
font = "write/orbitron.dxf";//["write/Letters.dxf":Basic,"write/orbitron.dxf":Orbitron,"write/BlackRose.dxf":BlackRose]
font_size=8;
text_height=0.4;
text_x_offset=0;
text_y_offset=0;

/* [Size] */
Width = 75.0;
Height= 15.0;
// Total thickness without text
Thickness = 1.6; // Total thickness without text
// Layer thickness for fold
HingeLayer = 0.4;
Angle=60;

/* [Band] */
// Band depth
BandRadius = 0.8; // Band depth
// Width at full depth
BandWidth = 1.0 ; // Width at full depth
// Band distance from end
BandDistance = 5; // Band distance from end

/* [Hidden] */
Manifoldfix = 0.01;

// ************* Executable part *************
use <write/Write.scad>

Placecard();

module Placecard(){
difference(){
		Assembly();
		translate([-Width/2+BandDistance-BandWidth/2,0,Thickness])
			rotate([90,0,0])
				color("red") Band();

		translate([Width/2-BandDistance+BandWidth/2,0,Thickness])
			rotate([90,0,0])
				color("red") Band();
	}
}

module Assembly(){
 	Namelayer();
	translate([0,-1*Height,0])
		Monomer();
	translate([0,0*Height,0])
		Monomer();
	translate([0,1*Height,0])
		Monomer();
}

module Monomer(){
	translate([0,-Height/2,0])
		rotate([90,0,90])
			linear_extrude(height = Width, center = true, convexity = 10, twist = 0)
					polygon(points=[[0,Thickness],[Height,Thickness],[Height-Thickness*sin(Angle)/cos(Angle),0],[Thickness*sin(Angle)/cos(Angle),0]], paths=[[0,1,2,3]]);
}

module Namelayer(){
	translate([text_x_offset,text_y_offset,text_height/2+Thickness])
color("black") 		write(text,t=text_height,h=font_size,center=true,font=font);

	translate([-text_x_offset,-text_y_offset+Height,text_height/2+Thickness])
		rotate([0,0,180])
color("black") 		write(text,t=text_height,h=font_size,center=true,font=font);

	translate([0,0,Thickness-HingeLayer/2])
		cube(size = [Width,2*Height-Thickness,HingeLayer], center = true);

}

module Band(){
		translate([-BandWidth/2,0,0])
	linear_extrude(height = 3*Height, center = true, convexity = 10, twist = 0)
		hull() {
   		translate([BandWidth,0,0]) circle(BandRadius);
   			circle(BandRadius);
 		}
}

```


[User]
I'd like a customizable storage bin generator. I need an OpenSCAD file that lets me specify the number of vertical and horizontal "slots" in the overall bin, as well as the number of internal dividers.

Here are the specifics:

**Overall Structure:**

*   The bin is made up of a grid of slots. I'll define the number of slots as "lines" (vertical slots) and "columns" (horizontal slots). So a 2x3 bin would have two vertical slots and three horizontal slots.

*   I need to be able to specify the number of vertical dividers and horizontal dividers within each slot grid.  For example, a 2x2 bin with one vertical and one horizontal divider would result in each grid slot having 4 sub-compartments

*   I need two preset case heights: "Shallow" and "Deep" (41 and 46.2 mm respectively), but I also want to be able to specify a custom height if necessary

*   The bin should have feet.

**Dimensions & Details:**

*   The basic dimensions for one "slot" are derived from existing organizers (one size which I call "single" is 37.1mm wide and 52.25mm tall, two together called "double" is 77.1mm wide and 107.4mm tall). The program will use these as building blocks and should handle the spacing between slots.
*   Wall thickness should be configurable.
*   There should be an option to split the design into a base and a top so it can be printed without supports and then glued together. I'd like to be able to choose "As One", "Base", or "Box" for this parameter; "As One" will mean no separation, "Base" will mean only the base is printed, and "Box" will mean only the box is printed. The design should handle the split by putting a small gap between the base and the top. The box should also be rotated 90 degrees if it is taller than it is wide to minimize the required space for the split.

*   The corners of the bin should be rounded.
*   The feet can be simple rounded rectangular prisms on the corners of the box, and I'd like to be able to specify the height of the feet and have an optional skirt around the base of the feet.
*   I want to be able to specify the skirt size as well.

**Libraries:**

I'd like to use the MCAD library for the rounded box primitive.

Essentially I'm looking for a parametric generator for these types of storage bins, I included my code for reference. Thanks in advance for helping me out!

[Assistant]
stanley_bin.scad:
```
use <MCAD/boxes.scad>

/* [Main] */

// Number of vertical "slots" in the case.
lines = 1; // [1,2,3,4,5]

// Number of horizontal "slots" in the case.
columns = 2; // [1,2,3,4,5,6,7,8,9,10]

vertical_dividers = 1; // [0,1,2,3,4,5,6,7,8,9,10]
horizontal_dividers = 1; // [0,1,2,3,4,5,6,7,8,9,10]

case_height = 20; // [41:Shallow, 46.2:Deep]

/* [Optional] */

skirt_size = 0;  // [0:50]

wall_thickness = 1.2;

// Creates 2 separate pieces that can be printed without support but that have to be glued together.
split_base_and_top = "As One"; // [As One, Both, Base, Box]

/* [Hidden] */

$fa=0.5; // default minimum facet angle is now 0.5
$fs=0.5; // default minimum facet size is now 0.5 mm

split_parts_separation = 10;

single_box_width = 37.1;
single_box_height = 52.25;

double_box_width = 77.1;
double_box_height = 107.4;

round_radius = wall_thickness / 2;

feet_height = 2.8;
feet_size = 6;

feet_subtract = 0;//wall_thickness + 0.5;

// Correction due to Simplify3D bug
simplify_correction = 0.5;

spacing_width = (double_box_width - single_box_width * 2);
spacing_height = (double_box_height - single_box_height * 2);

final_width = (single_box_width * columns) + (spacing_width * (columns - 1));
final_height = (single_box_height * lines) + (spacing_height * (lines - 1));

internal_width = final_width - 2 * wall_thickness;
internal_height = final_height - 2 * wall_thickness;

vertical_spacing = (internal_width - (wall_thickness * vertical_dividers)) / (vertical_dividers + 1);
horizontal_spacing = (internal_height - (wall_thickness * horizontal_dividers)) / (horizontal_dividers + 1);

echo("W=", final_width, " H=", final_height, " vs=", vertical_spacing, " hs=", horizontal_spacing);

if (split_base_and_top == "As One") {
    box();
} else if (split_base_and_top == "Base") {
    split_base();
} else if (split_base_and_top == "Box") {
    split_box();
} else {
    if (final_width > final_height) {
        translate([0, final_height / 2 + split_parts_separation / 2, 0])
        split_box();

        translate([0, -final_height / 2 - split_parts_separation / 2, 0])
        split_base();
    } else {
        translate([0, final_width / 2 + split_parts_separation / 2, 0])
        rotate([0, 0, 90])
        split_box();

        translate([0, -final_width / 2 - split_parts_separation / 2, 0])
        rotate([0, 0, 90])
        split_base();
    }
}

module split_base() {
    rotate([0, 180, 0])
    translate([0, 0, -feet_height - round_radius])
    difference() {
        box();
        translate([0, 0, feet_height + case_height / 2 + 1 + round_radius]) cube([final_width + 2, final_height + 2, case_height + 2], center = true);
    }
}

module split_box() {
    translate([0, 0, - feet_height - round_radius])
    difference() {
        box();
        translate([0, 0, - case_height/2 - 1 + feet_height + round_radius]) cube([final_width + 2, final_height + 2, case_height + 2], center = true);
    }
}

module feet() {
	translate([0,0,-(feet_height-round_radius)/2])
	difference() {
		union() {
			difference() {
				roundedBox([feet_size, feet_size, feet_height + round_radius], round_radius, sidesonly = true);
				rotate([0,0,45]) translate([-feet_size, 0, -feet_height]) cube([feet_size*2, feet_size, feet_height + 4]);
			}

			if (skirt_size > 0) {
				translate([0,0,-(feet_height + round_radius)/2]) cylinder(r = skirt_size, h = 0.3, center = false);
			}
		}
		if (skirt_size > 0) {
			translate([-skirt_size-1,0,-(feet_height + round_radius)/2-0.5]) cube([skirt_size+1, skirt_size+1, 1]);
		}
	}
}
module box() {
    translate([0, 0, case_height / 2 + feet_height])
    union() {
        difference() {
            roundedBox([final_width, final_height, case_height], round_radius);
            translate([0,0,wall_thickness]) roundedBox([final_width - 2 * wall_thickness, final_height - 2 * wall_thickness, case_height], round_radius/2);
        }

        if (vertical_dividers > 0) {
            translate([-(internal_width - wall_thickness) / 2,0,0])
            for (i = [1:vertical_dividers]) {
                translate([vertical_spacing*i+wall_thickness * (i-1),0,simplify_correction]) cube([wall_thickness, internal_height, case_height-wall_thickness-simplify_correction*2], center = true);
            }
        }

        if (horizontal_dividers > 0) {
            translate([0,-(internal_height - wall_thickness) / 2,0])
            for (i = [1:horizontal_dividers]) {
                translate([0,horizontal_spacing*i+wall_thickness * (i-1),simplify_correction]) cube([internal_width, wall_thickness, case_height-wall_thickness-simplify_correction*2], center = true);
            }
        }

        for (x=[1, -1]) {
            for (y=[1, -1]) {
                translate([x * (final_width - feet_size) / 2 - x * feet_subtract, y * (final_height - feet_size) / 2 - y * feet_subtract, -case_height / 2]) rotate([0,0, (x==1 && y ==1 ? 90 : (x == -1 && y == 1 ? 180 : (x == -1 && y == -1 ? 270 : 0)))]) feet();
            }
        }
    }
}

```


[User]
Hey, I'm looking to create a customizable box in OpenSCAD, and I'd like it to have a few specific features. I've been playing around with some basic shapes, but I need something more refined.

Here's what I'm envisioning:

1.  **Box Dimensions:** I need to be able to control the height, width, and depth of the box, all with a range between 10mm and 200mm.
2.  **Wall Thickness:** The box walls should have a user-adjustable thickness between 1mm and 5mm.
3.  **Optional CD Logo:** I'd like to include a CD logo on the top of the box, but this should be optional.
4.  **CD Logo Rise:** If the logo is enabled, I want to be able to adjust how much it rises above the box surface, with a range from 1mm to 5mm. I want a setting for 0mm to turn the logo off.
5.  **Build Plate Visualization:** I'd like the design to show a build plate visualization, allowing me to choose from a Replicator 2, Replicator, Thingomatic or a custom size build plate.
6.  **Custom Build Plate:** If "custom" is selected I'd like to be able to specify the x and y dimensions of the build plate for the visualization. I need both dimensions to be adjustable between 100mm and 400mm.

I am looking for a single `.scad` file that incorporates all this. Could you please generate this for me? I'd like to use a library that has a build plate module, something like `utils/build_plate.scad`. I expect the library will have to be included, but you don't need to generate it, just use it for the build plate visualization.

[Assistant]
Simply_Box.scad:
```
//preview[view:south east, tilt:top diagonal]
use <utils/build_plate.scad>
//for display only, doesn't contribute to final object
build_plate_selector = 3; //[0:Replicator 2,1: Replicator,2:Thingomatic,3:Manual]
//when Build Plate Selector is set to "manual" this controls the build plate x dimension
build_plate_manual_x = 200; //[100:400]
//when Build Plate Selector is set to "manual" this controls the build plate y dimension
build_plate_manual_y = 200; //[100:400]
build_plate(build_plate_selector,build_plate_manual_x,build_plate_manual_y);
/*[Box]*/
//10mm to 200mm :
box_height=20; //[10:200]
//10mm to 200mm :
box_width=90; //[10:200]
//10mm to 200mm :
box_depth=60; //[10:200]
//1mm to 5mm :
box_thikness=1; //[1:5]
/*[CD]*/
//0=none, 1mm to 5mm :
CD_rise=1; //[0,1,2,3,4,5]
cd_height=box_thikness+CD_rise;
cd_width=(box_width>box_depth)?((box_width-(box_thikness*2))*0.75):((box_depth-(box_thikness*2))*0.75);
Box();
module Box(){
 box_width2=box_width-(box_thikness*2)+0.001;
 box_depth2=box_depth-(box_thikness*2)+0.001;
 difference(){
  translate([0,0,0]) resize([box_width,box_depth,box_height]) cylinder($fn=300);
  translate([0,0,box_thikness]) resize([box_width2,box_depth2,box_height]) cylinder($fn=300);
 }
 if (CD_rise>0) CD(cd_height,cd_width);
}
module CD(cd_height,cd_width){
 cd_x1=cd_width;
 cd_x2=cd_x1-((cd_width/7)*2);
 cd_x3=(cd_x1-cd_x2)/2;
 cd_x4=cd_width/20;
 cd_y1=((cd_width/3)*2);
 cd_y2=cd_y1-((cd_width/7)*2);
 cd_y3=cd_y1/4;
 cd_y4=cd_y1+2;
 cd_z1=cd_height;
 cd_z2=cd_height+2;
 union(){
  difference(){
   translate([0,0,0]) resize([cd_x1,cd_y1,cd_z1]) cylinder($fn=300);
   translate([0,0,-1]) resize([cd_x2,cd_y2,cd_z2]) cylinder($fn=300);
   translate([-cd_x4/2,-cd_y4/2,-1]) cube([cd_x4,cd_y4,cd_z2]);
  }
  translate([-cd_x3-(cd_x4/2),+cd_y3/2,0]) cube([cd_x3,cd_y3,cd_z1]);
  translate([-cd_x3-(cd_x4/2),-cd_y3*1.5,0]) cube([cd_x3,cd_y3,cd_z1]);
  translate([cd_x4/2,-cd_y3*1.5,0]) cube([cd_x3,cd_y3*3,cd_z1]);
 }
}

```


[User]
Hi! I'm looking for an OpenSCAD design for a two-part mold to cast a custom silicone sheath for a headphone jack. I've got some basic dimensions in mind, but I'd like it to be fully parametric so I can adjust it for different sized jacks and cables.

Here's what I need:

*   **Jack Sheath:** The mold should create a sheath that tapers slightly, wider at the base where it connects to the cable, narrowing towards the headphone jack itself. Think of it like a small, soft, grippy housing.
    *   **Lower Diameter:** The base of the sheath needs to have a specific diameter, which I'll call `lowerDia`.
    *   **Upper Diameter:** The diameter of the sheath where it meets the headphone jack needs to be smaller than the base and is represented as `upperDia`.
    *   **Lower Length:**  The length of the wider section of the sheath should be adjustable (`lowerLength`).
    *   **Upper Length:** The length of the narrower section of the sheath should also be adjustable (`upperLength`).
    *   **Cable Diameter:**  The sheath should transition to a circular opening for the cable of a set diameter that is represented as `cableDia`.
    *   **Jack Diameter:** The mold needs a space for the jack itself and it's represented as `jackDia`.
    *   **Jack Length:** The length of the mold's jack space represented as `jackLen`.
    *   **Butt End Diameter:** The diameter of the very base of the sheath, at the very end, this is represented as `buttEndDia`.
     *   **Butt End Length:** The thickness of the very base of the sheath, at the very end, this is represented as `lengthButtEnd`.
    *   **Lower Taper Percent:** The lower section of the sheath should have a slight taper, which will make it easier to push into phone jacks. This should be represented as a percentage of the `lowerLength`, so I can control how much it tapers using the variable `lowerTaperPct`.
    *   **Jack Texture Depth:** I'd like to add some rings to the mold so that the silicone sheath is ribbed. I need to be able to control the depth of these rings using a variable `jackTexture`.

*   **Two-Part Mold:**  The design must create two interlocking halves that form the mold. The split should be along the Y axis of the model.
    *   **Mold Dimensions:** The mold needs to be large enough to surround the sheath. I'm not sure what the exact bounding box would be, but it should probably be a cube.
    *   **Bolt Holes:** There should be bolt holes to hold the two halves of the mold together. I want to be able to set the diameter of the bolts that I will use to hold the mold together with the variable `boltD`.

*   **Overages:** I would like a general overage value so I can make the jack opening and the outside of the mold a bit bigger to make sure everything fits okay. I would like this value to be represented as `pctOvr`.

*   **Parametric:** All of these dimensions and values need to be configurable as parameters in the OpenSCAD file so that I can easily modify them later.

*  **Library:** Please use the `BOSL2` library to accomplish this.

Could you generate the OpenSCAD file(s) to achieve this? Thanks!

[Assistant]
end_mold.scad:
```
/*

Version 0.4

Headphone end mold

    |  | -----Upper Diameter
    |  |
    |  |
    /  \
   |    | ----Lower Diameter
   |    |
   |    |
   |    |----Lower Taper (this makes it easier to fit into phone jacks)
    \__/
     == ----Butt End
     ||
     ||
     ||
     \/
TODO
* make transitions slopes equal to ~20% of length

*/

/*[Jack Sheath Dimensions]*/
lowerDia=10; //Lower Dia
upperDia=6; //Upper Dia
lowerLength=15; //Lower Length
upperLength=35; //Upper Length
cableDia=2; //Cable Diameter
jackTexture=.5; //Texture depth
jackDia=3.6; //Jack Diameter
jackLen=14; //Jack Length
buttEndDia=4.5; //Diameter of butt end
lengthButtEnd=1; //Thickness of butt end
//lowerTaper=1; //[0:True, 1:False]
lowerTaperPct=30;

/*[Closure]*/
boltD=3.1; //Bolt Diameter

/*[Overages]*/
pctOvr=1.1;

/*[Hidden]*/
lRad=lowerDia/2;
uRad=upperDia/2;
jackRad=jackDia/2*pctOvr; //add a bit to the jack diameter to account for swelling
cableRad=cableDia/2;
moldX=upperLength+lowerLength*2;
moldY=lowerDia*2.5;
moldZ=lowerDia*1.5;
buttEndRad=buttEndDia/2;
boltRad=boltD/2*pctOvr;
lTaper=lowerTaperPct/100;
echo(1-lTaper);
$fn=36;

module jSheath() {
  union() {
    //lower sectioa
    translate([0, 0, lowerLength*lTaper/2])
      cylinder(r=lRad, h=lowerLength*(1-lTaper), center=true);
    translate([0, 0, lowerLength*-lTaper-(lowerLength/2)+lowerLength*lTaper])
      cylinder(r2=lRad, r1=buttEndRad, h=lowerLength*lTaper, center=false);

    //tappered section between upper and lower
    translate([0, 0, lowerLength/2])
      cylinder(r1=lRad, r2=uRad, h=upperLength*.2);

    //upper section
    translate([0, 0, lowerLength/2])
      cylinder(r=uRad, h=upperLength-upperLength*.2);

    //tapered top
    translate([0, 0, lowerLength/2+upperLength-upperLength*.2])
      cylinder(r1=uRad, r2=cableRad, h=upperLength*.2);

    //cable
    translate([0, 0, lowerLength/2+upperLength])
      cylinder(r=cableRad, h=lowerLength+upperLength);

    //jack
    translate([0, 0, -jackLen-lowerLength/2])
      cylinder(r=jackRad, h=jackLen);

    //butt end
    translate([0, 0, -lowerLength/2-lengthButtEnd])
      cylinder(r=buttEndRad*pctOvr, h=lengthButtEnd*pctOvr);
  }

}

module texture() {
  difference() {
    jSheath();
    for (i = [1 : jackTexture*2 : lowerLength-jackTexture ]) {
      translate([-lRad, 0, -lowerLength/2+jackTexture/2+i])
        rotate([90, 0, 0])
        cylinder(r=jackTexture, h=upperDia, center=true);
        //#cube([jackText, upperDia, jackText], center=true);
      translate([lRad, 0, -lowerLength/2+jackTexture/2+i])
        rotate([90, 0, 0])
        //#cube([jackText, upperDia, jackText], center=true);
        cylinder(r=jackTexture, h=upperDia, center=true);
    }

  }
}

module jackPositive() {
  rotate([0, 90, 0])
  translate([0, 0, -lowerLength])
  texture();
}

module mNut(dia, cent=false) {
  m=0.8*dia;
  f=1.8*dia;
  r=(f*1/cos(30))/2;
  c=0.2*dia;
  difference() {
    cylinder(r=r, h=m, $fn=6, center=false);
    translate([0, 0, -m/2]) cylinder(r=dia/2, h=m*3, center=false);
  }

}

module mold(nut=false) {
  difference() {
    translate([0, 0, -moldZ/4])
      cube([moldX, moldY, moldZ/2], center=true);

    //Upper left
    translate([moldX/2-boltD, uRad*1.2+boltRad, 0])
      cylinder(r=boltRad, h=moldZ+pctOvr, center=true);

    //Lower left
    translate([-moldX/2+boltD, cableRad*1.2+boltD, 0])
      cylinder(r=boltRad, h=moldZ+pctOvr, center=true);

    //Lower right
    translate([-moldX/2+boltD, -cableRad*1.2-boltD, 0])
      cylinder(r=boltRad, h=moldZ+pctOvr, center=true);

    //Upper right
    translate([moldX/2-boltD, -uRad*1.2-boltRad, 0])
      cylinder(r=boltRad, h=moldZ+pctOvr, center=true);

    translate([0, lRad*1.2+boltRad, 0])
      cylinder(r=boltRad, h=moldZ+pctOvr, center=true);
    translate([0, -lRad*1.2-boltRad, 0])
      cylinder(r=boltRad, h=moldZ+pctOvr, center=true);

     translate([0, 0, 0])
      jackPositive();

  }
}

module main() {
  translate([0, -moldY/1.5, 0])
    mold();
  translate([0, moldY/1.5, 0])
    mold(nut=true);
}

//!jackPositive();
main();

```


[User]
Hey, I'm looking to get a parametric plate designed in OpenSCAD. It should be a rectangular plate with rounded corners and a grid of holes, kind of like a standard robotics building plate.

Here are the parameters I'd like to be able to control:

*   `width`: The width of the plate.
*   `length`: The length of the plate.
*   `height`: The thickness of the plate.
*   `fillet`: The radius of the rounded corners.
*   `hole_radius`: The radius of each hole.
*   `hole_spacing`: The spacing between the centers of the holes.

The plate should be a simple rectangular prism with the specified dimensions, but with rounded corners using a fillet. There should be a grid of holes through the plate, with the holes arranged at the specified `hole_spacing` in both the width and length directions. The grid of holes should be within the edges of the plate - that is, there should not be any partial holes along the edge of the plate. All parameters should be configurable.

Could you provide me with the OpenSCAD code for this? I'd prefer to have it in a single file if that makes sense. I am not using any libraries, so a single file should be fine.

[Assistant]
tamiyaplate.scad:
```
width = 120; //Plate width
length = 60;	//Plate length
height = 3;	//Plate height
fillet = 2;	//Plate fillet radius
hole_radius = 1.55;
hole_spacing = 5;
//--------
module roundedRect(size, r) {
	x = size[0];
	y = size[1];
	z = size[2];
	linear_extrude(height = z){
		hull(){
   			translate([r, r, 0])
    			circle(r=r, $fn = 36);

   			translate([r, y-r, 0])
    			circle(r=r, $fn = 36);

   			translate([x-r, y-r, 0])
   		 		circle(r=r, $fn = 36);

   			translate([x-r, r, 0])
   				circle(r=r, $fn = 36);
		}
	}
}
module holes(w, h, d, hr, hs){
	union(){
		for(i = [1 : w / hs - 1]){
			for(j = [1 : h / hs - 1]){
				translate([i * hs, j * hs, -0.1])
					cylinder(r = hr, h = d + 0.2, $fn = 36);
			}
		}
	}
}
module plate(w, h, d, f, hr, hs){
	difference(){
		roundedRect([w, h, d], f);
		holes(w, h, d, hr, hs);
	}
}
plate(width, length, height, fillet, hole_radius, hole_spacing);
```


[User]
I'd like a design for a 3D-printable object: a sphere captured inside a hollowed sphere, which is itself inside a cube. I'd like to be able to customize the sizes of the cube, the inner sphere, and the clearance between the inner sphere and the hollowed space.

Specifically, the cube should have sides of equal length, and the inner and outer sphere should be centered within the cube. The hollowed sphere should be slightly larger than the inner sphere, and the inner sphere should have a flat bottom so it prints well. I'd like to specify the cube's side length, the inner sphere's radius, and the gap between the inner sphere and the outer, hollowed sphere.

Also, please make it so the final object will sit flat on a surface – meaning the inner sphere doesn’t extend past the bottom face of the cube.

I'd prefer this to be made in OpenSCAD so I can adjust the parameters.

[Assistant]
Customized_Ball_within_Cube.scad:
```
//
//  Customized Ball within Cube
//      Robert Nix
//      January 27, 2015
//

$fn=100;			// set overall resolution

//
//  Customizing

// Size of each side of the cube
cubeSide=22;		// [15:40]

// Size of the captured sphere inside the cube
sphereRadius=11;	// [7:24]

// Make the hollowed space just a bit larger than the ball
sphereSpaceRadius=sphereRadius+3;

translate([0,0,(cubeSide/2)]) {
	difference() {
		// Draw the solid cube
		cube(cubeSide, center=true);

		// Then remove the larger sphere
		sphere(sphereSpaceRadius);
	}

	difference() {
		// Draw the solid sphere
		sphere(sphereRadius);

		// Then remove the very bottom of the
		// sphere so that it doesn't extend below
		// the build plate
		translate([0,0,((cubeSide/2)-(cubeSide/2)-sphereRadius)])
			#cube([cubeSide,cubeSide,(sphereRadius-(cubeSide/2))+2], center=true);
	}
}

```


[User]
I need to create a parametric support for a 3D printer filament spool. It should be designed to work with a bearing. I'm using a 3DRAG/K8200 printer.

Here are the key parameters I need to be able to adjust:

*   **Support Diameter:** The overall diameter of the support, ranging from 40mm to 100mm.
*   **Support Taper:** The amount of taper on the support diameter. It should specify the difference in diameter between the top and bottom of the support (or vice versa), ranging from 1mm to 10mm.
*   **Bearing External Diameter:** The outer diameter of the bearing, ranging from 10mm to 25mm.
*   **Bearing Internal Diameter:** The inner diameter of the bearing, ranging from 5mm to 10mm.
*   **Bearing Height:** The height of the bearing, ranging from 5mm to 20mm.

The support needs to have these features:

1.  A central cylindrical section where the bearing will be placed.
2.  A tapered support structure, connected to the central section, with a larger diameter at one end and a smaller diameter at the other.
3.  Four "CD" (I think of them as small support arms) spaced evenly around the circumference at the wider end of the tapered support section, these arms should not fully overlap with the central bearing section.

The "CD" arms should also be parametrically designed, with controls for height and width (and thus length, given the position of each). I think it should have a base shape that looks something like a rounded rectangle with a small rectangular section removed. It should also have 3 additional small cubes. It can be similar to the example code's CD module.

I'd like the design to be created using OpenSCAD and should be fully parametric with all the above values easily adjustable.

Could you generate the OpenSCAD code for this? I also need the preview to be set to a south east view, and with the tilt to a top diagonal.

[Assistant]
Coil_Filament_Support.scad:
```
//preview[view:south east, tilt:top diagonal]
/*[Support]*/
//40mm to 100mm :
support_diameter=53; //[40:100]
// the diameter tolerance you need (+/-) 1mm to 10mm :
support_taper=1; //[1:10]
/*[Bearing]*/
//10mm to 25mm :
bearing_external_diameter=19; //[10:25]
//5mm to 10mm :
bearing_internal_diameter=8; //[5:10]
//5mm to 20mm :
bearing_height=7; //[5:20]
/*[CD]*/
cd_width=(((support_diameter+support_taper)-bearing_external_diameter)/2)/2;
Support();
module Support(){
 support_height=bearing_height+5;
 support_radius1=(support_diameter-support_taper)/2;
 support_radius2=(support_diameter+support_taper)/2;
 difference(){
  union(){
   for (i=[1:4]){
    rotate([0,0,i*360/4]) translate([(bearing_external_diameter/2)+0.001,-(cd_width/3)*1.5,0]) cube([(support_radius1-(bearing_external_diameter)/2)-5+0.001,((cd_width/3)*2)*1.5,support_height]);
   }
   difference(){
     translate([0,0,0]) cylinder(r1=support_radius1,r2=support_radius2,h=support_height,$fn=300);
    difference(){
     translate([0,0,-1]) cylinder(r=support_radius1-5,h=support_height+2,$fn=300);
     translate([0,0,-1]) cylinder(r=(bearing_external_diameter/2)+5,h=support_height+2,$fn=300);
    }
    translate([0,0,5]) cylinder(r=bearing_external_diameter/2,h=bearing_height+1,$fn=300);
    translate([0,0,-1]) cylinder(r=bearing_internal_diameter/2,h=bearing_height+7,$fn=300);
   }
  }
  for (i=[1:4]){
   rotate([0,0,i*360/4]) translate([(bearing_external_diameter/2)+cd_width,0,support_height-1]) CD(2,((support_diameter+support_taper-bearing_external_diameter)/2)/2);
  }
 }
}
module CD(cd_height,cd_width){
 cd_x1=cd_width;
 cd_x2=cd_x1-((cd_width/7)*2);
 cd_x3=(cd_x1-cd_x2)/2;
 cd_x4=cd_width/20;
 cd_y1=((cd_width/3)*2);
 cd_y2=cd_y1-((cd_width/7)*2);
 cd_y3=cd_y1/4;
 cd_y4=cd_y1+2;
 cd_z1=cd_height;
 cd_z2=cd_height+2;
 union(){
  difference(){
   translate([0,0,0]) resize([cd_x1,cd_y1,cd_z1]) cylinder($fn=300);
   translate([0,0,-1]) resize([cd_x2,cd_y2,cd_z2]) cylinder($fn=300);
   translate([-cd_x4/2,-cd_y4/2,-1]) cube([cd_x4,cd_y4,cd_z2]);
  }
  translate([-cd_x3-(cd_x4/2),+cd_y3/2,0]) cube([cd_x3,cd_y3,cd_z1]);
  translate([-cd_x3-(cd_x4/2),-cd_y3*1.5,0]) cube([cd_x3,cd_y3,cd_z1]);
  translate([cd_x4/2,-cd_y3*1.5,0]) cube([cd_x3,cd_y3*3,cd_z1]);
 }
}

```


[User]
I need a desk hook designed in OpenSCAD. I've got a basic idea of the shape, and I want it to be parametric so I can adjust it to fit different desk thicknesses and item sizes. The basic shape is like a "C" that wraps around the edge of the desk, with a bit of extra support where the hook part juts out.

Here's how I envision it:

*   **Desk Clamp:** The part that goes under the desk needs to have a variable width (`desk_width`) that can be adjusted to clamp onto desks of different thicknesses, and a variable height, let's say `clamp_height`.
*   **Hook Extension:** The part that extends out from the desk should also have a variable length (`hook_length`).
*   **Hook Width:** The width of the hook and its supports should be adjustable (`hook_width`).
*   **Hook Height:** The height of the hook itself should be adjustable (`hook_height`)
*   **Support:** There needs to be support on the side of the clamp and the base of the hook to make it strong.  It would be like the example I gave, where there are two cube shapes connecting the main hook to the clamp. The length of these supports should also be a parameter, maybe `support_length`.
*   **Clearance:** Add some clearance where the clamp meets the desk. Let's call this parameter `clamp_clearance`.

I’m imagining something like what is represented by the scad file I included, but with all of the parameters defined to be adjustable. You can essentially recreate the design in that scad file, but all the dimensions should be adjustable by parameters. I'd prefer all the code to be in a single .scad file rather than being split across several.

I think I want to have all of the parameters defined up top. It should be easy to adjust from a single place. I’m not sure if I’ll need it later, but I think I should also have the code include the ability to easily set the object to be mirrored across the y axis. I can't imagine I'd want to mirror it across any other axis, but if there’s some simple code you can add that makes the user able to mirror it across other axes it might be helpful to have.

[Assistant]
deskhook.scad:
```
deskwidth = 39;
module deskhook()
{
	cube([10,50,40]);
	translate([10,40,0]) cube([40,10,40]);
	translate([50,-10,0]) cube([10,60,40]);
	translate([40,-10,0]) cube([10,10,40]);
	translate([-1*(deskwidth+10),0,0]) cube([deskwidth+10,10,40]);
	translate([-1*(deskwidth+10),10,0])cube([10,40,40]);
}
deskhook();
```


[User]
Hey there! I'm looking to create a kind of "groovy" circular or elliptical shape in OpenSCAD, and I need some help with the code. I've got some specific parameters I want to be able to tweak, and a particular overall design in mind.

Essentially, I want a ring with a certain thickness and a definable rim size. This main ring should also have two "wings" that come off it at an angle, and an interior beam running across the diameter. Think of it like a stylized, almost futuristic gear.

I'd like to control the following:

*   **Overall Diameter:** This will control the size of the outer ring.
*   **Rim:**  The percentage of the ring’s radius that remains solid; that is, the "rim".
*   **Thickness:** How thick the entire shape is.
*   **Beam Width:**  The width of the beam that cuts across the center, and also the width of the two "wings".
*   **Wing Angle:** The angle, in degrees, of the two "wings".
*    **Attachment Point:** An optional cylinder that is meant to be an attachment point. It would need an associated, smaller hole.
*   **Attachment Radius:** Radius of the attachment point cylinder. Set to 0 to not create.
*   **Attachment Hole:** Radius of the hole inside the attachment point. Set to 0 to not create.
*   **Shape (Circular or Elliptical):**  A boolean to switch between a circular base shape and an elliptical one.
*   **Elliptical Factor:** A scalar to stretch the design when it's set to elliptical.

It would also be nice if I could easily scale the whole object.

I'd really appreciate it if you could generate the appropriate OpenSCAD files. I don't need any special libraries. Let me know if you have any questions or need clarification. Thanks so much!

[Assistant]
groovy.scad:
```
$fn=64+0;

// Diameter (mm)
diameter=75;  // [10:1000]
// Rim amount (%)
rim=10; //[1:99]
// Thickness (mm)
thickness=4;     // [1:25]
// Width of interior beams (mm)
beamw=5;  //[1:25]

// Angle of "wings" (degrees)
angle=33; //[0:359]

// size of attachment point (0=none)
attach_radius=3;  //[0:10]
// size of attachment hole
attach_hole=1;  //[0:9]
// Shape
circular=1;  // [1:Circular, 0: Eliptical]
// Eliptical stretch factor (Golden Ratio=1.618)
factor=1.618;

r=diameter/2;

module attach() {
  difference() {
    cylinder(r=attach_radius,h=thickness,center=true);
		cylinder(r=attach_hole,h=thickness+1,center=true);
   }
}

module ring() {
   difference() {
     cylinder(r=r,h=thickness,center=true);
		 cylinder(r=(100-rim)/100*r,h=thickness+1,center=true);
     }
}

module groovy() {
	union() {
 	  ring();
		rotate([0,0,-angle]) translate([0,-beamw/2,-thickness/2]) cube([r*.95,beamw,thickness],center=false);
		rotate([0,0,angle]) translate([-r*.95,-beamw/2,-thickness/2])  cube([r*.95,beamw,thickness],center=false);
	  cube([beamw,diameter*.95,thickness],center=true);
   }
}

union() {
if (circular==0) {
  scale([1,factor,1]) groovy();
// don't want to scale the attach point
// but do need to adjust the amount to move
  if (attach_radius!=0) translate([0,r*factor+attach_radius/2,0]) attach();
}
else {
  groovy();
// don't want to scale the attach point
// but do need to adjust the amount to move
  if (attach_radius!=0) translate([0,r+attach_radius/2,0]) attach();
}

}
```


[User]
Hi! I'm just getting started with OpenSCAD and I've been watching some tutorials by Rudy Ruffel. He introduces basic shapes and how to make them using code. I'd like to build on that and create a few more complex, parametric designs.

First, I'd like to create a customizable rectangular prism (basically a box). I need to be able to set the width, depth, and height as parameters. Also, could you include a parameter for chamfering the edges? The chamfer should be applied to all 12 edges, and should be controllable via a single parameter.

Second, let's try making a cylinder with some different options. I want parameters for the height, the top radius, and the bottom radius, so that I can make a cone if I want to. I'd also like to be able to specify the number of sides, so I can make it into a prism instead.

Finally, I want to make something a bit more complex. I would like a sphere where you can cut out wedges (like slices of pie). I need to set the overall sphere radius, the number of wedges, and the angular width of each wedge.

I'd like these as separate .scad files please, and I don't need them in any specific order. I don't think I need any special libraries for this, right? Thanks!

[Assistant]
tutoriel-OpenScad1-rudy-ruffel.scad:
```
//********************
// la sphere
//********************
	//sphere (r=5);
	//sphere (d=15);

//********************
// le cube
//********************

	//cube(size=10);
	//cube(size=[width,depth,height]);
	//cube(size=[10,10,10]);

//********************
// le cylindre
//********************
	//cylinder(20,r=5);
	//cylinder(20,d=15);
	//cylinder(20,r1=15,r2=0);
	//cylinder(20,d1=0,d2=15);

//********************
// le Polyhedron
//********************

/*
polyhedron(
    points=[[-10,-10,0], [-10,10,0], [10,10,0], [10,-10,0],    // les 4 sommets de la base
            [-10,-10,20],[-10,10,20],[10,10,20],[10,-10,20]],  // les 4 sommets du haut
 triangles=[[0,4,7],[3,0,7],  // face avant
             [0,1,5],[4,0,5],  // face gauche
             [3,7,6],[2,3,6],  // face droite
             [5,1,6],[1,2,6],  // face arrière
             [1,0,2],[0,3,2],  // bas
             [4,5,6],[7,4,6]]  // haut
);

*/

```


[User]
I'm looking to generate a customizable spool holder for 3D printing filament. I've seen a design that's pretty close to what I need, but I want to make sure I can control the key parameters, specifically the core diameter and the reel width.

The basic design should consist of a cylindrical core where the spool sits, with a larger diameter base flange on one side for stability and a tapered section on the other end to help guide the spool on. I'll need a mounting bracket that's essentially a flat plate that the base flange is attached to. Additionally, there should be two screw holes for mounting the bracket. Finally, there needs to be a cut-out on the main cylinder with a slot so that a user can easily thread a new spool.

Here's a more detailed breakdown:

*   **Core Cylinder:** This is the main part that the spool will rest on. It needs to be a cylinder with a customizable diameter (`CD`) and a customizable width (`RW`).
*   **Base Flange:** This will be a wider cylinder attached to the base of the core cylinder, providing stability.
*   **Taper:** On the other end of the core cylinder, there will be a short section that gradually widens to help guide the spool.
*   **Mounting Bracket:** A flat plate attached to the base flange that will have screw holes.
*   **Screw Holes:** Two holes on the mounting bracket for screws that will go straight through.
*   **Slit Cutout:** A rectangular cutout with a circular cutout at the end that will be made through the core cylinder.

I'd like to be able to control the following parameters:

*   `CD` (Core Diameter): The diameter of the main cylinder where the spool will sit. This should be adjustable within a range, say 15 to 100 mm.
*  `RW` (Reel Width): The width of the main cylinder (and therefore, roughly the width of the spool). This should be adjustable, say from 20 to 120 mm.

I'd like an OpenSCAD design that uses parametric variables, so I can easily change the `CD` and `RW` and re-render the design. I don't have a particular library requirement, but feel free to use any library which you think will be helpful.

[Assistant]
custermizable_spool_holder2.scad:
```

//custermizing data

//Takuya Yamaguchi 2014/5/25
//Takuya Yamaguchi 2015/1/31

//Core Diameter
CD=22; //[15:100]

//Reel Width
RW=86; //[20:120]

difference(){
union(){
cube([20,CD+40,5],center=true); // Screw Braket
translate([0,0,0])rotate([0,0,0])
cylinder(h=5, r=CD/2+CD*0.1,$fn=48,center=true); // Base Fringe
translate([0,0,(RW+20)/2])
cylinder(h=RW+20, r=CD/2,$fn=48,center=true); //main cylinder
translate([0,0,RW+10])
cylinder(h=20, r2=CD/2,r1=CD/2+1.3,$fn=48,center=true); //taper
}
translate([0,CD/2+12,0])rotate([0,0,0])
#cylinder(h=20, r=2.8,$fn=48,center=true); //screw hole
translate([0,-(CD/2+12),0])rotate([0,0,0])
#cylinder(h=20, r=2.8,$fn=48,center=true); // screw hole
translate([0,0,(RW+20)/2+5])
cylinder(h=RW+25, r=CD/2-CD*0.05,$fn=48,center=true); //inner clinder
translate([0,0,RW*0.2+(RW+20)/2+CD/6])rotate([0,0,0])
#cube([CD/3,CD+10,RW+20],center=true); //Slit
translate([0,0,RW*0.2+CD/6])rotate([90,0,0])
#cylinder(h=RW+1, r=CD/6,$fn=48,center=true); //Slit R
}

```


[User]
I'd like to create a rounded cube pen holder, and I have a specific set of parameters in mind. The basic shape should be a cube with rounded corners created by intersecting spheres. I'd like the pen holder to have a hollow interior, also with rounded corners.

Here are the main parameters I'd like to control:

*   **`dimension`**: This is the outer dimension of the cube, in millimeters. I need to be able to set this to a value between 55 and 90.
*   **`wall`**: This is the wall thickness of the pen holder, in millimeters. The wall should have a thickness between 2 and 3 mm.
*   The radius of the spheres that form the rounded corners should be proportional to the cube's dimensions.  I think a good ratio is `radius = dimension * (12 / 80)`, where `12 / 80` is a configurable value, but I think keeping that at 0.15 is reasonable.
*   I need the interior to be hollow, with a flat bottom. The inner part should also have rounded corners, but with a slight extension on top.

I want to use the `hull()` function to create the overall shape and the `difference()` function to create the hollow interior. I also want to cut off the top with a difference operation.  I want to use the `color()` function for previewing.  I expect to set `$fn` to 50 when I render for a more finished part. I need the object to be centered at x=0, y=0, z=0.

I think the code should do the following:

1. Calculate the radius of the spheres based on the provided dimension and the fixed ratio.
2. Calculate an offset used for positioning the corner spheres.
3. Calculate a radius of the inner spheres based on the outer sphere radius and the wall thickness.
4. Use the `hull()` function to create the outer shell using the translated spheres.
5. Use the `hull()` function to create the inner shell with an extension for the top using inner spheres with a modified z-translation..
6. Use `difference()` to subtract the inner hull from the outer hull.
7. Use `translate()` to center the object.
8. Use `difference()` to subtract the top from the main object.
9. Add the `color()` function for previewing.
10. Set `$fn` to 50 for production and 15 for debugging by setting `$fn` variable globally.

Can you generate the OpenSCAD code for me?

[Assistant]
RoundedCubePenHolder.scad:
```
//
//
// Customizable Rounded Cube Pen Holder by Robert Halter
// Licensed: Creative Commons - Attribution - Non-Commercial - Share Alike (by-nc-sa)
// see: http://en.wikipedia.org/wiki/Creative_Commons
//
// parametrizable user values
// - outer dimension of hole Cube Pen Holder [mm]
// - factor for dimension to radius [Number]
// - wall thinkness [mm]
//
// author: Robert Halter - CH - 01.01.2015
//
// with:   OpenSCAD Version 2014.03
//
// History
// - adapted to http://customizer.makerbot.com/docs
// - translate to x, y, z = 0
// - inner rounded cube
// - color for visualisation

/* [Size] */

// parametrizable user values - change if you want

// outer dimension of hole Rounded Cube Pen Holder [mm]
dimension = 80; // [55:90]

/* [Hidden] */

// factor for dimension to radius [Number]
// This Number is the factor of radius to dimension
factorradius2dim = 12 / 80; // 0.15

// wall thinkness [mm]
wall = 2.0; // [2:3]

// color for visualisation i.e. dark blue
userColorRGB = [0/255, 48/255, 112/255];
// userColorRGB = [30/255, 55/255, 108/255];
// userColorRGB = "DarkBlue";
userColorAlpha = 255/255;

// preview[view:south east, tilt:top diagonal]

// calculated Values - do not change

// radius of outer eight spheres [mm]
radius = dimension * factorradius2dim; // 12 mm with dimension 80 mm and factor 0.15

// number of fragments 0, 3, 5 or bigger
// set to 15 for debugging
// $fn = 15;
// set to i.e. 50 for production
$fn = 50;

// offset for outer sphere translations
offset4sphere = dimension - (2 * radius);

// inner hull top extension
innerhulltopextension = wall + radius;

// radius of inner eight sphere
innerradius = radius - wall;

// begin of form

// color of following difference
color(userColorRGB, userColorAlpha)

// difference of 'difference' minus 'translated cube'
// to cut on top of the Cube the thin Wall Parts
difference() {

// translate to x, y, z = 0
translate([radius,radius,radius]) {

//  difference of 'Hull over outer eight spheres' minus 'Hull over inner eight spheres'
difference() {

  // hull over outer eight spheres
  hull() {

    // outer four bottom spheres
    translate([0,0,0]) {
      sphere(r = radius);
    }

    translate([offset4sphere,0,0]) {
      sphere(r = radius);
    }

    translate([0,offset4sphere,0]) {
      sphere(r = radius);
    }

    translate([offset4sphere,offset4sphere,0]) {
      sphere(r = radius);
    }

    // outer four top spheres
    translate([0,0,offset4sphere]) {
      sphere(r = radius);
    }

    translate([offset4sphere,0,offset4sphere]) {
      sphere(r = radius);
    }

    translate([0,offset4sphere,offset4sphere]) {
      sphere(r = radius);
    }

    translate([offset4sphere,offset4sphere,offset4sphere]) {
      sphere(r = radius);
    }

  } // hull

  // hull over inner eight spheres
  hull() {

    // inner four bottom spheres
    translate([0,0,0]) {
      sphere(r = innerradius);
    }

    translate([offset4sphere,0,0]) {
      sphere(r = innerradius);
    }

    translate([0,offset4sphere,0]) {
      sphere(r = innerradius);
    }

    translate([offset4sphere,offset4sphere,0]) {
      sphere(r = innerradius);
    }

    // inner four top spheres
    translate([0,0,offset4sphere + innerhulltopextension]) {
      sphere(r = innerradius);
    }

    translate([offset4sphere,0,offset4sphere + innerhulltopextension]) {
      sphere(r = innerradius);
    }

    translate([0,offset4sphere,offset4sphere + innerhulltopextension]) {
      sphere(r = innerradius);
    }

    translate([offset4sphere,offset4sphere,offset4sphere + innerhulltopextension]) {
      sphere(r = innerradius);
    }
  } // hull

} // difference

} // translate

translate([0,0,dimension - (radius * 4 / 5) + wall]) {
  cube([dimension,dimension, 2 * wall]);
}
} // difference

// end of form

```


[User]
Hey, I need some help designing a clip for holding wires against a Bowden tube. I've got a 3D printer and think it would be easier than using tape.

Basically, the clip needs to wrap around both the Bowden tube and the wires I want to secure to it. I'd like to be able to customize the dimensions to fit different Bowden tubes and wire bundles.

Here's what I'm thinking for parameters:

*   `bowden_tube_diameter`: The diameter of the Bowden tube.
*   `cable_diameter`: The diameter of the wire bundle.
*   `clip_width`: The width of the clip along the tube/wires.
*   `clip_thickness`: The minimum thickness of the clip material.
*   `middle_thing_width`: A small gap between the tube and wires.
*   `inner_gap_width` & `bowden_gap_width`:  These are calculated gaps for the inside "mouth" of the clip - they should be calculated from `bowden_tube_diameter` and `cable_diameter`.

The clip should be designed to be easy to print, with 100% infill recommended. It would be great if the design avoided overhangs as much as possible, since I don't always print with support material. Also, I'd need it to be a parametric design using OpenSCAD so that I can tweak the dimensions.

Could you generate the OpenSCAD file for this?

[Assistant]
bowden_tube_wire_clip.scad:
```
/* Bowden tube wire clips
 *
 * Used for holding wires against a Bowden tube. These clips are easier to
 * remove/replace than kapton tape! Printing considerations:
 *
 *   * 100% infill
 *
 *   * print more than one at once to avoid the need for cooling (move to
 *     opposite corners of your bed)
 *
 *   * choose your extrusion width so that `clip_width` is a multiple of it
 *
 * Author: Alex Hirzel <alex@hirzel.us>
 * License: BSD
 * Thingiverse: <http://www.thingiverse.com/thing:661426>
 * YouMagine: <https://www.youmagine.com/designs/bowden-tube-wire-clip>
 */

/* [Sizing] */

// (mm)
bowden_tube_diameter = 4.16;

// (mm)
cable_diameter = 5;

// - desired width of clip along the tube/wires (mm)
clip_width = 2.5;

/* [Strength] */

// - minimum thickness of any part of the clip (mm)
clip_thickness = 1;

/* [Hidden] */

// - gap between the tube and wires (mm)
middle_thing_width = 0.3;

// - lots of resolution
$fn = 30;

/* END PARAMETERS */

// computed for later
c2c_distance = (bowden_tube_diameter + cable_diameter)/2 + middle_thing_width;
inner_gap_width = 0.4*min(bowden_tube_diameter, cable_diameter);
bowden_gap_width = 0.5*bowden_tube_diameter;

difference() {

	// build the outside edge of the clip
	hull() {

		// cylinder around cables
		cylinder(d = cable_diameter + 2*clip_thickness,
		         h = clip_width, $fa = 1);

		// cylinder around bowden tube
		other() cylinder(d = bowden_tube_diameter + 2*clip_thickness,
		                 h = clip_width);
	}

	// subtract volume for cables
	cylinder(d = cable_diameter, h = clip_width);

	// subtract volume for bowden tube
	other() cylinder(d = bowden_tube_diameter, h = clip_width);

	// subtract a path between the two
	translate([0, -inner_gap_width/2, 0])
		cube([c2c_distance, inner_gap_width, clip_width]);

	// finally, subtract the "entrance hole" for the whole thing
	translate([0, -bowden_gap_width/2, 0])
		other() cube([c2c_distance, bowden_gap_width, clip_width]);
}

module other() {
	translate([c2c_distance, 0, 0])
		children();
}

```


[User]
I'm looking to design some custom punch cards for a Turbo Entabulator, and I need to be able to control the holes that represent the instructions, as well as add text for identification purposes.

Specifically, the punch card should be about 3.3 units wide, 1.8 units high, and 0.1 units thick (I guess that's in inches, based on what I'm seeing in the provided code) with two circular positioning holes and four smaller threading holes. The instructions are encoded using 10 different hole positions. There is a set of four instructions each for the left, middle, and right counter, plus one additional "no purpose" hole. I'd like to have the ability to toggle each of those holes on or off. The instructions for the counter holes are:

*   **Do Nothing:** No hole
*   **Increment:** Hole at position 1,2, or 10
*   **Decrement:** Hole at position 3,8, or 7
*   **Increment + Zerocheck:** Both increment hole AND hole at position 5,4, or 9
*   **Decrement + Zerocheck:** Both decrement hole AND hole at position 5,4, or 9

(The positions are based on the 1-10 numbering used in the existing SCAD file). The no purpose hole is at position 6.

I also need to be able to add some text to the punch card, probably for things like serial number or a description. I'd need the option to put the text in the top left corner, on the left side facing inwards, or on the left side facing outwards. The text position should be configurable.

I'd like the design to be parametric, so I can easily tweak the dimensions later if necessary.  I'm not too worried about fine details on the shape of the instruction holes - what you have in the example looks fine - but the text rendering is quite important so make it as readable as possible. I'd also prefer to use the standard `text()` command rather than rely on Write.scad.

Could you generate an OpenSCAD file (or files) to accomplish this? I think I should only need one, unless you think it would be better to split up.

[Assistant]
Punchcard.scad:
```

//Do Nothing = 0
//Increment = 1
//Decrement = 2
//Increment + Zerocheck = 3
//Decrement + Zerocheck = 4

//Text position:
//Top left: 0
//Left side inwards: 1
//Left side outwards: 2

/* [Instructions] */

//Instructions for the Left Counter
Left_counter = 0; // [0:Do Nothing,1:Increment,2:Decrement,3:Increment and Check Zero,4:Decrement and Check Zero]

//Instructions for the Middle Counter
Middle_counter = 0; // [0:Do Nothing,1:Increment,2:Decrement,3:Increment and Check Zero,4:Decrement and Check Zero]

//Instructions for the Right Counter
Right_counter = 0; // [0:Do Nothing,1:Increment,2:Decrement,3:Increment and Check Zero,4:Decrement and Check Zero]

//Hole that currently has no purpose
No_Purpose_Hole = 0; // [0:Don't create hole,1:Create hole]

/* [Text] */

//Text to show
Text="";

//Can be used for card number, description, etc.
Text_position=0;// [0:Top left corner (1-3 chars),1:Left side facing inwards (1-12 chars),2:Left side facing outwards (1-12 chars)]

/* [Hidden] */

$fn=30;

include <write/Write.scad>;

punchcard();

module punchcard(){

scale([25.4,25.4,25.4])
difference(){
card(Text);
union(){

if (Left_counter == 1)
	hole(3);
if (Left_counter == 2)
	hole(1);
if (Left_counter == 3){
	hole(3);
	hole(5);}
if (Left_counter == 4){
	hole(1);
	hole(5);}

if (Middle_counter == 1)
	hole(2);
if (Middle_counter == 2)
	hole(8);
if (Middle_counter == 3){
	hole(2);
	hole(4);}
if (Middle_counter == 4){
	hole(8);
	hole(4);}

if (Right_counter == 1)
	hole(10);
if (Right_counter == 2)
	hole(7);
if (Right_counter == 3){
	hole(10);
	hole(9);}
if (Right_counter == 4){
	hole(7);
	hole(9);}

if (No_Purpose_Hole == 1)
	hole(6);

}}}

module card(text){
	difference(){
		cube([3.3,1.8,.1]);
		translate([0,0,-.5])union(){
		//positioning holes
			translate([1.65,.25,0])
				cylinder(d=.25,h=1);
			translate([1.65, 1.55,0])
				cylinder(d=.25,h=1);
		//threading holes
			for(x=[.125,3.175])
				for(y=[.125,1.675])
					translate([x,y,0])
						cylinder(d=.125,h=1);
		}
if (Text_position == 0)
	translate([.4,1.675,.1])
	scale([.04,.04,.1])
		writecube(text = Text, face = "top", size = .01, font = "write/Letters.dxf");
if (Text_position == 1)
	translate([.1,.9,.1])
	scale([.04,.04,.1])
	rotate([0,0,90])
		writecube(text = Text, face = "top", size = .01,font = "write/Letters.dxf");
if (Text_position == 2)
	translate([.1,.9,.1])
	scale([.04,.04,.1])
	rotate([0,0,-90])
		writecube(text = Text, face = "top", size = .01,font = "write/Letters.dxf");

	}
}

module hole (position){

	translate([.3*position,0.7,-.5])
	union(){
		cylinder(d=.2, h=1);
		translate([-.1,0,0])
			cube([.2,.3,1]);
		translate([0,.3,0])
			cylinder(d=.2, h=1);
		}}

```


[User]
I need a parametric OpenSCAD design for a replacement toggle switch support for my FrSky Taranis RC transmitter. The stock supports don't always fit new switches, and I want to be able to adjust the dimensions to suit any switch I might use.

The basic shape is a rectangular frame with a hole for the switch's threaded part to pass through and a rectangular cutout to accommodate the switch's body. There's also a small slot cutout to allow the switch’s internal components to protrude.

Here are the key parameters I need to be able to control:

*   **`switch_dia`:** The diameter of the switch's threaded portion (standard is 6.2mm, but I need to be able to use others).
*   **`switch_width`:** The width of the switch body, not including the threaded portion (standard is 7.0mm, but again, needs to be adjustable).
*   **`frame_w`:** The width of the overall support frame. This should probably be derived from `switch_width` plus some fixed offset. I'd like to be able to specify the offset.
*   **`frame_l`:** The length of the support frame.
*   **`frame_height`:** The height of the main support frame.
*   **`slot`:** The width of the slot for switch components.
*   **`frame_t_height`:** The total height of the support frame, which needs to be higher than `frame_height`. This also needs to be adjustable based on the desired `frame_height` and some fixed offset.

Also, the main cube that forms the frame needs to extend beyond the rectangular cutout for the switch body so that there's a thin shell around that cutout. The threaded hole needs to go all the way through the part, and the slot cutout needs to extend beyond the main cube so it can print properly. Finally, I'd like the threaded hole centered in the frame, and the rectangular cutout for the switch body to also be centered in the frame lengthwise.

I think I would prefer to keep all of this in a single .scad file if that's reasonable. I don't need to use any external libraries for this design, I think it can all be done with basic OpenSCAD primitives.

[Assistant]
taranis_toggle_switch_support.scad:
```
//
//  support for (non-standard) toggle switches FrSky Taranis
//

// switch threaded part diameter, standard is 6.2
switch_dia = 6.0;

// switch body width, standard is 7.0
switch_width = 8.5;

frame_w = switch_width + 2.5;
frame_l = 1*10.6;

// height of support frame, 3.8 is standard
frame_height = 3.9;

slot = 1*1.4;

frame_t_height = frame_height + 2.1;

d = 1*0.01;

difference () {
	translate([-frame_w/2, -frame_l/2, 0]) cube([frame_w, frame_l, frame_t_height]);
	union () {

		translate([0,0,-d]) cylinder(r=switch_dia/2, h=frame_t_height+2*d, $fn=50);
		translate([-switch_width/2, -frame_l/2 - d, frame_height]) cube([switch_width, frame_l+2*d, frame_t_height]);
		translate([-slot/2, -frame_l/2 - d, -d]) cube([slot, frame_l+2*d, slot+d]);
	}
}

```


[User]
Hey, I'm looking to create a parametric phone dock that can hold a phone in both portrait and landscape orientations. I've got a few specific dimensions and features in mind.

For the portrait dock, I need a tilted back support. The height of the tilted back should be adjustable, as should the tilt angle. The base will have a cutout to accommodate the phone's charging connector (like a micro-usb) and a slot for the charging cable. I also need wire clips along the sides to hold the cable in place. I need to be able to adjust the width and depth of the connector cutout and the cable slot.

The main body of the dock needs to be customizable based on the width and depth of the phone, and I'd like an offset from the base to the front of the dock to allow room for the phone to sit in the dock. For the base, I want to adjust its length and have a way to adjust the base's offset from the main body. Finally, the dock should have feet underneath for stability.

For the landscape orientation, I'd like to have a sort of 'arm' that extends out from the side and cradles the phone so it can be set horizontally.

I'd prefer to have all of this be parametric so I can easily tweak the dimensions for different phones. Can you generate an OpenSCAD file for this? I don't think I need any specific libraries here - just some good old geometric primitives should do the job.

[Assistant]
phone_dock.scad:
```

// include landscape mount
include_horizontal=1; // [0,1]

//width of phone connector
w_usb = 11;
//depth of phone connector
d_usb = 6.5;
//length of phone connector
l_usb=29;

//height of tilted back
h_back = 35;
//angle of tilt
th_back = 15; // [10:25]

//width of phone
w_phone = 71;

//depth of phone
d_phone = 14.5;

dock_offset=10;
d_mount = 45;
h_mount = 42;

//width of wire
w_wire = 4.5;
l_feet=80;

h_horiz=150;

// calculated values (do not edit)

w_mount = w_phone + 4;
pos_back = h_back/tan(90-th_back);
y_usb = sin(th_back)*l_usb;
z_usb = l_usb-cos(th_back)*l_usb;
//

feet();
wire_clips();
upper_back();

difference() {
translate([0,-d_mount/2,0]) cube([w_mount,d_mount,h_mount]);
translate([0,dock_offset,0]) {
dock_cutout();
wire_slot();
}
}

if (include_horizontal) {
horizontal_dock();
}

module wire_slot() {

//micro-usb cutout
translate([w_mount/2-w_usb/2,y_usb-d_usb/2,h_mount+z_usb-l_usb])
rotate([th_back,0,0]) cube([w_usb, d_usb,l_usb]);

//wire cutouts
translate([w_mount/2-w_wire/2,y_usb+sin(th_back)*(h_mount+10)/2,0])
rotate([th_back,0,0]) cube([w_wire, d_mount,h_mount+10]);

translate([w_mount/2-w_wire/2,y_usb,0]) cube([w_wire, d_mount,h_mount]);

translate([w_mount/2-w_wire/2,-d_mount/2-dock_offset,0]) cube([w_wire,d_mount,7.5]);
}

module dock_cutout() {
translate([0,0,-3]) {
translate([2,0,1.03*h_mount]) rotate([0,90,0]) cylinder(r=d_phone/2,h=w_phone);
translate([2,-d_phone/2,1*h_mount]) cube([w_phone,d_phone,d_phone]);
}
}

module wire_clips() {
translate([w_mount/2-w_wire/2,-2.5,0]) cube([1.25,5,1.5]);
translate([w_mount/2+w_wire/4,10,0]) cube([1.25,5,1.5]);
translate([w_mount/2+w_wire/4,-15,0]) cube([1.25,5,1.5]);
}

module upper_back() {

//triangular prism
translate([0,-d_phone/2-pos_back+dock_offset,h_mount-0.1])
rotate([90,0,90]) linear_extrude(height=w_mount) {
polygon(points=[[0,0],[0,h_back],[pos_back,0]],paths=[[0,1,2]],convexity=1);
}

// add a cube from back of mount to back of triangular prism
translate([0,-d_mount/2,h_mount]) cube([w_mount,(d_mount/2-pos_back-d_phone/2)+dock_offset,h_back]);
}

module feet() {
translate([0,-40,0]) cube([15,l_feet,5]);
translate([w_mount-15,-40,0]) cube([15,l_feet,5]);
}

module horizontal_dock() {

hull() {
translate([-24+2,d_mount/2-5,0]) cube([24,5,h_horiz]);
translate([-5+2,-l_feet/2,0]) cube([5,10,h_horiz]);
}
}

```