[User]
Hey, I'm looking to create a customizable 2D origami elephant design using OpenSCAD, similar to the one I found on Thingiverse ([https://www.thingiverse.com/thing:2669551](https://www.thingiverse.com/thing:2669551)). I want to be able to control the overall size, height, and the thickness of both the outer and inner outlines. I also want an option to flip the model for mirroring purposes.

Specifically, the design should have an outer outline defined by a set of 20 points (A1 through A20), and some inner cut-out polygons defined by points B1, B2 and the points from the outer outline, where those inner points are given and the polygons are assembled from given point lists. The exact coordinates are:

*   A1 = [421, 965]
*   A2 = [478, 793]
*   A3 = [839, 563]
*   A4 = [1343, 570]
*   A5 = [1442, 639]
*   A6 = [1526, 783]
*   A7 = [1521, 1136]
*   A8 = [1620, 1135]
*   A9 = [1621, 1194]
*   A10 = [1378, 1192]
*   A11 = [1388, 1028]
*   A12 = [1336, 978]
*   A13 = [1267, 1386]
*   A14 = [1169, 1386]
*   A15 = [1098, 1243]
*   A16 = [877, 1234]
*   A17 = [804, 1386]
*   A18 = [662, 1386]
*   A19 = [616, 1229]
*   A20 = [519, 941]
*   B1 = [992, 695]
*   B2 = [1127, 939]

The polygons for the cutouts are:
*   C1 = [A1, A20, A2]
*   C2 = [A20, A2, A3, A16, A19]
*   C3 = [A19, A16, A17, A18]
*   C4 = [A3, A4, B1, B2, A12, A15, A16]
*   C5 = [A12, A13, A14, A15]
*   C6 = [B1, A4, A5, A12, B2]
*   C7 = [A5, A6, A11, A12]
*   C8 = [A6, A7, A11]
*   C9 = [A11, A7, A8, A9, A10]

I'd like to be able to set these parameters:

*   `max_size_in_millimeter`: The maximum length of the longest side (scaling the other side proportionally)
*   `model_height_in_millimeter`: The height/thickness of the 2D model.
*  `outline_size_in_millimeter`: The thickness of the outer outline.
*   `inline_size_in_millimeter`: The thickness of the inner cut-out outlines.
*   `inline_edge_radius_in_millimeter`: The radius of the rounded edges of the inner outlines.
*   `flip_model`: A boolean or string option to flip the model horizontally ("yes" or "no").

Could you generate the OpenSCAD code that does all this? I don't expect it to use any libraries besides the built-in OpenSCAD functions.

[Assistant]
customizable_origami_elephant_no2.scad:
```
/*
 * Customizable Origami - Elephant No. 2 - https://www.thingiverse.com/thing:2669551
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-11-26
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 2.0; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 0.9; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 0.9; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [421, 965];
A2 = [478, 793];
A3 = [839, 563];
A4 = [1343, 570];
A5 = [1442, 639];
A6 = [1526, 783];
A7 = [1521, 1136];
A8 = [1620, 1135];
A9 = [1621, 1194];
A10 = [1378, 1192];
A11 = [1388, 1028];
A12 = [1336, 978];
A13 = [1267, 1386];
A14 = [1169, 1386];
A15 = [1098, 1243];
A16 = [877, 1234];
A17 = [804, 1386];
A18 = [662, 1386];
A19 = [616, 1229];
A20 = [519, 941];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20];

// Inner Points
B1 = [992, 695];
B2 = [1127, 939];

// Polygons
C1 = [A1, A20, A2];
C2 = [A20, A2, A3, A16, A19];
C3 = [A19, A16, A17, A18];
C4 = [A3, A4, B1, B2, A12, A15, A16];
C5 = [A12, A13, A14, A15];
C6 = [B1, A4, A5, A12, B2];
C7 = [A5, A6, A11, A12];
C8 = [A6, A7, A11];
C9 = [A11, A7, A8, A9, A10];

cut_polygons = [C1, C2, C3, C4, C5, C6, C7, C8, C9];

min_x = A1[0];
min_y = A3[1];
max_x = A9[0];
max_y = A13[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }

            for(cut_polygon = [0:len(cut_polygons)]) {
                offset(r = +inline_edge_radius) {
                    offset(r = -inline_size - inline_edge_radius) {
                        polygon(points = cut_polygons[cut_polygon], convexity = 10);
                    }
                }
            }
        }
    }
}

```


[User]
Hey, I'm looking to design a vinyl roll stand, something similar to the one described in the provided text. I want it to be parametric so I can adjust it for different roll sizes, and I want a customizer to make it user-friendly for quick changes.

Here's what I'm envisioning:

The stand will have a cylindrical base, and I want to be able to adjust the following:

*   **`tube_id`**: The inner diameter of the outer tube (where the vinyl roll sits). This should have a default of 105mm, and a reasonable range should be 100-125mm.
*   **`tube_cen`**: The outer diameter of the inner tube (the core that extends up).  Default 75mm, range of 50-75mm.
*   **`tube_tall`**: The total height of the holder.  Default 75mm, range 50-100mm.

I also want the base of the cylinder to have an extended lip to prevent tipping, like the one in the provided code. Additionally, I would like to cut out some material, both for saving plastic and to give it a more interesting design.  The original code had a center knockout and some oval cutouts. I'd like those again, and I want to be able to adjust the oval size/placement.

Specifically, I’d like the inner cylinder to be a little smaller than the `tube_cen` (like in the provided code, make it `tube_cen-5`). The original code used an outer diameter for the knockout that was exactly the `tube_id`, I'd like to keep that the same. Also the original code has the main body cylinder extending past the base by `6.35` and I want to keep that as well.

The oval cutouts should be positioned symmetrically around the body of the cylinder, centered along the body circumference. It would be great to have two of them along the X axis and another two along the Y axis. I want the ovals to go through the entire height of the stand. It would be great if I could control the width and depth of these ovals. The code from the example had the height of the oval being the `tube_tall`, and then a width of `tube_tall / 4`. For the depth parameter, the code uses a hard-coded value of `5`. I'd like a customizable parameter called `oval_width_ratio`, where the width would be `tube_tall * oval_width_ratio`. I'd like another customizable parameter called `oval_depth` that controls the depth of the oval.

I think that should do it. Can you generate an OpenSCAD file or set of files that includes these features? I don't need any external libraries.

[Assistant]
vinyl_stand_v1.scad:
```
/* Open SCAD Name.: vinyl_stand_v1.scad
*  Copyright (c)..: 2017 www.DIY3DTech.com
*
*  Creation Date..: 11/26/2017
*  Description....: vinyl roll stand
*
*  Rev 1: Develop Model
*  Rev 2:
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*/

/*------------------Customizer View-------------------*/

// preview[view:north, tilt:top]

/*---------------------Parameters---------------------*/

//inter-dia of outer tube in mm
tube_id         =   105; //[100:1:125]

//outer-dia of inter-tube in mm
tube_cen        =   75; //[50:1:75]

//height of holder in mm
tube_tall       =   75; //[50:1:100]

/*-----------------------Execute----------------------*/

main_module();

/*-----------------------Modules----------------------*/

module main_module(){ //create module
    difference() {
            union() {//start union

                //created extended base to prevent tipping
                translate ([0,0,6.35/2]) rotate ([0,0,0]) cylinder(6.35,(tube_id+35)/2,(tube_id+35)/2,$fn=60,true);
                //create main body
                translate ([0,0,(tube_tall+6.35)/2]) rotate ([0,0,0]) cylinder(tube_tall+6.35,(tube_id+3)/2,(tube_id+3)/2,$fn=60,true);

                    } //end union

                //remove center to save plastic and time
                translate ([0,0,(tube_tall)/2]) rotate ([0,0,0]) cylinder(tube_tall+30,(tube_cen-5)/2,(tube_cen-5)/2,$fn=60,true);

                 //knock out center
                translate ([0,0,(tube_tall/2)+7]) rotate ([0,0,0]) knock_out(tube_id,tube_cen,tube_tall+1);

            //create flower like knockouts with oval
            translate ([(tube_id/2)-1,0,(tube_tall)+7]) rotate ([0,90,0])    oval(tube_tall,tube_tall/4,5, center = true);
            translate ([-(tube_id/2)+1,0,(tube_tall)+7]) rotate ([0,90,0])    oval(tube_tall,tube_tall/4,5, center = true);
            translate ([0,(tube_id/2)-1,(tube_tall)+7]) rotate ([90,90,0])    oval(tube_tall,tube_tall/4,5, center = true);
            translate ([0,-(tube_id/2)+1,(tube_tall)+7]) rotate ([90,90,0])    oval(tube_tall,tube_tall/4,5, center = true);

    //start subtraction of difference

    } //end difference
}//end module

module knock_out(ko_od,ko_id,ko_tall){ //create module
    difference() {
            union() {//start union

                //create outer shell
                translate ([0,0,0]) rotate ([0,0,0]) cylinder(ko_tall,ko_od/2,ko_od/2,$fn=60,true);

                    } //end union

    //start subtraction of difference

                //create inter knockout
                translate ([0,0,(5/2)]) rotate ([0,0,0]) cylinder(ko_tall+5,ko_id/2,ko_id/2,$fn=60,true);

    } //end difference
}//end module

module oval(w,h, height, center = true) //create oval
    {
        scale([1, h/w, 1]) cylinder(h=height, r=w, $fn=60,center=center);
    }//end module

/*----------------------End Code----------------------*/
//translate ([0,0,0]) rotate ([0,0,0]) cylinder(5,3,3,true);
//translate ([0,0,0]) rotate ([0,0,0]) cube([18,18,18],true);
//translate ([0,0,0]) sphere($fn = 0, $fa = 12, $fs = 2, r = 1);
//translate ([0,0,0]) rotate ([0,0,0]) rounded (15,15,1,1,true);
```


[User]
I'd like to create a customizable 2D origami deer design in OpenSCAD, similar to the one I found on Thingiverse. It should be parametric, allowing me to adjust the overall size, height, and outline thicknesses.

Here are the specific features I need:

*   **Overall Size:** The design should scale to fit within a specified maximum size, with the shorter side resizing proportionally. I need to be able to set this maximum dimension in millimeters.
*   **Height:** I need to control the height (thickness) of the extruded model.
*   **Outline Thicknesses:** I should be able to set the thickness of both the outer outline and the inner cut outlines. I need separate controls for each of these, as well as the radius for the corners of the inner cut outline.
*   **Flip Option:** There should be a way to mirror the design horizontally.
*   **Defined Geometry:** The deer's shape is defined by a set of outer points (A1-A35) and inner points (B1-B5), and cut polygons (C1-C9) that I have listed in the attached file, all in a 2D plane.
*   **Extrusion:** The model should be created through a linear extrusion.
*   **No Libraries:** Please do not use any external libraries for this design.

Essentially, the design should create a 2D deer shape with an outer border, and cut-out inner shapes with rounded corners. It should scale appropriately to a maximum size that the user sets, and the extrusion thickness should also be customizable.

Could you create an OpenSCAD file (or files, if needed) to generate this design?

[Assistant]
customizable_origami_deer.scad:
```
/*
 * Customizable Origami - Deer - https://www.thingiverse.com/thing:2670305
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-11-26
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 1.5; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 0.7; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 1.2; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [677, 768];
A2 = [666, 696];
A3 = [880, 652];
A4 = [936, 534];
A5 = [900, 455];
A6 = [917, 446];
A7 = [961, 541];
A8 = [915, 643];
A9 = [965, 619];
A10 = [999, 539];
A11 = [977, 473];
A12 = [994, 462];
A13 = [1019, 541];
A14 = [997, 605];
A15 = [1021, 598];
A16 = [1006, 694];
A17 = [927, 744];
A18 = [944, 921];
A19 = [1011, 1047];
A20 = [1097, 1048];
A21 = [1253, 1051];
A22 = [1299, 1026];
A23 = [1334, 1081];
A24 = [1293, 1115];
A25 = [1199, 1381];
A26 = [1184, 1610];
A27 = [1154, 1610];
A28 = [1156, 1460];
A29 = [1117, 1285];
A30 = [998, 1289];
A31 = [961, 1610];
A32 = [933, 1610];
A33 = [935, 1457];
A34 = [767, 1056];
A35 = [787, 800];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35];

// Inner Points
B1 = [873, 707];
B2 = [889, 742];
B3 = [908, 747];
B4 = [880, 815];
B5 = [892, 673];

// Polygons
C1 = [A2, A3, A8, B5, B1, B2, B3, B4, A35, A1];
C2 = [A3, A4, A5, A6, A7, A8];
C3 = [A11, A12, A13, A14, A9, A10];
C4 = [A8, A9, A14, A15, A16, A17, B3, B2, B1, B5];
C5 = [B3, A17, A18, A34, A35, B4];
C6 = [A18, A19, A30, A31, A32, A33, A34];
C7 = [A19, A20, A29, A30];
C8 = [A20, A21, A24, A25, A26, A27, A28, A29];
C9 = [A21, A24, A23, A22];

cut_polygons = [C1, /*C2, C3,*/ C4, C5, C6, C7, C8, C9];

min_x = A2[0];
min_y = A6[1];
max_x = A23[0];
max_y = A26[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }

            for(cut_polygon = [0:len(cut_polygons)]) {
                offset(r = +inline_edge_radius) {
                    offset(r = -inline_size - inline_edge_radius) {
                        polygon(points = cut_polygons[cut_polygon], convexity = 10);
                    }
                }
            }
        }
    }
}

```


[User]
I need a cable clamp designed in OpenSCAD. I'd like it to have a few key features:

First, there should be a main spherical body with a flat face. Think of it like a sphere that's had a slice taken off, leaving a flat circular area.

Then, on this flat area, I want a mounting hole. This hole should be surrounded by a raised circular area. The hole itself is for a screw, and the raised area is just for a bit of extra support.

Finally, the clamp needs a channel to hold a cable. This should be a semicircular groove on the other side of the sphere, going straight through, with a rectangular section to prevent the cable from sliding up and down the groove. There should also be a rectangular backing to the cable area, so that the clamp can be mounted with screws in more than one direction.

I’d like to be able to adjust:

*   The diameter of the main sphere
*   The diameter of the mounting screw hole
*   The diameter of the raised area around the screw hole
*   The position of the mounting hole on the flat face (both X and Y coordinates)
*   The thickness of the flat face
*   The diameter of the cable channel
*   The overall depth of the channel to account for the shape of a cable

Could you generate an OpenSCAD file for this, making sure everything is parametric?

[Assistant]
blatt.scad:
```
$fn=60;

cable_diameter=6;
screw_diameter=2.8;
sphere_diameter=18;
around_screw_diameter=14;
hole_pos_x=13;
hole_pos_y=7;
thickness=1.5;

    difference() {
        union() {
    rotate([90,0,0]) translate([0,0,0]) sphere(d=sphere_diameter);
linear_extrude(thickness) difference() {
hull() {
    translate([hole_pos_x,hole_pos_y,0]) circle(d=around_screw_diameter);
    circle(d=sphere_diameter);
}
translate([hole_pos_x,hole_pos_y,0]) circle(d=screw_diameter);
}
}
    rotate([90,0,0]) union()
    {
        translate([0,cable_diameter/2,-sphere_diameter/2-1]) cylinder(d=cable_diameter,h=sphere_diameter+2);
        translate([-cable_diameter/2,-cable_diameter/2,-sphere_diameter]) cube([cable_diameter,cable_diameter,sphere_diameter*2]);
        translate([-sphere_diameter/2-1,-sphere_diameter,-sphere_diameter/2-1]) cube([sphere_diameter+2,sphere_diameter,sphere_diameter+2]);
    } }

```


[User]
I need a cable clamp designed in OpenSCAD. It should have a main body with two cylindrical holes, one for a cable and another for a mounting screw. The cable hole should be angled at 90 degrees, exiting the side of the clamp. Think of it like a small clip that I'll screw down to hold the cable in place, with the cable running along the wall and then abruptly turning to face out. The screw and cable holes need to be precisely sized and positioned. I also want to be able to easily adjust the dimensions of all of this.

Specifically, I'd like the following parameters to be easily adjustable:

*   `cable_diameter`: The diameter of the cable it will hold.
*   `around_cable_thickness`: The thickness of the material surrounding the cable hole.
*   `cable_pos`: The horizontal/vertical position of the cable hole relative to the origin.
*   `screw_diameter`: The diameter of the mounting screw.
*   `around_screw_thickness`: The thickness of the material surrounding the screw hole.
*   `screw_pos`: The horizontal/vertical position of the screw hole relative to the origin.
*   `height`: The height of the clamp body.

I'm also going to want the part to be easily 3D-printable, so minimal overhangs would be ideal, and any sharp corners should be avoided if at all possible. I don't have any specific preferences for external shape, as long as it holds the cable and is mountable.

Could you please provide me with the OpenSCAD files for this? I'd prefer if everything is contained in a single file, with no external module requirements. I don't need anything too fancy, just a solid, functional model that's easy to modify. I'm expecting to generate .stl files for 3D printing, so the model should be suitable for that.

[Assistant]
halterung_2.scad:
```
$fn=30;
cable_diameter=6;
around_cable_thickness=5;
cable_pos=9;
screw_diameter=4;
around_screw_thickness=3;
screw_pos=4;
height=10;

difference() {
hull()
    {
        translate([screw_pos,screw_pos,0]) cylinder(d=around_screw_thickness+screw_diameter,h=height);
        translate([cable_pos,cable_pos,0]) cylinder(d=cable_diameter+around_cable_thickness,h=height);
    }
union() {
translate([0,0,-2])
{
translate([screw_pos,screw_pos,0]) cylinder(d=screw_diameter,h=height*2);

translate([cable_pos,cable_pos,0]) cylinder(d=cable_diameter,h=height*2);

}
translate([cable_pos,cable_pos,cable_diameter/2]) rotate([0,90,45]) {
    cylinder(d=cable_diameter,h=2*height);
    translate([cable_diameter/2,0,cable_diameter/2]) cube([cable_diameter,cable_diameter,cable_diameter],center=true);
    translate([-cable_diameter/2,0,0]) rotate([0,45,0])
        cylinder(d=cable_diameter,h=2*cable_diameter);

}
}
}
```


[User]
I'd like to create a customizable 2D origami penguin design using OpenSCAD, similar to the example I've seen online. I need the design to be parametric, so I can easily adjust its dimensions and line thicknesses.

Here are the specific parameters I want to control:

*   **Maximum Size:**  I should be able to specify the maximum dimension (either width or height) in millimeters, and the other dimension will automatically scale proportionally. Let's call this `max_size_in_millimeter`.
*   **Model Height:** I need to set the overall thickness of the 2D extrusion, which will be the height of the model in millimeters (`model_height_in_millimeter`).
*   **Outline Thickness:**  I need to control the thickness of the outer edge/outline of the penguin (`outline_size_in_millimeter`).
*   **Inner Outline Thickness:** The thickness of the inner lines that define the origami folds should be customizable as well (`inline_size_in_millimeter`).
*   **Inner Outline Edge Roundness:** I want to control how rounded the ends of the inner lines are (`inline_edge_radius_in_millimeter`).
*   **Flip Model:**  I need an option to flip the penguin design horizontally (`flip_model` which should be a `yes` or `no` option).

The penguin's basic shape will be defined by sets of coordinates. There should be an outer outline defined by points like `A1`, `A2`...`A15` and internal "cut" polygons defined by points `B1`, `B2`, ... `B8` and some combinations of `A` and `B` points. These are specified in the example as a series of hard-coded coordinates.

I'd like to use the built-in OpenSCAD `polygon()` function to create the basic 2D shapes.  The `offset()` function will probably come in handy for generating the line thicknesses, and `linear_extrude` to give it the height. It would be great if I don't have to change the coordinate system myself and that all of the coordinate scaling to fit the maximum dimension is handled automatically based on the `max_size_in_millimeter`.

[Assistant]
customizable_origami_penguin.scad:
```
/*
 * Customizable Origami - Penguin - https://www.thingiverse.com/thing:2673119
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-11-27
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 2.4; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 0.8; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 1.3; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [132, 684];
A2 = [90, 482];
A3 = [118, 301];
A4 = [193, 105];
A5 = [298, 79];
A6 = [329, 127];
A7 = [409, 165];
A8 = [335, 200];
A9 = [397, 347];
A10 = [415, 470];
A11 = [404, 624];
A12 = [366, 640];
A13 = [415, 684];
A14 = [329, 684];
A15 = [251, 684];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15];

// Inner Points
B1 = [180, 486];
B2 = [240, 431];
B3 = [280, 560];
B4 = [210, 619];
B5 = [334, 603];
B6 = [188, 274];
B7 = [306, 214];
B8 = [229, 522];

// Polygons
C1 = [A6, B7, A8, A7];
C2 = [B7, A6, A5, A4, A3, B6];
C3 = [B7, A8, A9, A10, B5, A15, A1, B4, B3, B8, B2, B6];
C4 = [A13, A12, A14];
C5 = [A15, A14, A12, A11, A10, B5];
C6 = [B4, B3, B8, B1];
C7 = [B8, B2, B1];
C8 = [B4, A1, A2, A3, B6, B2, B1];

cut_polygons = [C1, C2, C3, C4, C5, C6, C7, C8];

min_x = A2[0];
min_y = A5[1];
max_x = A10[0];
max_y = A1[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }

            for(cut_polygon = [0:len(cut_polygons)]) {
                offset(r = +inline_edge_radius) {
                    offset(r = -inline_size - inline_edge_radius) {
                        polygon(points = cut_polygons[cut_polygon], convexity = 10);
                    }
                }
            }
        }
    }
}

```


[User]
I'd like to create a customizable Pac-Man design similar to the one I saw on Thingiverse, but I need to be able to adjust more parameters. The original design was 2D, intended for laser cutting or 3D printing.

Specifically, I need the following:

1.  **Overall Size:** I should be able to specify the maximum size of the longest side (in millimeters), and the design should scale proportionately, keeping the correct aspect ratio.
2.  **Thickness:** I need separate controls for the outer outline thickness and the inner outline thickness, both in millimeters.
3.  **Inner Outline Radius:** I want to be able to adjust the radius of the rounded ends of the inner outlines.
4.  **Flip Option:** I want a simple "yes/no" toggle to flip the model horizontally (mirror on the y-axis).
5. **Fill Mode:** I need an option to toggle between a "solid" fill or a "hollow" fill where the insides of Pacman would be removed, only keeping the outlines.
6.  **Base Shape:** The basic Pac-Man shape should be defined by a series of 2D coordinates. I've included a basic set of points for the outer outline which I'd like you to use.
```
A1 = [0, 4];
A2 = [0, 2];
A3 = [1, 2];
A4 = [1, 1];
A5 = [3, 1];
A6 = [3, 0];
A7 = [8, 0];
A8 = [8, 1];
A9 = [10, 1];
A10 = [10, 2];
A11 = [11, 2];
A12 = [11, 4];
A13 = [12, 4];
A14 = [12, 9];
A15 = [11, 9];
A16 = [11, 11];
A17 = [10, 11];
A18 = [10, 12];
A19 = [8, 12];
A20 = [8, 13];
A21 = [3, 13];
A22 = [3, 12];
A23 = [1, 12];
A24 = [1, 11];
A25 = [0, 11];
A26 = [0, 9];
A27 = [2, 9];
A28 = [2, 8];
A29 = [5, 8];
A30 = [5, 7];
A31 = [7, 7];
A32 = [7, 6];
A33 = [5, 6];
A34 = [5, 5];
A35 = [2, 5];
A36 = [2, 4];
```
I'd also like the inner polygons to be defined as `C1` which uses the outline, and the variable `cut_polygons` to hold an array of these polygons.
```
C1 = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36];

cut_polygons = [C1];
```
7.  **Extrusion:** The final design should be extruded to a specified height in millimeters.
8.  **OpenSCAD:** Please provide the code in a single OpenSCAD file.

I think that should cover everything. Let me know if you have any questions. I'm not using any external libraries, so just stick to basic OpenSCAD.

[Assistant]
customizable_origami_pacman.scad:
```
/*
 * Customizable Origami - Pac-Man - https://www.thingiverse.com/thing:2674461
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-11-28
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 1.2; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 0.7; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 0.3; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

// Fill Mode
fill_mode = "solid"; //[solid,hollow]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [0, 4];
A2 = [0, 2];
A3 = [1, 2];
A4 = [1, 1];
A5 = [3, 1];
A6 = [3, 0];
A7 = [8, 0];
A8 = [8, 1];
A9 = [10, 1];
A10 = [10, 2];
A11 = [11, 2];
A12 = [11, 4];
A13 = [12, 4];
A14 = [12, 9];
A15 = [11, 9];
A16 = [11, 11];
A17 = [10, 11];
A18 = [10, 12];
A19 = [8, 12];
A20 = [8, 13];
A21 = [3, 13];
A22 = [3, 12];
A23 = [1, 12];
A24 = [1, 11];
A25 = [0, 11];
A26 = [0, 9];
A27 = [2, 9];
A28 = [2, 8];
A29 = [5, 8];
A30 = [5, 7];
A31 = [7, 7];
A32 = [7, 6];
A33 = [5, 6];
A34 = [5, 5];
A35 = [2, 5];
A36 = [2, 4];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36];

// Inner Points

// Polygons
C1 = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36];

cut_polygons = [C1];

min_x = A2[0];
min_y = A6[1];
max_x = A14[0];
max_y = A21[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }
            if(fill_mode == "hollow") {
                for(cut_polygon = [0:len(cut_polygons)]) {
                    offset(r = +inline_edge_radius) {
                        offset(r = -inline_size - inline_edge_radius) {
                            polygon(points = cut_polygons[cut_polygon], convexity = 10);
                        }
                    }
                }
            }
        }
    }
}

```


[User]
Hey there, I'm looking to create some customisable area-of-effect templates for tabletop games, and I think OpenSCAD is the right tool for the job. I've seen some existing designs, but I need something more specific to my needs, so I’d like to make a parameterized design that I can easily modify for different games.

The templates should be based on a hexagonal grid. Each hex cell represents a certain distance in-game. I need to be able to specify the size of a single cell, the units it uses (inches or millimeters), and the in-game scale it represents (for example, one inch cell might represent 5 feet in-game).

I need to control the shape of the area of effect. Specifically, the templates should be able to represent:
*   A specific range, given in terms of cells.
*   An angle, in degrees, to create cone-shaped AOEs. An angle of 0 would mean a line, like a ray, 360 would be a full circle area of effect.
*   An option to create just the outer contour of the area or the full honeycomb grid.

For the physical creation of the templates, I have a 3D printer and need to account for nozzle diameter and layer height. So I'd also like to set a minimum wall thickness (in mm), which will be approximated to the nearest nozzle diameter multiple and a minimum wall height (also in mm), which will be approximated to the nearest layer height multiple.

The idea is that the script should handle converting the user-provided parameters into mm if needed, calculate the cell radius and translate each cell appropriately on the hexagonal grid, and extrude each cell to the correct height. A function should also compute the angle between vectors for generating cone-shaped AOEs. Finally, it should include text that displays the current range (in game units) and angle on the template.

Could you generate the OpenSCAD code for this?

[Assistant]
AOE_template.scad:
```
// ©2017 - Mac Ryan <quasipedia@gmail.com>
// CC-Attribution-ShareAlike-NonCommercial

/* [PRINTER SETTINGS] */
nozzle_diameter = 0.4;
layer_height = 0.2;

/* [MAP SETTINGS] */
cell_units = "inches";  // [inches,millimiters]
// The cell size is measured side-to-side, not vertex-to-vertex
cell_size = 1;
// How many units does a cell represent in-game (e.g.: "5" if it represents 5 feet)
cell_scale = 5;

/* [TEMPLATE GEOMETRY] */
// Minimun thickness (mm) of the template lines (will be approximated up to a nozzle multiple)
min_wall_width = 1;
// Minimum height (mm) of the template (will be approximated up to a layer height multiple)
min_wall_height = 3;
// Range (in number of cells, *not* in-game units!)
range = 6;  // [1:30]
// Angle (in degrees)
angle = 45;  // [0:360]
// Only create the outer edge of the template, as opposed to the full honeycomb
contour_only = "no";  // [yes,no]

/* [Hidden] */
hex_circles_ratio = 1 / (sqrt(3) / 2);
mm_cell_size = cell_units == "inches" ? mm_from_inches(1) : cell_size;
echo(mm_cell_size);
cell_radius = mm_cell_size * (sqrt(3)/3);
tr_x = sqrt(3)/2 * mm_cell_size;  // modulo for translation on X axis
tr_y = mm_cell_size / 2;  // modulo for translation on Y axis
grid_line_thickness = ceil(min_wall_width / nozzle_diameter) * nozzle_diameter;
template_height = ceil(min_wall_height / layer_height) * layer_height;

// GEOMETRY

function mm_from_inches(x) = x * 25.4;
function abs_x(x, y) = x * tr_x;
function abs_y(x, y) = y * mm_cell_size + (x % 2) * tr_y;

module hex(x, y, origin, extra_padding) {
  // Extrude a hex cell at the location X, Y on an imaginary hexagonal grid
  carve_radius = (origin) ? 0 : cell_radius - grid_line_thickness / 2;
  linear_extrude(height = template_height, center = false,
    convexity = 10, twist = 0, slices = 1)
    translate([abs_x(x, y), abs_y(x, y), 0])
      difference() {
        circle($fn = 6, r = cell_radius + grid_line_thickness / 2 + extra_padding);
        circle($fn = 6, r = carve_radius);
      }
}

// CONDITION VERIFICATION

function compute_angle(a, b) =
  // a, b : vectors
  round(2 * atan2( norm(cross(a, b)), a * b));

function inrange(range, x, y) =
  sqrt(pow(abs_x(x, y), 2) + pow(abs_y(x, y), 2)) <= (ceil(range * mm_cell_size)) ?
    true : false;

function inangle(angle, x, y) =
  compute_angle([0, 1, 0], [abs_x(x, y), abs_y(x, y), 0]) <= angle ?
    true : false;

// BUSINESS LOGIC

module base_geometry(range, angle, infill, extra_padding) {
  safe_range = ceil(hex_circles_ratio * range);
  for (x = [-safe_range : safe_range], y = [-safe_range : safe_range]) {
    if (inrange(range, x, y) && inangle(angle, x, y)) {
      if (infill)
        hex(x, y, !(x||y), extra_padding);  // will evaluate `true` at the origin
      else
        hex(x, y, true, extra_padding);  // will create a solid plate
    }
  }
}

module template(range, angle, infill) {
  if (infill) {  // add text with range, angle
    base_geometry(range, angle, infill, extra_padding = 0);
    linear_extrude(height = template_height + 2 * layer_height)
      text(text = str("R", range * cell_scale, "A", angle),
        size = mm_cell_size / 6,
        halign = "center",
        valign = "center");
  } else {
    difference() {
      base_geometry(range, angle, infill, extra_padding = grid_line_thickness);
      // the double difference with translation is to avoid horrible artefact
      // when previewing, due to the co-planar difference operation
      translate([0, 0, template_height / 3]) {
        base_geometry(range, angle, infill, extra_padding = 0);
      }
      translate([0, 0, -template_height / 3]) {
        base_geometry(range, angle, infill, extra_padding = 0);
      }
    }
  }
}

template(range = range, angle = angle, infill = contour_only == "no");

```


[User]
I'd like to create a customizable 2D origami design of the bird from the game Heavy Rain, similar to the existing design on Thingiverse. I'll need a parametric OpenSCAD file that lets me control the overall size, the height/thickness of the design, and the thickness of both the inner and outer outlines. I also need to be able to specify the roundness of the ends of the inner outlines, and also have a simple "flip" option, so that the design can be mirrored along one axis.

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

*   **`max_size_in_millimeter`**: The maximum length of the longest side of the design, with the shorter side resized proportionally.
*   **`model_height_in_millimeter`**: The height/thickness of the extruded design.
*   **`outline_size_in_millimeter`**: The thickness of the outer outline of the design.
*   **`inline_size_in_millimeter`**: The thickness of the inner outlines.
*   **`inline_edge_radius_in_millimeter`**: The radius for rounding the ends of the inner outlines.
*   **`flip_model`**: A yes/no option to mirror the design.

The design's geometry is defined by a series of coordinates for the outer shape (named A1, A2, etc.), and a number of interior polygons created from different sets of those coordinates along with interior coordinates (B1, B2, etc.). The file has lists of these points and polygons to be used. Here are those values for reference:

```
// Outer Points
A1 = [323, 179];
A2 = [482, 110];
A3 = [609, 55];
A4 = [664, 189];
A5 = [732, 358];
A6 = [716, 399];
A7 = [841, 477];
A8 = [1018, 588];
A9 = [884, 629];
A10 = [740, 677];
A11 = [623, 604];
A12 = [546, 753];
A13 = [481, 622];
A14 = [461, 572];
A15 = [419, 637];
A16 = [405, 570];
A17 = [387, 457];
A18 = [502, 245];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18];

// Inner Points
B1 = [536, 239];
B2 = [585, 417];
B3 = [640, 562];
B4 = [422, 477];
B5 = [456, 557];
B6 = [441, 436];
B7 = [524, 237];
B8 = [523, 249];
B9 = [694, 515];
B10 = [684, 464];
B11 = [659, 525];

// Polygons
C1 = [A1, A2, B1];
C2 = [A2, A3, B1];
C3 = [A3, A4, B1];
C4 = [A4, A5, B1];
C5 = [B8, B2, A5];
C6 = [A5, B2, B3, B11, B10, A6];
C7 = [B3, A11, A12, A13];
C8 = [B4, B3, A13, A14, B5];
C9 = [B4, B2, B3];
C10 = [B4, B6, B8, B2];
C11 = [A15, A14, B5, A16];
C12 = [A16, A17, B4, B5];
C13 = [A17, B4, B6];
C14 = [A1, B1, A5, B8, B6, A17, A18];
C15 = [A6, A7, B9, B10];
C16 = [B11, B9, B10];
C17 = [A11, B3, B11, B9, A10];
C18 = [B9, A7, A10];
C19 = [A7, A9, A10];
C20 = [A7, A9, A8];

cut_polygons = [C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20];
```
I don't need any additional libraries, just the standard OpenSCAD functionality.

[Assistant]
customizable_origami_heavy_rain_-_the_bird.scad:
```
/*
 * Customizable Origami - Heavy Rain - The Bird - https://www.thingiverse.com/thing:2677493
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-11-29
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 1.4; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 0.7; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 0.5; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [323, 179];
A2 = [482, 110];
A3 = [609, 55];
A4 = [664, 189];
A5 = [732, 358];
A6 = [716, 399];
A7 = [841, 477];
A8 = [1018, 588];
A9 = [884, 629];
A10 = [740, 677];
A11 = [623, 604];
A12 = [546, 753];
A13 = [481, 622];
A14 = [461, 572];
A15 = [419, 637];
A16 = [405, 570];
A17 = [387, 457];
A18 = [502, 245];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18];

// Inner Points
B1 = [536, 239];
B2 = [585, 417];
B3 = [640, 562];
B4 = [422, 477];
B5 = [456, 557];
B6 = [441, 436];
B7 = [524, 237];
B8 = [523, 249];
B9 = [694, 515];
B10 = [684, 464];
B11 = [659, 525];

// Polygons
C1 = [A1, A2, B1];
C2 = [A2, A3, B1];
C3 = [A3, A4, B1];
C4 = [A4, A5, B1];
C5 = [B8, B2, A5];
C6 = [A5, B2, B3, B11, B10, A6];
C7 = [B3, A11, A12, A13];
C8 = [B4, B3, A13, A14, B5];
C9 = [B4, B2, B3];
C10 = [B4, B6, B8, B2];
C11 = [A15, A14, B5, A16];
C12 = [A16, A17, B4, B5];
C13 = [A17, B4, B6];
C14 = [A1, B1, A5, B8, B6, A17, A18];
C15 = [A6, A7, B9, B10];
C16 = [B11, B9, B10];
C17 = [A11, B3, B11, B9, A10];
C18 = [B9, A7, A10];
C19 = [A7, A9, A10];
C20 = [A7, A9, A8];

cut_polygons = [C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20];

min_x = A1[0];
min_y = A3[1];
max_x = A8[0];
max_y = A12[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }

            for(cut_polygon = [0:len(cut_polygons)]) {
                offset(r = +inline_edge_radius) {
                    offset(r = -inline_size - inline_edge_radius) {
                        polygon(points = cut_polygons[cut_polygon], convexity = 10);
                    }
                }
            }
        }
    }
}

```


[User]
Hey, I'm looking to design a parametric moon clip for a revolver. I want to be able to specify the number of rounds, the outer and inner diameters, the notch size and offset, and the slot size and offset. I need to be able to choose whether the inner shape is a polygon or a circle.

I'd like the output to be switchable between a 2D shape for laser or water jet cutting and a 3D shape for printing.

Could you create a parametric OpenSCAD file (or files, if that makes it easier) that can handle all of this? I'm not using any specific libraries, but if you find that certain libraries would be helpful for this design, feel free to use them.

Thanks!

[Assistant]
moon_clip.scad:
```
// This is a Moon Clip.
//
// Warning -- some sanding and fitting may be required.
//
// This is licensed under the creative commons+attribution license
//
// To fulfil the attribution requirement, please link to:
// http://www.thingiverse.com/thing:2677639

/* [Main] */

// Define type of output
shape=1; // [0:2D for Laser or Water Jet Cutting,1:3D for printing]

// Define inner shape
inner_shape=0; // [0:for polygon,1:for round]

// Define number of faces (more faces for smoother surfaces)
$fn=100;

// Define thickness in mm
thickness=1.0;

// Define number of rounds
num_rounds=6;

// Define outside diameter in mm
outside_diameter=28.0;

// Define inside diameter in mm
inside_diameter=10.0;

// Define notch diameter in mm
notch_diameter=8.5;

// Define center-to-center notch offset in mm
notch_offset=12.0;

// Define slot width in mm
slot_width=0.5;

// Define slot length in mm
slot_length=6.0;

// Define slot offset in mm
slot_offset=outside_diameter/2-slot_length/2;

module outer_body2d()
{
    circle(outside_diameter/2,true);
}

module polygon_inner_body2d()
{
    $fn=(num_rounds);
    rotate([0,0,(360/num_rounds)/2])
    circle(inside_diameter/2,true);
}

module round_inner_body2d()
{
    rotate([0,0,(360/num_rounds)/2])
    circle(inside_diameter/2,true);
}

module notch2d()
{
    #translate([notch_offset,0.0]) circle(notch_diameter/2,true);
    //translate([1.0*outside_diameter,0.0]) square(notch_diameter,true);
}
module slot2d()
{
    translate([slot_offset,0.0]) square([slot_length,slot_width],true);
}

module outer_body3d()
{
    cylinder(h=thickness,r=outside_diameter/2,center=true);
}

module polygon_inner_body3d()
{
    $fn=(num_rounds);
    rotate([0,0,(360/num_rounds)/2])
    cylinder(h=thickness+1,r=inside_diameter/2,center=true);
}

module round_inner_body3d()
{
    rotate([0,0,(360/num_rounds)/2])
    cylinder(h=thickness+1,r=inside_diameter/2,center=true);
}

module notch3d()
{
    translate([notch_offset,0.0,0.0]) cylinder(h=thickness+1,r=notch_diameter/2,center=true);
    //translate([1.0*outside_diameter,0.0,thickness/2]) square(notch_diameter,true);
}
module slot3d()
{
    translate([slot_offset,0.0,0])
    rotate(90,0,0)
    #cube([slot_width,slot_length,thickness+1],center=true);
    // Add cylinder at end of slot to round corners for stress relief
}

if(shape==0)
{
    difference()
    {
        outer_body2d();
        union()
    {
        if(inner_shape==1)
        {
            round_inner_body2d();
        }
        if(inner_shape==0)
        {
            polygon_inner_body2d();
        }
            for(angle=[0:360/num_rounds:360])
            {
                rotate([0,0,angle]) notch2d();
                rotate([0,0,angle+360/(2*num_rounds)]) slot2d();
            }
        }
    }
}

if(shape==1)
{
    difference()
    {
        outer_body3d();
        union()
    {
            if(inner_shape==1)
            {
                round_inner_body3d();
            }
            if(inner_shape==0)
            {
                polygon_inner_body3d();
            }
            for(angle=[0:360/num_rounds:360])
            {
                rotate([0,0,angle]) notch3d();
                rotate([0,0,angle+360/(2*num_rounds)]) slot3d();
            }
        }
    }
}
```


[User]
I'd like to create a customizable origami sheep design in OpenSCAD, similar to the one described in the provided text. I need it to be parametric so I can adjust the size, thickness of the outline, and the height of the model.

Specifically, I need:

*   A way to set a `max_size` for the longest side of the design, with the other side scaling proportionally.
*   A `model_height` parameter to control the extrusion height.
*   Separate parameters for the thickness of the outer outline (`outline_size_in_millimeter`) and inner outlines (`inline_size_in_millimeter`).
*   A parameter `inline_edge_radius_in_millimeter` to control the roundness of the ends of the inner outlines.
*  A flip_model parameter that accepts "yes" or "no", and when "yes" mirrors the model across the X axis.
*   The design should start with the defined outer points (A1-A41) and inner points (B1-B7) and polygon definitions (C1-C9).

I'd expect that the model is constructed by extruding the shape defined by the outer points, and then subtracting the shapes of the inner polygons, taking the given inner and outer thickness into account.

I'm not sure how to specify the points and polygons in the code, but they are listed in the attached description.

Could you generate the necessary OpenSCAD file(s) for this? I don't need any external libraries like MCAD or BOSL for this - I expect it will only require the core OpenSCAD functionality.

[Assistant]
customizable_origami_sheep.scad:
```
/*
 * Customizable Origami - Sheep - https://www.thingiverse.com/thing:2679929
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-11-30
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 1.4; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 0.7; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 0.6; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [231, 938];
A2 = [468, 724];
A3 = [448, 719];
A4 = [470, 650];
A5 = [723, 507];
A6 = [784, 514];
A7 = [803, 541];
A8 = [1000, 600];
A9 = [938, 626];
A10 = [913, 631];
A11 = [1126, 680];
A12 = [1812, 620];
A13 = [2266, 660];
A14 = [2363, 718];
A15 = [2480, 903];
A16 = [2433, 1220];
A17 = [2452, 1511];
A18 = [2421, 1527];
A19 = [2419, 1570];
A20 = [2186, 1864];
A21 = [2151, 1864];
A22 = [2248, 1547];
A27 = [1850, 1376];
A28 = [1627, 1533];
A29 = [1396, 1520];
A30 = [1050, 1501];
A35 = [1000, 1779];
A36 = [943, 1864];
A37 = [910, 1864];
A38 = [898, 1481];
A39 = [798, 1430];
A40 = [416, 1069];
A41 = [246, 1046];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A27, A28, A29, A30, A35, A36, A37, A38, A39, A40, A41];

// Inner Points
B1 = [1667, 1112];
B2 = [1727, 931];
B3 = [1656, 954];
B4 = [2301, 1573];
B5 = [807, 651];
B6 = [677, 684];
B7 = [580, 950];
//B8 = [1130, 1501];

// Polygons
C1 = [A3, A4, A5, A6, B6, A2];
C2 = [A40, B7, B5, A39];
C3 = [B5, A10, A11, A12, A39];
C4 = [A39, A38, A30, A29, B3, A12];
C5 = [B3, A12, A13, A14, B2];
C6 = [B3, B2, B1, A27, A29];
C7 = [B2, A14, A15, A16, B4, A22, A27, B1];
C8 = [A16, A17, A18, B4];
C9 = [A27, A29, A28];

cut_polygons = [C1, C2, C3, C4, C5, C6, C7, C8, C9];

min_x = A1[0];
min_y = A5[1];
max_x = A15[0];
max_y = A36[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }

            for(cut_polygon = [0:len(cut_polygons)]) {
                offset(r = +inline_edge_radius) {
                    offset(r = -inline_size - inline_edge_radius) {
                        polygon(points = cut_polygons[cut_polygon], convexity = 10);
                    }
                }
            }
        }
    }
}

```


[User]
I need a parametric OpenSCAD design for a socket rail, similar to the one I've seen, but with a few key features for flexibility. I want to be able to customize the length, and have options for different mounting methods.

Specifically, I need the following:

*   **Rail Length:** This should be a primary parameter.
*   **Mounting Options:**
    *   A hanging mount (like a tab at the back) should be toggleable on or off. If enabled, it should also have a parameter controlling whether it adds to the total length.
    *   Dovetail connectors on the ends to join multiple rails should be toggleable. These should also have a tolerance parameter for 3D printing. The dovetails should replace the end stops if enabled.
    *   Screw holes should be an option in place of the hanger or sidemount. They need a toggle and should have parameters to control screw head width, head height, and stem width, as well as an offset from the end.
    *   A side mount option should allow for the rail to be mounted vertically, but still hold sockets. This should cancel the hanger or screw hole options and should have its own dimension parameters (thickness, height) as well as having screw hole parameters.

*   **Rail Details:**
    *   The rail should have toothed lips that the socket clips attach to. There should be parameters for tooth depth, tooth pitch, and the overhang depth and height.
    *   There should also be parameters for the depth and length of the end stops.
*   **Overall dimensions:**
    *   Overall height and width should be adjustable but should have default values as well.

Could you create this design with all of these parameters using OpenSCAD? I'd also like it to use the BOSL2 library if possible.

[Assistant]
socket_rail_customizer.scad:
```
// Total length of rail
railLength = 140; //[20:5:500]
// Should a hanger be included?
includeHanger = 1; //[0,1]
// Should Rail Length be increased by 24mm to accomodate the hanger?
hangerAddsLength = 1; //[0,1]
// Add dovetail to the beginning of rail and remove beginning stop and hanger.
includeDovetailBegin = 0; //[0,1]
// Add dovetail to the end of rail and remove end stop.
includeDovetailEnd = 1; //[0,1]
// Tolerance of dovetail, the dovetail end will be this much smaller. Adjust to fit your printer
dovetailTolerance=0.2;
// Add 2 screw holes, remove the hanger
addScrewHole = 0; //[0,1]
//Add side mount, for use in shallow drawers to point long sockets sideway. Cancels hanger and screwhole
addSideMount = 1;//[0,1]
// screw dimension, adjust based on your screw
screwCapWidth=8;
screwCapHeight=4;
screwStemWidth=5;

module dragons() {
    // All variables beyond this point can be tuned, but may result in a rail that is incompatible with the clips it's designed to work with.
}

//  Items tagged with "compatibility" will create a rail that does not work with commercial clips.
//  All values here are designed to create something that's pretty close to a commercially available rail system.

// Lips that socket clips attach to
overhangDepth = 2; // Warning: compatibility
overhangHeight = 2; // Warning: compatibility
stopDepth = 1;
stopLength = 5;
toothDepth = .3;
toothPitch = 1;

// The hanger inset
hangerLength = 20;
hangerThickness = 2;
hangerBorder = 2;
hangerEndOffset = 2;
hangerSlotWidth = 5;
hangerSlotRadius = hangerSlotWidth/2;
hangerFlairBorder = 1;
hangerSlotFlairWidth = 9;
hangerSlotFlairRadius = hangerSlotFlairWidth /2;

// Dovetail dimension
dovetailWidthShort=7;
dovetailWidthLong=12;
dovetailLength=10;

//screwhole offset
screwHoleOffset=dovetailLength+10;  // to make sure it does not fall into dovetail

//side mount dimension
sideMountThickness = 7;
sideMountHeight = 16;
clipEndThickness = 3;

// Overall dimensions
length = includeHanger && hangerAddsLength ? railLength + hangerLength + hangerBorder : railLength;
height = 9;
width = 20; // Does not include lips/stops. Warning: compatibility

booleanFudgeFactor = 0.001 * 1; // Thanks customizer! I didn't realize I needed to do this and was doing a full render to see my booleans.
difference() {
    union() {
        // Body
        cube([length, width, height]);

        // Base lips
        // Doesn't print well due to overhang. Not functional except maybe to make base wider.
        // translate([0,-overhangDepth,height-overhangHeight]) cube([length, overhangDepth, overhangHeight]);
        // translate([0,width,height-overhangHeight]) cube([length, overhangDepth, overhangHeight]);

        // Toothed lips
        translate([length,0,0]) rotate([0,0,180]) toothedLip(length);
        translate([0,width,0]) toothedLip(length);

        // Stops
        if(!includeDovetailBegin){
            translate([0,-overhangDepth-stopDepth,0]) cube([stopLength, width+2*(overhangDepth+stopDepth), overhangHeight]);
        }
        if(!includeDovetailEnd){
            translate([length-stopLength,-overhangDepth-stopDepth,0]) cube([stopLength, width+2*(overhangDepth+stopDepth), overhangHeight]);
        }
        if(includeDovetailEnd){
            translate([length,width/2,0])dovetail(dovetailTolerance);

        }
        if(addSideMount){
            sidemount();
        }
    } // End union, begin difference
    if(!includeDovetailBegin){
        if(!addScrewHole){
            if(!addSideMount){
                if (includeHanger) {
                    hanger();
                }
            }
        }
    }
    if(includeDovetailBegin){
        translate([0,width/2,0])dovetail(0);
    }
    if(!addSideMount){
        if(addScrewHole){
            translate([screwHoleOffset,width/2,0])screwhole();
            translate([length-screwHoleOffset,width/2,0])screwhole();
        }
    }
}

module toothedLip(length) {
    cube([length, overhangDepth-toothDepth, overhangHeight]);
    for( i = [0 : toothPitch : length-toothPitch]) {
        translate([i,overhangDepth-toothDepth,0]) tooth();
    }
}

module tooth() {
    linear_extrude(height=overhangHeight, slices=2) polygon([[0,0],[toothPitch, 0],[toothPitch/2, toothDepth]],[[0,1,2]]);
}

module hanger() {
    hangerWidth = width - (2*hangerBorder);
    translate([hangerBorder + hangerEndOffset, (width-hangerWidth)/2, hangerThickness]) cube([hangerLength,hangerWidth, height-hangerThickness+booleanFudgeFactor]);
    translate([hangerBorder + hangerEndOffset + hangerSlotRadius, width/2, -booleanFudgeFactor]) cylinder(h = hangerThickness+(2*booleanFudgeFactor), r=hangerSlotRadius, $fn=60);
    translate([hangerBorder + hangerEndOffset + hangerLength - hangerSlotFlairRadius - hangerFlairBorder, width/2, -booleanFudgeFactor]) cylinder(h = (hangerThickness+2*booleanFudgeFactor), r=hangerSlotFlairRadius, $fn=60);
    hangerSlotLength=hangerLength - hangerSlotRadius - hangerSlotFlairRadius - hangerFlairBorder;
    translate([hangerBorder + hangerEndOffset + hangerSlotRadius, (width - hangerSlotWidth)/2, -booleanFudgeFactor]) cube([hangerSlotLength,hangerSlotWidth,hangerThickness + (2*booleanFudgeFactor)]);
}

module sidemount() {
    difference(){
        translate([0,width-sideMountThickness+hangerThickness+clipEndThickness,height+sideMountHeight-4])
        rotate(a=[0,90,0])
        linear_extrude (height=length)
        polygon([[0,0],[0,sideMountThickness],[sideMountHeight-4,sideMountThickness],[ sideMountHeight,0]]);

    translate([20,width-sideMountThickness+hangerThickness+clipEndThickness-1, height+sideMountHeight-2-screwCapWidth])
    rotate(a=[270,0,0])
    screwhole();

    translate([length-20,width-sideMountThickness+hangerThickness+clipEndThickness-1, height+sideMountHeight-2-screwCapWidth])
    rotate(a=[270,0,0])
    screwhole();
    }

}

module dovetail(tolerance) {
    linear_extrude (height=height)
    polygon([[0,(dovetailWidthShort/2)-tolerance],[dovetailLength-tolerance,(dovetailWidthLong/2)-tolerance],[dovetailLength-tolerance,-(dovetailWidthLong/2)+tolerance],[0,-(dovetailWidthShort/2)+tolerance]]);
}

module screwhole(){
    union(){
        cylinder(h=screwCapHeight,r1=screwCapWidth/2,r2=screwStemWidth/2);
        cylinder(h=height,r=screwStemWidth/2);
    }
}
```


[User]
Hey, I'd like to create a customizable badge with a star in the center and text around the edges. I have a rough idea of how it should look, and I'd like to be able to tweak some parameters.

Specifically, I want the badge to have a circular ring with text embossed on both the top and bottom. I need to be able to control the radius and thickness of this ring. The text should be customizable for both top and bottom lines, including the font, size, and character spacing. I'd also like to be able to adjust how far the text is from the center of the ring, and how deep the text is cut into the ring.

Then, in the center of the ring, I want a star. It needs to be a regular star (like a five-pointed star, but I want to vary the number of points), with adjustable height, and the length of each point should also be adjustable, relative to the radius of the main ring. I also need to be able to rotate the entire star around the center of the badge.

Could you generate OpenSCAD code for this? I'm not using any libraries for this currently, so I need all the basic code included. Let me know if you need any more info.

[Assistant]
StarBadge.scad:
```

RingRadius=35;//[30,35,40,45]
RingHeight=4;//[2,3,4,5,6]
StarPoints = 5;//[3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
StarHeight=4;//[3,4,5,6]
StarRotate = 348;//[0:360]
TopWord = "CUSTOM";
BtmWord = "TEXT HERE";
SelectedFont = "Stardos Stencil"; // [Arial, Stardos Stencil, Allerta Stencil, Sirin Stencil]
TextSize = 7; //[5,6,7,8]
TopCharSpacing = 0;//[0,1,2,3]
BtmCharSpacing = 0;//[0,1,2,3]
TextPosition = 0; //[-5:5]
TextDepth = 1.5; //[1,1.5,2,2.5,3,3.5,4]

$fn=128;

charsTop = TopWord;
charsBtm = BtmWord;
radius = RingRadius-9+(TextPosition/5);

//Top Text
module revolveTop_text(radius, charsTop) {
    //PI = 3.14159;
    //circumference = 2 * PI * radius;
    charsTop_len = len(charsTop);
    font_size = TextSize;//circumference / chars_len;
    step_angle = (120-TopCharSpacing*20) / charsTop_len;
    for(i = [0 : charsTop_len - 1]) {
        rotate((0-TopCharSpacing*10)-i * step_angle)
            translate([0, radius + font_size / 2, 0])
                text(
                    charsTop[i],
                    font = SelectedFont,
                    size = font_size, valign = "center", halign = "center"
                );
    }
}
//Bottom Text
module revolveBtm_text(radius, charsBtm) {
    //PI = 3.14159;
    //circumference = 2 * PI * radius;
    charsBtm_len = len(charsBtm);
    font_size = TextSize;//circumference / chars_len;
    step_angle = (-120+BtmCharSpacing*20) / charsBtm_len;
    for(i = [0 : charsBtm_len - 1]) {
        rotate((180-BtmCharSpacing*10) - (-i * step_angle))
            translate([0, radius + font_size / 2, 0])
               rotate(180,0,0)
                text(
                    charsBtm[charsBtm_len - i - 1],
                    font = SelectedFont,
                    size = font_size, valign = "center", halign = "center"
                );
    }
}
//Ring creation removing text
difference(){
 difference(){
  difference(){
    cylinder(h=RingHeight,r=RingRadius, center = false);
    translate([0,0,-1])cylinder(h=RingHeight+2,r=RingRadius-10,center=false);
  } translate([0,0,RingHeight-TextDepth])linear_extrude(RingHeight+2)revolveTop_text(radius, charsTop);
 } translate([0,0,RingHeight-TextDepth])linear_extrude(RingHeight+2)revolveBtm_text(radius, charsBtm);
}
//Star definition follows
// number of points on the star (3 or more makes sense)
_points = StarPoints;
// length of ech point from center.  1/2 the rounding value will be added to the length
_point_len = RingRadius-10;
// used to adjust width of each point +/-
_adjust = 0;
// point height at end of points (thinkness of objet at thinest part. Should be less than cent_h
_pnt_h = StarHeight / 3;
// height at center of star. set equal to pnt_h for flat object
_cent_h = StarHeight;
// diameter of rounding at end of point (must be greater than 0).
_rnd=1;

// resolution for rounded point
_fn = 25;

// modules in library:
module star_3d(points, point_len, adjust=0, pnt_h =1, cent_h=1, rnd=0.1, fn=25)
{
    // star_3d: star with raised center.
    //----------------------------------------------//
    // points = num points on star (should be >3.
    //          Using 3 may require addisional
    //          adjust be applied.)
    // point_len = len of point on star
    //              (actual len of point will add
    //              1/2 rnd to the length.)
    // adjust = +/- adjust of width of point
    // pnt_h = height of star at end of point
    // cent_h = height of star in center needs to be > pnt_h to have effect.
    // rnd = roundness of end of point (diameter)
    // fn = $fn value for rounded point
    //----------------------------------------------//

    point_deg= 360/points;
    point_deg_adjusted = point_deg + (-point_deg/2) +  adjust;

    if(points == 3 && adjust == 0)
    {  // make a pyramid (this is to avoid rendering
       //            issues in this special case)
        hull()
        {
           for(i=[0:2])
           {
               rotate([0,0,i*point_deg])
               translate([point_len,0,0])
                    cylinder(pnt_h, d=rnd, $fn=fn);
           }
           cylinder(cent_h, d=.001);
        }
    }
    else
    { // use algorithm
        for(i=[0:points-1])
        {
            rotate([0,0,i * point_deg])
                translate([0,-point_len,0])
                point(point_deg_adjusted,
                      point_len,
                      rnd,
                      pnt_h,
                      cent_h,
                      fn);
        }
    }

}

module point(deg, leng, rnd, h1, h2, fn=25)
{   // create a point of the star.
    hull()
    {
        cylinder(h1, d=rnd, $fn=fn);
        translate([0,leng,0]) cylinder(h2, d=.001);
        rotate([0,0,-deg/2])
            translate([0,leng,0]) cylinder(h1, d=rnd);
        rotate([0,0,deg/2])
            translate([0,leng,0]) cylinder(h1, d=rnd);
    }
}

// star object:
rotate([0,0,StarRotate])star_3d(points = _points,
        point_len = _point_len,
        adjust = _adjust,
        pnt_h = _pnt_h,
        cent_h =_cent_h,
        rnd = _rnd,
        fn = _fn);

```


[User]
Hey, I need help creating a parametric OpenSCAD design for a timing belt. I want to be able to specify the belt's tooth profile, the number of teeth, the belt width, and the thickness of the belt.

The tooth profiles I need are: MXL, 40 D.P., XL, H, T2.5, T5, T10, AT5, HTD 3mm, HTD 5mm, HTD 8mm, GT2 2mm, GT2 3mm, and GT2 5mm. It needs to accurately model the tooth shape for each profile.

I also want a way to adjust the tooth width and depth. This should act like a scaling parameter so that I can adjust how well the belt fits with a given pulley. These should be adjustable by a small amount, such as plus or minus 0.1 or 0.2 mm.

The output of this design should be a single belt segment, with no pulley.

I’m not sure if this is a lot to ask, but is it possible to use modules for each tooth profile? I’m trying to follow the code I saw online as a starting point, and it looks like they have a module for each tooth profile. This might make it easier to follow and maintain the code.

I don’t need to connect this to other parts of my designs. I’m just working on the belt design first and I’ll use the belt module in other designs.

I'm not using any external libraries, so please don't assume any are available, I just want it to be pure OpenSCAD code.

[Assistant]
Parametric_Pulley_Belt.scad:
```
// Parametric pulley belt
// Remixed by Vivalize December 2017

// Based on:
// Parametric Pulley with multiple belt profiles
// by droftarts January 2012

// Based on pulleys by:
// http://www.thingiverse.com/thing:11256 by me!
// https://github.com/prusajr/PrusaMendel by Josef Prusa
// http://www.thingiverse.com/thing:3104 by GilesBathgate
// http://www.thingiverse.com/thing:2079 by nophead

// dxf tooth data from http://oem.cadregister.com/asp/PPOW_Entry.asp?company=915217&elementID=07807803/METRIC/URETH/WV0025/F
// pulley diameter checked and modelled from data at http://www.sdp-si.com/D265/HTML/D265T016.html

/**
 * @name Pulley Belt
 * @category Printed
 */

// tuneable constants

teeth = 50;            // Number of teeth
profile = 10;        // 1=MXL 2=40DP 3=XL 4=H 5=T2.5 6=T5 7=T10 8=AT5 9=HTD_3mm 10=HTD_5mm 11=HTD_8mm 12=GT2_2mm 13=GT2_3mm 14=GT2_5mm
thickness = 2.5;
width = 9;

//    ********************************
//    ** Scaling tooth for good fit **
//    ********************************
/*    To improve fit of belt to pulley, set the following constant. Decrease or increase by 0.1mm at a time. We are modelling the *BELT* tooth here, not the tooth on the pulley. Increasing the number will *decrease* the pulley tooth size. Increasing the tooth width will also scale proportionately the tooth depth, to maintain the shape of the tooth, and increase how far into the pulley the tooth is indented. Can be negative */

additional_tooth_width = 0; //mm

//    If you need more tooth depth than this provides, adjust the following constant. However, this will cause the shape of the tooth to change.

additional_tooth_depth = 0; //mm

// The following set the pulley diameter for a given number of teeth

MXL_pulley_dia = tooth_spacing (2.032,0.254);
40DP_pulley_dia = tooth_spacing (2.07264,0.1778);
XL_pulley_dia = tooth_spacing (5.08,0.254);
H_pulley_dia = tooth_spacing (9.525,0.381);
T2_5_pulley_dia = tooth_spaceing_curvefit (0.7467,0.796,1.026);
T5_pulley_dia = tooth_spaceing_curvefit (0.6523,1.591,1.064);
T10_pulley_dia = tooth_spacing (10,0.93);
AT5_pulley_dia = tooth_spaceing_curvefit (0.6523,1.591,1.064);
HTD_3mm_pulley_dia = tooth_spacing (3,0.381);
HTD_5mm_pulley_dia = tooth_spacing (5,0.5715);
HTD_8mm_pulley_dia = tooth_spacing (8,0.6858);
GT2_2mm_pulley_dia = tooth_spacing (2,0.254);
GT2_3mm_pulley_dia = tooth_spacing (3,0.381);
GT2_5mm_pulley_dia = tooth_spacing (5,0.5715);

// The following calls the pulley creation part, and passes the pulley diameter and tooth width to that module

if ( profile == 1 ) { pulley ( "MXL" , MXL_pulley_dia , 0.508 , 1.321 ); }
if ( profile == 2 ) { pulley ( "40 D.P." , 40DP_pulley_dia , 0.457 , 1.226 ); }
if ( profile == 3 ) { pulley ( "XL" , XL_pulley_dia , 1.27, 3.051 ); }
if ( profile == 4 ) { pulley ( "H" , H_pulley_dia ,1.905 , 5.359 ); }
if ( profile == 5 ) { pulley ( "T2.5" , T2_5_pulley_dia , 0.7 , 1.678 ); }
if ( profile == 6 ) { pulley ( "T5" , T5_pulley_dia , 1.19 , 3.264 ); }
if ( profile == 7 ) { pulley ( "T10" , T10_pulley_dia , 2.5 , 6.13 ); }
if ( profile == 8 ) { pulley ( "AT5" , AT5_pulley_dia , 1.19 , 4.268 ); }
if ( profile == 9 ) { pulley ( "HTD 3mm" , HTD_3mm_pulley_dia , 1.289 , 2.27 ); }
if ( profile == 10 ) { pulley ( "HTD 5mm" , HTD_5mm_pulley_dia , 2.199 , 3.781 ); }
if ( profile == 11 ) { pulley ( "HTD 8mm" , HTD_8mm_pulley_dia , 3.607 , 6.603 ); }
if ( profile == 12 ) { pulley ( "GT2 2mm" , GT2_2mm_pulley_dia , 0.764 , 1.494 ); }
if ( profile == 13 ) { pulley ( "GT2 3mm" , GT2_3mm_pulley_dia , 1.169 , 2.31 ); }
if ( profile == 14 ) { pulley ( "GT2 5mm" , GT2_5mm_pulley_dia , 1.969 , 3.952 ); }

// Functions

function tooth_spaceing_curvefit (b,c,d)
= ((c * pow(teeth,d)) / (b + pow(teeth,d))) * teeth ;

function tooth_spacing(tooth_pitch,pitch_line_offset)
= (2*((teeth*tooth_pitch)/(3.14159265*2)-pitch_line_offset)) ;

// Main Module

module pulley( belt_type , pulley_OD , tooth_depth , tooth_width )
{
    echo (str("Belt type = ",belt_type,"; Number of teeth = ",teeth,"; Pulley Outside Diameter = ",pulley_OD,"mm "));
    tooth_distance_from_centre = sqrt( pow(pulley_OD/2,2) - pow((tooth_width+additional_tooth_width)/2,2));
    tooth_width_scale = (tooth_width + additional_tooth_width ) / tooth_width;
    tooth_depth_scale = ((tooth_depth + additional_tooth_depth ) / tooth_depth) ;

    difference() {
        translate([0,0,0.005]) cylinder (h = width-0.01, r=(pulley_OD/2)+thickness, center = false, $fn = teeth*10);
        difference()
        {
            union()
            {
                difference()
                {
                    //shaft - diameter is outside diameter of pulley
                    rotate ([0,0,360/(teeth*4)])
                    cylinder(r=pulley_OD/2,h=width, $fn=teeth*4);

                    //teeth - cut out of shaft

                    for(i=[1:teeth])
                    rotate([0,0,i*(360/teeth)])
                    translate([0,-tooth_distance_from_centre,pulley_b_ht -1])
                    scale ([ tooth_width_scale , tooth_depth_scale , 1 ])
                    {
                        if ( profile == 1 ) { MXL();}
                        if ( profile == 2 ) { 40DP();}
                        if ( profile == 3 ) { XL();}
                        if ( profile == 4 ) { H();}
                        if ( profile == 5 ) { T2_5();}
                        if ( profile == 6 ) { T5();}
                        if ( profile == 7 ) { T10();}
                        if ( profile == 8 ) { AT5();}
                        if ( profile == 9 ) { HTD_3mm();}
                        if ( profile == 10 ) { HTD_5mm();}
                        if ( profile == 11 ) { HTD_8mm();}
                        if ( profile == 12 ) { GT2_2mm();}
                        if ( profile == 13 ) { GT2_3mm();}
                        if ( profile == 14 ) { GT2_5mm();}
                    }
                }
            }
        }
    }
}

// Tooth profile modules

module MXL()
{
    linear_extrude(width=width+2) polygon([[-0.660421,-0.5],[-0.660421,0],[-0.621898,0.006033],[-0.587714,0.023037],[-0.560056,0.049424],[-0.541182,0.083609],[-0.417357,0.424392],[-0.398413,0.458752],[-0.370649,0.48514],[-0.336324,0.502074],[-0.297744,0.508035],[0.297744,0.508035],[0.336268,0.502074],[0.370452,0.48514],[0.39811,0.458752],[0.416983,0.424392],[0.540808,0.083609],[0.559752,0.049424],[0.587516,0.023037],[0.621841,0.006033],[0.660421,0],[0.660421,-0.5]]);
}

module 40DP()
{
    linear_extrude(width=width+2) polygon([[-0.612775,-0.5],[-0.612775,0],[-0.574719,0.010187],[-0.546453,0.0381],[-0.355953,0.3683],[-0.327604,0.405408],[-0.291086,0.433388],[-0.248548,0.451049],[-0.202142,0.4572],[0.202494,0.4572],[0.248653,0.451049],[0.291042,0.433388],[0.327609,0.405408],[0.356306,0.3683],[0.546806,0.0381],[0.574499,0.010187],[0.612775,0],[0.612775,-0.5]]);
}

module XL()
{
    linear_extrude(width=width+2) polygon([[-1.525411,-1],[-1.525411,0],[-1.41777,0.015495],[-1.320712,0.059664],[-1.239661,0.129034],[-1.180042,0.220133],[-0.793044,1.050219],[-0.733574,1.141021],[-0.652507,1.210425],[-0.555366,1.254759],[-0.447675,1.270353],[0.447675,1.270353],[0.555366,1.254759],[0.652507,1.210425],[0.733574,1.141021],[0.793044,1.050219],[1.180042,0.220133],[1.239711,0.129034],[1.320844,0.059664],[1.417919,0.015495],[1.525411,0],[1.525411,-1]]);
}

module H()
{
    linear_extrude(width=width+2) polygon([[-2.6797,-1],[-2.6797,0],[-2.600907,0.006138],[-2.525342,0.024024],[-2.45412,0.052881],[-2.388351,0.091909],[-2.329145,0.140328],[-2.277614,0.197358],[-2.234875,0.262205],[-2.202032,0.334091],[-1.75224,1.57093],[-1.719538,1.642815],[-1.676883,1.707663],[-1.62542,1.764693],[-1.566256,1.813112],[-1.500512,1.85214],[-1.4293,1.880997],[-1.353742,1.898883],[-1.274949,1.905021],[1.275281,1.905021],[1.354056,1.898883],[1.429576,1.880997],[1.500731,1.85214],[1.566411,1.813112],[1.625508,1.764693],[1.676919,1.707663],[1.719531,1.642815],[1.752233,1.57093],[2.20273,0.334091],[2.235433,0.262205],[2.278045,0.197358],[2.329455,0.140328],[2.388553,0.091909],[2.454233,0.052881],[2.525384,0.024024],[2.600904,0.006138],[2.6797,0],[2.6797,-1]]);
}

module T2_5()
{
    linear_extrude(width=width+2) polygon([[-0.839258,-0.5],[-0.839258,0],[-0.770246,0.021652],[-0.726369,0.079022],[-0.529167,0.620889],[-0.485025,0.67826],[-0.416278,0.699911],[0.416278,0.699911],[0.484849,0.67826],[0.528814,0.620889],[0.726369,0.079022],[0.770114,0.021652],[0.839258,0],[0.839258,-0.5]]);
}

module T5()
{
    linear_extrude(width=width+2) polygon([[-1.632126,-0.5],[-1.632126,0],[-1.568549,0.004939],[-1.507539,0.019367],[-1.450023,0.042686],[-1.396912,0.074224],[-1.349125,0.113379],[-1.307581,0.159508],[-1.273186,0.211991],[-1.246868,0.270192],[-1.009802,0.920362],[-0.983414,0.978433],[-0.949018,1.030788],[-0.907524,1.076798],[-0.859829,1.115847],[-0.80682,1.147314],[-0.749402,1.170562],[-0.688471,1.184956],[-0.624921,1.189895],[0.624971,1.189895],[0.688622,1.184956],[0.749607,1.170562],[0.807043,1.147314],[0.860055,1.115847],[0.907754,1.076798],[0.949269,1.030788],[0.9837,0.978433],[1.010193,0.920362],[1.246907,0.270192],[1.273295,0.211991],[1.307726,0.159508],[1.349276,0.113379],[1.397039,0.074224],[1.450111,0.042686],[1.507589,0.019367],[1.568563,0.004939],[1.632126,0],[1.632126,-0.5]]);
}

module T10()
{
    linear_extrude(width=width+2) polygon([[-3.06511,-1],[-3.06511,0],[-2.971998,0.007239],[-2.882718,0.028344],[-2.79859,0.062396],[-2.720931,0.108479],[-2.651061,0.165675],[-2.590298,0.233065],[-2.539962,0.309732],[-2.501371,0.394759],[-1.879071,2.105025],[-1.840363,2.190052],[-1.789939,2.266719],[-1.729114,2.334109],[-1.659202,2.391304],[-1.581518,2.437387],[-1.497376,2.47144],[-1.408092,2.492545],[-1.314979,2.499784],[1.314979,2.499784],[1.408091,2.492545],[1.497371,2.47144],[1.581499,2.437387],[1.659158,2.391304],[1.729028,2.334109],[1.789791,2.266719],[1.840127,2.190052],[1.878718,2.105025],[2.501018,0.394759],[2.539726,0.309732],[2.59015,0.233065],[2.650975,0.165675],[2.720887,0.108479],[2.798571,0.062396],[2.882713,0.028344],[2.971997,0.007239],[3.06511,0],[3.06511,-1]]);
}

module AT5()
{
    linear_extrude(width=width+2) polygon([[-2.134129,-0.75],[-2.134129,0],[-2.058023,0.005488],[-1.984595,0.021547],[-1.914806,0.047569],[-1.849614,0.082947],[-1.789978,0.127073],[-1.736857,0.179338],[-1.691211,0.239136],[-1.653999,0.305859],[-1.349199,0.959203],[-1.286933,1.054635],[-1.201914,1.127346],[-1.099961,1.173664],[-0.986896,1.18992],[0.986543,1.18992],[1.099614,1.173664],[1.201605,1.127346],[1.286729,1.054635],[1.349199,0.959203],[1.653646,0.305859],[1.690859,0.239136],[1.73651,0.179338],[1.789644,0.127073],[1.849305,0.082947],[1.914539,0.047569],[1.984392,0.021547],[2.057906,0.005488],[2.134129,0],[2.134129,-0.75]]);
}

module HTD_3mm()
{
    linear_extrude(width=width+2) polygon([[-1.135062,-0.5],[-1.135062,0],[-1.048323,0.015484],[-0.974284,0.058517],[-0.919162,0.123974],[-0.889176,0.206728],[-0.81721,0.579614],[-0.800806,0.653232],[-0.778384,0.72416],[-0.750244,0.792137],[-0.716685,0.856903],[-0.678005,0.918199],[-0.634505,0.975764],[-0.586483,1.029338],[-0.534238,1.078662],[-0.47807,1.123476],[-0.418278,1.16352],[-0.355162,1.198533],[-0.289019,1.228257],[-0.22015,1.25243],[-0.148854,1.270793],[-0.07543,1.283087],[-0.000176,1.28905],[0.075081,1.283145],[0.148515,1.270895],[0.219827,1.252561],[0.288716,1.228406],[0.354879,1.19869],[0.418018,1.163675],[0.477831,1.123623],[0.534017,1.078795],[0.586276,1.029452],[0.634307,0.975857],[0.677809,0.91827],[0.716481,0.856953],[0.750022,0.792167],[0.778133,0.724174],[0.800511,0.653236],[0.816857,0.579614],[0.888471,0.206728],[0.919014,0.123974],[0.974328,0.058517],[1.048362,0.015484],[1.135062,0],[1.135062,-0.5]]);
}

module HTD_5mm()
{
    linear_extrude(width=width+2) polygon([[-1.89036,-0.75],[-1.89036,0],[-1.741168,0.02669],[-1.61387,0.100806],[-1.518984,0.21342],[-1.467026,0.3556],[-1.427162,0.960967],[-1.398568,1.089602],[-1.359437,1.213531],[-1.310296,1.332296],[-1.251672,1.445441],[-1.184092,1.552509],[-1.108081,1.653042],[-1.024167,1.746585],[-0.932877,1.832681],[-0.834736,1.910872],[-0.730271,1.980701],[-0.62001,2.041713],[-0.504478,2.09345],[-0.384202,2.135455],[-0.259708,2.167271],[-0.131524,2.188443],[-0.000176,2.198511],[0.131296,2.188504],[0.259588,2.167387],[0.384174,2.135616],[0.504527,2.093648],[0.620123,2.04194],[0.730433,1.980949],[0.834934,1.911132],[0.933097,1.832945],[1.024398,1.746846],[1.108311,1.653291],[1.184308,1.552736],[1.251865,1.445639],[1.310455,1.332457],[1.359552,1.213647],[1.39863,1.089664],[1.427162,0.960967],[1.467026,0.3556],[1.518984,0.21342],[1.61387,0.100806],[1.741168,0.02669],[1.89036,0],[1.89036,-0.75]]);
}

module HTD_8mm()
{
    linear_extrude(width=width+2) polygon([[-3.301471,-1],[-3.301471,0],[-3.16611,0.012093],[-3.038062,0.047068],[-2.919646,0.10297],[-2.813182,0.177844],[-2.720989,0.269734],[-2.645387,0.376684],[-2.588694,0.496739],[-2.553229,0.627944],[-2.460801,1.470025],[-2.411413,1.691917],[-2.343887,1.905691],[-2.259126,2.110563],[-2.158035,2.30575],[-2.041518,2.490467],[-1.910478,2.66393],[-1.76582,2.825356],[-1.608446,2.973961],[-1.439261,3.10896],[-1.259169,3.22957],[-1.069074,3.335006],[-0.869878,3.424485],[-0.662487,3.497224],[-0.447804,3.552437],[-0.226732,3.589341],[-0.000176,3.607153],[0.226511,3.589461],[0.447712,3.552654],[0.66252,3.497516],[0.870027,3.424833],[1.069329,3.33539],[1.259517,3.229973],[1.439687,3.109367],[1.608931,2.974358],[1.766344,2.825731],[1.911018,2.664271],[2.042047,2.490765],[2.158526,2.305998],[2.259547,2.110755],[2.344204,1.905821],[2.411591,1.691983],[2.460801,1.470025],[2.553229,0.627944],[2.588592,0.496739],[2.645238,0.376684],[2.720834,0.269734],[2.81305,0.177844],[2.919553,0.10297],[3.038012,0.047068],[3.166095,0.012093],[3.301471,0],[3.301471,-1]]);
}

module GT2_2mm()
{
    linear_extrude(width=width+2) polygon([[0.747183,-0.5],[0.747183,0],[0.647876,0.037218],[0.598311,0.130528],[0.578556,0.238423],[0.547158,0.343077],[0.504649,0.443762],[0.451556,0.53975],[0.358229,0.636924],[0.2484,0.707276],[0.127259,0.750044],[0,0.76447],[-0.127259,0.750044],[-0.2484,0.707276],[-0.358229,0.636924],[-0.451556,0.53975],[-0.504797,0.443762],[-0.547291,0.343077],[-0.578605,0.238423],[-0.598311,0.130528],[-0.648009,0.037218],[-0.747183,0],[-0.747183,-0.5]]);
}

module GT2_3mm()
{
    linear_extrude(width=width+2) polygon([[-1.155171,-0.5],[-1.155171,0],[-1.065317,0.016448],[-0.989057,0.062001],[-0.93297,0.130969],[-0.90364,0.217664],[-0.863705,0.408181],[-0.800056,0.591388],[-0.713587,0.765004],[-0.60519,0.926747],[-0.469751,1.032548],[-0.320719,1.108119],[-0.162625,1.153462],[0,1.168577],[0.162625,1.153462],[0.320719,1.108119],[0.469751,1.032548],[0.60519,0.926747],[0.713587,0.765004],[0.800056,0.591388],[0.863705,0.408181],[0.90364,0.217664],[0.932921,0.130969],[0.988924,0.062001],[1.065168,0.016448],[1.155171,0],[1.155171,-0.5]]);
}

module GT2_5mm()
{
    linear_extrude(width=width+2) polygon([[-1.975908,-0.75],[-1.975908,0],[-1.797959,0.03212],[-1.646634,0.121224],[-1.534534,0.256431],[-1.474258,0.426861],[-1.446911,0.570808],[-1.411774,0.712722],[-1.368964,0.852287],[-1.318597,0.989189],[-1.260788,1.123115],[-1.195654,1.25375],[-1.12331,1.380781],[-1.043869,1.503892],[-0.935264,1.612278],[-0.817959,1.706414],[-0.693181,1.786237],[-0.562151,1.851687],[-0.426095,1.9027],[-0.286235,1.939214],[-0.143795,1.961168],[0,1.9685],[0.143796,1.961168],[0.286235,1.939214],[0.426095,1.9027],[0.562151,1.851687],[0.693181,1.786237],[0.817959,1.706414],[0.935263,1.612278],[1.043869,1.503892],[1.123207,1.380781],[1.195509,1.25375],[1.26065,1.123115],[1.318507,0.989189],[1.368956,0.852287],[1.411872,0.712722],[1.447132,0.570808],[1.474611,0.426861],[1.534583,0.256431],[1.646678,0.121223],[1.798064,0.03212],[1.975908,0],[1.975908,-0.75]]);
}

```


[User]
I'm looking to create a customizable 2D Froebel star for laser cutting and 3D printing, similar to the one on Thingiverse by mightynozzle. I need a parametric OpenSCAD file that allows me to adjust the overall size, the height, and the thickness of both the outer and inner outlines. I want the inner outline to have rounded edges. Also, the design should have a toggle for flipping/mirroring the design.

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

*   **max\_size\_in\_millimeter:** The maximum dimension of the star (longest side), automatically resizing the other dimension to maintain the aspect ratio.
*   **model\_height\_in\_millimeter:** The overall height/thickness of the model.
*   **outline\_size\_in\_millimeter:** The thickness of the outer outline.
*   **inline\_size\_in\_millimeter:** The thickness of the inner outlines.
*  **inline\_edge\_radius\_in\_millimeter:** The radius for rounding the ends of the inner outlines
*   **flip\_model:** A boolean or toggle option to mirror the model.

The design itself is based on a set of points defining the outer shape, as well as inner points and polygons defining the cutouts. I'd expect the code to use these to generate the necessary shapes, applying the requested sizing and outline parameters. I do not expect the use of any specific library. I'm looking for a single .scad file that encompasses the entire design.

[Assistant]
customizable_origami_froebel_star.scad:
```
/*
 * Customizable Origami - Froebel star - https://www.thingiverse.com/thing:2682883
 * by Dennis Hofmann - https://www.thingiverse.com/mightynozzle/about
 * created 2017-12-01
 * version v1.0
 *
 * Changelog
 * --------------
 * v1.0:
 *      - final design
 * --------------
 *
 * This work is licensed under the Creative Commons - Attribution - NonCommercial - ShareAlike license.
 * https://creativecommons.org/licenses/by-nc-sa/3.0/
 */

 // Parameter Section //
//-------------------//

// preview[view:north, tilt:top]

// The maximum size of the longest side. The shorter side will be automatically resized in same ratio.
max_size_in_millimeter = 120; //[20:300]

// The height of the model.
model_height_in_millimeter = 5; //[0.2:0.2:100]

// Thickness of the outer outline.
outline_size_in_millimeter = 2.8; //[0.5:0.1:20]

// Thickness of the inner outline.
inline_size_in_millimeter = 1.1; //[0.5:0.1:20]

// Roundiness of the ends of the inner outlines.
inline_edge_radius_in_millimeter = 1.3; //[0.0:0.1:5]

// Flip model
flip_model = "no"; //[yes,no]

/*[hidden]*/
max_size = max_size_in_millimeter;
model_height = model_height_in_millimeter;
$fn=32;

// Outer Points
A1 = [2, 0];
A2 = [3, 1];
A3 = [4, 0];
A4 = [4, 2];
A5 = [6, 2];
A6 = [5, 3];
A7 = [6, 4];
A8 = [4, 4];
A9 = [4, 6];
A10 = [3, 5];
A11 = [2, 6];
A12 = [2, 4];
A13 = [0, 4];
A14 = [1, 3];
A15 = [0, 2];
A16 = [2, 2];

outline = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16];

// Inner Points
B1 = [3, 3];

// Polygons
C1 = [A1, A2, A16];
C2 = [A2, A4, A16];
C3 = [A3, A4, A2];
C4 = [A4, A5, A6];
C5 = [A4, A6, A8];
C6 = [A8, A6, A7];
C7 = [A8, A9, A10];
C8 = [A12, A8, A10];
C9 = [A12, A10, A11];
C10 = [A13, A14, A12];
C11 = [A14, A16, A12];
C12 = [A15, A16, A14];
C13 = [A16, A4, B1];
C14 = [A4, A8, B1];
C15 = [A8, A12, B1];
C16 = [A12, A16, B1];

cut_polygons = [C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16];

min_x = A13[0];
min_y = A1[1];
max_x = A5[0];
max_y = A11[1];

x_size = max_x - min_x;
y_size = max_y - min_y;

x_factor = max_size / x_size;
y_factor = max_size / y_size;

inline_size = x_size > y_size ? inline_size_in_millimeter / x_factor / 2: inline_size_in_millimeter / y_factor / 2;
inline_edge_radius = x_size > y_size ? inline_edge_radius_in_millimeter / x_factor: inline_edge_radius_in_millimeter / y_factor;
outline_size = x_size > y_size ? outline_size_in_millimeter / x_factor - inline_size: outline_size_in_millimeter / y_factor - inline_size;

 // Program Section //
//-----------------//

if(x_size > y_size) {
    resize(newsize=[max_size, x_factor * y_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
} else {
    resize(newsize=[y_factor * x_size, max_size, model_height]){
        if(flip_model == "yes") {
            mirror([0,1,0]) {
                rotate([180,180,0]) {
                    create(outline, cut_polygons);
                }
            }
        } else {
            create(outline, cut_polygons);
        }
    }
}

 // Module Section //
//----------------//

module create() {
    linear_extrude(height=1) {
        difference() {
            offset(r = -0) {
                offset(r = +outline_size) {
                    polygon(points = outline, convexity = 10);
                }
            }

            for(cut_polygon = [0:len(cut_polygons)]) {
                offset(r = +inline_edge_radius) {
                    offset(r = -inline_size - inline_edge_radius) {
                        polygon(points = cut_polygons[cut_polygon], convexity = 10);
                    }
                }
            }
        }
    }
}

```