[User]
Hey, I'm looking to create a customizable Zelda-style headband, and I'd like your help designing the OpenSCAD files. I've found a really solid starting point, and I want to build upon it. The original design was good, but I need more flexibility for sizing and some other tweaks.

Here's what I'm aiming for:

**Core Idea:** A headband with mounting points for decorative elements (leaves, a centerpiece, and a back piece), inspired by the Zelda aesthetic. I want to make it parametric so it fits different head sizes.

**Key Features:**

*   **Customizable Headband:** The headband itself needs to be generated based on the user's head circumference measured in millimeters. I should be able to input a `HeadCircumference_mm` parameter and the headband should scale appropriately. The base shape of the headband is an oval. The default dimensions for this would be a base width of 152mm and a base length of 190mm, and it should be scaled according to the circumference. Also, the band should have parameters to set `BandHeight_mm` and `BandThickness_mm` -- with defaults of 12.7mm and 3mm respectively, along with corresponding variables for BaseLength and BaseWidth to use in calculations.  The width of the oval, `CalcWidth` should be about 79.9% of the `CalcLength`.
*   **Integrated Mounting Blocks:** The headband should include small, square mounting blocks built directly into the design. These will be used to attach the decorative elements. I would like these to be filleted on the bottom so that the headband can be printed without supports. The blocks should be designed with a hole for a pin, so that accessories can easily be glued on or attached.
*   **Rear Mounting Hole:** There should be a hole at the back of the band to allow a rear ornament to be attached.
*   **Adjustable Parameters:** I need to be able to change various dimensions through parameters, particularly the `HeadCircumference_mm`.
*   **Mounting Block Placement:** The decorative elements should be placed according to a defined ratio of their distance along the length of the oval (which will change due to the `HeadCircumference_mm` parameter), and their y-axis distance away from the center of the oval, using the given angles of rotation for the mounting blocks, as detailed in the original code.
*   **Libraries:** I don't need you to include files for the libraries, but this needs to be designed using BOSL2 for its utility and ease of use.

**Specific Design Elements (from the original, but please recreate, don't improve):**

*   The band itself should have an oval cross-section, created using `scale()` to achieve the oval shape from a cylinder.
*   The mounting blocks are like small cubes with a pin hole for attachment of other parts
*   The rear hole in the headband is a cylinder
*   All mounting blocks use the same code, but the positions are based on a ratio (like `84/101*CalcLength`) along the curve and a position relative to the center of the band (`43.5*CircPercent`), which should be rotated around the z-axis with the corresponding angles, for example, `rotate([0,0,39])`.
*   The mounting blocks are offset to fit the band
*   The mounting blocks have cylindrical pin attachments for mounting other parts to them.

The original code includes constants for the placement of the mounting blocks as a ratio, which I'd like to keep similar.  So please use the same ratios and offsets used to place the mounting blocks. The blocks are arranged like this:

*   **Front Mount:** At the very front of the band
*   **XL Leaf Mounts:** Roughly 84/101 along the length of the band
*   **L Leaf Mounts:** Roughly 60/101 along the length of the band
*   **M Leaf Mounts:** Roughly 38/101 along the length of the band
*   **S Leaf Mounts:** Roughly 18/101 along the length of the band

All of the leaf mounts are placed at some distance above and below the horizontal centerline of the band, and rotated appropriately to orient them in the direction of their location along the curve of the oval.

I'm really looking for the core headband and mounting block functionality right now. I can work on the decorative elements separately.

Could you create the necessary OpenSCAD files using BOSL2 for the headband with these features? I'm hoping to get something parametric and well-organized that I can easily build upon. Thanks so much!

[Assistant]
ZeldaHeadband-cstm.scad:
```
$fn=128;

BaseWidth=152*1;
BaseLength=190*1;
BandHeight_mm=12.7*1;
BandThickness_mm=3*1;

//Measure your head in mm with a sewing tape measure
HeadCircumference_mm = 540; //[450:750]

CircPercent = HeadCircumference_mm/540;
CalcLength = BaseLength*CircPercent/2;
CalcWidth = CalcLength*0.799;
echo(CalcLength);
echo(CalcWidth);

//Define an Oval (shape of band)
module oval(w,h, height, center = false) {
 scale([1, h/w, 1]) cylinder(h=height, r=w, center=center);
};
//Create the Band, with hole in back for rear ornament
difference() {
    difference() {oval (CalcLength+BandThickness_mm,CalcWidth+BandThickness_mm,BandHeight_mm,center=false,center=false);
translate ([0,0,-1]) oval (CalcLength,CalcWidth,BandHeight_mm+2,center=false);};
translate([(CalcLength+20)*-1,0,BandHeight_mm/2]) rotate([0,90,0]) cylinder(40,r=2.45,center=false);}

//Define the Mounting Bracket
module CubeMount(width, height, center=false){
    difference() {translate([-2.25,-3,BandHeight_mm/2-3]) cube([4.45,5.95,5.95]); difference() {translate([0.71,3,BandHeight_mm/2-3.05]) rotate([90,0,0]) cube([1.5,1.5,6.1]);
    translate([0.71,3,BandHeight_mm/2-3+1.45]) rotate([90,0,0]) cylinder(h=8,r=1.5,center=center);}}
};
//Front Mount for centerpiece
translate([CalcLength+BandThickness_mm,0,0]) CubeMount();
//Mounts for XL Leaves
translate([84/101*CalcLength+BandThickness_mm,43.5*CircPercent,0]) rotate([0,0,39]) CubeMount();
translate([84/101*CalcLength+BandThickness_mm,-43.5*CircPercent,0]) rotate([0,0,-39]) CubeMount();
//Mounts for L Leaves
translate([60/101*CalcLength+BandThickness_mm,62.8*CircPercent,0]) rotate([0,0,59]) CubeMount();
translate([60/101*CalcLength+BandThickness_mm,-62.8*CircPercent,0]) rotate([0,0,-59]) CubeMount();
//Mounts for M Leaves
translate([38/101*CalcLength+BandThickness_mm,72.3*CircPercent,0]) rotate([0,0,71]) CubeMount();
translate([38/101*CalcLength+BandThickness_mm,-72.3*CircPercent,0]) rotate([0,0,-71]) CubeMount();
//Mounts for S Leaves
translate([18/101*CalcLength+BandThickness_mm,76.9*CircPercent,0]) rotate([0,0,81]) CubeMount();
translate([18/101*CalcLength+BandThickness_mm,-76.9*CircPercent,0]) rotate([0,0,-81]) CubeMount();
```


[User]
I'd like to generate a parametric model for a saxophone or clarinet reed, similar to the one I've been using. The goal is to have a highly customizable design that allows for precise control over the reed's shape, especially the vamp.

Here's a breakdown of the parameters I need:

**Basic Parameters:**

*   `txt`: A short text string for labeling the reed, e.g., "Alto", "Tenor".
*   `length`: The overall length of the reed in millimeters.
*   `reed_cyl_rad`: The radius of the cylindrical part of the reed that contacts the ligature.
*   `butt_thickness`: The thickness of the reed at its butt (ligature) end.
*   `butt_width`: The width of the reed at the butt end.
*   `butt_const`:  A percentage value controlling the length of the reed with constant width at the butt, in percent of overall length (0 to 66).
*   `side_curv`: An integer representing the side curvature. 0 for flat sides, 1 for concave sides (negative curvature), and 2 for convex sides (positive curvature).
*   `width`: The width of the reed at the tip.
*   `tip_round`: The amount of rounding at the reed tip, represented as the length of the ellipse's semiminor axis used for rounding.
*   `tip_thickness`: The initial thickness of the reed at its tip.
*   `reed_vamp_cov`: The percentage of the reed's overall length that is covered by the vamp (between 33 and 66%).

**Vamp Element Parameters:**
For each of the 9 vamp elements (0 through 8):

*   `reed_vamp_riseN`: The percentage rise of the element, where 0% is the tip thickness and 100% is the butt thickness.
*   `reed_vamp_radiusN`: The curvature radius of the cross-section of the vamp at that element.

The reed model should be built up from a base cylinder, cut out to give the basic outline and width, using the `butt_const` and `side_curv` parameters to define sides with either straight lines, concave or convex curves. Then the vamp should be added to that base cylinder using cone sections that are defined by the vamp elements. I would like the code to use the for loop to construct vamp of cone section based on `vamp_rise` and `vamp_radius` list.

Also I'd like the reed to be displayed with text. The text size is 6 unless the `butt_width` is smaller than 12. In that case, the text size will be half the `butt_width`. I would like the text to be placed on the reed at the butt side of the reed, with a height based on `butt_thickness`.

I'm imagining the design process will involve building the base reed shape, then using the cone-section approach with the defined vamp parameters to create the gradual thickness changes of the vamp. Finally, I want to use an intersection operation to combine the cone-section based vamp with the rest of the reed.

I do not need to use any external libraries. Can you generate this for me using a single OpenSCAD (.scad) file?

[Assistant]
reed_v2_1.scad:
```
/* [Basic] */
// Reed Name (short text string)
txt="iAlto";
// Reed Overall Length (mm)
length=73;
// Reed Cylinder Radius (mm)
reed_cyl_rad=14;
// Reed Butt Thickness (mm)
butt_thickness=3.5;
// Reed Butt Width (in mm)
butt_width=13;
// Reed Butt Width Stability (percent)
butt_const=0; // [0:66]
// Reed Side Curvature (Flat,Negative,Positive)
side_curv=0; // [0:Flat,1:Negative,2:Positive]
// Reed Tip Width (mm)
width=17;
// Reed Tip Round (mm)
tip_round=4;
// Reed Tip Initial Thickness (mm)
tip_thickness=0.3;
// Reed Vamp Coverage (percent)
reed_vamp_cov=50; // [33:66]
/* [Vamp Element 0] */
// Reed Vamp Crosscut Rise Element 0 (percent)
reed_vamp_rise0=0; // [100]
// Reed Vamp Crosscut Curvature Element 0 (mm)
reed_vamp_radius0=200;
/* [Vamp Element 1] */
// Reed Vamp Crosscut Rise Element 1 (percent)
reed_vamp_rise1=5; // [100]
// Reed Vamp Crosscut Curvature Element 1 (mm)
reed_vamp_radius1=170;
/* [Vamp Element 2] */
// Reed Vamp Crosscut Rise Element 2 (percent)
reed_vamp_rise2=7; // [100]
// Reed Vamp Crosscut Curvature Element 2 (mm)
reed_vamp_radius2=155;
/* [Vamp Element 3] */
// Reed Vamp Crosscut Rise Element 3 (percent)
reed_vamp_rise3=11; // [100]
// Reed Vamp Crosscut Curvature Element 3 (mm)
reed_vamp_radius3=140;
/* [Vamp Element 4] */
// Reed Vamp Crosscut Rise Element 4 (percent)
reed_vamp_rise4=17; // [100]
// Reed Vamp Crosscut Curvature Element 4 (mm)
reed_vamp_radius4=125;
/* [Vamp Element 5] */
// Reed Vamp Crosscut Rise Element 5 (percent)
reed_vamp_rise5=25; // [100]
// Reed Vamp Crosscut Curvature Element 5 (mm)
reed_vamp_radius5=110;
/* [Vamp Element 6] */
// Reed Vamp Crosscut Rise Element 6 (percent)
reed_vamp_rise6=38; // [100]
// Reed Vamp Crosscut Curvature Element 6 (mm)
reed_vamp_radius6=95;
/* [Vamp Element 7] */
// Reed Vamp Crosscut Rise Element 7 (percent)
reed_vamp_rise7=56; // [100]
// Reed Vamp Crosscut Curvature Element 7 (mm)
reed_vamp_radius7=70;
/* [Vamp Element 8] */
// Reed Vamp Crosscut Rise Element 8 (percent)
reed_vamp_rise8=85; // [100]
// Reed Vamp Crosscut Curvature Element 8 (mm)
reed_vamp_radius8=55;

/* [Hidden] */
$fs=0.4;
$fa=0.5;
vamp_rise=[reed_vamp_rise0,reed_vamp_rise1,reed_vamp_rise2,reed_vamp_rise3,reed_vamp_rise4,reed_vamp_rise5,reed_vamp_rise6,reed_vamp_rise7,reed_vamp_rise8];
vamp_radius=[reed_vamp_radius0,reed_vamp_radius1,reed_vamp_radius2,reed_vamp_radius3,reed_vamp_radius4,reed_vamp_radius5,reed_vamp_radius6,reed_vamp_radius7,reed_vamp_radius8];
eps=0.03;

module curv_cylinder(side_length)
{
	scale([1,(width-butt_width)*0.5/(side_length+eps),1]) cylinder(r=side_length+eps,h=butt_thickness+2*(1+eps));
}

module side_shape()
{
	side_length=length*(100-butt_const)*0.01-tip_round;
	difference()
	{
		translate([0,0,-1]) cube([side_length+2*eps,reed_cyl_rad,butt_thickness+2]);
		if (side_curv != 2)
		{
			translate([-eps,-(width-butt_width)*0.5-eps,-2]) rotate([0,0,atan2((width-butt_width)*0.5,side_length)]) cube([length+2,(width-butt_width)*0.5+eps,butt_thickness+4]);
		}
		else
		{
			translate([side_length,0,-1-eps]) curv_cylinder(side_length);
		}
	}
	difference()
	{
		rotate([0,0,atan2((width-butt_width)*0.5,side_length)]) translate([-eps,0,-1]) cube([side_length+eps,(butt_width-width),butt_thickness+2]);
		if (side_curv == 2 && width < butt_width)
		{
			translate([0,(width-butt_width)*0.5,-1-eps]) curv_cylinder(side_length);
		}
	}
	if (side_curv == 1)
	{
		if (width > butt_width)
		{
			translate([0,(width-butt_width)*0.5,0]) difference()
			{
				translate([0,0,-1]) curv_cylinder(side_length);
				translate([-side_length-2*eps,-1-(width-butt_width)*0.5,-1-eps]) cube([side_length+eps,abs(width-butt_width)+2,butt_thickness+2*(1+eps)]);
			}
		}
		else
		{
			translate([side_length-eps,0,-1]) curv_cylinder(side_length);
		}
	}
}

module reed_base()
{
	color([0.8314,0.686,0.215]) difference()
	{
		const_length=length*butt_const*0.01;
		union()
		{
			translate([0,0,butt_thickness-reed_cyl_rad]) rotate([0,90,0])
				cylinder(r=reed_cyl_rad,h=length-tip_round);
			if (tip_round > 0)
			{
	 			translate([length-tip_round,0,-0.01]) scale([2 * tip_round / width,1,1])
					cylinder(d=width,h=butt_thickness);
			}
		}
		translate([-1,-reed_cyl_rad-1,-reed_cyl_rad*2])
			cube([length+2,reed_cyl_rad*2+2,reed_cyl_rad*2]);
		if (butt_const > 0.1)
		{
			translate([-1,butt_width*0.5,-1]) cube([const_length+1,reed_cyl_rad,butt_thickness+2]);
			translate([-1,-butt_width*0.5-reed_cyl_rad,-1]) cube([const_length+1,reed_cyl_rad,butt_thickness+2]);
		}
		translate([const_length,butt_width*0.5,-1]) side_shape();
		translate([const_length,-butt_width*0.5,-1+butt_thickness]) rotate([180,0,0]) side_shape();
	}
}

module cone_section(rad1,shift1,rad2,shift2,h)
{
	if (abs(rad2-rad1) >= 0.1)
	{
		shift_corr=-rad1+rad1*(shift2-shift1)/(rad2-rad1);
		translate([-rad1+shift1-shift_corr,0,0]) linear_extrude(height=h,convexity=10,scale=rad2/rad1)
			translate([shift_corr,0]) circle(r=rad1);
	}
	else
	{
		hull()
		{
			translate([-rad1+shift1,0,0]) cylinder(r=rad1,h=0.01);
			translate([-rad2+shift2,0,h-0.01]) cylinder(r=rad2,h=0.01);
		}
	}
}

module reed()
{
	intersection()
	{
		z_interval=butt_thickness-tip_thickness;
		reed_base();
		for_end=len(vamp_rise)-2;
		color([1.0,0.843,0]) union()
		{
			for(i=[0:1:for_end])
			{
				translate([length-0.01*i*length*reed_vamp_cov/(for_end+1),0,tip_thickness]) rotate([0,-90,0]) cone_section(vamp_radius[i],vamp_rise[i]*(z_interval*0.01),vamp_radius[i+1],vamp_rise[i+1]*(z_interval*0.01),0.01*length*reed_vamp_cov/(for_end+1));
			}
			translate([length*(100-reed_vamp_cov)*0.01,0,tip_thickness]) rotate([0,-90,0])
				cone_section(vamp_radius[for_end+1],vamp_rise[for_end+1]*(z_interval*0.01),vamp_radius[for_end+1]+reed_cyl_rad,butt_thickness*3,length*(100-reed_vamp_cov)*0.01);
		}
	}
}

module reed_with_text()
{
	text_size=6;
	if (butt_width < 12)
	{
		text_size=butt_width*0.5;
	}
	difference()
	{
		reed();
		if (butt_thickness > 1.5)
		{
			color([1.0,0.843,0]) translate([1,-text_size*0.5,butt_thickness-1.0]) linear_extrude(1.1) text(text=txt,size=6);
		}
		else
		{
			color([1.0,0.843,0]) translate([1,-text_size*0.5,butt_thickness*0.5]) linear_extrude(1.1) text(text=txt,size=6);
		}
	}
}

reed_with_text();

```


[User]
I want to create a customizable Lego brick generator. I'd like it to be parametric, meaning I can define the dimensions of the brick, and it should generate the appropriate 3D model.

Here are the parameters I'd like to control:

*   **`dot_x`**: The number of studs (dots) along the X-axis (length) of the brick. This should be an integer.
*   **`dot_y`**: The number of studs along the Y-axis (width) of the brick. This should also be an integer.
*   **`BH`**: The overall height of the brick. This will control the basic height of the block, not including studs or holes.
*  The code should use the following fixed dimensions internally:
    *  `P`: Stud spacing (8mm)
    *   `C`: Stud diameter (4.8mm)
    *  `H2`: Stud height (1.8mm)
    *  `K`: Offset for brick size (0.2mm)
    *  `SW`: Side Wall width(1.2mm)
    *  `TW`: Base wall width(1mm)
    *  `OC` : Calculated offset of dots, defined as  (P-K/2)/2

The generator should create:

*   A rectangular brick base with rounded corners.
*   The appropriate number of studs on top. The studs should be cylindrical with the provided diameter and height.
*   A hollow section underneath the brick, created by using a difference operation, which should be offset from the edges by `SW` on the X and Y axis. The thickness of the hollow should be `TW`.
*   Small support cubes under the inside edges, as seen in the example code, to connect the top and bottom wall. They should not be rounded or have fancy shapes.
*   The necessary circular 'tubes' or recesses on the underside of the brick that interlock with the studs on another brick, and should include a cylinder that represents the 'tube' and a second cylinder representing the inner hole. The tubes should be slightly offset inwards, as seen in the example code provided.

I'd also like it to be in red, please, just as a default. And I'd like to make sure it can be generated up to at least a 15x15 stud brick. I don't need any fancy features; just a simple, functional Lego brick with the defined parameters. I'm not requesting anything using existing code, please generate from scratch. Let me know if you need more clarification.

[Assistant]
Lego.scad:
```
/*[Lego Block Setting]*/

//Number for Dot(X)
dot_x=5;// [2:15]

//Number for Dot(Y)
dot_y=2;// [2:15]

//Lego Height
BH=9.6;//  [3.2,9.6]

/* [HIDDEN] */
P=8;    //[8]
C=4.8;  //[4.8]
H2=1.8; //[1.8]
K=0.2;  //[0.2]
SW=1.2; //[1.2]
TW=1;   //[1]

OC=(P-K/2)/2;

color ("Red")
union(){
    difference(){
        union(){
            cube([(P*dot_x)-K,(P*dot_y)-K,BH]);
            for(sy = [0 : 1 : dot_y-1]){
                for(sx = [0 : 1 : dot_x-1]){
                    translate([OC+P*sx,OC+P*sy,BH])
                    cylinder (h=H2, d=C,, $fn=50);
                }
            }

        }
        translate([SW,SW,0-TW])
        cube([(P*dot_x)-K-SW*2,(P*dot_y)-K-SW*2,BH]);
    }
    for(sx = [0 : 1 : dot_x-TW]){
        translate([3.6+P*sx,SW,0])
        cube([0.6,0.3,BH-1]);
        translate([3.6+8*sx,(8*dot_y)-0.2-1.2-0.3,0])
        cube([0.6,0.3,BH-1]);
    }
    for(sy = [0 : 1 : dot_y-TW]){
        translate([1.2,3.6+8*sy,0])
        cube([0.3,0.6,BH-1]);
        translate([(8*dot_x)-0.2-1.2-0.3,3.6+8*sy,0])
        cube([0.3,0.6,BH-1]);
    }

    for(sy = [0 : 1 : dot_y-2]){
        for(sx = [0 : 1 : dot_x-2]){
            difference(){
                translate([7.9+8*sx,7.9+8*sy,0])
                cylinder (BH-TW, d=6.51,true, $fn=50);
                translate([7.9+8*sx,7.9+8*sy,-1])
                cylinder (BH-TW, d=4.8,true, $fn=50);
            }
        }
    }
}
```


[User] I'd like to design a customizable stand for small bottles, like beard oils or vape liquids. I need it to hold a variable number of bottles, and for the size of the stand and the holes to be parametric so I can adjust it for different sized bottles. I imagine it as a rectangular solid with cylindrical holes cut into it. I'd like to be able to specify the diameter and height of the bottles, the number of bottles, some spacing around the edges, and the spacing between the bottles. I'm not sure if it's better to have one single OpenSCAD file for this, or to have a few different modules in separate files - I'm happy for you to decide.

[Assistant]
bottleStand.scad:
```
/***********************************************************************
Name ......... : bottleStand.scad
Description....: Customizable Small Bottle Stand
Author ....... : Garrett Melenka
Version ...... : V1.0 2016/12/31
Licence ...... : GPL
***********************************************************************/

//measured bottle diameter + a small clearance
bottleDiameter = 35.0;
//measured bottle height + a small clearance
bottleHeight = 85.0;

//number of bottles
numBottles = 4;

//Spacing around edges
edge = 10;
//Spacing Between Bottles
bottleSpace = 5;

module bottleStand()
{

    L = (bottleDiameter + bottleSpace)*numBottles + edge*0.5;

    difference(){
    cube([L, bottleHeight+edge, bottleDiameter*0.5], center = true);

    for(i=[0:1:numBottles-1]){

     x = -L*0.5 + (bottleDiameter*0.5+edge*0.5) + (bottleDiameter+bottleSpace)*i;
     //x=-L*0.5 + bottleDiameter-edge*0.5;

    translate([x,0,bottleDiameter*0.5]){

    rotate([90,0,0]){
    cylinder(r=bottleDiameter*0.5, h=bottleHeight, center = true, $fn=100);
    }
    }
    }
    }

}

bottleStand();

```


[User]
I'm looking for an OpenSCAD design for a small parts tray with a funnel spout. It should be customizable in several ways.

The main body of the tray should be a rounded rectangle, with parameters for:

*   `width`: the external width of the tray
*   `length`: the external length of the tray
*   `height`: the external height of the tray
*   `corner_radius`: the radius of the rounded corners of the tray
*   `wall_thickness`: the thickness of the walls
*   `base_thickness`: the thickness of the base

The tray should have a spout extending from one corner. The spout should have these parameters:

*   `spout_base_width`: the width of the spout where it connects to the tray
*   `spout_tip_width`: the width of the spout at its end
*  `spout_tip_height_fraction`: the height of the spout tip as a fraction of the tray's wall height
*   `spout_tip_base_thickness`: the thickness of the spout base at the tip
*   `spout_length_control`: a parameter to control the length of the spout - tweaking this value should control the length of the spout.

The spout should transition smoothly from the tray wall height down to the `spout_tip_height_fraction` of the wall height and also taper from `spout_base_width` to `spout_tip_width`.

Additionally, I'd like a parameter `left_hand` which should be 0 for a right-handed spout and 1 for a left-handed spout.

Finally, there should be a parameter for `$fn` to control circle smoothness (number of faces).

I’d like the whole design to be parametric so I can adjust these values in OpenSCAD.

[Assistant]
tray_funnel.scad:
```

// Tray external width.
width = 60;

// Tray external length.
length = 100;

// Tray external height.
height = 13;

// Tray corner radius
corner_radius = 5;

// Thickness of wall around the tray
wall_thickness = 2;

// Thickness of the base
base_thickness = 2;

// Spout width at the tray end.
spout_base_width = 35;

// Spout width at the outer end.
spout_tip_width = 25;

// Spout end height as a fraction of the tray wall height.
spout_tip_height_fraction = 0.7;

// Base thickness at the outer end of the spout.
spout_tip_base_thickness = 0.8;

// Controls spout length. Tweak to get desired spout length.
spout_length_control = 20;

// 0 for right handed, 1 for left handed.
left_hand = 0;

// Circle smoothness (number of faces).
$fn = 90;

spout_vertical_angle = max(0, atan((height - height * spout_tip_height_fraction)/ spout_length_control));

// Adding '0' to hide in thingiverse customizer.
eps1 = 0.01 + 0;
eps2 = 2 * eps1;

module rounder_cube(w, l, h, r) {
    dx = l/2-r;
    dy = w/2-r;
  hull() {
      translate([dx, dy, 0]) cylinder(r=r, h=h);
      translate([dx, -dy, 0]) cylinder(r=r, h=h);
      translate([-dx, dy, 0]) cylinder(r=r, h=h);
      translate([-dx, -dy, 0]) cylinder(r=r, h=h);
  }
}

module spout() {
  hull() {
    translate([0, -spout_base_width/2, 0]) cube([eps1, spout_base_width, height]);
    translate([spout_length_control-eps1, -spout_tip_width/2, 0]) cube([eps1, spout_tip_width, height]);
  }
}

module spout_slot() {
  hull() {
    translate([-eps1, -(spout_base_width-sqrt(2)*2*wall_thickness)/2, base_thickness])
      cube([eps1, spout_base_width-sqrt(2)*2*wall_thickness, height]);

    translate([spout_length_control, -(spout_tip_width-2*wall_thickness)/2, spout_tip_base_thickness]) cube([eps1, spout_tip_width-2*wall_thickness, height]);
  }

  // Extra cut in case the spout end include the tray's missing
  // corner so we don't have a leftover from that corner.
  translate([spout_length_control - eps1, -width, -height]) cube([width, 2*width, 3*height]);
}

module main() {
  mirror([left_hand, 0, 0])
  difference() {
     union() {
          //bowel();
               rounder_cube(width, length, height, corner_radius);

          translate([
            length/2-(spout_base_width/2)/sqrt(2),
            width/2-(spout_base_width/2)/sqrt(2),
            0])
                rotate([0, 0, 45]) spout();
     }

     translate([0, 0, base_thickness])
     rounder_cube(width-2*wall_thickness, length-2*wall_thickness, height-base_thickness+eps1, max(0.1, corner_radius-wall_thickness));

     translate([
            length/2-(spout_base_width/2)/sqrt(2),
            width/2-(spout_base_width/2)/sqrt(2),
            0])
                rotate([0, 0, 45]) spout_slot();

     translate([
         length/2-(spout_base_width/2)/sqrt(2),
         width/2-(spout_base_width/2)/sqrt(2),
         height])
       rotate([0, 0, 45])
       rotate([0, spout_vertical_angle, 0])
       cylinder(d=2*length, h=height);
 }

}

//spout_slot();

main();

```


[User]
Hey, I'm looking to get an OpenSCAD file for a simple, customizable headband. I want it to be basically an oval-shaped band that fits around the head, and I'd like the dimensions to be parametric.

Specifically, I need to be able to control the following:

*   **Head Circumference:**  This will determine the overall size of the headband and should be an input in mm.
*   **Band Height:**  This is the vertical height or thickness of the band and should be an input in mm as well.
*   **Band Thickness:** This controls the width of the band if looking at it from the side, and it should also be an input in mm.
*   **Number of Facets:** To make the curved oval shape smooth, it would be best if I could define the resolution with `$fn`.

The design should create an oval band and then subtract a slightly smaller oval band from the middle to create a band of the defined `BandThickness`.

I’d really appreciate it if you could generate the SCAD file for this. I don't need any mounting holes or blocks or anything like that, just the basic band. Thanks!

[Assistant]
Headband-cstm.scad:
```

BaseWidth=152*1;
BaseLength=190*1;

//Measure your head in mm with a sewing tape measure
HeadCircumference_mm = 540; //[450:750]
//13mm is a average size
BandHeight_mm=13;//[3:20]
//3mm thick is still flexible
BandThickness_mm=3;//[1:8]
//Determines number of sides / facets... more is smoother
$fn=128;

CircPercent = HeadCircumference_mm/540;
CalcLength = BaseLength*CircPercent/2;
CalcWidth = CalcLength*0.799;
echo(CalcLength);
echo(CalcWidth);

//Define an Oval (shape of band)
module oval(w,h, height, center = false) {
 scale([1, h/w, 1]) cylinder(h=height, r=w, center=center);
};
//Create the Band, with hole in back for rear ornament

    difference() {oval (CalcLength+BandThickness_mm,CalcWidth+BandThickness_mm,BandHeight_mm,center=false,center=false);
translate ([0,0,-1]) oval (CalcLength,CalcWidth,BandHeight_mm+2,center=false);}

```


[User]
Hey, I'm looking to generate an OpenSCAD design for a string light winder, and I have some specific parameters in mind. I need it to be a flat, 2D design that can be easily 3D printed. Here are the key features:

The main body will be a rectangle. I want to control the length and width of this rectangle with `MainBodyLength` and `MainBodyWidth` variables. The thickness of the entire object should be controlled by a `Thickness` variable, which will be the z-height of the printed object.

On each of the shorter ends of the main body, there should be an "exterior arm" extending outwards. These arms should run the entire length of the main body and have their own width defined by the `ExteriorArmWidth` variable.

Inside the main body, there should be "interior arms" that extend along the *width* of the main body. The spacing between the interior arms needs to be controlled by `InteriorArmSpacing`, while their width is defined by `InteriorArmWidth`. I guess the center point of the inside arms should be aligned with the center of the main body.

I want to be able to put supports between the interior and exterior arms; I want the number of these supports to be adjustable via `NumberCenterSupports`. The width of each of these center supports is controlled by `CenterSupportWidth`. The supports need to be spaced evenly between the two long arms and in between the inner and outer arms.

Finally, there should be a notch for securing the light string. I want to be able to control how far into the main body this notch extends using `NotchDepth`. I also want to be able to move the notch along the y-axis, controlled by a `VaryNotchPosition` variable. The notch should be perpendicular to the outer arms and the thickness of the notch itself should be very minimal, like 2-3mm.

I’d like to have a separate module for each of the main components - ExteriorArms, InteriorArms, CenterSupports, and MainBody, which utilizes the other modules.

Could you create an OpenSCAD file for this, keeping in mind these parameters and the module structure?

[Assistant]
string_light_winder_holder_wrap_final.scad:
```
Thickness=4; // z height, determines the sturdiness
MainBodyLength=200; //
MainBodyWidth=90; // wires are wrapped around this axis
ExteriorArmWidth=20;
InteriorArmSpacing=70; // how much you HAVE to wrap cord around
InteriorArmWidth=15;
NotchDepth=5;
VaryNotchPosition=0;
NumberCenterSupports=2;
CenterSupportWidth=10;

module ExteriorArms(){
    union(){
        cube(([MainBodyLength,ExteriorArmWidth,Thickness]));
        translate([0, ((MainBodyWidth)-(ExteriorArmWidth)) ,0])
        cube(([MainBodyLength,ExteriorArmWidth,Thickness]));
    }
}

module InteriorArms(){
    union(){
        cube(([InteriorArmWidth,MainBodyWidth,Thickness]));
        translate([((InteriorArmSpacing)-(InteriorArmWidth)),0,0])
        cube(([InteriorArmWidth,MainBodyWidth,Thickness]));
    }
}

module CenterSupports(){

    union(){
        cube(([0,0,0]));
        translate([0,0,0])
        cube(([0,0,0]));
    }

}

module MainBody(){
    union(){
        ExteriorArms();
        translate([(MainBodyLength/2)-(InteriorArmSpacing/2),0,0])
        InteriorArms();
    }
    for (i=[0:NumberCenterSupports-1]){
        translate([(MainBodyLength/2)-(InteriorArmSpacing/2)*0.99, ((ExteriorArmWidth)-(CenterSupportWidth/2)) + (i+1)*(((MainBodyWidth-(2*ExteriorArmWidth))+ CenterSupportWidth)/(NumberCenterSupports+1)) - (CenterSupportWidth/2)  ,0])
        cube(([InteriorArmSpacing*0.99,CenterSupportWidth,Thickness]));

    }
}

module Notch(){
    cube(([100,3,100]));
}

difference(){
    MainBody();
    translate([(MainBodyLength/2)+(InteriorArmSpacing/2)-NotchDepth,MainBodyWidth-ExteriorArmWidth-( (MainBodyWidth-(2*ExteriorArmWidth))/4)+VaryNotchPosition,-0.50])
    Notch();
}

```


[User]
Okay, I need to design a PCB holder for CNC milling, and I want to make it customizable in OpenSCAD. The basic idea is a rectangular recess that the PCB sits snugly in, with a surrounding lip or frame.

Specifically, I need a design that takes into account:

*   **PCB Dimensions:** I need to be able to specify the PCB's length, width, and thickness. Let's call these `board_x`, `board_y`, and `board_z`.
*   **Frame Thickness:** The thickness of the surrounding frame (the "edge thickness") should be adjustable – `edge_thickness`.
*   **Lip Size:** There should be a flat lip around the frame to allow for clamping, adjustable in size - `flat_lip_size`.
*   **Holder Height:** The total height of the holder should be adjustable, call this `item_height`.
*   **Mounting Holes:** I'd like to include mounting holes for screws, positioned at each corner of the PCB frame, and their diameter should be parametric (`screw_dia`).
*   **Pop-Out Hole:** I need a cylindrical hole in the base of the holder, beneath the PCB, to allow me to push the PCB out of the recess easily after milling, call the radius `pop_out_radius`.

I also want the holder to be built as a combination of two main components. First is the main holder piece, and second, the solid piece that the holder rests on. The second piece is a bit larger than the holder and serves as a bed, and I'd like to be able to adjust how thick the bed is - `field_thickness`. This "bed" should be placed slightly off-center from the holder's origin, a distance of `offset` on both the x and y axis.

Finally, I want a finger-hole on the top of the holder that can be used for gripping or for securing. This finger hole should be able to have it's radius set as `finger_hole_radius`. The location of the center of the finger hole should also be configurable as an `finger_hole_x` and `finger_hole_y` parameter.

I’d like the design to use `difference()` and `union()` effectively to create the necessary shapes. Please make sure the variables are defined at the start of the file so they can be easily customized.

So the files should be parametric and have parameters for all of the dimensions and features mentioned above: `board_x`, `board_y`, `board_z`, `edge_thickness`, `flat_lip_size`, `item_height`, `screw_dia`, `field_thickness`, `pop_out_radius`, `offset`, `finger_hole_radius`, `finger_hole_x`, and `finger_hole_y`. I think it would also be useful to define computed dimensions as well, such as `combi_x` and `combi_y` which account for the PCB, frame and lip size.

[Assistant]
pcbholder.scad:
```
$fn=30;
board_x = 100.5;
board_y = 70.5;
board_z = 1.5;

flat_lip_size = 10;

screw_dia = 2.5;

edge_thickness = 15;

item_height = 4;

combi_x = board_x + edge_thickness+(flat_lip_size*2);
combi_y = board_y + edge_thickness+(flat_lip_size*2);
field_thickness = 2;

module exterior()
{
    difference()
    {
    translate([-edge_thickness/2,-edge_thickness/2,0]) cube([board_x+edge_thickness,board_y+edge_thickness,item_height]);

    translate([-edge_thickness/4, -edge_thickness/4,item_height-(item_height/2)]) cylinder(r=screw_dia/2, h=item_height/2);

    translate([-edge_thickness/4, ((-edge_thickness/4)+board_y+edge_thickness/2),item_height-(item_height/2)]) cylinder(r=screw_dia/2, h=item_height/2);

    translate([
        (-edge_thickness/4)+board_x+edge_thickness/2,
        ((-edge_thickness/4)+board_y+edge_thickness/2),
        (item_height-(item_height/2))
        ])
            cylinder(r=screw_dia/2, h=item_height/2);
    translate([
        ((-edge_thickness/4)+board_x+edge_thickness/2),
        ((-edge_thickness/4)),
        (item_height-(item_height/2))
        ])

            cylinder(r=screw_dia/2, h=item_height/2);

    }

}

module pcb()
{
    color([1,0,0]) translate([0,0,item_height-board_z]) cube([board_x, board_y, board_z]);
}

module field()
{
    cube([combi_x,combi_y,field_thickness]);
}

module holder()
{
    union() {
    difference() {
        exterior();
        pcb();
    }
    translate([-combi_x/8,-combi_x/8])field();
}
}

module plus_fingerhole() {
    difference()
    {
        holder();
        translate([combi_x/4,combi_x/4,0])cylinder(r=10, h=10);
    }
}
plus_fingerhole();

```


[User]
Hi, I'm looking to create some customizable bases and signs for tabletop gaming miniatures, and I'd like to use OpenSCAD to make them. I want the bases to be circular with a flat bottom and a small lip around the bottom edge. There should be small posts along the bottom edge so that when combined with the sign, they can align and even be press-fit if the fit is tight enough. The sign part should clip into these posts. I would like a customizable height and diameter, with the ability to generate just the base, just the sign, or both together.

Specifically, I want the base to have a flat circular surface, with a small raised lip around the bottom edge. The sign should sit on top of this base via two posts which allow the sign to slightly angle up from the base. These posts should be small cylinders on the base and corresponding cutouts in the sign. The sign itself should be a flat rectangle with the mounting cutouts.

I'd like to be able to specify a base size, and this will affect the diameter of the base and the size of the sign. The height of the sign should also be adjustable. I'd like to have some pre-set sizes for the base: Small, Medium, Large, Huge, Gargantuan and Colossal, but also a way to input a custom base size in inches.  The sign height can just be in millimeters.

I'm imagining using wet erase markers on the sign so it should have a smooth flat surface.

Could you help me design the OpenSCAD code for these parts, making them all parametric? I also want to be able to specify whether I want just the base, just the sign, or both together as a single part. I'd rather not rely on any OpenSCAD libraries for this design, if at all possible. Thanks!

[Assistant]
baseSign.scad:
```
// D&D Base w/Sign
// Created by Doug Kress
// First published on 2017-01-01.

// Use Wet erase markers to identify monsters in your battles.
/* [Options] */

// What would you like to create?
PrintOption = "both"; // [both:Both, base:Base Only, sign:SignOnly]

// select a size
BaseSize = 1;   // [0.75:Small, 1:Medium, 2:Large, 3:Huge, 4:Gargantuan, 6:Colossal]

// hight of sign (millimeters)
SignHeight = 10;

/* [Custom] */

// base size (in inches) - "Base Size" above will be ignored
Custom = 0;

printBase(PrintOption, Custom > 0 ? Custom : BaseSize);

module printBase(option, size) {
    if (option != "sign") {
        base(size * 25.4);
    }
    if (option != "base") {
        translate([0,-(SignHeight+5),0]) baseSign(size * 25.4);
    }
}

module base(baseSize)
{
    difference() {
        cube([baseSize, baseSize, 3]);
        union() {
        translate([baseSize/2, baseSize/2, 1])
            cylinder(r=baseSize/2*1.1 , h=3, $fn=64);

        offset = baseSize * 0.04;
        translate([offset*1.5, offset*1.5, 1])
            cylinder(r=offset, h=3, $fn=32);
        translate([baseSize-offset*1.5, offset*1.5, 1])
            cylinder(r=offset, h=3, $fn=32);
        }
    }
}

module signTab(baseSize, reverse)
{
    offset = baseSize * 0.0325;
    position = reverse ? baseSize * .2 - offset * 1.5 : offset * 1.5;
    cylPosition = reverse ? baseSize*.2 - baseSize/2-1 : baseSize/2+1;
    difference() {
        cube([baseSize*.2, baseSize*.2, 1]);
        translate([cylPosition,baseSize/2, -1])
            cylinder(r=baseSize/2*1.1 , h=3, $fn=64);

    }
    translate([position, baseSize*.15, 0])
        cylinder(r=offset, h=3, $fn=32);

}
module baseSign(baseSize)
{
    offset = baseSize * 0.035;
    cube([baseSize, SignHeight, 1]);
    rotate([75, 0, 0])  {
        translate([0,0.6,-2])
            signTab(baseSize, false);
        translate([baseSize-baseSize*.2,0.6,-2])
            signTab(baseSize, true);
   }
}
```


[User]
Hi there,

I'm looking to create a parametric vacuum hose adapter in OpenSCAD. I need it to have an outside fit on both ends, meaning both ends of the adapter will slide *over* the hoses or nozzles they are connecting.

I'd like to be able to customize the following:

*   `wallThickness`: the thickness of the adapter's walls.
*   `insideVacuum`: the inside diameter of the smaller end of the adapter (this end fits over a vacuum nozzle, for example).
*   `vacuumLength`: the length of the smaller end of the adapter.
*   `insideBandsaw`: the inside diameter of the larger end of the adapter (this end fits over, say, a bandsaw dust port).
*   `bandsawLength`: the length of the larger end of the adapter.

The adapter should be a simple stepped cylinder, smoothly transitioning between the two different diameters, and should have the wall thickness specified. I don't need any fancy features, just a solid, functional adapter. I am happy with the standard OpenSCAD libraries and functions; I don't need any additional libraries to be used. I'd like the design to be reasonably simple and easy to read so I could modify it in the future if needed.

Basically, I need a similar thing as that original thingy # 97238, but with an outside fit on both ends of the adapter. If you need anything else from me, let me know!

[Assistant]
vacuum_hose_adapter_outside_outside.scad:
```
//CUSTOMIZER VARIABLES

//How thick your walls are (in mm)
wallThickness = 2;

//The diameter inside the "small" end. Fits over the vacuum.
insideVacuum = 34;
//The length of the tube that fits over the vacuum.
vacuumLength = 24;

//The diameter of the inside of the "large" end. Fits outside something else
insideBandsaw = 59;
//The length of the larger tube.
bandsawLength=24;

//CUSTOMIZER VARIABLES END

$fn=55;
rotate([0,180,0])
difference() {
  union() {
    translate([0,0,bandsawLength+(vacuumLength+bandsawLength)/3])
    cylinder(r=(insideVacuum/2)+wallThickness, h=vacuumLength);

    translate([0,0,bandsawLength])
    cylinder(r2=(insideVacuum/2)+wallThickness, r1=(insideBandsaw/2)+wallThickness,h=(vacuumLength+bandsawLength)/3);

    cylinder(r=(insideBandsaw/2)+wallThickness, h=bandsawLength);
 }

translate([0,0,bandsawLength+(vacuumLength+bandsawLength)/3-0.5])
#cylinder(r=(insideVacuum/2),h=vacuumLength+1);

  translate([0,0,bandsawLength])
   #cylinder(r2=(insideVacuum/2), r1=(insideBandsaw/2),h=(vacuumLength+bandsawLength)/3 );

translate([0,0,-0.5])
#cylinder(r=(insideBandsaw/2), h=bandsawLength+1);
 }
```


[User]
I'd like to design a staple box, and I'd like to be able to easily customize it for different staple sizes or even other small items. I saw this design online (the code is attached) and I really like the sliding lid and rounded corners, but I'd like it to be fully parametric. I'd like you to create the OpenSCAD file(s) for me.

Specifically, I want to be able to adjust the following:

*   **Inner Dimensions:** The width, depth, and height of the inner box, where the staples would go.
*   **Wall Thickness:** The thickness of the box walls and lid.
*   **Corner Roundness:**  The radius of the rounded corners for both the box and lid.
*   **Lid Text:** Two lines of text to label the lid. I'd want to control the text content and font size.
*   **Tolerance:**  The gap between the box and the lid.
*   **Finger Pull:**  A cylindrical finger pull on the side of the lid. I'd like to control its diameter, length, and position.

I think I'd like a single SCAD file. I don't need any special libraries, just vanilla OpenSCAD. I'd also like to specify the print tolerance to allow for different printer characteristics.

[Assistant]
StapleBox.scad:
```
//
//  StapleBox.scad
//
//  EvilTeach
//
//  01/25/2017
//
//  A nice box with a slidable lid, with text on it
//  for holding staples or anything else.
//
//  This model is based on http://www.thingiverse.com/thing:468917
//  Thank you http://www.thingiverse.com/Aisjam/about for your quality work.
//
//  if you measure the size of the box that the staples come in
//  those dimensions will be reasonable values for the inner variables below.
//

/* [Box Dimensions] */
wallThickness = 3.0;   // [2:5]

innerWidth  = 100.0;   // [80:120]
innerDepth  = 100.0;   // [80:120]
innerHeight =  15.0;   // [4:30]

/* [Lid Text] */
topText    = "       SOME ";
bottomText = "     STAPLES";

/* [Finishing] */
$fn       = 180;
tolerance = 0.3;
edgeRoundness = wallThickness + 2.0;

// innerWidth  = 101;
// innerDepth  = 88;
// innerHeight = 20;
// topText     = "T50 9/16";
// bottomText  = "STAPLES";

// innerWidth  = 107.5;
// innerDepth  = 91;
// innerHeight = 15;
// topText     = "T50 5/16";
// bottomText  = "STAPLES";

//////////////////////////////////////////////////////////////////////////

/* [HIDDEN] */
width  = innerWidth + 2 * wallThickness;
depth  = innerDepth + 2 * wallThickness;
height = innerHeight;

innerBoxDimensions = [depth,width,height];

module add_outer_corners(x = 0, y = 0)
{
	translate([(innerBoxDimensions[0] - edgeRoundness * 2 + 0.1) * x,
               (innerBoxDimensions[1] - edgeRoundness * 2 + 0.1) * y,
               0] + [edgeRoundness, edgeRoundness, 0]
             )
    	cylinder(innerBoxDimensions[2] + wallThickness,
                 edgeRoundness,
                 edgeRoundness);
}

module add_inner_corners(x = 0, y = 0)
{
	translate(
                 [(innerBoxDimensions[0] - edgeRoundness * 2 + 0.1) * x,
                  (innerBoxDimensions[1] - edgeRoundness * 2 + 0.1) * y,
                  0] + [edgeRoundness, edgeRoundness, 0]
             )
	    cylinder(innerBoxDimensions[2],
                 edgeRoundness - wallThickness,
                 edgeRoundness - wallThickness);
}

module add_lid_corners(x = 0, y = 0)
{
	translate(
               [(innerBoxDimensions[0] - edgeRoundness * 2 - 0.1 +wallThickness) * x,
                (innerBoxDimensions[1] - edgeRoundness * 2 + 0.1) * y,
                0] + [edgeRoundness, edgeRoundness, 0]
             )
    	cylinder(wallThickness,
                 edgeRoundness - wallThickness + 1.5,
                 edgeRoundness - wallThickness + 0.5);
}

module lid(x = 0, y = 0)
{
    translate(
               [(innerBoxDimensions[0] - edgeRoundness * 2 - 0.1 + wallThickness - 2) * x,
                (innerBoxDimensions[1] - edgeRoundness * 2 + 0.1) * y,
                 0] + [edgeRoundness,edgeRoundness, 0]
             )
        cylinder(wallThickness,
                 edgeRoundness - wallThickness + 1.5 - tolerance,
                 edgeRoundness - wallThickness + 0.5 - tolerance);
}

module lid_label()
{
    color("cyan")
        translate([20, 5, 1])
            rotate([0, 0, 90])
            {
                translate([0, -10, 0])
                    linear_extrude(height = wallThickness - 1)
                        text(topText, size = 10);

                translate([0, -40, 0])
                    linear_extrude(height = wallThickness - 1)
                        text(bottomText, size = 10);
            }
}

module finger_pull()
{
    color("cyan")
        translate([depth - 20, width / 2, 10.5])
            rotate([0, 100, 0])
                cylinder(d = 15, h = 15);
}

module main()
{

    rotate([0, 0, 90])
    {
        // Shim so the lid stays in place
        color("blue")
            translate([depth - wallThickness, wallThickness, height])
                cube([wallThickness, width - 2 * wallThickness, 0.75]);

        // The box
        difference ()
        {
            hull()
            {
                add_outer_corners(0,0);
                add_outer_corners(1,0);
                add_outer_corners(0,1);
                add_outer_corners(1,1);
            }

            translate([0, 0, wallThickness])
                hull()
                {
                    add_inner_corners(0,0);
                    add_inner_corners(1,0);
                    add_inner_corners(0,1);
                    add_inner_corners(1,1);
                }

            translate([0, 0, innerBoxDimensions[2] + 0.1])
                hull()
                {
                    add_lid_corners(0,0);
                    add_lid_corners(1,0);
                    add_lid_corners(0,1);
                    add_lid_corners(1,1);
                }

            translate
            (
                [innerBoxDimensions[0] - wallThickness,
                 0,
                 innerBoxDimensions[2] + 0.1]
            )
                cube([wallThickness, innerBoxDimensions[1], wallThickness]);
        }
    }

    // The lid
    translate([0, depth, 0])
        rotate([0, 0, 90])
            difference ()
            {
                hull()
                {
                    lid(0,0);
                    lid(1,0);
                    lid(0,1);
                    lid(1,1);
                }

                lid_label();

                finger_pull();
            }
}

// Put it in the middle of the build plate
translate([depth, width / 2, 0])
    rotate([0, 0, 90])
        main();

```


[User]
Hey, I'm looking for an OpenSCAD design for a dustpan, and I'd like it to be fully parametric so I can adjust the size and shape to fit my needs. I've got a decent idea of the shape I want.

Basically, it should be a rectangular pan with a curved back. The back corners should be rounded with a radius, and the front should be a straight edge. I need to be able to control the overall width and length, the height at the closed end, and the height at the open end. I'd also like to control the radius of those rounded corners and the thickness of the walls and base, independently.

Additionally, I want a sloped section at the front edge, where the base gets thinner. I'd need to specify how long that sloped section is and how much the base thins out. Finally, a small, but critical feature is an option to inset the first layer of the print. I need to be able to control the inset width and height so that my first layer doesn’t bulge and cause issues printing. I should be able to enable or disable the inset feature.

I’d like it to be constructed using `hull()` operations to create the basic form of the dustpan. I'm not familiar with any specific OpenSCAD libraries for this design.

[Assistant]
dust_pan.scad:
```

$fn=64;

// Width at the opening, includes wall thickness.
width = 80;
// Length including wall thickness.
length = 90;
// Wall height at the closed end
height = 25;
// Wall height at the open end.
front_height = 10;
// Radius of the two corners at the closed end.
corner_radius=15;
// Wall thickness
wall_thickness = 2.5;
// Base thickness
base_thickness = 2.5;
// Reduced base thickness at the open end.
slope_height = 0.8;
// Length of base slope at the open end.
slope_length = 30;
// Inset first layer by this dimension (0 to disable). Helps prevnting
// 'elephant foot' syndrom.
first_layer_inset_width = 0.3;
// Height of first layer. Ignored if first_layer_inset_width is zero or negative.
first_layer_inset_height = 0.2;

eps1 = 0.01 + 0;  // hide on thingiverse customizer.
eps2 = 2*eps1;

// Operator to inset first layer to eliminate elephant foot.
// Children are assumed to be on the z=0 plane.
module inset_first_layer(w=0.4, h=0.2, eps=0.01) {
  if (w == 0 || h < 0) {
    children();
  } else {
    difference() {
      children();
      // TODO: use actual extended children projection instead
      // of a clube with arbitrary large x,y values.
      cube([200, 200, h], center=true);
    }
    linear_extrude(height=h+eps)
      offset(r = -w)
        projection(cut=true)
          children();
  }
}

module block() {
  hull() {
    translate([length-corner_radius, width/2-corner_radius, 0])
        cylinder(r=corner_radius, h=height);
    translate([length-corner_radius, -(width/2-corner_radius), 0])
        cylinder(r=corner_radius, h=height);

    translate([0, -width/2, 0]) cube([eps1, width, front_height]);
  }
}

module hollow() {
  w = width - 2*wall_thickness;
  l = length - wall_thickness;
  r = corner_radius - wall_thickness;

  hull() {
    translate([l-r, w/2-r, base_thickness])
        cylinder(r=r, h=height);
    translate([l-r, -(w/2-r), base_thickness])
        cylinder(r=r, h=height);
    translate([-eps1, -w/2, base_thickness]) cube([eps1, w, height]);
  }
}

module slope() {
  w = width - 2*wall_thickness;
  hull() {
    translate([-eps1, -w/2, slope_height])
        cube([eps1, w, height]);
    translate([slope_length-eps1, -w/2, base_thickness+eps1])
        cube([eps1, w, height]);
  }
}

module main() {
  inset_first_layer(first_layer_inset_width, first_layer_inset_height) {
    difference() {
      block();
      hollow();
      slope();
    }
  }
}

main();

```


[User]
I'd like to create a maze that's projected onto a sphere using stereographic projection. I've seen some examples of this before, and it looks really cool. I want to be able to adjust several things, like the number of rows in the maze, the width of each block in the maze's shadow (before projection), the width of the walls, and the height of the walls. I'd also like an option to generate a 2D "shadow" of the maze on the XY-plane, sort of as a base, underneath the 3D projected version. Finally, I need a parameter for the number of steps used to create the smooth surface when generating the sphere projection.

Here are the key parameters I need to control:

*   `maze_rows`: The number of rows (and columns, since it's a square) in the maze.
*   `block_width`: The width of each square block in the 2D shadow of the maze.
*   `wall_width`: The thickness of the walls of the maze.
*   `wall_height`: The height of the maze walls.
*   `shadow`:  A "YES" or "NO" option to generate the 2D maze shadow.
*   `line_steps`: How many steps to use when generating the curved walls on the sphere. More steps will create a smoother surface.

The maze generation should be recursive using a depth-first search algorithm. Every block should start with both a top and right wall, and then we should carve passages by removing these walls until the maze is complete. I also need functions for performing the stereographic projection from Cartesian coordinates to polar coordinates to spherical coordinates and then back to Cartesian coordinates, all using math based on the code I found.

Could you generate an OpenSCAD file (or files, if that makes more sense) that does all of this? I don't think I need any external libraries for this project. Let me know if you have any questions.

[Assistant]
stereographic_projection_maze.scad:
```
maze_rows = 5;
block_width = 40;
wall_width = 20;
wall_height = 2.5;
shadow = "YES"; //[YES, NO]
line_steps = 8;

/* [Hidden] */

NO_WALL = 0;
UPPER_WALL = 1;
RIGHT_WALL = 2;
UPPER_RIGHT_WALL = 3;

function cartesian_to_polar(xy) =
    [
        sqrt(xy[0] * xy[0] + xy[1] * xy[1]),
        atan2(xy[1], xy[0])
    ];

function spherical_to_cartesian(r_theta_phi) =
    [
        r_theta_phi[0] * cos(r_theta_phi[2]) * cos(r_theta_phi[1]),
        r_theta_phi[0] * cos(r_theta_phi[2]) * sin(r_theta_phi[1]),
        r_theta_phi[0] * sin(r_theta_phi[2])
    ];

function stereographic_projection_polar_to_spherical(r, polar) =
    [
        2 * r * sin(atan2(polar[0], (r * 2))),
        polar[1],
        atan2(polar[0], (r * 2))
    ];

function stereographic_projection_xy_to_xyz(r, xy) =
    spherical_to_cartesian(
        stereographic_projection_polar_to_spherical(
            r, cartesian_to_polar(xy)
        )
    );

function cube_line_pts(xs, ys, height) = concat(
    [for(i = [0:3]) [xs[i], ys[i], 0]],
    [for(i = [0:3]) [xs[i], ys[i], height]]
);

function horizontal_line_pts(p, length, width, height, offset) =
    cube_line_pts(
        [
            p[0], p[0] + length,
            p[0] + length, p[0]
        ],
        [
            p[1] - offset, p[1] - offset, p[1] - offset + width ,
            p[1] - offset + width
        ],
        height
    );

function vertical_line_pts(p, length, width, height, offset) =
    cube_line_pts(
        [
            p[0] - offset, p[0] - offset + width ,
            p[0] - offset + width, p[0] - offset
        ],
        [
            p[1], p[1], p[1] + length,
            p[1] + length
        ],
        height
    );

function block_data(x, y, wall_type, visited) = [x, y, wall_type, visited];
function get_x(block_data) = block_data[0];
function get_y(block_data) = block_data[1];
function get_wall_type(block_data) = block_data[2];

// create a starting maze for being visited later.
function starting_maze(rows, columns) =  [
    for(y = [1:rows])
        for(x = [1:columns])
            block_data(
                x, y,
                // all blocks have upper and right walls except the exit
                UPPER_RIGHT_WALL,
                // unvisited
                false
            )
];

// find out the index of a block with the position (x, y)
function indexOf(x, y, maze, i = 0) =
    i > len(maze) ? -1 : (
        [get_x(maze[i]), get_y(maze[i])] == [x, y] ? i :
            indexOf(x, y, maze, i + 1)
    );

// is (x, y) visited?
function visited(x, y, maze) = maze[indexOf(x, y, maze)][3];

// is (x, y) visitable?
function visitable(x, y, maze, rows, columns) =
    y > 0 && y <= rows &&     // y bound
    x > 0 && x <= columns &&  // x bound
    !visited(x, y, maze);     // unvisited

// setting (x, y) as being visited
function set_visited(x, y, maze) = [
    for(b = maze)
        [x, y] == [get_x(b), get_y(b)] ?
            [x, y, get_wall_type(b), true] : b
];

// 0（right）、1（upper）、2（left）、3（down）
function rand_dirs() =
    [
        [0, 1, 2, 3],
        [0, 1, 3, 2],
        [0, 2, 1, 3],
        [0, 2, 3, 1],
        [0, 3, 1, 2],
        [0, 3, 2, 1],
        [1, 0, 2, 3],
        [1, 0, 3, 2],
        [1, 2, 0, 3],
        [1, 2, 3, 0],
        [1, 3, 0, 2],
        [1, 3, 2, 0],
        [2, 0, 1, 3],
        [2, 0, 3, 1],
        [2, 1, 0, 3],
        [2, 1, 3, 0],
        [2, 3, 0, 1],
        [2, 3, 1, 0],
        [3, 0, 1, 2],
        [3, 0, 2, 1],
        [3, 1, 0, 2],
        [3, 1, 2, 0],
        [3, 2, 0, 1],
        [3, 2, 1, 0]
    ][round(rands(0, 24, 1)[0])];

// get x value by dir
function next_x(x, dir) = x + [1, 0, -1, 0][dir];
// get y value by dir
function next_y(y, dir) = y + [0, 1, 0, -1][dir];

// go right and carve the right wall
function go_right_from(x, y, maze) = [
    for(b = maze) [get_x(b), get_y(b)] == [x, y] ? (
        get_wall_type(b) == UPPER_RIGHT_WALL ?
            [x, y, UPPER_WALL, visited(x, y, maze)] :
            [x, y, NO_WALL, visited(x, y, maze)]

    ) : b
];

// go up and carve the upper wall
function go_up_from(x, y, maze) = [
    for(b = maze) [get_x(b), get_y(b)] == [x, y] ? (
        get_wall_type(b) == UPPER_RIGHT_WALL ?
            [x, y, RIGHT_WALL, visited(x, y, maze)] :
            [x, y, NO_WALL, visited(x, y, maze)]

    ) : b
];

// go left and carve the right wall of the left block
function go_left_from(x, y, maze) = [
    for(b = maze) [get_x(b), get_y(b)] == [x - 1, y] ? (
        get_wall_type(b) == UPPER_RIGHT_WALL ?
            [x - 1, y, UPPER_WALL, visited(x - 1, y, maze)] :
            [x - 1, y, NO_WALL, visited(x - 1, y, maze)]
    ) : b
];

// go down and carve the upper wall of the down block
function go_down_from(x, y, maze) = [
    for(b = maze) [get_x(b), get_y(b)] == [x, y - 1] ? (
        get_wall_type(b) == UPPER_RIGHT_WALL ?
            [x, y - 1, RIGHT_WALL, visited(x, y - 1, maze)] :
            [x, y - 1, NO_WALL, visited(x, y - 1, maze)]
    ) : b
];

// 0（right）、1（upper）、2（left）、3（down）
function try_block(dir, x, y, maze, rows, columns) =
    dir == 0 ? go_right_from(x, y, maze) : (
        dir == 1 ? go_up_from(x, y, maze) : (
            dir == 2 ? go_left_from(x, y, maze) :
                 go_down_from(x, y, maze)   // 這時 dir 一定是 3

        )
    );

// find out visitable dirs from (x, y)
function visitable_dirs_from(x, y, maze, rows, columns) = [
    for(dir = [0, 1, 2, 3])
        if(visitable(next_x(x, dir), next_y(y, dir), maze, maze_rows, columns))
            dir
];

// go maze from (x, y)
function go_maze(x, y, maze, rows, columns) =
    //  have visitable dirs?
    len(visitable_dirs_from(x, y, maze, rows, columns)) == 0 ?
        set_visited(x, y, maze)      // road closed
        : walk_around_from(
            x, y,
            rand_dirs(),
            set_visited(x, y, maze),
            rows, columns
        );

// try four directions
function walk_around_from(x, y, dirs, maze, rows, columns, i = 4) =
    // all done?
    i > 0 ?
        // not yet
        walk_around_from(x, y, dirs,
            // try one direction
            try_routes_from(x, y, dirs[4 - i], maze, rows, columns),
            , rows, columns,
            i - 1)
        : maze;

function try_routes_from(x, y, dir, maze, rows, columns) =
    // is the dir visitable?
    visitable(next_x(x, dir), next_y(y, dir), maze, rows, columns) ?
        // try the block
        go_maze(
            next_x(x, dir), next_y(y, dir),
            try_block(dir, x, y, maze, rows, columns),
            rows, columns
        )
        // road closed so return maze directly
        : maze;

module draw_block(wall_type, block_width, wall_thickness, wall_height, line_steps) {

    cubefaces = [
      [0,1,2,3],
      [4,5,1,0],
      [7,6,5,4],
      [5,6,2,1],
      [6,7,3,2],
      [7,4,0,3]
    ];

    leng = (block_width + wall_thickness) / line_steps;

    function upper_wall_pts_lt(hpts) = [
        for(i = [0:line_steps - 1]) [
            for(hp = hpts) hp + [leng * i, 0, 0]
        ]
    ];

    function right_wall_pts_lt(vpts) = [
        for(i = [0:line_steps - 1]) [
            for(vp = vpts) vp + [0, leng * i, 0]
        ]
    ];

    if(wall_type == UPPER_WALL || wall_type == UPPER_RIGHT_WALL) {
        // draw a upper wall
        hpts = horizontal_line_pts(
        [-wall_thickness / 2, block_width], leng, wall_thickness, wall_height, wall_thickness / 2);

        for(i = [0:line_steps - 1]) {
            polyhedron([
                for(hp = hpts) hp + [leng * i, 0, 0]
            ], cubefaces);
        }

    }

    if(wall_type == RIGHT_WALL || wall_type == UPPER_RIGHT_WALL) {
        // draw a right wall
        vpts = vertical_line_pts(
        [block_width, -wall_thickness / 2], leng, wall_thickness, wall_height, wall_thickness / 2);

        for(i = [0:line_steps - 1]) {
            polyhedron([
                for(vp = vpts) vp + [0, leng * i, 0]
            ], cubefaces);
        }
    }
}

module draw_stereographic_projection_block(sphere_r, tranlt_pt, wall_type, block_width, wall_thickness, wall_height, line_steps) {
    cubefaces = [
      [0,1,2,3],
      [4,5,1,0],
      [7,6,5,4],
      [5,6,2,1],
      [6,7,3,2],
      [7,4,0,3]
    ];

     leng = (block_width + wall_thickness) / line_steps;

    face_offset = 0.1;

    if(wall_type == UPPER_WALL || wall_type == UPPER_RIGHT_WALL) {
        hpts = horizontal_line_pts(
        [-wall_thickness / 2, block_width], leng, wall_thickness, wall_height, wall_thickness / 2);

        for(i = [0:line_steps - 1]) {
            inner1 = [
                for(j = [0:3])
                    stereographic_projection_xy_to_xyz(sphere_r - wall_height, hpts[j] + [leng * i, 0, 0] + tranlt_pt) +
                    [0, 0, wall_height]
            ];
            inner2 = [
                for(j = [0:3])
                    stereographic_projection_xy_to_xyz(sphere_r - wall_height + face_offset, hpts[j] + [leng * i, 0, 0] + tranlt_pt) +
                    [0, 0, wall_height]
            ];

            outer1 = [for(j = [0:3]) stereographic_projection_xy_to_xyz(sphere_r - face_offset, hpts[j] + [leng * i, 0, 0] + tranlt_pt)];
            outer2 = [for(j = [0:3]) stereographic_projection_xy_to_xyz(sphere_r, hpts[j] + [leng * i, 0, 0] + tranlt_pt)];

            hull() {
                polyhedron(concat(inner2, inner1), cubefaces);
                polyhedron(concat(outer2, outer1), cubefaces);
            }
        }
    }

    if(wall_type == RIGHT_WALL || wall_type == UPPER_RIGHT_WALL) {
        vpts = vertical_line_pts(
        [block_width, -wall_thickness / 2], leng, wall_thickness, wall_height, wall_thickness / 2);

        for(i = [0:line_steps - 1]) {
            inner1 = [
                for(j = [0:3])
                    stereographic_projection_xy_to_xyz(sphere_r - wall_height, vpts[j] + [0, leng * i, 0] + tranlt_pt) +
                    [0, 0, wall_height]
            ];

            inner2 = [
                for(j = [0:3])
                    stereographic_projection_xy_to_xyz(sphere_r - wall_height + face_offset, vpts[j] + [0, leng * i, 0] + tranlt_pt) +
                    [0, 0, wall_height]
            ];

            outer1 = [for(j = [0:3]) stereographic_projection_xy_to_xyz(sphere_r - face_offset, vpts[j] + [0, leng * i, 0] + tranlt_pt)];
            outer2 = [for(j = [0:3]) stereographic_projection_xy_to_xyz(sphere_r, vpts[j] + [0, leng * i, 0] + tranlt_pt)];

            hull() {
                polyhedron(concat(inner2, inner1), cubefaces);
                polyhedron(concat(outer2, outer1), cubefaces);
            }
        }
    }
}

module draw_stereographic_projection_maze(rows, columns, blocks, block_width, wall_thickness, wall_height, line_steps) {
    sphere_r = block_width * rows / 6;
    for(block = blocks) {
        draw_stereographic_projection_block(
            sphere_r,
            [get_x(block) - 1 - columns / 2, get_y(block) - 1 - rows / 2, 0] * block_width,
            get_wall_type(block),
            block_width,
            wall_thickness,
            wall_height,
            line_steps
        );
    }
}

module draw_maze(rows, columns, blocks, block_width, wall_thickness, wall_height, line_steps) {

    for(block = blocks) {
        // move a block to a right position.
        translate([get_x(block) - 1 - columns / 2, get_y(block) - 1 - rows / 2] * block_width)
            draw_block(
                get_wall_type(block),
                block_width,
                wall_thickness,
                wall_height,
                line_steps
            );
    }
}

// create a starting maze for being visited later.
function starting_maze(rows, columns) =  [
    for(y = [1:rows])
        for(x = [1:columns])
            block_data(
                x, y,
                UPPER_RIGHT_WALL,
                false
            )
];

function append_left_down_walls(rows, columns, blocks) = concat(
        concat(
            blocks,
            [for(r = [1:rows]) block_data(0, r, RIGHT_WALL, true)]
        ),
        [for(c = [1:columns]) block_data(c, 0, UPPER_WALL, true)]
    );

module main() {
    maze_blocks = append_left_down_walls(maze_rows, maze_rows, go_maze(
        1, 1,
        starting_maze(maze_rows, maze_rows),
        maze_rows, maze_rows
    ));

    draw_stereographic_projection_maze(
        maze_rows,
        maze_rows,
        maze_blocks,
        block_width,
        wall_width,
        wall_height,
        line_steps
    );

    if(shadow == "YES") {
        color("black") draw_maze(
            maze_rows,
            maze_rows,
            maze_blocks,
            block_width,
            wall_width,
            wall_height,
            1
        );
    }
}

main();
```


[User]
I need a parametric OpenSCAD design for an oiler nozzle cap. The cap should have three main sections, with a small cap on top. The bottom section should be a cylinder that fits over the nozzle of the oiler bottle and is the longest section. The middle section connects the bottom to the top, acting as a short transition piece. Finally, the top section is designed to hold a rubber band and has a cut-out to allow the band to be attached. The top also has a small "cap" on top of the middle section, where the top section and middle section join.

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

*   `wallThickness`: The thickness of the walls of all cylindrical parts.
*   `topDiameter`: The inner diameter of the top section (where the rubber band sits).
*   `topHeight`: The height of the top section.
*   `middleDiameter`: The inner diameter of the middle section.
*   `middleHeight`: The height of the middle section.
*   `bottomDiameter`: The inner diameter of the bottom section.
*   `bottomHeight`: The height of the bottom section.
*   `capHeight`: The height of the small cap that sits on top of the middle section

I'd like the top section to have a rectangular cutout on the side for the rubber band to pass through. The cut-out should be centered, extending from the bottom of the top cylinder to the top. The cap should be a short cylinder placed on the middle section and will visually blend with the top section.

The bottom section should be a cylinder at the bottom, followed by a middle section that transitions to the top. The top section should be the narrowest cylinder with a cut-out for the rubber band.

For aesthetic purposes, I'd like to assign two colors to different parts. The main sections (top and middle) should be DodgerBlue (`[0.117, 0.565, 1]`) and the small cap and the bottom section should be a lighter shade of DodgerBlue (`[0.384, 0.726, 1]`). Please use the standard `$fa`, `$fs`, and `delta` variables as well for smooth curves and boolean operations, setting them to 0.3, 0.3, and 0.1, respectively.

I don't think this requires any extra libraries, but I'll leave that to your judgment.

[Assistant]
Oiler_cap.scad:
```
// Oiler nozzle cap with rubber band
// by György Balássy 2016 (http://gyorgybalassy.wordpress.com)
// http://www.thingiverse.com/thing:2014720

// The thickness of the wall in mm.
wallThickness = 2;

// The inner diameter of the top, rubber band holder section (dark blue) in mm.
topDiameter = 3.5;

// The height of the top, rubber band holder section (dark blue) in mm.
topHeight = 5;

// The inner diameter of the central section (dark blue) in mm.
middleDiameter = 3.5;

// The height of the central section (dark blue) in mm.
middleHeight = 3;

// The inner diameter of the bottom section (light blue) in mm.
bottomDiameter = 6.5;

// The height of the bottom section (light blue) in mm.
bottomHeight = 20;

/* [Hidden] */

capHeight = wallThickness;

mainColor = [0.117, 0.565, 1];      // DodgerBlue: RGB(30, 144, 255)
highlightColor = [0.384, 0.726, 1]; // Lighter DodgerBlue: RGB(98, 185, 255)

$fa = 0.3;     // Default minimum facet angle.
$fs = 0.3;     // Default minimum facet size.
delta = 0.1;   // Ensures that no faces remains after boolean operations.

// Top section.
color(mainColor) {
  difference() {
    translate([0, 0, middleHeight + capHeight])
      cylinder(d1 = topDiameter + 2 * wallThickness, d2 = topDiameter + 2 * wallThickness, h = topHeight);

    translate([-(topDiameter + 2 * wallThickness) / 3 / 2, -(topDiameter + 2 * wallThickness) / 2, middleHeight + wallThickness - delta])
      cube([(topDiameter + 2 * wallThickness) / 3, topDiameter + 2 * wallThickness + 2 * delta, topHeight + 2 * delta]);
  }
}

// Cap.
color(highlightColor) {
  translate([0, 0, middleHeight])
    cylinder(d1 = middleDiameter + 2 * wallThickness, d2 = topDiameter + 2 * wallThickness, h = capHeight);
}

// Middle section.
color(mainColor) {
  tube(middleDiameter, topDiameter, wallThickness, middleHeight);
}

// Bottom section.
color(highlightColor) {
  translate([0, 0, -bottomHeight])
    tube(bottomDiameter, middleDiameter, wallThickness, bottomHeight);
}

module tube(bottomInnerDiameter, topInnerDiameter, wallThickness, height) {
  difference() {
    cylinder(d1 = bottomInnerDiameter + 2 * wallThickness, d2 = topInnerDiameter + 2 * wallThickness, h = height);  // Outer
    translate([0, 0, -delta])
      cylinder(d1 = bottomInnerDiameter, d2 = topInnerDiameter, h = height + 2 * delta);  // Inner
  }
}
```


[User]
Hey, I need some OpenSCAD files for a shoe rack bracket, and I've got a specific design in mind based on some existing ones I found online. I need a parametric design that uses standard 1/2" EMT pipe, which is about 18.27mm in diameter, as the rack itself, instead of a 10mm rod. I've also got some specific needs for door jamb clearance.

Basically, I need two versions: a standard bracket and a tapered bracket.

**Here's what I need for both versions, which should be parameterized:**

*   **Lw:** Distance from the wall to the center of the pipe. (This should be 82mm as the default).
*   **Dt:** Diameter of the EMT pipe (18.27mm by default).
*   **DtH:** Height that the bracket covers the pipe (this will be 16mm for tapered and 10mm for the standard).
*   **WL:** Length of the mounting plank (50mm).
*   **WH:** Thickness of the mounting plank (10mm).
*   **HH:** The overall height of the main body, which is DtH + 2 (so DtH is a base parameter for HH).

The design will have a main body shaped like a rounded rectangle that wraps around a pipe with the specified diameter. This main body will have two mounting holes on the wall side. I'd prefer you to use hulling to create the rounded rectangle shape for the main bracket, and use `shHole()` like in the example for creating the mounting holes (I'm not going to be using the specific code I'm including as an example other than as a reference for function names).

**Standard Bracket specifics:**
*   `taperLength` should be 0.
*   `taperAngle` should also be 0.

**Tapered Bracket specifics:**

*   `taperLength` will be 15mm, to account for door jamb clearance.
*   The bracket should be rotated 9 degrees on the Y axis, so the bracket tapers away from the wall at an angle of 9 degrees. Also, include a "cutting" cube at the end to remove the part that hangs in the negative X space.

Also, there are `dOkr` circle cutouts.  It should be 30 by default, but paramatrizable.

For both versions, use a `cutout()` module to make the cutouts for the pipe shape. I'd also prefer you to use mirroring to produce the mirrored cutouts and mirrored mounting holes on both sides, instead of recreating the shapes twice for each side. Use a `shHole` module for generating the mounting holes.

The final files should be parametric so that all of these values can be easily adjusted. I do not want to use modules unless they are absolutely necessary. I think that should cover everything!

[Assistant]
polka2-82mm.scad:
```
$fn=120;
Lw=82; //расстояние от стены
Dt=18.27; //диаметр трубки
DtH=10; //высота охвата трубки
WL=50;//длина планки
WH=10;//толщина планки
HH=DtH+2;
taperLength=0; //to clear door jam when used on indoor closet since brackets must be installed on edge of hollow door
    dOkr=30;
taperAngle=0;

module shHole(diam){
    cylinder(d=diam,h=40);
        cylinder(d1=diam+4,d2=diam,h=3);
        translate([0,0,-80])cylinder(d=diam+4,h=80);
}

module cutout () {
    hull(){
        translate([-10,(Dt+6)/2+dOkr/2,0])cylinder(d=dOkr,h=HH+0.02+taperLength);
        translate([Lw-WH-dOkr/2,(Dt+6)/2+dOkr/2,-0.01])cylinder(d=dOkr,h=HH+0.02+taperLength);
        translate([Lw-WH-dOkr/2,(Dt+6)/2+dOkr/2+50,-0.01])cylinder(d=dOkr,h=HH+0.02+taperLength);

    }
}

rotate([0,taperAngle,0]) {
difference(){
    hull(){
        cylinder(d=Dt+3*2,h=HH);
        scale([1,1,1])translate([Lw,-WL/2,0])cube([0.01,WL,HH+taperLength]);
    }
    cylinder(d=Dt,h=DtH);
    translate([Lw-7,WL/4+3,taperLength+HH/2])rotate([90,0,90-10]){
        shHole(4);
    }

    mirror([0,1,0])translate([Lw-5,WL/4+3,taperLength+HH/2])rotate([90,0,90-10]){
        shHole(4);
    }

    cutout();
    mirror([0,1,0]) cutout();
    //translate([-(4+18.27/2),-50,-(DtH+taperLength)+2])rotate([0,-taperAngle,0])cube([2*Lw,100,DtH+taperLength]);
    //translate([-(4+18.27/2),-50,DtH])rotate([0,-taperAngle,0])cube([2*Lw,100,DtH+taperLength]);
}
}
```
polka2-82mm-tapered.scad:
```
$fn=120;
Lw=82; //расстояние от стены
Dt=18.27; //диаметр трубки
DtH=16; //высота охвата трубки
WL=50;//длина планки
WH=10;//толщина планки
HH=DtH+2;
taperLength=15; //to clear door jam when used on indoor closet since brackets must be installed on edge of hollow door
    dOkr=30;

module shHole(diam){
    cylinder(d=diam,h=40);
        cylinder(d1=diam+4,d2=diam,h=3);
        translate([0,0,-80])cylinder(d=diam+4,h=80);
}

module cutout () {
    hull(){
        translate([-10,(Dt+6)/2+dOkr/2,0])cylinder(d=dOkr,h=HH+0.02+taperLength);
        translate([Lw-WH-dOkr/2,(Dt+6)/2+dOkr/2,-0.01])cylinder(d=dOkr,h=HH+0.02+taperLength);
        translate([Lw-WH-dOkr/2,(Dt+6)/2+dOkr/2+50,-0.01])cylinder(d=dOkr,h=HH+0.02+taperLength);

    }
}

rotate([0,9,0]) {
difference(){
    hull(){
        cylinder(d=Dt+3*2,h=HH);
        scale([1,1,1])translate([Lw,-WL/2,0])cube([0.01,WL,HH+taperLength]);
    }
    cylinder(d=Dt,h=DtH);
    translate([Lw-7,WL/4+3,taperLength+HH/2])rotate([90,0,90-10]){
        shHole(4);
    }

    mirror([0,1,0])translate([Lw-5,WL/4+3,taperLength+HH/2])rotate([90,0,90-10]){
        shHole(4);
    }

    cutout();
    mirror([0,1,0]) cutout();
    translate([-(4+18.27/2),-50,-(DtH+taperLength)+2])rotate([0,-9,0])cube([2*Lw,100,DtH+taperLength]);
    translate([-(4+18.27/2),-50,DtH])rotate([0,-9,0])cube([2*Lw,100,DtH+taperLength]);
}
}
```


[User]
Okay, I'm looking to design an eccentric pipe reducer for 3D printing, similar to the one I saw on Thingiverse. I need a parametric OpenSCAD design that lets me specify the dimensions of both the lower and upper pipes, as well as the transition piece between them.

Specifically, I'd like to define the following:

*   **Lower Pipe:**
    *   Inner diameter
    *   Height
    *   Wall thickness
*   **Upper Pipe:**
    *   Inner diameter
    *   Height
    *   Wall thickness
*   **Transition Piece:**
    *   Height (the gap between the two pipes)
    *   Offset: I need to be able to offset the upper pipe's center relative to the lower pipe's center.
        *   Angle: A rotation angle to specify the offset direction in degrees (0 being along the +X axis, 90 being +Y, and so on).
        *   Offset Ratio: A percentage value (0-100%) that scales the amount of offset, where 0% means concentric, and 100% means the outer or inner walls of the two pipes will be parallel (depending on another parameter, see below).
    *   Wall Preference: An option to choose whether to make the inner walls or outer walls parallel between the two pipes. If the offset is significant, the other wall will have a step where the upper and lower sections connect, so this is about the preferred inner/outer profile and which will be parallel across the transition.
*   **Resolution:** A parameter to control the number of segments used to create the pipe cylinders. I'd like to be able to switch between low, medium, and high resolution options (using a named enum or similar approach is fine).

I imagine the code would involve calculating the offset of the upper pipe's center based on the angle and ratio parameters. Also, some kind of loop would be needed to generate the sides of the transition piece using polygons to fill the space between the upper and lower pipes.

The code should create the lower pipe, the upper pipe, and the transition as separate objects or parts of an object. Color should be applied to make them easier to distinguish visually in the preview.

I don't need any specific additional features or special shapes in the reducer; the basic eccentric pipe reducer is all I need. Can you help with that?

I'm not sure what libraries would be appropriate but if any of the standard ones apply I'd appreciate it, perhaps MCAD, BOSL, or BOSL2?

[Assistant]
Customizer_reducer.scad:
```
// eccentric pipe reducer
// by MisterC

// input parameters

/* lower pipe */
// lower pipe inner diameter
lower_diameter = 32; // min/max:[1:100]
// lower pipe height
lower_height = 20; // min/max:[1:100]
// lower pipe wall
lower_wall = 4; // min/max:[0.5:0.5:10]

/* transition piece */
// gap between lower and upper pipes
trans_height = 20; // min/max:[5:50]

// offset of reducer:
trans_angle = 0; // min/max:[0:360]
// angle (0=+X,90=+Y etc)
// ratio to cl
trans_ratio = 100; // min/max:[0:100]
// 0 ratio is concentric
// 100 ratio is wall parallel

// should inside walls run through?
in_parallel = true; // [true,false]
// true if inner wall would be parallel, false if outer

// resolution of reducer
segments = 36; //[36:Low, 90:Medium, 180:High]

/* upper pipe */
// upper pipe inner diameter
upper_diameter = 12; // min/max:[1:100]
// upper pipe height
upper_height = 20; // min/max:[1:100]
// upper pipe wall
upper_wall = 2; // min/max:[0.5:0.5:10]

// calculated values
/* [Hidden]*/
ang = 360 / segments; // degrees per segment
$fn = segments; // make the pipes as accurate as the transition
fudge = 1; // fudge for cuts

// heights
lower_btm = 0;
lower_top = lower_btm + lower_height;
upper_btm = lower_top + trans_height;
upper_top = upper_btm + upper_height;

// pipe radii
lower_in = lower_diameter / 2;
lower_out = lower_in + lower_wall;
upper_in = upper_diameter / 2;
upper_out = upper_in + upper_wall;

// if parallel_check is inners (in_parallel is true) then centre_offset is inners else outers
// using SCAD's conditional syntax
ctr_off = in_parallel
    ? (lower_in - upper_in)
    : (lower_out - upper_out);

// now work out where the upper pipe centre is
x_offset = cos(trans_angle) * ctr_off * trans_ratio / 100;
y_offset = sin(trans_angle) * ctr_off * trans_ratio / 100;

// modules and functions
// cos_fill & sin_fill create a list of x&y co-ordinates using a loop structure copied from Mathgrrl's snowflakerator sequence generators
function cos_fill(distance, switch)
    = [for(step=[0:segments])
        distance*cos(ang*step) + x_offset*switch];

function sin_fill(distance, switch)
    = [for(step=[0:segments])
        distance*sin(ang*step) + y_offset*switch];

// lots of co-ordinate calcs
lower_Ox=cos_fill(lower_out,0);
lower_Oy=sin_fill(lower_out,0);

upper_Ox=cos_fill(upper_out,1);
upper_Oy=sin_fill(upper_out,1);

lower_Ix=cos_fill(lower_in,0);
lower_Iy=sin_fill(lower_in,0);

upper_Ix=cos_fill(upper_in,1);
upper_Iy=sin_fill(upper_in,1);

// and now to business
color ("green")
difference()    // lower pipe
{
    translate([0,0,lower_btm])
        cylinder(r=lower_out, h=lower_height);
    translate([0,0,lower_btm-fudge])
        cylinder(r=lower_in, h=lower_height+(2*fudge));
}
color ("red")
difference()    // upper pipe
{
    translate([x_offset,y_offset,upper_btm])
        cylinder(r=upper_out, h=upper_height);
    translate([x_offset,y_offset,upper_btm-fudge])
        cylinder(r=upper_in, h=upper_height+(2*fudge));
}
// 'cubes' (really trapezoidal blocks) for reducer using polyhedron command as per OpenSCAD wiki example 1 by Bruno Bronosky
color ("blue")
for (step=[1:segments])
{
    polyhedron(points = [
        [lower_Ox[step-1],lower_Oy[step-1],lower_top],
        [lower_Ox[step],lower_Oy[step],lower_top],
        [lower_Ix[step],lower_Iy[step],lower_top],
        [lower_Ix[step-1],lower_Iy[step-1],lower_top],
        [upper_Ox[step-1],upper_Oy[step-1],upper_btm],
        [upper_Ox[step],upper_Oy[step],upper_btm],
        [upper_Ix[step],upper_Iy[step],upper_btm],
        [upper_Ix[step-1],upper_Iy[step-1],upper_btm]
        ], faces = [
        [0,1,2,3],[4,5,1,0],[7,6,5,4],
        [5,6,2,1],[6,7,3,2],[7,4,0,3]]);
}
```


[User]
Hey, I'm looking to create a customizable box with text debossed on the lid. I've got a basic idea, but I'd like a parametric OpenSCAD design to make it flexible.

Here's what I need:

*   **Box Dimensions:** I want to be able to control the internal X and Y dimensions of the box, as well as the external wall thickness. Let's call them `intX`, `intY`, and `extWall`, respectively.

*   **Text:** The text should be debossed onto the lid in a grid-like pattern. I'd like to specify the text using a 2D array, like `[["text1", "text2"], ["text3", "text4"]]`, where each inner array represents a row of text on the lid.

*   **Text Size:** The size of the text should be a percentage of the height of a single row in the grid.  For example, if I set the text size to 50%, the text would be half the height of one grid row. I need a parameter for this, maybe called `textSize` in the range 1-100.

*   **Debossing:** The text should be debossed (cut into the lid), to a depth equal to the wall thickness of the box (`extWall`).

*   **Flexibility:** I need a parameter for rotating the whole grid of text by multiples of 90 degrees (0, 1, 2, or 3). Let's call this `rot` (defaulting to 0).

I'm thinking something like the provided sample file, but I'd like the AI to generate it from scratch.  I don't need any specific libraries like MCAD or BOSL for this, just the base OpenSCAD functionality, if that's possible. Can you help me with that?

[Assistant]
sample.scad:
```
/* [Box Dimensions] */
//internal X Dimension
intX = 45;
//internal Y Dimension
intY = 50;
extWall = 2;

/* [Text] */
//2 dimensional array for text on lid in the format [["abc", "qrs"], ["xyz", "123"]]
strings = [["AM1", "AM2"], ["PM1", "PM2"]];
//height of text as percentage of one row height
textSize = 45; //[1:100]

module deboss(strings = [["a", "b", "c"], ["1", "2", "3"]], rot = 0) {
  xTrans = (intX + 2*extWall)/len(strings[0]);
  yTrans = (intY + 2*extWall)/len(strings);
  textHeight = textSize/100 * yTrans;

  rotate([0, 0, 90 * rot])
  translate([(-xTrans*(len(strings[0])-1))/2, (yTrans*(len(strings)-1))/2, 0]){
    for (i = [0:len(strings)-1]) {
      for (j = [0:len(strings[i])-1]) {
        translate([xTrans*(j), yTrans*(-i), 0])
          linear_extrude(height = extWall) {
            text(strings[i][j], halign = "center", valign = "center", size = textHeight);
          }
      }
    }
  }
}
deboss(strings = strings);

```


[User]
Hey, I'm looking to design a little accessory for my Aeropress coffee maker, something that can hold the measuring spoon and the stirrer. I've seen some designs out there, but I want to create my own, and I think I'd like to do it with OpenSCAD.

Basically, the design needs to clip around the bottom of the Aeropress filter holder, and it should have two distinct holders coming off of it: one for a small spoon/scoop, and one for the stirrer.

Here are the specifics I'm thinking of:

*   **Filter Holder Clip:**
    *   The filter holder itself has a cylindrical body, about 70mm in diameter, and a bottom flange that's roughly 80mm across the flats of its hex shape and about 10mm thick. Let's call these `fh_od`, `fl_wd`, and `fh_ht`, respectively. We'll need a small clearance for the clip to snap on, plus a bit of wall thickness.
    *   The clip should be shaped to fit around a portion of the cylinder, extending downward to hold onto the flat part. It doesn't have to go all the way around, just enough to secure it.
*   **Spoon Holder:**
    *   The spoon handle is about 12mm in diameter, so we'll need a slightly bigger hole for it. Let's add a bit of slop, and the spoon handle is roughly 36mm tall which is how tall this holder should be. So `sp_od` and `sp_ht`.
    *   The spoon holder should be a rounded cylinder shape, positioned to the side of the filter holder clip.
*   **Stirrer Holder:**
    *   The stirrer is basically a flat stick, about 32mm wide and 5mm thick and the holder is the same height as the spoon holder. So `st_wd`, `st_th`, and `st_ht`.
    *   The stirrer holder should be a simple clip that extends from the filter holder section.

*   **Wall Thickness:**
    *   Let's make the overall wall thickness of the design `wl_th` around 1.3mm.

*   **General:**
    *   I want this to be parametric, so I can adjust the size later.
    *   I'd like to use `$fa = 3` to make the shapes a little smoother.

I'm imagining the final piece would kinda look like a bracket that hugs a portion of the filter holder, with the spoon and stirrer holders sort of sticking out to the sides.

Could you generate an OpenSCAD file (or files if that makes sense to organize it better) for this? I am very new to OpenSCAD.

[Assistant]
aeroholder.scad:
```
fh_od = 70; // filter holder OD (minus some for spring)
fh_ht = 10; // filter holder bottom flange thickness
fl_wd = 80; // filter holder bottom flange width (across flats)

sp_od = 12; // spoon handle OD + slop
sp_ht = 36; // height of spoon holder

st_wd = 32;  // stirrer width
st_th = 5;  // stirrer thickness
st_ht = sp_ht; // height of stirrer holder

wl_th = 1.3;  // wall thickness

$fa = 3;

module spoon_holder() {
    translate([0,0,sp_od/2+wl_th])
    difference() {
        hull() {
            union() {
                cylinder(d = sp_od + 2*wl_th, h=sp_ht-sp_od/2);
                sphere(d = sp_od + 2*wl_th);
            }
            translate([0,0,-sp_od/2-wl_th])
            children();
        }
        union() {
            cylinder(d = sp_od, h=sp_ht + 1);
            sphere(d = sp_od);
        }
    }
}

module filter_clip() {
    translate([-st_wd/2,0,0])
    difference() {
        hull() {
            cube([st_wd + 2*wl_th, st_th + 2*wl_th, st_ht + wl_th]);
            translate([st_wd/2,0,0])
            children();
        }

        translate([wl_th,wl_th,wl_th])
        cube([st_wd, st_th, st_ht+2*wl_th]);
    }

}

module filter_section(th0, th1) {
    rotate([0,0,th0])
    let(ht = sp_ht - fh_ht, x0 = fh_od/2, x1 = x0 + wl_th)
    {
        translate([0,0,fh_ht+wl_th])
        rotate_extrude(height=sp_ht - fh_ht, angle=th1-th0)
        polygon([[0, 0], [x1, 0], [x1, ht], [0, ht]]);
    }
}

module filter_holder() {
    filter_section(-120, 120);
}

module filter_ghost() {
    cylinder(d=fh_od, h=100);
    translate([0,0,-fh_ht])
    cylinder(d=fl_wd * 1.16, h=fh_ht, $fn=6);
}

module filter_hole() {
    cylinder(d=fh_od, h=100);
}

module main() {
difference() {
    union() {
        translate([0,fh_od/2,0])
        filter_clip() {
            translate([0,-fh_od/2,0])
            filter_section(60,120);
        }

        translate([0,-(fh_od+sp_od)/2-wl_th,0])
        spoon_holder() {
            translate([0,(fh_od+sp_od)/2+wl_th,0])
            filter_section(-110,-70);
        }
        filter_holder();
    }
    filter_hole();
}
}

if(0) {
main();
%filter_ghost();
}
else
rotate([180,0,0]) main();

```


[User]
I'm looking to design a parametric wall mount for an Xbox One Kinect, similar to the one I saw on Thingiverse but I want to make it a bit more robust and also customizable. I've got some specific dimensions and ideas in mind.

The basic design involves an adapter with two main parts: a vertical section that attaches to the Kinect and a horizontal section that attaches to the wall. I want these pieces to connect at a right angle. Then, there should be a support that angles down from the vertical piece to the horizontal piece to provide additional strength. This is all similar to the provided example, but I have some variations in mind.

Here's a breakdown of the parameters I need:

*   **Adapter Height:** This determines the vertical length of the adapter. Let's start with a default value of 91 mm, but this should be easily adjustable.
*   **Adapter Width:** The width of the adapter, starting at 28 mm.
*  **Adapter Length:** The horizontal part extending from the wall is two-thirds of the adapter height by default.
*   **Adapter Thickness:** The thickness of the adapter material, defaulting to 4 mm.
*   **Wall Mount Screw Diameter:** The diameter of the screw holes for mounting to the wall. Start with 7 mm.
*   **Wall Mount Screw Separation (X):** The horizontal spacing between the wall mount screw holes, relative to the adapter width. This should be some fraction of the adapter width, starting at 1/3.
*   **Wall Mount Screw Separation (Y):** The vertical spacing between the wall mount screw holes, relative to the adapter height. This should also be a fraction of the adapter height, starting at 1/4.
*   **Kinect Mount Screw Diameter:** The diameter of the hole for mounting the Kinect. Start at 10 mm.
*   **Support Cutout X:** The width of the cutout on the support piece, expressed as a percentage of the adapter width. I'd like it to be 65% by default.
*   **Support Cutout Y:** The height of the cutout on the support piece, also as a percentage, this time of the adapter height, start with 80%.
*   **Support Angle:** The angle of the support, relative to the horizontal piece.  Start with 45 degrees.
*   **Support Length:**  The length of the support itself, starting at 87 mm.

I'd like to be able to control all these values in the code, and I'd like to be able to preview the model in OpenSCAD to make sure everything is aligned as I expect. The existing code uses `cube` and `cylinder` and `difference` and `rotate` and `translate`, so hopefully you can work with those! I'm also expecting multiple modules for modularity. Let me know if you need any more information.

[Assistant]
customizable_xbox_one_kinect_mount.scad:
```
adapter_height=91;
adapter_width=28;
adapter_length=adapter_height*2/3;
adapter_thickness=4;
wall_mount_screw_diameter=7;
wall_mount_screw_separation_x=adapter_width/3;
wall_mount_screw_separation_y=adapter_height/4;
kinect_mount_screw_diameter=10;
support_cutout_x=0.65; //percentage of width
support_cutout_y=0.8; //percentage of height
support_angle=45;
support_length=87;

adapter_combined();

module adapter_combined(){
rotate([90,0,0]){adapter_height();};
adapter_width();
translate([0,adapter_length,adapter_thickness])
rotate([90+support_angle,0,0]){adapter_support();};
}

module adapter_height(){
    difference(){
    cube([adapter_width,adapter_height,adapter_thickness]);
        translate([adapter_width/2,adapter_height-adapter_width/2,-0.1])
        cylinder(d=kinect_mount_screw_diameter,h=adapter_thickness+0.2);
    }
}

module adapter_width(){
    difference(){
    cube([adapter_width,adapter_length,adapter_thickness]);

//    translate([adapter_width/2-wall_mount_screw_separation_x/2,adapter_width/3,-0.1])
//        cylinder(d=wall_mount_screw_diameter,h=adapter_thickness+0.2);
    translate([adapter_width/2+wall_mount_screw_separation_x/2,adapter_width/3,-0.1])
        cylinder(d=wall_mount_screw_diameter,h=adapter_thickness+0.2);

//    translate([adapter_width/2-wall_mount_screw_separation_x/2,adapter_width/2-wall_mount_screw_separation_y,-0.1])
//        cylinder(d=wall_mount_screw_diameter,h=adapter_thickness+0.2);
    translate([adapter_width/2-wall_mount_screw_separation_x/2,adapter_width/2+wall_mount_screw_separation_y,-0.1])
        cylinder(d=wall_mount_screw_diameter,h=adapter_thickness+0.2);
    }
}

module adapter_support(){
    difference(){
    cube([adapter_width,support_length,adapter_thickness]);
        translate([(adapter_width-adapter_width*support_cutout_x)/2,(adapter_height-adapter_height*support_cutout_y)/2,-0.1])
    cube([adapter_width*support_cutout_x,support_length*support_cutout_y,adapter_thickness+0.2]);
    }
}
```


[User]
Hey, I'm looking to generate a pulley design in OpenSCAD and I'd like to make it parametric. I've been playing around with some code, but I'd like something a bit cleaner and more robust.

The pulley needs to have three main parameters that I can control: the rope diameter, the pulley diameter, and the outer diameter of the bearings that will be used. I'd like the code to automatically adjust the minimum pulley diameter based on the rope and bearing diameters to ensure the rope fits properly. Essentially, there needs to be a bit of extra space based on both the rope and bearing diameters to ensure everything works smoothly.

The pulley itself should have a groove for the rope, and it should also include a space for the bearing. I think a revolve with a 2D profile is probably the best approach, but I'm not sure how to get all the fillets right.  I am aiming for something more than just basic squares cut out, I want to add some curves to make the final print look nice. I have tried a bunch of different methods but most of them look weird or don't work right. I'd like it to be a bit more organic.

Could you generate the necessary OpenSCAD code for this? I don't need to do anything special with modules; I think I only need a single file, but if multiple are needed, just let me know. I'm aiming for fairly standard pulley design with two sides, each mirrored and joined in the middle. No fancy features, just a robust and parametric pulley design. Could we also add a text label of the diameter values to a side of the pulley?

I'm not looking to use any libraries at the moment, so please don't include any external library dependencies. Thanks!

[Assistant]
pulley.scad:
```

//rope diameter
rd=10;//[5:20]

//pulley diameter
pd=80;//[40:200]

//Bearings outer diameter
bo=15;//[10:50]

/*[hidden]*/

wall_w=3;

rd2=rd+4;
bo2=bo+0.2;

minpd=(rd+bo+25);
pd2= minpd>pd?minpd:pd;
echo(pd2);

rad=1.5;

polygon=100;

module polley() {
    rotate_extrude(convexity = 10,$fn=polygon)
    translate([0,0,0])
    union(){
        //Fillet 1
        translate([bo2/2+5-rad,wall_w+rd2/2+1-rad])
        circle(r=rad, $fn=polygon);

        //Fillet 2
        difference(){
            translate([bo2/2+5,5])
            square(size = [rad,rad]);

            translate([bo2/2+5+rad,5+rad])
            circle(r=rad, $fn=polygon);
        }

        intersection(){
            difference(){
                union(){
                    translate([bo2/2,0])
                    square(size = [(pd2-wall_w-bo2)/2,wall_w+rd2/2]);

                    translate([pd2/2-wall_w/2,rd2/2+wall_w/2])
                    circle(d=wall_w, $fn=polygon);
                }
                translate([pd2/2-wall_w/2,0])
                circle(d=rd2, $fn=polygon);
            }

            translate([pd2/2-wall_w/2,0])
            circle(d=rd2+10, $fn=polygon);
        }

        rr=(rd2+10)/2+rad;
        xx=pow((pow(rr,2)-pow((5+rad),2)),(1/2));
        //Fillet 2
        difference(){
            polygon(points=[[pd2/2-wall_w/2-xx,0],
                        [pd2/2-wall_w/2-xx,5+rad],
                        [pd2/2-wall_w/2,0]
                        ]);

            translate([pd2/2-wall_w/2-xx,5+rad])
            circle(r=rad,, $fn=polygon);

            translate([pd2/2-wall_w/2,0])
            circle(d=rd2+10, $fn=polygon);
        }

        polygon(points=[[bo2/2,0],
                        [bo2/2,wall_w+rd2/2+1],
                        [bo2/2+5-rad,wall_w+rd2/2+1],
                        [bo2/2+5,wall_w+rd2/2+1-rad],
                        [bo2/2+5,5],
                        [pd2/2-wall_w/2-xx,5],
                        [pd2/2-wall_w/2-xx,0]
                        ]);
    }
}

color("OrangeRed")
difference(){
    union(){
        polley();
        mirror([0,0,1])
        polley();
    }
    translate([0, (pd2)/2-pow(pow(rd2/2+10,2)-pow(rd2/2+wall_w,2),1/2)/2+wall_w/2,rd2/2+wall_w-0.2]) {
        linear_extrude(height = 1)
        text(str("D",pd2,":",rd,":",bo),size = 2.5,halign ="center",valign ="center");
    }

}

```