rodclamps: rewrite

rodclamps: rewrite

include <thing_libutils/attach.scad>
include <thing_libutils/shapes.scad>
include <thing_libutils/screws.scad>
include <config.scad>

mount_rod_clamp_conn_rod = [[0,0,0],[1,0,0]];

module mount_rod_clamp_half(part, rod_d=10, screw_dist=undef, width=4, thick=undef, base_thick=undef, thread=ThreadM4, align=[0,0,0], orient=[0,0,1])
{
    thick_=thick==undef?rod_d:thick;
    outer_d= rod_d+thick_*2;
    thread_dia=lookup(ThreadSize, thread);
    screw_dist_=screw_dist==undef?outer_d+thread_dia+thick_:screw_dist;
    base_thick_=base_thick==undef?thick_*1.2:base_thick;
    clamp_tolerance = 0.5*mm;

    if(part==undef)
    {
        difference()
        {
            mount_rod_clamp_half(part="pos", rod_d=rod_d, screw_dist=screw_dist, width=width, thick=thick, base_thick=base_thick, thread=thread, align=align, orient=orient);
            mount_rod_clamp_half(part="neg", rod_d=rod_d, screw_dist=screw_dist, width=width, thick=thick, base_thick=base_thick, thread=thread, align=align, orient=orient);
        }
        if($show_vit)
        {
            %mount_rod_clamp_half(part="vit", rod_d=rod_d, screw_dist=screw_dist, width=width, thick=thick, base_thick=base_thick, thread=thread, align=align, orient=orient);
        }
    }
    else if(part=="pos")
    {
        s=[outer_d, base_thick_, width];
        size_align(size=s, align=align, orient=orient, orient_ref=ZAXIS)
        translate([-outer_d/2,0,0])
        {
            hull()
            {
                // cylinder around rod
                cylindera(d=outer_d, h=width, orient=[0,0,1], align=[0,0,0], round_radius=2);

                // base
                rcubea([base_thick_, screw_dist_+thread_dia*2.5, width], align=[1,0,0]);
            }
        }
    }
    else if(part=="neg")
    {
        s=[outer_d, base_thick_, width];
        size_align(size=s, align=align, orient=orient, orient_ref=ZAXIS)
        translate([-outer_d/2,0,0])
        {
            // cut bottom of cylinder
            cubea([outer_d/2+.1, screw_dist_+thread_dia*2.5+.1, width+1], align=[-1,0,0]);

            // cut clamp screw holes
            for(i=[-1,1])
            translate([0, i*screw_dist_/2, 0])
            {
                screw_cut(thread=thread, orient=-XAXIS);
            }

            // cut rod
            translate(-clamp_tolerance*XAXIS)
            cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
        }
    }
    else if(part=="vit")
    {
        s=[outer_d, base_thick_, width];
        size_align(size=s, align=align, orient=orient, orient_ref=ZAXIS)
        translate([-outer_d/2,0,0])
        {
            translate(-clamp_tolerance*XAXIS)
            cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
        }
    }
}

module mount_rod_clamp_full(part, rod_d=10, screw_dist=undef, width=4, thick=undef, base_thick=undef, thread=ThreadM4, align=[0,0,0], orient=[0,0,1])
{
    thick_=thick==undef?rod_d:thick;
    outer_d= rod_d+thick_*2;
    thread_dia=lookup(ThreadSize, thread);
    screw_dist_=screw_dist==undef?outer_d+thread_dia*2+thick_:screw_dist;
    base_thick_=base_thick==undef?thick_*1.2:base_thick;
    clamp_tolerance = 0.5*mm;

    s=[base_thick_, screw_dist_+thread_dia*2.5, width];
    if(part==undef)
    {
        difference()
        {
            mount_rod_clamp_full(part="pos", rod_d=rod_d, screw_dist=screw_dist, width=width, thick=thick, base_thick=base_thick, thread=thread, align=align, orient=orient);
            mount_rod_clamp_full(part="neg", rod_d=rod_d, screw_dist=screw_dist, width=width, thick=thick, base_thick=base_thick, thread=thread, align=align, orient=orient);
        }
        if($show_vit)
        {
            %mount_rod_clamp_full(part="vit", rod_d=rod_d, screw_dist=screw_dist, width=width, thick=thick, base_thick=base_thick, thread=thread, align=align, orient=orient);
        }
    }
    else if(part=="pos")
    {
        size_align(size=s, align=align, orient=orient, orient_ref=ZAXIS)
        translate([-base_thick_/2,0,0])
        {
            hull()
            {
                // cylinder around rod
                translate([rod_d/2,0,0])
                cylindera(d=outer_d, h=width, orient=[0,0,1], align=[0,0,0], round_radius=2);

                // base
                /*translate([-rod_d/2,0,0])*/
                rcubea([base_thick_, screw_dist_+thread_dia*2.5, width], align=[1,0,0]);
            }
        }
    }
    else if(part=="neg")
    {
        size_align(size=s, align=align, orient=orient, orient_ref=ZAXIS)
        translate([-base_thick_/2,0,0])
        {
            // cut bottom of cylinder
            /*translate(-rod_d/2*XAXIS)*/
            cubea([outer_d/2, screw_dist_+thread_dia*2.5+.1, width+1], align=[-1,0,0]);

            // cut clamp screw holes
            for(i=[-1,1])
            translate([0, i*screw_dist_/2, 0])
            {
                screw_cut(thread=thread, orient=-XAXIS);
            }

            // cut rod
            translate([rod_d/2,0,0])
            translate(-clamp_tolerance*XAXIS)
            hull()
            {
                stack(axis=-XAXIS, dist=100)
                {
                    cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
                    cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
                }
            }
        }
    }
    else if(part=="vit")
    {
        size_align(size=s, align=align, orient=orient, orient_ref=ZAXIS)
        translate([-base_thick_/2,0,0])
        {
            %translate([rod_d/2,0,0])
            translate(-clamp_tolerance*XAXIS)
            cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
        }
    }
}

if(false)
{
    /*$show_vit=false;*/
    /*$preview_mode=false;*/
    stack(axis=XAXIS, dist=15)
    {
        mount_rod_clamp_half(rod_d=yaxis_rod_d,  width=extrusion_size, thick=4, thread=ThreadM5, align=-ZAXIS+XAXIS);
        mount_rod_clamp_full(rod_d=yaxis_rod_d,  width=extrusion_size, thick=4, thread=ThreadM5, align=-ZAXIS+XAXIS);
    }
}

include <thing_libutils/attach.scad>
include <thing_libutils/shapes.scad>
include <config.scad>

mount_rod_clamp_conn_rod = [[0,0,0],[1,0,0]];

module mount_rod_clamp_half(rod_d=10, screw_dist=undef, width=4, thick=undef, base_thick=undef, thread=ThreadM4, orient=[0,0,1])
{
    thick_=thick==undef?rod_d:thick;
    outer_d= rod_d+thick_*2;
    thread_dia=lookup(ThreadSize, thread);
    screw_dist_=screw_dist==undef?outer_d+thread_dia+thick_:screw_dist;
    base_thick_=base_thick==undef?thick_*1.5:base_thick;

    orient(orient)
    difference()
    {
        clamp_tolerance = 0.5*mm;
        union()
        {
            // cylinder around rod
            cylindera(d=outer_d, h=width, orient=[0,0,1], align=[0,0,0], round_radius=2);

            // base
            rcubea([base_thick_, screw_dist_+thread_dia*2.5, width], align=[1,0,0]);
        }

        // cut bottom of cylinder
        cubea([outer_d/2+.1, screw_dist_+thread_dia*2.5+.1, width+1], align=[-1,0,0], extrasize=[clamp_tolerance,0,0], extrasize_align=[1,0,0]);

        // cut clamp screw holes
        for(i=[-1,1])
        translate([0, i*screw_dist_/2, 0])
        {
            cylindera(d=thread_dia, h=base_thick_*3, orient=[1,0,0]);
        }

        // cut zrod
        cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
    }
}

module mount_rod_clamp_full(rod_d=10, screw_dist=undef, width=4, thick=undef, base_thick=undef, thread=ThreadM4, orient=[0,0,1])
{
    thick_=thick==undef?rod_d:thick;
    outer_d= rod_d+thick_*2;
    thread_dia=lookup(ThreadSize, thread);
    screw_dist_=screw_dist==undef?outer_d+thread_dia*2+thick_:screw_dist;
    base_thick_=base_thick==undef?thick_*1.5:base_thick;

    orient(orient)
    difference()
    {
        clamp_tolerance = 0.5*mm;
        base_cut = -rod_d/2 + clamp_tolerance;
        union()
        {
            // cylinder around rod
            cylindera(d=outer_d, h=width, orient=[0,0,1], align=[0,0,0], round_radius=2);

            // base
            translate([base_cut,0,0])
            rcubea([base_thick_, screw_dist_+thread_dia*2.5, width], align=[1,0,0]);
        }

        // cut bottom of cylinder
        translate([base_cut,0,0])
        cubea([outer_d/2+.1, screw_dist_+thread_dia*2.5+.1, width+1], align=[-1,0,0], extrasize=[clamp_tolerance,0,0], extrasize_align=[1,0,0]);

        // cut clamp screw holes
        for(i=[-1,1])
        translate([0, i*screw_dist_/2, 0])
        {
            cylindera(d=thread_dia, h=base_thick_*3, orient=[1,0,0]);
        }

        // cut zrod
        cylindera(d=rod_d*rod_fit_tolerance, h=width*2, orient=[0,0,1]);
    }
}

/*translate([20,0,0])*/
/*mount_rod_clamp_half(rod_d=yaxis_rod_d,  width=extrusion_size, thick=4, thread=ThreadM5);*/
/*mount_rod_clamp_full(rod_d=yaxis_rod_d,  width=extrusion_size, thick=4, thread=ThreadM5);*/


add the connector bar

add the connector bar

use <../../../basics/rounded-edges/doughnuts/doughnuts.scad>;

use <../../../shapes/geometry/arc/extruded/extruded-arc.scad>;

module halfCirclePhoneStand(height = 19.125,
                            minkowskiSphereRadius = 0.5,
                            arcRadius = 36,
                            arcRadiusExtension = 1.5)
{
    halfCirclePhoneStand_cradle(height = height,
                                minkowskiSphereRadius = minkowskiSphereRadius,
                                radius = arcRadius,
                                radiusExtension = arcRadiusExtension);

    halfCirclePhoneStand_stand(height = height,
                               minkowskiSphereRadius = minkowskiSphereRadius);
}

// sub-modules and functions follow

function halfCirclePhoneStand_cradle_cutout_zLength() = 4.2;

function halfCirclePhoneStand_cradle_cutout_zTranslate(minkowskiSphereRadius,
                                                        bedHeight,
                                                        zLength) = minkowskiSphereRadius + (bedHeight / 2.0) - (zLength / 2.0);

module halfCirclePhoneStand_cradle(height,
                                   minkowskiSphereRadius,
                                   radius,
                                   radiusExtension)
{
    xTranslate = 30;
    yTranslate = 32.7;

    difference()
    {
        halfCirclePhoneStand_cradle_bed(height = height,
                                           minkowskiSphereRadius = minkowskiSphereRadius,
                                           radius = radius,
                                           radiusExtension = radiusExtension,
                                           xTranslate = xTranslate,
                                           yTranslate = yTranslate);

        halfCirclePhoneStand_cradle_cutout(bedHeight = height,
                                        minkowskiSphereRadius = minkowskiSphereRadius,
                                        radius = radius,
                                        radiusExtension = radiusExtension,
                                        bed_xTranslate = xTranslate,
                                        bed_yTranslate = yTranslate);
    }
}

module halfCirclePhoneStand_cradle_bed(height,
                                       minkowskiSphereRadius,
                                       radius,
                                       radiusExtension,
                                       xTranslate,
                                       yTranslate)
{
    zTranslate = minkowskiSphereRadius;
    color("magenta")
    translate([xTranslate, yTranslate, zTranslate])
    rotate([0, 0, 213])
    roundedRectangularArc(angle = 150,
                          height = height,
                          minkowskiRadius = minkowskiSphereRadius,
                          radius = radius,
                          radiusExtension = radiusExtension);
}

module halfCirclePhoneStand_cradle_cutout(bedHeight,
                                          minkowskiSphereRadius,
                                          radius,
                                          radiusExtension,
                                          bed_xTranslate,
                                          bed_yTranslate)
{
    zLength = halfCirclePhoneStand_cradle_cutout_zLength();

    cutoutRadiusExtension = radiusExtension + 3;

    xTranslate = bed_xTranslate + 0.2;
    yTranslate = bed_yTranslate + 0.2;
    zTranslate = halfCirclePhoneStand_cradle_cutout_zTranslate(minkowskiSphereRadius = minkowskiSphereRadius,
                                                                bedHeight = bedHeight,
                                                                zLength = zLength);

    color("DarkTurquoise")
    translate([xTranslate, yTranslate, zTranslate])
    rotate([0, 0, 227])
    roundedRectangularArc(angle = 37,
                          height = zLength,
                          minkowskiRadius = minkowskiSphereRadius,
                          radius = radius,
                          radiusExtension = cutoutRadiusExtension);
}

module halfCirclePhoneStand_stand(height,
                                  minkowskiSphereRadius)
{
    halfCirclePhoneStand_stand_top(height = height,
                                   minkowskiSphereRadius = minkowskiSphereRadius);

    halfCirclePhoneStand_stand_connectorBar(bedHeight = height,
                                            minkowskiSphereRadius = minkowskiSphereRadius);

    halfCirclePhoneStand_stand_base(height = height,
                                    minkowskiSphereRadius = minkowskiSphereRadius);
}

module halfCirclePhoneStand_stand_base(height,
                                       minkowskiSphereRadius)
{
    color("green")
    translate([0, 0, minkowskiSphereRadius])
    roundDoughnut(height = height,
                innerRadius = 4.9,      // 4.9
                outerRadius = 5.59,     // 5.59
                minkowskiSphereRadius = minkowskiSphereRadius);
}

module halfCirclePhoneStand_stand_connectorBar(minkowskiSphereRadius, bedHeight)
{
    xLength = 40;
    yLength = 3;
    zLength = halfCirclePhoneStand_cradle_cutout_zLength() + minkowskiSphereRadius;

    xTranslate = 0;
    yTranslate = 0;
    zTranslate = halfCirclePhoneStand_cradle_cutout_zTranslate(minkowskiSphereRadius = minkowskiSphereRadius,
                                                                bedHeight = bedHeight,
                                                                zLength = zLength)
                    + (zLength / 2.0);

    translate([xTranslate, yTranslate, zTranslate])
//    rotate([0, 0, 45])
    cube([xLength, yLength, zLength]
    , center = true
    );
}

module halfCirclePhoneStand_stand_top(height,
                                      minkowskiSphereRadius)
{
    xTranslate = 8.105;  // 8.05     // 8.1
    yTranslate = 8.85;  // 8.85     // 8.9

    color("green")
    translate([xTranslate, yTranslate, minkowskiSphereRadius])
    roundDoughnut(height = height,
                innerRadius = 1.9,  // 2.0
                outerRadius = 2.6,  // 2.6
                minkowskiSphereRadius = minkowskiSphereRadius);
}

use <../../../basics/rounded-edges/doughnuts/doughnuts.scad>;

use <../../../shapes/geometry/arc/extruded/extruded-arc.scad>;

module halfCirclePhoneStand(height = 19.125,
                            minkowskiSphereRadius = 0.5,
                            arcRadius = 36,
                            arcRadiusExtension = 1.5)
{
    halfCirclePhoneStand_cradle(height = height,
                                minkowskiSphereRadius = minkowskiSphereRadius,
                                radius = arcRadius,
                                radiusExtension = arcRadiusExtension);

    halfCirclePhoneStand_stand(height = height,
                               minkowskiSphereRadius = minkowskiSphereRadius);
}

// sub-modules and functions follow

function halfCirclePhoneStand_cradle_cutout_zLength() = 4.2;

function halfCirclePhoneStand_cradle_cutout_zTranslate(minkowskiSphereRadius,
                                                        bedHeight,
                                                        zLength) = minkowskiSphereRadius + (bedHeight / 2.0) - (zLength / 2.0);

module halfCirclePhoneStand_cradle(height,
                                   minkowskiSphereRadius,
                                   radius,
                                   radiusExtension)
{
    xTranslate = 30;
    yTranslate = 32.7;

    difference()
    {
        halfCirclePhoneStand_cradle_bed(height = height,
                                           minkowskiSphereRadius = minkowskiSphereRadius,
                                           radius = radius,
                                           radiusExtension = radiusExtension,
                                           xTranslate = xTranslate,
                                           yTranslate = yTranslate);

        halfCirclePhoneStand_cradle_cutout(bedHeight = height,
                                        minkowskiSphereRadius = minkowskiSphereRadius,
                                        radius = radius,
                                        radiusExtension = radiusExtension,
                                        bed_xTranslate = xTranslate,
                                        bed_yTranslate = yTranslate);
    }
}

module halfCirclePhoneStand_cradle_bed(height,
                                       minkowskiSphereRadius,
                                       radius,
                                       radiusExtension,
                                       xTranslate,
                                       yTranslate)
{
    zTranslate = minkowskiSphereRadius;
    color("magenta")
    translate([xTranslate, yTranslate, zTranslate])
    rotate([0, 0, 213])
    roundedRectangularArc(angle = 150,
                          height = height,
                          minkowskiRadius = minkowskiSphereRadius,
                          radius = radius,
                          radiusExtension = radiusExtension);
}

module halfCirclePhoneStand_cradle_cutout(bedHeight,
                                          minkowskiSphereRadius,
                                          radius,
                                          radiusExtension,
                                          bed_xTranslate,
                                          bed_yTranslate)
{
    zLength = halfCirclePhoneStand_cradle_cutout_zLength();

    cutoutRadiusExtension = radiusExtension + 3;

    xTranslate = bed_xTranslate + 0.2;
    yTranslate = bed_yTranslate + 0.2;
    zTranslate = halfCirclePhoneStand_cradle_cutout_zTranslate(minkowskiSphereRadius = minkowskiSphereRadius,
                                                                bedHeight = bedHeight,
                                                                zLength = zLength);

    color("DarkTurquoise")
    translate([xTranslate, yTranslate, zTranslate])
    rotate([0, 0, 227])
    roundedRectangularArc(angle = 37,
                          height = zLength,
                          minkowskiRadius = minkowskiSphereRadius,
                          radius = radius,
                          radiusExtension = cutoutRadiusExtension);
}

module halfCirclePhoneStand_stand(height,
                                  minkowskiSphereRadius)
{
//PICK UP HERE

    halfCirclePhoneStand_stand_top(height = height,
                                   minkowskiSphereRadius = minkowskiSphereRadius);

//    halfCirclePhoneStand_stand_connectorBar();

    halfCirclePhoneStand_stand_base(height = height,
                                    minkowskiSphereRadius = minkowskiSphereRadius);
}

module halfCirclePhoneStand_stand_base(height,
                                       minkowskiSphereRadius)
{
    color("green")
    translate([0, 0, minkowskiSphereRadius])
    roundDoughnut(height = height,
                innerRadius = 4.9,      // 4.9
                outerRadius = 5.59,     // 5.59
                minkowskiSphereRadius = minkowskiSphereRadius);
}

module halfCirclePhoneStand_stand_connectorBar()
{
    cube([40, 5, 5]);
}

module halfCirclePhoneStand_stand_top(height,
                                      minkowskiSphereRadius)
{
    xTranslate = 8.105;  // 8.05     // 8.1
    yTranslate = 8.85;  // 8.85     // 8.9

    color("green")
    translate([xTranslate, yTranslate, minkowskiSphereRadius])
    roundDoughnut(height = height,
                innerRadius = 1.9,  // 2.0
                outerRadius = 2.6,  // 2.6
                minkowskiSphereRadius = minkowskiSphereRadius);
}


сахар Дезоксирибоза

сахар Дезоксирибоза

//Дезоксирибоза

$fn=5;
cylinder(15, 100, 100);

error: pathspec '3D-models/SCAD/DeOxyRibose.scad' did not match any file(s) known to git


buttons

buttons

$fn = 50;
button_h = 13;
overlap = 5;
//total_height = 22;
total_height = 19;
th = 2; // enclosure thickness
eps = 1e-1;

cap_r = 10.2 / 2;
cap_h = total_height - button_h + overlap;
cap_r_bottom = 3;

border_offset = 4 + th;
border_h = 3;
border_r = cap_r + 2;

socket_r = 3.2 / 2;

difference() {
  union() {
    cylinder(r=cap_r_bottom, h=cap_h);
    translate([0, 0, cap_h - border_h - border_offset]) {
      cylinder(r=border_r, h=border_h);
      cylinder(r=cap_r, h=border_h + border_offset);
    }
  }
  translate([0, 0, -eps]) {
    cylinder(r=socket_r, h=overlap+eps);
  }
}

$fn = 50;
button_h = 13;
overlap = 5;
//total_height = 22;
total_height = 19;
th = 2; // enclosure thickness
eps = 1e-1;

//cap_r = 4.5;
cap_r = 6.5 / 2;
cap_h = total_height - button_h + overlap;

border_offset = 4.5 + th;
border_h = 3;
border_r = cap_r + 2;

socket_r = 3.2 / 2;

difference() {
  union() {
    cylinder(r=cap_r, h=cap_h);
    translate([0, 0, cap_h - border_h - border_offset]) {
      cylinder(r=border_r, h=border_h);
    }
  }
  translate([0, 0, -eps]) {
    cylinder(r=socket_r, h=overlap+eps);
  }
}


Adding cut-outs

Adding cut-outs

UP = 0;
DOWN = 180;
LEFT = 90;
RIGHT = 270;
MID = 360;

generate = $generate == undef ? 0: $generate;

if (generate == 1)
{
    // openscad examples.scad -D generate=1 -o /tmp/d.csg 2>&1 >/dev/null  | sed 's/ECHO: \"\[LC\] //' | sed 's/"$//' | sed '$a;' >./generate.scad ; openscad ./generate.scad -o generate.dxf
    // (from http://forum.openscad.org/Sharing-Dump-echo-output-to-a-file-td12529.html)
    echo("[LC] use <lasercut.scad>; \nprojection(cut = false) \n\t");
}

module lasercutoutSquare(thickness=3.1, x=0, y=0,
        simple_tabs=[], simple_tab_holes=[],
        captive_nuts=[], captive_nut_holes = [],
        finger_joints = [],
        circles_add = [],
        circles_remove = [],
        slits = [],
        cutouts = [],
)
{
    points = [[0,0], [x,0], [x,y], [0,y], [0,0]];
lasercutout(thickness=thickness,
        points = points,
        simple_tabs = simple_tabs,
        simple_tab_holes = simple_tab_holes,
        captive_nuts = captive_nuts,
        captive_nut_holes = captive_nut_holes,
        finger_joints = finger_joints,
        circles_add = circles_add,
        circles_remove = circles_remove,
        slits = slits,
        cutouts = cutouts
    );
}

module lasercutout(thickness=3.1,  points= [],
        simple_tabs=[], simple_tab_holes=[],
        captive_nuts=[], captive_nut_holes = [],
        finger_joints = [],
        circles_add = [],
        circles_remove = [],
        slits = [],
        cutouts = [],
)
{
    path_total = len(points);
    path = [ for (p = [0 : 1 : path_total]) p ];

    function max_y(points) = max([for (a = [0:1:len(points)-1])  points[a][1]]);
    function min_y(points) = min([for (a = [0:1:len(points)-1])  points[a][1]]);
    function max_x(points) = max([for (a = [0:1:len(points)-1])  points[a][0]]);
    function min_x(points) = min([for (a = [0:1:len(points)-1])  points[a][0]]);

    max_y = max_y(points);
    min_y = min_y(points);
    max_x = max_x(points);
    min_x = min_x(points);

    difference()
    {
        union()
        {
            linear_extrude(height = thickness , center = false)  polygon(points=points, path=path);
            for (t = [0:1:len(simple_tabs)-1])
            {
                simpleTab(simple_tabs[t][0], simple_tabs[t][1], simple_tabs[t][2], thickness);
            }
            for (t = [0:1:len(captive_nuts)-1])
            {
                captiveNutTab(captive_nuts[t][0], captive_nuts[t][1], captive_nuts[t][2], thickness);
            }
            for (t = [0:1:len(circles_add)-1])
            {
                circlesAdd(circles_add[t][0], circles_add[t][1], circles_add[t][2], thickness);
            }
            for (t = [0:1:len(finger_joints)-1])
            {
                fingerJoint(finger_joints[t][0], finger_joints[t][1], finger_joints[t][2], thickness, max_y, min_y, max_x, min_x) ;
            }

        } // end union

        for (t = [0:1:len(simple_tab_holes)-1])
        {
               simpleTabHole(simple_tab_holes[t][0], simple_tab_holes[t][1], simple_tab_holes[t][2], thickness);
        }
        for (t = [0:1:len(captive_nuts)-1])
        {
            captiveNutBoltHole(captive_nuts[t][0], captive_nuts[t][1], captive_nuts[t][2], thickness);
        }
        for (t = [0:1:len(captive_nut_holes)-1])
        {
            captiveNutHole(captive_nut_holes[t][0], captive_nut_holes[t][1], captive_nut_holes[t][2], thickness);
        }
        for (t = [0:1:len(circles_remove)-1])
        {
            circlesRemove(circles_remove[t][0], circles_remove[t][1], circles_remove[t][2], thickness);
        }
        for (t = [0:1:len(slits)-1])
        {
               simpleSlit(slits[t][0], slits[t][1], slits[t][2], slits[t][3], thickness);
        }
        for (t = [0:1:len(cutouts)-1])
        {
               simpleCutouts(cutouts[t][0], cutouts[t][1], cutouts[t][2], cutouts[t][3], thickness);
        }

    }

    if ($children) translate([0, max_y(points) + thickness*3, 0])
            children();

    if (generate == 1)
    {
        output = str(
        "[LC] lasercutout(thickness=", thickness, ", \n
            points= ", points, ", \n
            simple_tabs = ",simple_tabs,", \n
            simple_tab_holes = ",simple_tab_holes,", \n
            captive_nuts = ",captive_nuts,", \n
            captive_nut_holes = ",captive_nut_holes,", \n
            finger_joints = ",finger_joints,", \n
            circles_add = ",circles_add,", \n
            circles_remove = ",circles_remove,", \n
            slits = ",slits,", \n
            cutouts = ",cutouts,") \n"
        );
        echo(output);
    }
}

module simpleTab(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle]) translate([-thickness/2,0,0]) cube([thickness, thickness, thickness]);
}

module simpleTabHole(angle, x, y, thickness)
{
     // Special case does not go past edge - so make only 1 thickness y
     if (angle == 360)
     {
         translate([x,y,0]) rotate([0,0,0]) translate([0,0,-thickness]) cube([thickness, thickness, thickness*3]);
     }
     else
     {
         translate([x,y,0]) rotate([0,0,angle-180]) translate([-thickness/2,-thickness,-thickness]) cube([thickness, thickness*2, thickness*3]);
     }
}

module captiveNutBoltHole(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle-180]) union()
    {
        translate([-thickness/2,-thickness,-thickness]) cube([thickness, thickness*4, thickness*3]);
        translate([-thickness/2-thickness,thickness,-thickness]) cube([thickness*3, thickness, thickness*3]);
    }
}

module fingerJoint(angle, start_up, fingers, thickness, max_y, min_y, max_x, min_x)
{
    if ( angle == UP )
    {
        range_min = min_x;
        range_max = max_x;
        t_x = min_x;
        t_y = max_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }
    if ( angle == DOWN )
    {
        range_min = min_x;
        range_max = max_x;
        t_x = max_x;
        t_y = min_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }
    if ( angle == LEFT )
    {
        range_min = min_y;
        range_max = max_y;
        t_x = min_x;
        t_y = min_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }
    if ( angle == RIGHT )
    {
        range_min = min_y;
        range_max = max_y;
        t_x = max_x;
        t_y = max_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }

}

module fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y)
{
    // The tweaks to y translate([0, -thickness,0]) ... thickness*2 rather than *1
    // Are to avoid edge cases and make the dxf export better.
    // All fun
    translate([t_x, t_y,0]) rotate([0,0,angle]) translate([0, -thickness,0])
    {
        for ( i = [range_min : (range_max-range_min)/fingers : range_max - (range_max-range_min)/fingers] )
        {
            if(start_up == 1)
                {
                    translate([i,0,0]) cube([ (range_max-range_min)/(fingers*2), thickness*2, thickness]);
                }
            else
            {
                    translate([i+(range_max-range_min)/(fingers*2),0,0]) cube([ (range_max-range_min)/(fingers*2), thickness*2, thickness]);

            }
        }
    }

}

module captiveNutTab(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle]) union()
    {
        translate([-thickness/2+thickness*2,0,0]) cube([thickness*3, thickness, thickness]);
        translate([-thickness/2-thickness*4,0,0]) cube([thickness*3, thickness, thickness]);
    }
}

module captiveNutHole(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle]) union()
    {
        translate([-thickness/2,-thickness*2,-thickness]) cube([thickness, thickness, thickness*3]);
        translate([-thickness/2+thickness*2,-thickness*2,-thickness]) cube([thickness*3, thickness, thickness*3]);
        translate([-thickness/2-thickness*4,-thickness*2,-thickness]) cube([thickness*3, thickness, thickness*3]);
    }
}

module circlesAdd(radius, x, y, thickness)
{
    translate([x,y,0]) cylinder(h=thickness, r=radius);
}

module circlesRemove(radius, x, y, thickness)
{
    translate([x,y,-thickness]) cylinder(h=thickness*3, r=radius);
}

module simpleSlit(angle, x, y, length, thickness)
{
     translate([x,y,0]) rotate([0,0,angle-180]) translate([-thickness/2,-thickness,-thickness]) cube([thickness, length+thickness, thickness*3]);
}

module simpleCutouts(x, y, width, height, thickness)
{
     translate([x,y,0]) rotate([0,0,0]) translate([0,0,-thickness]) cube([width, height, thickness*3]);
}

module lasercutoutBox(thickness = 3.1, x=0, y=0, z=0, sides=6,
        simple_tab_holes_a=[],
        captive_nuts_a=[], captive_nut_holes_a=[],
        circles_add_a=[],
        circles_remove_a=[],
        slits_a = [],
        cutouts_a = [],
)
{
    if (sides==4)
    {
        fj = [
            [ [UP, 1, 4], [DOWN, 1, 4],    ],
            [ [UP, 0, 4], [DOWN, 1, 4],    ],
            [ [UP, 1, 4], [DOWN, 0, 4],    ],
            [ [UP, 1, 4], [DOWN, 1, 4],    ],
        ];
        translate([0,thickness,0]) lasercutoutBoxAdjustedFJ(thickness = thickness, x=x, y=y-thickness*2 , z=z-thickness*2, sides=sides, fj=fj,
            simple_tab_holes_a=simple_tab_holes_a,
            captive_nuts_a=captive_nuts_a, captive_nut_holes_a=captive_nut_holes_a,
            circles_add_a=circles_add_a,
            circles_remove_a=circles_remove_a,
            slits_a=slits_a,
            cutouts_a=cutouts_a);
    }
    if (sides==5)
    {
        st = [
        [[DOWN, -thickness/2, 0], [DOWN, -thickness/2, y-thickness] ],
        [[DOWN, -thickness/2, 0], ],
        [[UP, -thickness/2, z-thickness*2], ],
        ];
        fj = [
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4],   ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 1, 4],   ],
            [ [UP, 1, 4], [DOWN, 0, 4], [LEFT, 1, 4],   ],
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4],   ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 0, 4], [RIGHT, 1, 4]  ],
        ];

        translate([thickness,thickness,0]) lasercutoutBoxAdjustedFJ(thickness = thickness, x=x-thickness, y=y-thickness*2 , z=z-thickness*2, sides=sides, fj=fj, st=st,
            simple_tab_holes_a=simple_tab_holes_a,
            captive_nuts_a=captive_nuts_a, captive_nut_holes_a=captive_nut_holes_a,
            circles_add_a=circles_add_a,
            circles_remove_a=circles_remove_a,
            slits_a=slits_a,
            cutouts_a=cutouts_a);
        }
    if (sides==6)
    {
        st = [
        [[DOWN, -thickness/2, 0], [DOWN, -thickness/2, y-thickness] , [RIGHT, x-thickness*2, -thickness/2]],
        [[DOWN, -thickness/2, 0], [RIGHT, x-thickness*2, -thickness/2]],
        [[UP, -thickness/2, z-thickness*2], [DOWN, x-thickness*1.5, 0], ],
        [[UP, z-thickness*1.5, y-thickness*2], ],
        ];
        fj = [
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 1, 4], [DOWN, 0, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 0, 4], [RIGHT, 1, 4]  ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 0, 4], [RIGHT, 1, 4]  ],
        ];
        translate([thickness,thickness,0]) lasercutoutBoxAdjustedFJ(thickness = thickness, x=x-thickness*2, y=y-thickness*2 , z=z-thickness*2, sides=sides, fj=fj, st=st,
            simple_tab_holes_a=simple_tab_holes_a,
            captive_nuts_a=captive_nuts_a, captive_nut_holes_a=captive_nut_holes_a,
            circles_add_a=circles_add_a,
            circles_remove_a=circles_remove_a,
            slits_a=slits_a,
            cutouts_a=cutouts_a);
    }
}

module lasercutoutBoxAdjustedFJ(thickness = 3.1, x=0, y=0, z=0, sides=6, fj=[], st=[],
        simple_tab_holes_a=[],
        captive_nuts_a=[], captive_nut_holes_a = [],
        circles_add_a = [],
        circles_remove_a = [],
        slits_a = [],
        cutouts_a = [])
{
    translate([0,0,0]) lasercutoutSquare(x=x, y=y, simple_tabs = st[0], finger_joints = fj[0],
                                simple_tab_holes=simple_tab_holes_a[0], captive_nuts=captive_nuts_a[0],
                                captive_nut_holes = captive_nut_holes_a[0],
                                circles_add = circles_add_a[0], circles_remove = circles_remove_a[0],
                                slits = slits_a[0],
                                cutouts = cutouts_a[0]);

    translate([0,0,z+thickness]) lasercutoutSquare(x=x, y=y, simple_tabs = st[1], finger_joints = fj[1],
                                simple_tab_holes=simple_tab_holes_a[1], captive_nuts=captive_nuts_a[1],
                                captive_nut_holes = captive_nut_holes_a[1],
                                circles_add = circles_add_a[1], circles_remove = circles_remove_a[1],
                                slits = slits_a[1],
                                cutouts = cutouts_a[1]);

    translate([0,0,thickness]) rotate([90,0,0]) lasercutoutSquare(x=x, y=z, finger_joints = fj[2],
                                simple_tab_holes=simple_tab_holes_a[2], captive_nuts=captive_nuts_a[2],
                                captive_nut_holes = captive_nut_holes_a[2],
                                circles_add = circles_add_a[2], circles_remove = circles_remove_a[2],
                                slits = slits_a[2],
                                cutouts = cutouts_a[2]);

    translate([0,y+thickness,thickness]) rotate([90,0,0]) lasercutoutSquare(x=x, y=z, simple_tabs = st[2],
                                finger_joints = fj[3],
                                simple_tab_holes=simple_tab_holes_a[3], captive_nuts=captive_nuts_a[3],
                                captive_nut_holes = captive_nut_holes_a[3],
                                circles_add = circles_add_a[3], circles_remove = circles_remove_a[3],
                                slits = slits_a[3],
                                cutouts = cutouts_a[3]);

    if (sides>4)
    {
        translate([0,0,thickness]) rotate([0,-90,0]) lasercutoutSquare(x=z, y=y, finger_joints = fj[4],
                                simple_tab_holes=simple_tab_holes_a[4], captive_nuts=captive_nuts_a[4],
                                captive_nut_holes = captive_nut_holes_a[4],
                                circles_add = circles_add_a[4], circles_remove = circles_remove_a[4],
                                slits = slits_a[4],
                                cutouts = cutouts_a[4]);
        }

    if (sides>5)
    {
        translate([x+thickness,0,thickness]) rotate([0,-90,0]) lasercutoutSquare(x=z, y=y,
                                simple_tabs = st[3], finger_joints = fj[5],
                                simple_tab_holes=simple_tab_holes_a[5], captive_nuts=captive_nuts_a[5],
                                captive_nut_holes = captive_nut_holes_a[5],
                                circles_add = circles_add_a[5], circles_remove = circles_remove_a[5],
                                slits = slits_a[5],
                                cutouts = cutouts_a[5]);
    }
}

UP = 0;
DOWN = 180;
LEFT = 90;
RIGHT = 270;
MID = 360;

generate = $generate == undef ? 0: $generate;

if (generate == 1)
{
    // openscad examples.scad -D generate=1 -o /tmp/d.csg 2>&1 >/dev/null  | sed 's/ECHO: \"\[LC\] //' | sed 's/"$//' | sed '$a;' >./generate.scad ; openscad ./generate.scad -o generate.dxf
    // (from http://forum.openscad.org/Sharing-Dump-echo-output-to-a-file-td12529.html)
    echo("[LC] use <lasercut.scad>; \nprojection(cut = false) \n\t");
}

module lasercutoutSquare(thickness=3.1, x=0, y=0,
        simple_tabs=[], simple_tab_holes=[],
        captive_nuts=[], captive_nut_holes = [],
        finger_joints = [],
        circles_add = [],
        circles_remove = [],
        slits = [],
)
{
    points = [[0,0], [x,0], [x,y], [0,y], [0,0]];
lasercutout(thickness=thickness,
        points = points,
        simple_tabs = simple_tabs,
        simple_tab_holes = simple_tab_holes,
        captive_nuts = captive_nuts,
        captive_nut_holes = captive_nut_holes,
        finger_joints = finger_joints,
        circles_add = circles_add,
        circles_remove = circles_remove,
        slits = slits
    );
}

module lasercutout(thickness=3.1,  points= [],
        simple_tabs=[], simple_tab_holes=[],
        captive_nuts=[], captive_nut_holes = [],
        finger_joints = [],
        circles_add = [],
        circles_remove = [],
        slits = [],
)
{
    path_total = len(points);
    path = [ for (p = [0 : 1 : path_total]) p ];

    function max_y(points) = max([for (a = [0:1:len(points)-1])  points[a][1]]);
    function min_y(points) = min([for (a = [0:1:len(points)-1])  points[a][1]]);
    function max_x(points) = max([for (a = [0:1:len(points)-1])  points[a][0]]);
    function min_x(points) = min([for (a = [0:1:len(points)-1])  points[a][0]]);

    max_y = max_y(points);
    min_y = min_y(points);
    max_x = max_x(points);
    min_x = min_x(points);

    difference()
    {
        union()
        {
            linear_extrude(height = thickness , center = false)  polygon(points=points, path=path);
            for (t = [0:1:len(simple_tabs)-1])
            {
                simpleTab(simple_tabs[t][0], simple_tabs[t][1], simple_tabs[t][2], thickness);
            }
            for (t = [0:1:len(captive_nuts)-1])
            {
                captiveNutTab(captive_nuts[t][0], captive_nuts[t][1], captive_nuts[t][2], thickness);
            }
            for (t = [0:1:len(circles_add)-1])
            {
                circlesAdd(circles_add[t][0], circles_add[t][1], circles_add[t][2], thickness);
            }
            for (t = [0:1:len(finger_joints)-1])
            {
                fingerJoint(finger_joints[t][0], finger_joints[t][1], finger_joints[t][2], thickness, max_y, min_y, max_x, min_x) ;
            }

        } // end union

        for (t = [0:1:len(simple_tab_holes)-1])
        {
               simpleTabHole(simple_tab_holes[t][0], simple_tab_holes[t][1], simple_tab_holes[t][2], thickness);
        }
        for (t = [0:1:len(captive_nuts)-1])
        {
            captiveNutBoltHole(captive_nuts[t][0], captive_nuts[t][1], captive_nuts[t][2], thickness);
        }
        for (t = [0:1:len(captive_nut_holes)-1])
        {
            captiveNutHole(captive_nut_holes[t][0], captive_nut_holes[t][1], captive_nut_holes[t][2], thickness);
        }
        for (t = [0:1:len(circles_remove)-1])
        {
            circlesRemove(circles_remove[t][0], circles_remove[t][1], circles_remove[t][2], thickness);
        }
        for (t = [0:1:len(slits)-1])
        {
               simpleSlit(slits[t][0], slits[t][1], slits[t][2], slits[t][3], thickness);
        }

    }

    if ($children) translate([0, max_y(points) + thickness*3, 0])
            children();

    if (generate == 1)
    {
        output = str(
        "[LC] lasercutout(thickness=", thickness, ", \n
            points= ", points, ", \n
            simple_tabs = ",simple_tabs,", \n
            simple_tab_holes = ",simple_tab_holes,", \n
            captive_nuts = ",captive_nuts,", \n
            captive_nut_holes = ",captive_nut_holes,", \n
            finger_joints = ",finger_joints,", \n
            circles_add = ",circles_add,", \n
            circles_remove = ",circles_remove,", \n
            slits = ",slits,") \n"
        );
        echo(output);
    }
}

module simpleTab(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle]) translate([-thickness/2,0,0]) cube([thickness, thickness, thickness]);
}

module simpleTabHole(angle, x, y, thickness)
{
     // Special case does not go past edge - so make only 1 thickness y
     if (angle == 360)
     {
         translate([x,y,0]) rotate([0,0,0]) translate([0,0,-thickness]) cube([thickness, thickness, thickness*3]);
     }
     else
     {
         translate([x,y,0]) rotate([0,0,angle-180]) translate([-thickness/2,-thickness,-thickness]) cube([thickness, thickness*2, thickness*3]);
     }
}

module captiveNutBoltHole(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle-180]) union()
    {
        translate([-thickness/2,-thickness,-thickness]) cube([thickness, thickness*4, thickness*3]);
        translate([-thickness/2-thickness,thickness,-thickness]) cube([thickness*3, thickness, thickness*3]);
    }
}

module fingerJoint(angle, start_up, fingers, thickness, max_y, min_y, max_x, min_x)
{
    if ( angle == UP )
    {
        range_min = min_x;
        range_max = max_x;
        t_x = min_x;
        t_y = max_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }
    if ( angle == DOWN )
    {
        range_min = min_x;
        range_max = max_x;
        t_x = max_x;
        t_y = min_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }
    if ( angle == LEFT )
    {
        range_min = min_y;
        range_max = max_y;
        t_x = min_x;
        t_y = min_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }
    if ( angle == RIGHT )
    {
        range_min = min_y;
        range_max = max_y;
        t_x = max_x;
        t_y = max_y;
        fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y);
    }

}

module fingers(angle, start_up, fingers, thickness, range_min, range_max, t_x, t_y)
{
    // The tweaks to y translate([0, -thickness,0]) ... thickness*2 rather than *1
    // Are to avoid edge cases and make the dxf export better.
    // All fun
    translate([t_x, t_y,0]) rotate([0,0,angle]) translate([0, -thickness,0])
    {
        for ( i = [range_min : (range_max-range_min)/fingers : range_max - (range_max-range_min)/fingers] )
        {
            if(start_up == 1)
                {
                    translate([i,0,0]) cube([ (range_max-range_min)/(fingers*2), thickness*2, thickness]);
                }
            else
            {
                    translate([i+(range_max-range_min)/(fingers*2),0,0]) cube([ (range_max-range_min)/(fingers*2), thickness*2, thickness]);

            }
        }
    }

}

module captiveNutTab(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle]) union()
    {
        translate([-thickness/2+thickness*2,0,0]) cube([thickness*3, thickness, thickness]);
        translate([-thickness/2-thickness*4,0,0]) cube([thickness*3, thickness, thickness]);
    }
}

module captiveNutHole(angle, x, y, thickness)
{
    translate([x,y,0]) rotate([0,0,angle]) union()
    {
        translate([-thickness/2,-thickness*2,-thickness]) cube([thickness, thickness, thickness*3]);
        translate([-thickness/2+thickness*2,-thickness*2,-thickness]) cube([thickness*3, thickness, thickness*3]);
        translate([-thickness/2-thickness*4,-thickness*2,-thickness]) cube([thickness*3, thickness, thickness*3]);
    }
}

module circlesAdd(radius, x, y, thickness)
{
    translate([x,y,0]) cylinder(h=thickness, r=radius);
}

module circlesRemove(radius, x, y, thickness)
{
    translate([x,y,-thickness]) cylinder(h=thickness*3, r=radius);
}

module simpleSlit(angle, x, y, length, thickness)
{
     translate([x,y,0]) rotate([0,0,angle-180]) translate([-thickness/2,-thickness,-thickness]) cube([thickness, length+thickness, thickness*3]);
}

module lasercutoutBox(thickness = 3.1, x=0, y=0, z=0, sides=6,
        simple_tab_holes_a=[],
        captive_nuts_a=[], captive_nut_holes_a=[],
        circles_add_a=[],
        circles_remove_a=[],
        slits_a = [],
)
{
    if (sides==4)
    {
        fj = [
            [ [UP, 1, 4], [DOWN, 1, 4],    ],
            [ [UP, 0, 4], [DOWN, 1, 4],    ],
            [ [UP, 1, 4], [DOWN, 0, 4],    ],
            [ [UP, 1, 4], [DOWN, 1, 4],    ],
        ];
        translate([0,thickness,0]) lasercutoutBoxAdjustedFJ(thickness = thickness, x=x, y=y-thickness*2 , z=z-thickness*2, sides=sides, fj=fj,
            simple_tab_holes_a=simple_tab_holes_a,
            captive_nuts_a=captive_nuts_a, captive_nut_holes_a=captive_nut_holes_a,
            circles_add_a=circles_add_a,
            circles_remove_a=circles_remove_a,
            slits_a=slits_a);
    }
    if (sides==5)
    {
        st = [
        [[DOWN, -thickness/2, 0], [DOWN, -thickness/2, y-thickness] ],
        [[DOWN, -thickness/2, 0], ],
        [[UP, -thickness/2, z-thickness*2], ],
        ];
        fj = [
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4],   ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 1, 4],   ],
            [ [UP, 1, 4], [DOWN, 0, 4], [LEFT, 1, 4],   ],
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4],   ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 0, 4], [RIGHT, 1, 4]  ],
        ];

        translate([thickness,thickness,0]) lasercutoutBoxAdjustedFJ(thickness = thickness, x=x-thickness, y=y-thickness*2 , z=z-thickness*2, sides=sides, fj=fj, st=st,
            simple_tab_holes_a=simple_tab_holes_a,
            captive_nuts_a=captive_nuts_a, captive_nut_holes_a=captive_nut_holes_a,
            circles_add_a=circles_add_a,
            circles_remove_a=circles_remove_a,
            slits_a=slits_a);
        }
    if (sides==6)
    {
        st = [
        [[DOWN, -thickness/2, 0], [DOWN, -thickness/2, y-thickness] , [RIGHT, x-thickness*2, -thickness/2]],
        [[DOWN, -thickness/2, 0], [RIGHT, x-thickness*2, -thickness/2]],
        [[UP, -thickness/2, z-thickness*2], [DOWN, x-thickness*1.5, 0], ],
        [[UP, z-thickness*1.5, y-thickness*2], ],
        ];
        fj = [
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 1, 4], [DOWN, 0, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 1, 4], [DOWN, 1, 4], [LEFT, 1, 4], [RIGHT, 0, 4]  ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 0, 4], [RIGHT, 1, 4]  ],
            [ [UP, 0, 4], [DOWN, 1, 4], [LEFT, 0, 4], [RIGHT, 1, 4]  ],
        ];
        translate([thickness,thickness,0]) lasercutoutBoxAdjustedFJ(thickness = thickness, x=x-thickness*2, y=y-thickness*2 , z=z-thickness*2, sides=sides, fj=fj, st=st,
            simple_tab_holes_a=simple_tab_holes_a,
            captive_nuts_a=captive_nuts_a, captive_nut_holes_a=captive_nut_holes_a,
            circles_add_a=circles_add_a,
            circles_remove_a=circles_remove_a,
            slits_a=slits_a);
    }
}

module lasercutoutBoxAdjustedFJ(thickness = 3.1, x=0, y=0, z=0, sides=6, fj=[], st=[],
        simple_tab_holes_a=[],
        captive_nuts_a=[], captive_nut_holes_a = [],
        circles_add_a = [],
        circles_remove_a = [],
        slits_a)
{
    translate([0,0,0]) lasercutoutSquare(x=x, y=y, simple_tabs = st[0], finger_joints = fj[0],
                                simple_tab_holes=simple_tab_holes_a[0], captive_nuts=captive_nuts_a[0],
                                captive_nut_holes = captive_nut_holes_a[0],
                                circles_add = circles_add_a[0], circles_remove = circles_remove_a[0],
                                slits = slits_a[0]);

    translate([0,0,z+thickness]) lasercutoutSquare(x=x, y=y, simple_tabs = st[1], finger_joints = fj[1],
                                simple_tab_holes=simple_tab_holes_a[1], captive_nuts=captive_nuts_a[1],
                                captive_nut_holes = captive_nut_holes_a[1],
                                circles_add = circles_add_a[1], circles_remove = circles_remove_a[1],
                                slits = slits_a[1]);

    translate([0,0,thickness]) rotate([90,0,0]) lasercutoutSquare(x=x, y=z, finger_joints = fj[2],
                                simple_tab_holes=simple_tab_holes_a[2], captive_nuts=captive_nuts_a[2],
                                captive_nut_holes = captive_nut_holes_a[2],
                                circles_add = circles_add_a[2], circles_remove = circles_remove_a[2],
                                slits = slits_a[2]);

    translate([0,y+thickness,thickness]) rotate([90,0,0]) lasercutoutSquare(x=x, y=z, simple_tabs = st[2],
                                finger_joints = fj[3],
                                simple_tab_holes=simple_tab_holes_a[3], captive_nuts=captive_nuts_a[3],
                                captive_nut_holes = captive_nut_holes_a[3],
                                circles_add = circles_add_a[3], circles_remove = circles_remove_a[3],
                                slits = slits_a[3]);

    if (sides>4)
    {
        translate([0,0,thickness]) rotate([0,-90,0]) lasercutoutSquare(x=z, y=y, finger_joints = fj[4],
                                simple_tab_holes=simple_tab_holes_a[4], captive_nuts=captive_nuts_a[4],
                                captive_nut_holes = captive_nut_holes_a[4],
                                circles_add = circles_add_a[4], circles_remove = circles_remove_a[4],
                                slits = slits_a[4]);
        }

    if (sides>5)
    {
        translate([x+thickness,0,thickness]) rotate([0,-90,0]) lasercutoutSquare(x=z, y=y,
                                simple_tabs = st[3], finger_joints = fj[5],
                                simple_tab_holes=simple_tab_holes_a[5], captive_nuts=captive_nuts_a[5],
                                captive_nut_holes = captive_nut_holes_a[5],
                                circles_add = circles_add_a[5], circles_remove = circles_remove_a[5],
                                slits = slits_a[5]);
    }
}


make support wall a little thicker for cura

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/JansenFoot.scad $
// $Id: JansenFoot.scad 438 2015-03-03 14:39:59Z mrwhat $

padH = 0.3;  // extra clearance amount for H end of CH link

module bracedFoot(dLeft,dBase,dPerp) { // ---------------- foot with out-of-axis support
braceHeight = NodeHeight3; // 3*TrueNodeHeight-.4;  // A little shorter than the hinge-pin
dRight = 0.9 * (dBase-dLeft);  // scoot brace in a bit from foot
dLeft1 = dLeft-Frad-1-((0.5*Frad)/(dLeft-Frad-1));
union() { difference() { union() {
   translate([-dLeft,0,0]) {
      cylinder(h=NodeHeight,r1=Frad+.2,r2=Frad-.2,$fn=48); }
   hull() {
      translate([0,dPerp,0]) cylinder(h=braceHeight,r1=Hrad+2,r2=Hrad+1.6,$fn=48);
      translate([0,dPerp-3,0]) cylinder(h=braceHeight-1,r1=Hrad+1,r2=Hrad+0.5,$fn=32);
      translate([.22*dRight,.85*dPerp,1.1]) sphere(r=1,$fn=6); }
   hull() {
      translate([0,dPerp,0]) cylinder(h=braceHeight,r1=Hrad+1.9,r2=Hrad+1.4,$fn=48);
      translate([0,dPerp-3,0]) cylinder(h=braceHeight-1,r1=Hrad+1,r2=Hrad+0.5,$fn=32);
      translate([-.28*dLeft1,(1-.23)*dPerp,2]) sphere(r=1,$fn=6); }

   // foot
   translate([dBase-dLeft-LinkRad,0,0]) cylinder(h=NodeHeight+.5,r=LinkRad,$fn=80);

   hull() {
      translate([0,dPerp ,0]) cylinder(h=braceHeight  ,r1=1.6,r2=1,$fn=6);
      translate([dRight,0,0]) cylinder(h=BarHeight+1.5,r1=1.6,r2=1,$fn=6); }
   hull() {
      translate([0,dPerp ,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6);
      translate([dRight,0,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6); }
   hull() {
      translate([-dLeft1,-Frad*0.5,0])  cylinder(h=BarHeight+1.5,r1=1.6,r2=1,$fn=6);
      translate([0,dPerp,0])            cylinder(h=braceHeight  ,r1=1.6,r2=1,$fn=6); }
   hull() {
      translate([-dLeft1+((8*Frad)/(dLeft-Frad-1)),0,0])
                             cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6);
      translate([0,dPerp,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6); }
   hull() {     // re-inforcing pyramid over main, long leg
      translate([-dLeft+2*Frad,0,0]) cylinder(h=BarHeight,r1=Frad-1,r2=Frad-3,$fn=6);
      translate([dBase-dLeft-2*LinkRad,0,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-2,$fn=6);
      translate([0,0,1.5*NodeHeight-1]) sphere(r=1,$fn=16);   }

   difference() { hull() {   // main, long-leg segment
      translate([-dLeft,0,0]) {      nodeCyl(BarHeight,Frad-1);
      translate([dBase-LinkRad,0,0]) nodeCyl(BarHeight,LinkRad-1); }
     }
     translate([-dLeft,0,-1.5]) hull(){nodeCyl(BarHeight,Frad-2.4);
        translate([dBase-LinkRad-2,0,0])nodeCyl(BarHeight,.4);}
   }

   hull(){   // stop to keep "knee" from hyper-extending
      translate([-dLeft-Frad+2,0,0]) cylinder(h=BarHeight,r=2,$fn=8);
      translate([-dLeft,-Frad+2,0])  cylinder(h=BarHeight,r=2,$fn=8);
      translate([-dLeft-Frad+2,-Frad-3,0]) cylinder(h=BarHeight,r=2,$fn=12); }
   translate(   [-dLeft-Frad+2,-Frad-3,0]) cylinder(h=3*BarHeight,r1=3,r2=2,$fn=24);
   }
   translate([0,dPerp,0])  drillHole(Hrad);
   translate([-dLeft,0,0]) drillHole(Drad);

   // hollow out re-inforcing pyramid
   hull() { translate([-dLeft+2*Frad+2,0,-1.5]) cylinder(h=BarHeight,r1=Frad-2,r2=Frad-4,$fn=6);
      translate([dBase-dLeft-3*LinkRad,0,-1.5]) cylinder(h=BarHeight,r1=1.5,r2=.2,$fn=6);
      translate([0,0,1.5*NodeHeight-2.5]) sphere(r=0.5,$fn=16); }

   // had trouble with fill around braced link.  See if adding little hollows
   // helps slicer to fill better
   translate([-dLeft,0,NodeHeight/2]) {
      for(a=[0,30,60,90,120,150,180,210,240,270,300,330]) {
         translate([0.5*(Frad+Drad)*cos(a),0.5*(Frad+Drad)*sin(a),0])
            cylinder(h=NodeHeight-1.4,r=.4,$fn=6,center=true);
   }}

   // knock out a slot to take the CH linkage.
   translate([0,dPerp,NodeHeight-padH]) {
      cylinder(h=NodeHeight+2*padH,r=Hrad+3,$fn=48);
      hull() {
         translate([ 0,-4,0]) cube([.1,.1,NodeHeight+2*padH]);
         translate([ 7,-1,0]) cube([2,5,NodeHeight+2*padH]);
         translate([-7,-2,0]) cube([1,5,NodeHeight+2*padH]);
      }
   }

   //cube([3,11,11]);   // diagnostic slice to examine pyramid shell
   }
}

// custom support at H node
color("Cyan") union() {
  translate([0,29,NodeHeight-padH*.9]) difference() {
    cylinder(r2=4.4,r1=3.73,h=NodeHeight-.5,$fn=8);
    translate([0,0,-.1]) cylinder(r2=2.6,r1=3.4,h=5,$fn=8);
  }
if(0) {
  translate([0,29,NodeHeight*2-padH*2.5]) difference() {
    cylinder(r=4.55,h=1,$fn=8);
    translate([0,0,-.1]) cylinder(r=4.1,h=1.2,$fn=8);
  }
  translate([0,29.4,NodeHeight*2-padH*2.5]) difference() {
    cylinder(r=3.55,h=1,$fn=8);
    translate([0,0,-.1]) cylinder(r=3.1,h=1.2,$fn=8);
  }
  translate([4,28,NodeHeight*2-1.6]) rotate([0,0,60]) rotate([25,0,0]) cube([4,.35,4],center=true);
  translate([-3.5,27,NodeHeight*2-1.6]) rotate([0,0,-50]) rotate([25,0,0]) cube([4,.35,4],center=true);
} else {
  translate([0,dPerp,NodeHeight+2+padH]) {
    Hblade(4);
    rotate([0,0, 20]) Hblade();
    rotate([0,0, 50]) Hblade();
    rotate([0,0, 80]) Hblade();
    rotate([0,0,110]) Hblade();
    rotate([0,0,140]) Hblade();
    rotate([0,0,170]) Hblade();
    rotate([0,0,200]) Hblade(3.6);
    rotate([0,0,230]) Hblade(3.3);
    rotate([0,0,250]) Hblade(3.3);
    rotate([0,0,270]) Hblade(3.3);
    rotate([0,0,290]) Hblade(3.3);
    rotate([0,0,310]) Hblade(3.3);
    rotate([0,0,330]) Hblade(3.3);
    rotate([0,0,345]) Hblade(4.5);
  }
}
}

}

// Support blade for H node
lineW = 0.41;  // single line width
plateH = NodeHeight-2-padH*0.2;
module Hblade(len=3,h=plateH,w=lineW,cr=2) {
  translate([cr,-w/2,0]) cube([len,w,h]);
}

// example from config E, circa 140227
//bracedFoot(28.3675,75.792,29.3843);

// $URL: svn+ssh://mrwhat@ssh.boim.com/home/mrwhat/svn/Walker/trunk/JansenFoot.scad $
// $Id: JansenFoot.scad 438 2015-03-03 14:39:59Z mrwhat $

padH = 0.3;  // extra clearance amount for H end of CH link

module bracedFoot(dLeft,dBase,dPerp) { // ---------------- foot with out-of-axis support
braceHeight = NodeHeight3; // 3*TrueNodeHeight-.4;  // A little shorter than the hinge-pin
dRight = 0.9 * (dBase-dLeft);  // scoot brace in a bit from foot
dLeft1 = dLeft-Frad-1-((0.5*Frad)/(dLeft-Frad-1));
union() { difference() { union() {
   translate([-dLeft,0,0]) {
      cylinder(h=NodeHeight,r1=Frad+.2,r2=Frad-.2,$fn=48); }
   hull() {
      translate([0,dPerp,0]) cylinder(h=braceHeight,r1=Hrad+2,r2=Hrad+1.6,$fn=48);
      translate([0,dPerp-3,0]) cylinder(h=braceHeight-1,r1=Hrad+1,r2=Hrad+0.5,$fn=32);
      translate([.22*dRight,.85*dPerp,1.1]) sphere(r=1,$fn=6); }
   hull() {
      translate([0,dPerp,0]) cylinder(h=braceHeight,r1=Hrad+1.9,r2=Hrad+1.4,$fn=48);
      translate([0,dPerp-3,0]) cylinder(h=braceHeight-1,r1=Hrad+1,r2=Hrad+0.5,$fn=32);
      translate([-.28*dLeft1,(1-.23)*dPerp,2]) sphere(r=1,$fn=6); }

   // foot
   translate([dBase-dLeft-LinkRad,0,0]) cylinder(h=NodeHeight+.5,r=LinkRad,$fn=80);

   hull() {
      translate([0,dPerp ,0]) cylinder(h=braceHeight  ,r1=1.6,r2=1,$fn=6);
      translate([dRight,0,0]) cylinder(h=BarHeight+1.5,r1=1.6,r2=1,$fn=6); }
   hull() {
      translate([0,dPerp ,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6);
      translate([dRight,0,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6); }
   hull() {
      translate([-dLeft1,-Frad*0.5,0])  cylinder(h=BarHeight+1.5,r1=1.6,r2=1,$fn=6);
      translate([0,dPerp,0])            cylinder(h=braceHeight  ,r1=1.6,r2=1,$fn=6); }
   hull() {
      translate([-dLeft1+((8*Frad)/(dLeft-Frad-1)),0,0])
                             cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6);
      translate([0,dPerp,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-.5,$fn=6); }
   hull() {     // re-inforcing pyramid over main, long leg
      translate([-dLeft+2*Frad,0,0]) cylinder(h=BarHeight,r1=Frad-1,r2=Frad-3,$fn=6);
      translate([dBase-dLeft-2*LinkRad,0,0]) cylinder(h=BarHeight,r1=LinkRad,r2=LinkRad-2,$fn=6);
      translate([0,0,1.5*NodeHeight-1]) sphere(r=1,$fn=16);   }

   difference() { hull() {   // main, long-leg segment
      translate([-dLeft,0,0]) {      nodeCyl(BarHeight,Frad-1);
      translate([dBase-LinkRad,0,0]) nodeCyl(BarHeight,LinkRad-1); }
     }
     translate([-dLeft,0,-1.5]) hull(){nodeCyl(BarHeight,Frad-2.4);
        translate([dBase-LinkRad-2,0,0])nodeCyl(BarHeight,.4);}
   }

   hull(){   // stop to keep "knee" from hyper-extending
      translate([-dLeft-Frad+2,0,0]) cylinder(h=BarHeight,r=2,$fn=8);
      translate([-dLeft,-Frad+2,0])  cylinder(h=BarHeight,r=2,$fn=8);
      translate([-dLeft-Frad+2,-Frad-3,0]) cylinder(h=BarHeight,r=2,$fn=12); }
   translate(   [-dLeft-Frad+2,-Frad-3,0]) cylinder(h=3*BarHeight,r1=3,r2=2,$fn=24);
   }
   translate([0,dPerp,0])  drillHole(Hrad);
   translate([-dLeft,0,0]) drillHole(Drad);

   // hollow out re-inforcing pyramid
   hull() { translate([-dLeft+2*Frad+2,0,-1.5]) cylinder(h=BarHeight,r1=Frad-2,r2=Frad-4,$fn=6);
      translate([dBase-dLeft-3*LinkRad,0,-1.5]) cylinder(h=BarHeight,r1=1.5,r2=.2,$fn=6);
      translate([0,0,1.5*NodeHeight-2.5]) sphere(r=0.5,$fn=16); }

   // had trouble with fill around braced link.  See if adding little hollows
   // helps slicer to fill better
   translate([-dLeft,0,NodeHeight/2]) {
      for(a=[0,30,60,90,120,150,180,210,240,270,300,330]) {
         translate([0.5*(Frad+Drad)*cos(a),0.5*(Frad+Drad)*sin(a),0])
            cylinder(h=NodeHeight-1.4,r=.4,$fn=6,center=true);
   }}

   // knock out a slot to take the CH linkage.
   translate([0,dPerp,NodeHeight-padH]) {
      cylinder(h=NodeHeight+2*padH,r=Hrad+3,$fn=48);
      hull() {
         translate([ 0,-4,0]) cube([.1,.1,NodeHeight+2*padH]);
         translate([ 7,-1,0]) cube([2,5,NodeHeight+2*padH]);
         translate([-7,-2,0]) cube([1,5,NodeHeight+2*padH]);
      }
   }

   //cube([3,11,11]);   // diagnostic slice to examine pyramid shell
   }
}

// custom support at H node
color("Cyan") union() {
  translate([0,29,NodeHeight-padH*.9]) difference() {
    cylinder(r2=4.4,r1=3.73,h=NodeHeight-.5,$fn=8);
    translate([0,0,-.1]) cylinder(r2=2.6,r1=3.4,h=5,$fn=8);
  }
if(0) {
  translate([0,29,NodeHeight*2-padH*2.5]) difference() {
    cylinder(r=4.55,h=1,$fn=8);
    translate([0,0,-.1]) cylinder(r=4.1,h=1.2,$fn=8);
  }
  translate([0,29.4,NodeHeight*2-padH*2.5]) difference() {
    cylinder(r=3.55,h=1,$fn=8);
    translate([0,0,-.1]) cylinder(r=3.1,h=1.2,$fn=8);
  }
  translate([4,28,NodeHeight*2-1.6]) rotate([0,0,60]) rotate([25,0,0]) cube([4,.35,4],center=true);
  translate([-3.5,27,NodeHeight*2-1.6]) rotate([0,0,-50]) rotate([25,0,0]) cube([4,.35,4],center=true);
} else {
  translate([0,dPerp,NodeHeight+2+padH]) {
    Hblade(4);
    rotate([0,0, 20]) Hblade();
    rotate([0,0, 50]) Hblade();
    rotate([0,0, 80]) Hblade();
    rotate([0,0,110]) Hblade();
    rotate([0,0,140]) Hblade();
    rotate([0,0,170]) Hblade();
    rotate([0,0,200]) Hblade(3.6);
    rotate([0,0,230]) Hblade(3.3);
    rotate([0,0,250]) Hblade(3.3);
    rotate([0,0,270]) Hblade(3.3);
    rotate([0,0,290]) Hblade(3.3);
    rotate([0,0,310]) Hblade(3.3);
    rotate([0,0,330]) Hblade(3.3);
    rotate([0,0,345]) Hblade(4.5);
  }
}
}

}

// Support blade for H node
lineW = 0.38;  // single line width
plateH = NodeHeight-2-padH*0.2;
module Hblade(len=3,h=plateH,w=lineW,cr=2) {
  translate([cr,-w/2,0]) cube([len,w,h]);
}

// example from config E, circa 140227
//bracedFoot(28.3675,75.792,29.3843);


[scad] add kube scaling factor

[scad] add kube scaling factor

$fn = 100; /* number of facets per circle */

/*
	_h = height
	_w = width
	_r = radius
	_t = tolerance
	_s = scaling factor (printer specific)
*/

dim_s = 1.04;
kube_s = [dim_s, dim_s, dim_s];

magnet_h = 5;
magnet_t = 0.2;
magnet_r = 13.5 + magnet_t;

flk_h = 23.5;
flk_t = 0.2;
flk_w = 30.5 + 2*flk_t;

wall_w = 2;
outer_w = flk_w + 2*wall_w;

support_r = 5;
support_h = outer_w - wall_w - flk_h;

echo("scaling vector", kube_s);
echo("magnet diameter", magnet_r*2);
echo("flk width", flk_w);
echo("kube width", outer_w);
echo("support height", support_h);

module kube()
{
	difference() {
		cube(outer_w);
		translate([wall_w, wall_w, wall_w + magnet_h]) {
			cube(flk_w, flk_w, outer_w - (wall_w + magnet_h));
		}
		translate([outer_w/2, outer_w/2, wall_w]) {
			cylinder(r=magnet_r, h=magnet_h);
		}
	}

	translate([outer_w/2, outer_w/2, wall_w]) {
		cylinder(r=support_r, h=support_h);
	}
}

scale(kube_s) kube();

/*
	_h = height
	_w = width
	_r = radius
	_t = tolerance
*/

magnet_h = 5;
magnet_r = 13.5;
magnet_t = 0.2;

flk_h = 23.5;
flk_w = 30.5;
flk_t = 0.5;

wall_w = 2;

support_r = 5;
support_h = outer_w - wall_w - flk_h;

inner_w = flk_w + flk_t;
outer_w = inner_w + 2*wall_w;

module kube()
{
	difference() {
		cube(outer_w);
		translate([wall_w, wall_w, wall_w + magnet_h]) {
			cube(inner_w, inner_w, outer_w - (wall_w + magnet_h));
		}
		translate([outer_w/2, outer_w/2, wall_w]) {
			cylinder(r=magnet_r + magnet_t, h=magnet_h);
		}
	}

	translate([outer_w/2, outer_w/2, wall_w]) {
		cylinder(r=support_r, h=support_h);
	}
}

kube();


test cube is now 20x20x20, just to keep some ratio

/*
 * small 3D cube for test prints
 */
cube([20, 20, 20]);

/*
 * small 3D cube for test prints
 */
cube([50, 30, 10]);


Update solid_layers.scad

Update solid_layers.scad

Oops, left a hardcoded 0.3 in. Fixed.

// Used to generate a modifier mesh to do something every few layers.
// Load into OpenSCAD, tweak the variables below, export as STL and load as
// a modifier mesh. Then change settings for the modifier mesh.

// Written by Joseph Lenox; in public domain.

layer_height = 0.3; // set to layer height in slic3r for "best" results.
number_of_solid_layers = 2;
N = 4; // N > number_of_solid_layers or else the whole thing will be solid
model_height = 300.0;
model_width = 300.0; // these two should be at least as big as the model
model_depth = 300.0; // but bigger isn't a problem
initial_offset=0; // don't generate below this

position_on_bed=[0,0,0]; // in case you need to move it around

// don't touch below unless you know what you are doing.
simple_layers = round(model_height/layer_height);
translate(position_on_bed)
  for (i = [initial_offset:N:simple_layers]) {
    translate([0,0,i*layer_height])
      translate([0,0,(layer_height*number_of_solid_layers)/2])
      cube([model_width,model_depth,layer_height*number_of_solid_layers], center=true);
  }

// Used to generate a modifier mesh to do something every few layers.
// Load into OpenSCAD, tweak the variables below, export as STL and load as
// a modifier mesh. Then change settings for the modifier mesh.

// Written by Joseph Lenox; in public domain.

layer_height = 0.3; // set to layer height in slic3r for "best" results.
number_of_solid_layers = 2;
N = 4; // N > number_of_solid_layers or else the whole thing will be solid
model_height = 300.0;
model_width = 300.0; // these two should be at least as big as the model
model_depth = 300.0; // but bigger isn't a problem
initial_offset=0; // don't generate below this

position_on_bed=[0,0,0]; // in case you need to move it around

// don't touch below unless you know what you are doing.
simple_layers = round(model_height/0.3);
translate(position_on_bed)
  for (i = [initial_offset:N:simple_layers]) {
    translate([0,0,i*layer_height])
      translate([0,0,(layer_height*number_of_solid_layers)/2])
      cube([model_width,model_depth,layer_height*number_of_solid_layers], center=true);
  }


Added pantilt OpenScad model

Added pantilt OpenScad model

$fn = 250;

R = 50;
ballShell = 3;
supportX = 35;
supportY = 8;
supportZ = 60;
mik = 2;
sThickness = 5;
supportBaseHeight = 5;
baseHeight = 31;

module box(Xdim, Ydim, Zdim, thickness, application)
//Creates a box, dimensions are internal
{
	difference() {
		//translate([10,0,-thickness])
		cube([Xdim + thickness, Ydim + thickness, Zdim], center = true);
		translate([0, 0, thickness / 2]) cube([Xdim, Ydim, Zdim], center = true);
		if(application == "servo")
	{
		translate([-Xdim/2,0,-0.5*Zdim])cube([5,Ydim+2*thickness,Zdim/2+thickness], center=true);
		translate([+Xdim/2,0,-0.5*Zdim])cube([5,Ydim+2*thickness,Zdim/2+thickness], center=true);
		translate([+Xdim/2,0,0])cube([thickness/2,0.3*Ydim,Zdim], center=true);
		translate([-Xdim/2,0,0])cube([thickness/2,0.3*Ydim,Zdim], center=true);
	}
	}
}

module support() {
	difference() {
		union() {
			intersection() {
				sphere(R);
				translate([-R, -R+(supportY+sThickness)/2, 0])  cube([500, 25, 200], center = true);
			}

		}
	}

	translate([0, -R+(supportY+sThickness/2), -supportZ/2]) {
		minkowski() {
			box(supportX, supportY, supportZ, sThickness , "none");
			cylinder(r = mik, h = 1);
			//rotate([90,0,0])cylinder(r = mik, h = 1);
		}
	}
}

module base() {
translate([0, 0, -supportZ])
		minkowski() {
			cylinder(r= R+mik, h= supportBaseHeight);
		rotate([90,0,0])cylinder(r = mik, h = 1);
}
}

sphere(R);
support();
mirror([0, 10, 0]) support();
//need to understnad -2 in  2*R-5-mik-2
base();

translate([0, 0, -supportZ-supportBaseHeight-baseHeight])
{difference(){
	minkowski() {
cylinder(r= R+mik, h = baseHeight);
rotate([90,0,0])cylinder(r = mik, h = 1);
}

translate([0, 0, 5])cylinder(r= (R+mik)/2, h = 10*baseHeight);
}
translate([0, 0, 17-3])	box(24.5, 13, 17, 3,"servo");}

error: pathspec 'hardware/pantilt.scad' did not match any file(s) known to git


more mounts, fix screws

more mounts, fix screws

$fn=100;

button_radius = 49;
hole_radius = 14.5;
table_padding = 40;
extra_padding = 2;
bottom_padding = 30;

wall_thickness = 4;

mount_height = table_padding + extra_padding + button_radius + hole_radius + bottom_padding;
mount_depth = 50;
mount_width = (hole_radius * 2) + (bottom_padding * 2);

// difference() {
//     cube(size=[mount_width, mount_height, mount_depth]);

//     translate([wall_thickness, wall_thickness, wall_thickness])
//     cube(size=[mount_width - (wall_thickness*2), mount_height, mount_depth]);
// }

module screw_mount() {
    difference() {
        cube([10, wall_thickness, 10]);

        rotate([90, 0, 0])
        translate([5, 5, -wall_thickness-1])
        cylinder(r=2, h=wall_thickness+2);
    }
}

module bottom() {
    difference() {
    hull() {
        // lower left
        translate([wall_thickness*2, wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // lower right
        translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // upper right
        translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);

        // upper left
        translate([0, mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);
    }

    union() {
        translate([mount_width/2, wall_thickness+7.5, -1])
        cylinder(r=3, h=wall_thickness+2);

        translate([mount_width/2-4.5, wall_thickness+7.5-2.5, wall_thickness-.8])
        cube(size=[9, 5, 1]);
    }
    }
}

module sides() {
    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);

            // upper left
            translate([0, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);
        }

        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);
        }
    }

    intersection() {
        translate([wall_thickness, wall_thickness, 0])
        cube([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), mount_depth]);

        union() {
            translate([wall_thickness, wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);

            translate([wall_thickness, mount_height-wall_thickness, mount_depth-6-wall_thickness])
            cylinder(r=9, h=6);
            translate([wall_thickness, mount_height-wall_thickness, mount_depth-10-wall_thickness])
            cylinder(r1=3, r2=9, h=4);
        }
    }
}

module cover() {
    hole_center = mount_height - table_padding - button_radius;

    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);
        }

        translate([mount_width/2, hole_center, -1])
        cylinder(r=hole_radius, h=wall_thickness*2);
    }

    // Fake button
    // translate([mount_width/2, hole_center, 5])
    // cylinder(r=button_radius, h=20);
}

module screws() {
    translate([wall_thickness+3.5, wall_thickness+3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([mount_width-wall_thickness-3.5, wall_thickness+3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([mount_width-wall_thickness-3.5, mount_height-wall_thickness-3.5, mount_depth/2])
    cylinder(r=1.5, h=30);

    translate([wall_thickness+3.5, mount_height-wall_thickness-3.5, mount_depth/2])
    cylinder(r=1.5, h=30);
}

bottom();
difference() {
    sides();
    screws();
}

// difference() {
//     translate([0, 0, mount_depth-wall_thickness])
//     cover();
//     screws();
// }

$fn=100;

button_radius = 49;
hole_radius = 14.5;
table_padding = 40;
extra_padding = 2;
bottom_padding = 30;

wall_thickness = 4;

mount_height = table_padding + extra_padding + button_radius + hole_radius + bottom_padding;
mount_depth = 50;
mount_width = (hole_radius * 2) + (bottom_padding * 2);

// difference() {
//     cube(size=[mount_width, mount_height, mount_depth]);

//     translate([wall_thickness, wall_thickness, wall_thickness])
//     cube(size=[mount_width - (wall_thickness*2), mount_height, mount_depth]);
// }

module screw_mount() {
    difference() {
        cube([10, wall_thickness, 10]);

        rotate([90, 0, 0])
        translate([5, 5, -wall_thickness-1])
        cylinder(r=2, h=wall_thickness+2);
    }
}

module bottom() {
    hull() {
        // lower left
        translate([wall_thickness*2, wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // lower right
        translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
        cylinder(r=wall_thickness*2, h=wall_thickness);

        // upper right
        translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);

        // upper left
        translate([0, mount_height-(wall_thickness*2), 0])
        cube(size=[wall_thickness*2, wall_thickness*2, wall_thickness]);
    }
}

module sides() {
    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness*2, h=mount_depth);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);

            // upper left
            translate([0, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness*2, wall_thickness*2, mount_depth]);
        }

        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=mount_depth+1);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, mount_depth+1]);
        }
    }

    intersection() {
        translate([wall_thickness, wall_thickness, 0])
        cube([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), mount_depth]);

        union() {
            translate([wall_thickness, wall_thickness, mount_depth-6])
            cylinder(r=9, h=6);
            translate([wall_thickness, wall_thickness, mount_depth-10])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, wall_thickness, mount_depth-6])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, wall_thickness, mount_depth-10])
            cylinder(r1=3, r2=9, h=4);

            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-6])
            cylinder(r=9, h=6);
            translate([mount_width-wall_thickness, mount_height-wall_thickness, mount_depth-10])
            cylinder(r1=3, r2=9, h=4);

            translate([wall_thickness, mount_height-wall_thickness, mount_depth-6])
            cylinder(r=9, h=6);
            translate([wall_thickness, mount_height-wall_thickness, mount_depth-10])
            cylinder(r1=3, r2=9, h=4);
        }
    }
}

module cover() {
    hole_center = mount_height - table_padding - button_radius;

    difference() {
        hull() {
            // lower left
            translate([wall_thickness*2, wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // lower right
            translate([mount_width-(wall_thickness*2), wall_thickness*2, 0])
            cylinder(r=wall_thickness, h=wall_thickness);

            // upper right
            translate([mount_width-(wall_thickness*2), mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);

            // upper left
            translate([wall_thickness, mount_height-(wall_thickness*2), 0])
            cube(size=[wall_thickness, wall_thickness, wall_thickness]);
        }

        translate([mount_width/2, hole_center, -1])
        cylinder(r=hole_radius, h=wall_thickness*2);
    }

    // Fake button
    // translate([mount_width/2, hole_center, 5])
    // cylinder(r=button_radius, h=20);
}

bottom();
sides();

translate([0, 0, mount_depth + 15])
cover();


config: Fix main width, should be 340mm

config: Fix main width, should be 340mm

include <MCAD/stepper.scad>
include <bearings.scad>
include <screws.scad>
include <thing_libutils/metric-thread.scad>
include <thing_libutils/metric-hexnut.scad>
include <thing_libutils/misc.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

// enable preview model (faster openscad)
preview_mode=true;

main_width = 340*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;
extrusion_thread_dia = lookup(ThreadSize, extrusion_thread);
extrusion_nut = MHexNutM5;
extrusion_nut_dia = lookup(MHexNutWidthMax, extrusion_nut);

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_thickness = 4;
ziptie_width = 4;
ziptie_bearing_distance=2;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;
xaxis_pulley_d = 12.2;
xaxis_belt_width = 6*mm;

xaxis_carriage_bearing_offset_z = ziptie_thickness/2;
xaxis_carriage_beltpath_offset = xaxis_carriage_bearing_offset_z+xaxis_bearing[1]/2;

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
yaxis_bearing_distance_y = 7*cm;

yaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 21.5*mm);

// 2GT2 20T pulley
yaxis_pulley_d = 18;
ymotor_mount_thickness = 5;
ymotor_mount_thickness_h = 5;
yaxis_motor_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_motor_offset_z = -5*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_d/2 + yaxis_idler_pulley_tight_len;
yaxis_idler_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_idler_offset_z = 10*mm;
yaxis_idler_pulley_h = 8.65*mm;

yaxis_carriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// Nema17 motor w/340mm long 8*mm leadscrew
zaxis_motor = dict_replace_multiple(Nema17,
        [
        [NemaAxleDiameter, 8*mm],
        [NemaFrontAxleLength, 340*mm],
        ]);

zaxis_motor_offset_z = 10*mm;
zmotor_mount_thickness = 5;
zmotor_mount_thickness_h = 10;
zmotor_mount_motor_offset=5;

// GT2
// there is bunch of GT2 belts with different tooth-to-tooth distance
// this one is most common in reprap world
// adjust to your needs.
belt_width = 6.5;
belt_tooth_distance = 2;
belt_tooth_ratio = 0.5;
belt_thickness = 0.8;

//T2.5
//belt_tooth_distance = 2.5;
//belt_tooth_ratio = 0.5;

//T5 (strongly discouraged)
//belt_tooth_distance = 5;
//belt_tooth_ratio = 0.75;

//HTD3
//belt_tooth_distance = 3;
//belt_tooth_ratio = 0.75;

//MXL
//belt_tooth_distance = 2.032;
//belt_tooth_ratio = 0.64;

include <MCAD/stepper.scad>
include <bearings.scad>
include <screws.scad>
include <thing_libutils/metric-thread.scad>
include <thing_libutils/metric-hexnut.scad>
include <thing_libutils/misc.scad>

e=0.01;

// resolution of any round object (segment length)
fnr                         = 0.4;

extrusion_height            = 0.4*mm;

// width of a single wall, should match your slicer settings
extrusion_width             = 0.4*mm;

// how many lines should a normal wall have (i.e. 0.6(extrusion_width)*6(normal_wall_factor)= 3.6mm wall width)
normal_wall_factor          = 3;

thick_wall_factor           = 4;

// diameter of your filament.
filament_d                  = 1.75*mm;
filament_r                  = filament_d/2;

// enable preview model (faster openscad)
preview_mode=true;

main_width = 300*mm;
main_depth = 420*mm;
main_height = 400*mm;
main_upper_width = 420*mm;

extrusion_color = [0.5,0.5,0.5];
extrusion_size = 20*mm;
extrusion_thread = ThreadM5;
extrusion_thread_dia = lookup(ThreadSize, extrusion_thread);
extrusion_nut = MHexNutM5;
extrusion_nut_dia = lookup(MHexNutWidthMax, extrusion_nut);

main_lower_dist_z= 80*mm;
main_upper_dist_y= 160*mm;

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_thickness = 4;
ziptie_width = 4;
ziptie_bearing_distance=2;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_bearing=bearing_igus_rj4jp_01_10;
xaxis_pulley_d = 12.2;
xaxis_belt_width = 6*mm;

xaxis_carriage_bearing_offset_z = ziptie_thickness/2;
xaxis_carriage_beltpath_offset = xaxis_carriage_bearing_offset_z+xaxis_bearing[1]/2;

yaxis_rod_distance = 170*mm;
yaxis_rod_d = 11.975*mm;
yaxis_rod_l = 500*mm;
yaxis_bearing=bearing_igus_rj4jp_01_12;
yaxis_bearing_distance_y = 7*cm;

yaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 21.5*mm);

// 2GT2 20T pulley
yaxis_pulley_d = 18;
ymotor_mount_thickness = 5;
ymotor_mount_thickness_h = 5;
yaxis_motor_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_motor_offset_z = -5*mm;
yaxis_belt_path_offset_x = -yaxis_pulley_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_d/2 + yaxis_idler_pulley_tight_len;
yaxis_idler_offset_x = lookup(NemaSideSize,yaxis_motor)/2+ymotor_mount_thickness;
yaxis_idler_offset_z = 10*mm;
yaxis_idler_pulley_h = 8.65*mm;

yaxis_carriage_size=[220*mm,220*mm,5*mm];

zaxis_rod_d = 11.975*mm;
zaxis_rod_l = 500*mm;
zaxis_bearing=bearing_igus_rj4jp_01_12;

// Nema17 motor w/340mm long 8*mm leadscrew
zaxis_motor = dict_replace_multiple(Nema17,
        [
        [NemaAxleDiameter, 8*mm],
        [NemaFrontAxleLength, 340*mm],
        ]);

zaxis_motor_offset_z = 10*mm;
zmotor_mount_thickness = 5;
zmotor_mount_thickness_h = 10;
zmotor_mount_motor_offset=5;

// GT2
// there is bunch of GT2 belts with different tooth-to-tooth distance
// this one is most common in reprap world
// adjust to your needs.
belt_width = 6.5;
belt_tooth_distance = 2;
belt_tooth_ratio = 0.5;
belt_thickness = 0.8;

//T2.5
//belt_tooth_distance = 2.5;
//belt_tooth_ratio = 0.5;

//T5 (strongly discouraged)
//belt_tooth_distance = 5;
//belt_tooth_ratio = 0.75;

//HTD3
//belt_tooth_distance = 3;
//belt_tooth_ratio = 0.75;

//MXL
//belt_tooth_distance = 2.032;
//belt_tooth_ratio = 0.64;


linear-extrusion: fix missing includes

linear-extrusion: fix missing includes

include <system.scad>
include <units.scad>

use <shapes.scad>
use <transforms.scad>

module linear_extrusion(h=10, center=true, align=N, orient=Z)
{
    size_align(size=[20,20,h], align=align, orient=orient, orient_ref=Z)
    {
        linear_extrude(height = h, center = true, convexity = 10, twist = 0)
        {
            import (file = "data/misumi-extrusion/hfs5-2020-profile.dxf");
        }
    }
}

/*include <system.scad>*/
/*include <units.scad>*/
/*include <misc.scad>*/
/*for(axis=concat(AXES,-AXES))*/
/*translate(axis*20/2)*/
/*{*/
    /*c= v_abs(axis*.3 + v_clamp(v_sign(axis),0,1)*.7);*/
    /*color(c)*/
        /*linear_extrusion(h=100, align=axis, orient=axis);*/
/*}*/