pulley: add pulley_height function

pulley: add pulley_height function

include <thing_libutils/units.scad>
include <thing_libutils/shapes.scad>

// h, full_h, inner_d, outer_d, walls, bore
pulley_2GT_20T_idler = [8.65*mm, undef, 12*mm, 18*mm, 1*mm, 5*mm];
pulley_2GT_20T       = [8.65*mm, 16*mm, 12*mm, 16*mm, 1.15*mm, 5*mm];

function pulley_height(pulley) = pulley[1]==undef?pulley[0]:pulley[1];

module pulley(pulley=pulley_2GT_20T, flip=false, align=[0,0,0], orient = [0,0,1])
{
    is_idler = pulley[1] == undef;
    pulley_full(
            is_idler=is_idler,
            h=pulley[0],
            full_h=is_idler?undef:pulley[1],
            inner_d=pulley[2],
            outer_d=pulley[3],
            walls=pulley[4],
            bore=pulley[5],
            flip=flip,
            align=align,
            orient=orient
            );
}

module pulley_full(h, inner_d, outer_d, bore, walls, is_idler=false, full_h, flip=false, align=[0,0,0], orient = [0,0,1])
{
    size_align(size=[outer_d, outer_d, full_h==undef?h:full_h], align=align, orient=orient)
    {
        //for flipping
        mirror([0,0,flip?-1:0])
        //center
        translate([0,0,full_h==undef?-h/2:-full_h/2])
        difference()
        {
            union()
            {
                cylindera(d = outer_d, h = walls, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,0])
                cylindera(d = inner_d, h = h, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,h-walls])
                cylindera(d = outer_d, h = walls, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,h])
                if(!is_idler)
                {
                    cylindera(d = outer_d, h = full_h-h, align=[0,0,1], orient=[0,0,1]);
                }
            }
            translate([0,0,-.1])
            cylindera(d = bore, h = full_h+.2, align=[0,0,1], orient=[0,0,1]);
        }
    }
}

if(false)
{
    /*pulley(pulley_2GT_20T_idler, align=[0,0,1], orient=[0,0,1]);*/
    pulley(pulley_2GT_20T, align=[0,0,1], orient=[0,0,-1], flip=false);
    /*pulley(pulley_2GT_20T, align=[0,0,-1], orient=[0,0,1], flip=false);*/
}

include <thing_libutils/units.scad>
include <thing_libutils/shapes.scad>

// h, full_h, inner_d, outer_d, walls, bore
pulley_2GT_20T_idler = [8.65*mm, undef, 12*mm, 18*mm, 1*mm, 5*mm];
pulley_2GT_20T       = [8.65*mm, 16*mm, 12*mm, 16*mm, 1.15*mm, 5*mm];

module pulley(pulley=pulley_2GT_20T, flip=false, align=[0,0,0], orient = [0,0,1])
{
    is_idler = pulley[1] == undef;
    pulley_full(
            is_idler=is_idler,
            h=pulley[0],
            full_h=is_idler?undef:pulley[1],
            inner_d=pulley[2],
            outer_d=pulley[3],
            walls=pulley[4],
            bore=pulley[5],
            flip=flip,
            align=align,
            orient=orient
            );
}

module pulley_full(h, inner_d, outer_d, bore, walls, is_idler=false, full_h, flip=false, align=[0,0,0], orient = [0,0,1])
{
    size_align(size=[outer_d, outer_d, full_h==undef?h:full_h], align=align, orient=orient)
    {
        //for flipping
        mirror([0,0,flip?-1:0])
        //center
        translate([0,0,full_h==undef?-h/2:-full_h/2])
        difference()
        {
            union()
            {
                cylindera(d = outer_d, h = walls, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,0])
                cylindera(d = inner_d, h = h, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,h-walls])
                cylindera(d = outer_d, h = walls, align=[0,0,1], orient=[0,0,1]);

                translate([0,0,h])
                if(!is_idler)
                {
                    cylindera(d = outer_d, h = full_h-h, align=[0,0,1], orient=[0,0,1]);
                }
            }
            translate([0,0,-.1])
            cylindera(d = bore, h = full_h+.2, align=[0,0,1], orient=[0,0,1]);
        }
    }
}

if(false)
{
    /*pulley(pulley_2GT_20T_idler, align=[0,0,1], orient=[0,0,1]);*/
    pulley(pulley_2GT_20T, align=[0,0,1], orient=[0,0,-1], flip=false);
    /*pulley(pulley_2GT_20T, align=[0,0,-1], orient=[0,0,1], flip=false);*/
}


shapes/cuberound: Simplify

shapes/cuberound: Simplify

use <misc.scad>

// translate children
module lineup(arr=undef)
{
    /*echo(arr);*/
    /*echo($children);*/
    if($children>0)
    {
        for (i = [0 : $children-1])
            translate(arr[i]) children(i);
    }
}

module stack(separations)
{
    union()
    {
        for (i = [0:len(separations)-1])
        {
            offset = v_sum(separations,i);
            /*echo("i",i,"offset",offset);*/
            translate ([0,0,offset])
            {
                child(i);
            }
        }
    }
}

module orient(zaxes, roll=0)
{
    zaxes = len(zaxes.x) == undef && zaxes.x != undef? [zaxes] : zaxes;
    for(zaxis=zaxes)
    {
        rotate(_orient_angles(zaxis))
        /*rotate(roll*z)*/
            children();
    }
}

module size_align(size=[10,10,10], align=[0,0,0], orient=[0,0,1])
{
    bounds = _rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1];
    t=hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]);
    translate(t)
    {
        orient(orient)
        {
            children();
        }
    }
}

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module cuberounda(size=[10,10,10], facets=32, rounding_radius=1, align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cuberound(size=size+extrasize, facets=facets, rounding_radius=rounding_radius);
        }
    }
}

module cuberound(size=[20,20,20], rounding_radius=1, fn=32)
{
    hull()
    for(x=[-(size[0]/2-rounding_radius),(size[0]/2-rounding_radius)])
    for(y=[-(size[1]/2-rounding_radius),(size[1]/2-rounding_radius)])
    for(z=[-(size[2]/2-rounding_radius),(size[2]/2-rounding_radius)])
    translate([x,y,z])
    sphere(r=rounding_radius, $fn=fn);
}

module cylindera(h=10, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, align=[0,0,0], extra_h=0,extra_r=undef,extra_d=undef,extra_align=[0,0,0])
{
    extra_r_=(extra_r==undef?0:extra_r);
    extra_d_=(extra_d==undef?0:extra_d);
    extra_sizexy=extra_r_*2 + extra_d_;
    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {
        r_=(r==undef?0:r);
        d_=(d==undef?0:d);
        sizexy=r_*2 + d_;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r+extra_r_, r1=r1, r2=r2, d=d+extra_d_, d1=d1, d2=d2, center=true);
        }
    }
}

module fncylinder(r, r2, d, d2, h, fn, center=false, enlarge=0, fnr=0.8){
    translate(center==false?[0,0,-enlarge]:[0,0,-h/2-enlarge]) {
        if (fn==undef) {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            }
        } else {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=fn);
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=fn);
            }
        }
    }
}

// specify segment length with fnr, $fn not needed but if desired use fn instead but if desired use fn instead
module fncylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        orient=[0,0,1],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,1],
        fn,
        fnr=0.8,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    r_= useDia?d/2:(r==undef?0:r);
    r1r2max = max(r1,r2) == undef ? max(d1,d2)/2 : max(r1,r2);
    r__ = r_==undef? r1r2max : r_;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_r);

    sizexy=r__*2;
    extra_sizexy=extra_r_*2;

    // some orient hax here to properly support extra_align
    orient(-orient)
    size_align([extra_sizexy,extra_sizexy,extra_h], align=extra_align, orient=orient)
    orient(orient)
    {
        fn_r = r__;

        fn_=fn==undef?(floor(2*(r__)*pi/fnr)):fn;

        if(debug)
        {
            echo(useDia, h, r_, r1_, r2_, extra_r_, align, fn_);
        }

        // some orient hax here to properly support extra_align
        orient(-orient)
        size_align([sizexy,sizexy,h], align=align, orient=orient)
        {
            cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true, $fn=fn_);
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

module hollow_cylinder(d=10, thickness=1, h=10, taper=false, orient=[0,0,1], align=[0,0,0])
{
    outer_d = d+thickness/2;
    inner_d = d-thickness/2;
    size_align(size=[outer_d, outer_d, h], orient=orient, align=align)
    difference()
    {
        hull()
        {
            fncylindera(h=h, d=outer_d, orient=[0,0,1], align=[0,0,0]);

            taper_h = outer_d/2;
            if(taper)
            {
                for(z=[-1,1])
                translate([0,0,z*h/2])
                mirror([0,0,z==-1?1:0])
                difference()
                {
                    fncylindera(d1=outer_d, d2=0, h=taper_h, align=[0,0,1]);
                    fncylindera(d1=inner_d, d2=inner_d*2, h=taper_h, align=[0,0,1]);
                }
            }
        }

        fncylindera(h=h+.2, d=inner_d, orient=[0,0,1], align=[0,0,0]);

    }
}

/*hollow_cylinder(thickness=2, h=9, taper=true, orient=[0,0,1], align=[0,0,1]);*/

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/
/*fncylindera(h=10, r=5, extra_r=2, align=[0,0,1], orient=[1,0,0]);*/

/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,-1], orient=[0,0,1]);*/
/*translate([0,-10,0])*/
/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,1], orient=[0,0,1]);*/
/*translate([0,-20,0])*/
/*fncylindera(h=10, d=10, extra_h=5, orient=[1,0,0], align=[1,0,0], extra_align=[1,0,0]);*/
/*translate([0,-30,0])*/
/*fncylindera(h=10, d=7.5, extra_h=5, orient=[1,0,0], align=[-1,0,0], extra_align=[1,0,0]);*/

/*fncylindera(h=10, r1=5, r2=10, orient=[1,0,0], align=[-1,0,0], extra_align=[1,0,0]);*/
/*fncylindera(h=10, d1=5, d2=30, orient=[0,0,1], align=[0,0,1]);*/

use <misc.scad>

// translate children
module lineup(arr=undef)
{
    /*echo(arr);*/
    /*echo($children);*/
    if($children>0)
    {
        for (i = [0 : $children-1])
            translate(arr[i]) children(i);
    }
}

module stack(separations)
{
    union()
    {
        for (i = [0:len(separations)-1])
        {
            offset = v_sum(separations,i);
            /*echo("i",i,"offset",offset);*/
            translate ([0,0,offset])
            {
                child(i);
            }
        }
    }
}

module orient(zaxes, roll=0)
{
    zaxes = len(zaxes.x) == undef && zaxes.x != undef? [zaxes] : zaxes;
    for(zaxis=zaxes)
    {
        rotate(_orient_angles(zaxis))
        /*rotate(roll*z)*/
            children();
    }
}

module size_align(size=[10,10,10], align=[0,0,0], orient=[0,0,1])
{
    bounds = _rotate_matrix(_orient_angles(orient)) * [size.x,size.y,size.z,1];
    t=hadamard(align, [abs(bounds.x/2),abs(bounds.y/2),abs(bounds.z/2)]);
    translate(t)
    {
        orient(orient)
        {
            children();
        }
    }
}

module cubea(size=[10,10,10], align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cube(size+extrasize, center=true);
        }
    }
}

module cuberounda(size=[10,10,10], facets=32, rounding_radius=1, align=[0,0,0], extrasize=[0,0,0], extrasize_align=[0,0,0])
{
    size_align(extrasize,extrasize_align)
    {
        size_align(size,align)
        {
            cuberound(size=size+extrasize, facets=facets, rounding_radius=rounding_radius);
        }
    }
}

module cuberound(size=[10,10,10], facets=32, rounding_radius=1)
{
    translate(-size/2)
    hull()
    {
        translate([rounding_radius,rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([rounding_radius,size[1]-rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,size[1]-rounding_radius,rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([rounding_radius,rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([rounding_radius,size[1]-rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
        translate([size[0]-rounding_radius,size[1]-rounding_radius,size[2]-rounding_radius]) sphere (r=rounding_radius,$fn=facets);
    }
}

module cylindera(h=10, r=undef, r1=undef, r2=undef, d=undef, d1=undef, d2=undef, align=[0,0,0], extra_h=0,extra_r=undef,extra_d=undef,extra_align=[0,0,0])
{
    extra_r_=(extra_r==undef?0:extra_r);
    extra_d_=(extra_d==undef?0:extra_d);
    extra_sizexy=extra_r_*2 + extra_d_;
    size_align([extra_sizexy,extra_sizexy,extra_h],extra_align)
    {
        r_=(r==undef?0:r);
        d_=(d==undef?0:d);
        sizexy=r_*2 + d_;
        size_align([sizexy,sizexy,h],align)
        {
            cylinder(h=h+extra_h, r=r+extra_r_, r1=r1, r2=r2, d=d+extra_d_, d1=d1, d2=d2, center=true);
        }
    }
}

module fncylinder(r, r2, d, d2, h, fn, center=false, enlarge=0, fnr=0.8){
    translate(center==false?[0,0,-enlarge]:[0,0,-h/2-enlarge]) {
        if (fn==undef) {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=floor(2*(r?r:d?d/2:1)*PI/fnr));
            }
        } else {
            if (r2==undef && d2==undef) {
                cylinder(r=r?r:d?d/2:1,h=h+enlarge*2,$fn=fn);
            } else {
                cylinder(r=r?r:d?d/2:1,r2=r2?r2:d2?d2/2:1,h=h+enlarge*2,$fn=fn);
            }
        }
    }
}

// specify segment length with fnr, $fn not needed but if desired use fn instead but if desired use fn instead
module fncylindera(
        h=10,
        r=undef,
        r1=undef,
        r2=undef,
        d=undef,
        d1=undef,
        d2=undef,
        align=[0,0,0],
        orient=[0,0,1],
        extra_h=0,
        extra_r=undef,
        extra_d=undef,
        extra_align=[0,0,1],
        fn,
        fnr=0.8,
        debug=false
        )
{
    pi=3.1415926536;

    useDia = r == undef && (r1 == undef && r2 == undef);

    r1_ = useDia?((d1==undef?undef:d1)/2):r1;
    r2_ = useDia?((d2==undef?undef:d2)/2):r2;
    r_= useDia?d/2:(r==undef?0:r);
    r1r2max = max(r1,r2) == undef ? max(d1,d2)/2 : max(r1,r2);
    r__ = r_==undef? r1r2max : r_;
    extra_r_ = useDia?((extra_d==undef?0:extra_d)/2):((extra_r==undef)?0:extra_r);

    sizexy=r__*2;
    extra_sizexy=extra_r_*2;

    // some orient hax here to properly support extra_align
    orient(-orient)
    size_align([extra_sizexy,extra_sizexy,extra_h], align=extra_align, orient=orient)
    orient(orient)
    {
        fn_r = r__;

        fn_=fn==undef?(floor(2*(r__)*pi/fnr)):fn;

        if(debug)
        {
            echo(useDia, h, r_, r1_, r2_, extra_r_, align, fn_);
        }

        // some orient hax here to properly support extra_align
        orient(-orient)
        size_align([sizexy,sizexy,h], align=align, orient=orient)
        {
            cylinder(h=h+extra_h, r=r_+extra_r_, r1=r1_, r2=r2_, center=true, $fn=fn_);
        }
    }
}

module pie_slice_shape(r, start_angle, end_angle) {
    R = r * sqrt(2) + 1;
    a0 = (4 * start_angle + 0 * end_angle) / 4;
    a1 = (3 * start_angle + 1 * end_angle) / 4;
    a2 = (2 * start_angle + 2 * end_angle) / 4;
    a3 = (1 * start_angle + 3 * end_angle) / 4;
    a4 = (0 * start_angle + 4 * end_angle) / 4;
    if(end_angle > start_angle)
    {
        intersection() {
            circle(r);
            polygon([
                    [0,0],
                    [R * cos(a0), R * sin(a0)],
                    [R * cos(a1), R * sin(a1)],
                    [R * cos(a2), R * sin(a2)],
                    [R * cos(a3), R * sin(a3)],
                    [R * cos(a4), R * sin(a4)],
                    [0,0]
            ]);
        }
    }
}

module pie_slice(r, start_angle, end_angle, h)
{
    linear_extrude(h)
    {
        pie_slice_shape(r, start_angle, end_angle);
    }
}

module hollow_cylinder(d=10, thickness=1, h=10, taper=false, orient=[0,0,1], align=[0,0,0])
{
    outer_d = d+thickness/2;
    inner_d = d-thickness/2;
    size_align(size=[outer_d, outer_d, h], orient=orient, align=align)
    difference()
    {
        hull()
        {
            fncylindera(h=h, d=outer_d, orient=[0,0,1], align=[0,0,0]);

            taper_h = outer_d/2;
            if(taper)
            {
                for(z=[-1,1])
                translate([0,0,z*h/2])
                mirror([0,0,z==-1?1:0])
                difference()
                {
                    fncylindera(d1=outer_d, d2=0, h=taper_h, align=[0,0,1]);
                    fncylindera(d1=inner_d, d2=inner_d*2, h=taper_h, align=[0,0,1]);
                }
            }
        }

        fncylindera(h=h+.2, d=inner_d, orient=[0,0,1], align=[0,0,0]);

    }
}

/*hollow_cylinder(thickness=2, h=9, taper=true, orient=[0,0,1], align=[0,0,1]);*/

/*%pie_slice(r=10, start_angle=-30, end_angle=270, h=10);*/

/*cubea([10,10,10],[1,0,0]);*/
/*%cubea([10,10,10],[1,0,0],[5,5,5],[1,1,1]);*/

/*%cubea([10,10,10],[-1,0,1]);*/
/*%cubea([10,10,10],[-1,0,1],[1,1,1],[-1,0,1]);*/
/*%cylindera(h=10, r=10/2, align=[-1,1,1], extra_r=5/2, extra_h=2, extra_align=[-1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[-1,1,1], extra_d=5, extra_h=2, extra_align=[-1,1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=15, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,-1,1], extra_d=5, extra_h=2, extra_align=[-1,-1,1], $fn=100);*/
/*%cylindera(h=10, d=10, align=[1,1,1], extra_d=5, extra_h=2, extra_align=[1,1,1], $fn=100);*/

/*%cylindera(h=10, d=10, align=[1,0,0], extra_d=10);*/
/*fncylindera(h=10, r=5, extra_r=2, align=[0,0,1], orient=[1,0,0]);*/

/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,-1], orient=[0,0,1]);*/
/*translate([0,-10,0])*/
/*fncylindera(h=10, d=5, extra_r=2, align=[0,0,1], orient=[0,0,1]);*/
/*translate([0,-20,0])*/
/*fncylindera(h=10, d=10, extra_h=5, orient=[1,0,0], align=[1,0,0], extra_align=[1,0,0]);*/
/*translate([0,-30,0])*/
/*fncylindera(h=10, d=7.5, extra_h=5, orient=[1,0,0], align=[-1,0,0], extra_align=[1,0,0]);*/

/*fncylindera(h=10, r1=5, r2=10, orient=[1,0,0], align=[-1,0,0], extra_align=[1,0,0]);*/
/*fncylindera(h=10, d1=5, d2=30, orient=[0,0,1], align=[0,0,1]);*/


Fix wrong parameter name applied to align() in negativeExtrude()

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2017 Jean-Sebastien CONAN
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Part of the camelSCAD library.
 *
 * Operators that extrude children modules with respect to particular rules.
 *
 * @package operator/extrude
 * @author jsconan
 */

/**
 * Extrudes linearly the children modules, and apply a wall adjustment to ensure
 * the final object will not produce artifacts after a `difference()` operation.
 *
 * @param Number [height] - The height of the extrusion. If the value is negative,
 *                          the extrusion will be made top to bottom (below the origin).
 * @param Number|String [direction] - Tells on what sides adjust the height to make sure
 *                                    the difference won't produce dummy walls.
 * @param Boolean [center] - Whether or not center the extrusion on the vertical axis.
 * @param Number [convexity] - If the extrusion fails for a non-trivial 2D shape,
 *                             try setting the convexity parameter.
 * @param Number [twist] - The number of degrees of through which the shape is extruded.
 * @param Number [slices] - Defines the number of intermediate points along the Z axis
 *                          of the extrusion.
 * @param Number|Vector [scale] - Scales the 2D shape by this value over the height of
 *                                the extrusion.
 */
module negativeExtrude(height, direction, center, convexity, twist, slices, scale) {
    center = boolean(center);
    convexity = numberOr(convexity, 10);
    height = align(value=height, direction=direction, center=center);

    translateZ(height[1]) {
        linear_extrude(height=height[0], center=center, convexity=convexity, twist=twist, slices=slices, scale=scale) {
            children();
        }
    }
}

/**
 * @license
 * MIT License
 *
 * Copyright (c) 2017 Jean-Sebastien CONAN
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Part of the camelSCAD library.
 *
 * Operators that extrude children modules with respect to particular rules.
 *
 * @package operator/extrude
 * @author jsconan
 */

/**
 * Extrudes linearly the children modules, and apply a wall adjustment to ensure
 * the final object will not produce artifacts after a `difference()` operation.
 *
 * @param Number [height] - The height of the extrusion. If the value is negative,
 *                          the extrusion will be made top to bottom (below the origin).
 * @param Number|String [direction] - Tells on what sides adjust the height to make sure
 *                                    the difference won't produce dummy walls.
 * @param Boolean [center] - Whether or not center the extrusion on the vertical axis.
 * @param Number [convexity] - If the extrusion fails for a non-trivial 2D shape,
 *                             try setting the convexity parameter.
 * @param Number [twist] - The number of degrees of through which the shape is extruded.
 * @param Number [slices] - Defines the number of intermediate points along the Z axis
 *                          of the extrusion.
 * @param Number|Vector [scale] - Scales the 2D shape by this value over the height of
 *                                the extrusion.
 */
module negativeExtrude(height, direction, center, convexity, twist, slices, scale) {
    center = boolean(center);
    convexity = numberOr(convexity, 10);
    height = align(height=height, direction=direction, center=center);

    translateZ(height[1]) {
        linear_extrude(height=height[0], center=center, convexity=convexity, twist=twist, slices=slices, scale=scale) {
            children();
        }
    }
}


Create CornerMount.scad

Create CornerMount.scad

/*
 Modeus 20mm corner mount
*/

module Cornermount (){
$fn=50;
    union (){
 difference (){

    color( "DarkGray", 1 ) {
     cube ([39,39,18]) ;
}

//  difference starts here
     translate ([2,2,3]){
    cube ([39,39,18]) ;
     }

  translate ([39,2,-1]){
      rotate ([0,0,45]){
    cube ([55,55,22]) ;
     }}

     hull() {
      translate ([9,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}
      translate ([14,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}}

     hull() {
      translate ([27,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}
      translate ([32,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}}

   rotate ([0,0,90]){
     hull() {
      translate ([9,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}
      translate ([14,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}}

     hull() {
      translate ([27,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}
           translate ([32,-3,9]){
      rotate ([270,0,0]){
    cylinder(h = 20, d = 5,  center = false);
     }}}
 }

}

// bults
       translate ([12,5,9]){
           rotate ([90,0,0]){
   difference (){

     union (){
     color( "Silver", 1 ) {
     cylinder(h = 3, d = 8,  center = false);
     cylinder(h = 12, d = 4,  center = false);
    }}
    translate ([0,0,-2]){
    cylinder(h = 4, d = 5, $fn=6, center = false);

    }
    }

    }}
           translate ([30,5,9]){
           rotate ([90,0,0]){
   difference (){

     union (){
     color( "Silver", 1 ) {
     cylinder(h = 3, d = 8,  center = false);
     cylinder(h = 12, d = 4,  center = false);
    }}
    translate ([0,0,-2]){
    cylinder(h = 4, d = 5, $fn=6, center = false);

    }
    }
    }}
           translate ([5,30,9]){
           rotate ([270,0,90]){
   difference (){

     union (){
     color( "Silver", 1 ) {
     cylinder(h = 3, d = 8,  center = false);
     cylinder(h = 12, d = 4,  center = false);
    }}
    translate ([0,0,-2]){
    cylinder(h = 4, d = 5, $fn=6, center = false);

    }
    }
    }}
           translate ([5,12,9]){
           rotate ([270,0,90]){
   difference (){

     union (){
     color( "Silver", 1 ) {
     cylinder(h = 3, d = 8,  center = false);
     cylinder(h = 12, d = 4,  center = false);
    }}
    translate ([0,0,-2]){
    cylinder(h = 4, d = 5, $fn=6, center = false);

    }
    }
    }}

}
}

/*
placing mounts
*/
translate ([20,1,35]) {
rotate ([90,270,180]){
Cornermount ();
}}
translate ([20,1,105]) {
rotate ([90,270,180]){
Cornermount ();
}}

translate ([420,1,35]) {
rotate ([90,0,180]){
Cornermount ();
}}
translate ([420,1,105]) {
rotate ([90,0,180]){
Cornermount ();
}}

translate ([20,1,300]) {
rotate ([90,180,180]){
Cornermount ();
}}
translate ([420,1,300]) {
rotate ([90,90,180]){
Cornermount ();
}}

translate ([20,339,35]) {
rotate ([90,0,0]){
Cornermount ();
}}

translate ([420,339,35]) {
rotate ([90,270,0]){
Cornermount ();
}}

translate ([20,339,300]) {
rotate ([90,90,0]){
Cornermount ();
}}
translate ([420,339,300]) {
rotate ([90,180,0]){
Cornermount ();
}}

translate ([1,20,105]) {
rotate ([90,0,90]){
Cornermount ();
}}
translate ([1,320,300]) {
rotate ([270,0,270]){
Cornermount ();
}}

translate ([1,20,300]) {
rotate ([90,90,90]){
Cornermount ();
}}
translate ([1,320,105]) {
rotate ([90,270,90]){
Cornermount ();
}}

translate ([439,319,300]) {
rotate ([270,90,90]){
Cornermount ();
}}
translate ([439,20,105]) {
rotate ([270,270,90]){
Cornermount ();
}}
translate ([439,20,300]) {
rotate ([270,0,90]){
Cornermount ();
}}
translate ([439,319,105]) {
rotate ([270,180,90]){
Cornermount ();
}}

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


cadcorn update

cadcorn update

// Cadcorn, a parametric model of a 3D-printable unicorn
// ©2015 Paul Houghton, paul.houghton@futurice.com, CC-attribution-sharealike license, http://creativecommons.org/licenses/by-sa/4.0/
low_poly = 8;
high_poly = 128;

scale = 1;

head_big_radius = 10*scale;
head_small_radius = 4.5*scale;
head_length = 18*scale;
head_angle = 50;

horn_length = 20*scale;
horn_radius = 2.8*scale;

mane_thickness = 2*horn_radius;
mane_radius = head_big_radius;
mane_height = head_big_radius * 0.7;
mane_x = head_big_radius * 0.28;
mane_length_x = 10*scale;
mane_length_z = 20*scale;

hair_thickness = mane_thickness / 8;
hair_spacing = mane_thickness / 2;

neck_radius = 3*scale;
neck_ratio = .2; // Flattens the interface to the top body
neck_top_x = 3*scale;

body_x = 15*scale;
body_z = 28*scale;
body_radius = 14*scale;
body_back_radius = 12*scale;
body_length = 33*scale;

leg_length = (33*scale + body_radius);
leg_radius = 4*scale;

cute_leg_first_ratio = 0.5;
cute_leg_second_ratio = 0.25;
cute_leg_third_ratio = 0.11;

tail_thickness = mane_thickness;
tail_radius = 10 * hair_thickness;
tail_x = 2*body_x + body_length - tail_radius;
tail_height = -body_z + 1.7*tail_radius;
tail_tip_length = 29*scale;

base_thickness = 10*scale;
base_width = 40*scale;
base_corner_radius = 5*scale;
base_length = 100*scale;

cadcorn(poly=low_poly);

module cadcorn(poly=high_poly) {
    union() { // difference() -> no base, or union() -> solid base
        union() {
            head(p=poly);
//        horn();  // Uncomment either horn() or chili_horn or neither
            color("red") chili_horn();
            neck(p=poly);
            mane(p=poly);
            body(p=poly);
            leg(p=poly, theta=5, sideways=3*scale);
            cute_leg(p=poly, theta=-5, sideways=-3*scale, downwards=3*scale);
            leg(p=poly, lengthwards = body_length, sideways=2*scale, theta=15);
            leg(p=poly, lengthwards = body_length, sideways=-2*scale, theta=-15);
            tail(p=poly);
        }
        base(p=poly);
    }
}

module head(p=high_poly) {
    rotate([0, -head_angle, 0]) {
        hull () {
            sphere($fn=p, r=head_big_radius);
            translate([-head_length, 0, 0])
                sphere($fn=p, r=head_small_radius);
        }
    }
}

module horn(p=high_poly) {
    rotate([0, -head_angle, 0]) {
        translate([0, 0, head_big_radius - .2*scale])
        cylinder($fn=p, h=horn_length, r1=horn_radius, r2=0);
    }
}

module chili_horn(p=high_poly) {
    rotate([0, -head_angle, 0]) {
        z = 1.1*scale + head_big_radius - .2*scale;
        translate([0, 0, z])
            hull() {
                sphere($fn=p, r=horn_radius);
                translate([0, 0, horn_length/3])
                    sphere($fn=p, r=horn_radius*.8);
            }
       translate([0, 0, z + horn_length/3])
            hull() {
                sphere($fn=p, r=horn_radius*.8);
                rotate([0, -10, 0]) {
                    translate([0, 0, 3*horn_length/6])
                        sphere($fn=p, r=horn_radius*.6);
                }
            }
    }
}

module neck(p=high_poly) {
    hull() {
        translate([neck_top_x, 0, 0]) rotate([0, 180, 0]) {
            cylinder($fn=p, h=head_big_radius - .2*scale, r1=neck_radius, r2=neck_radius);
        }
        translate([body_x, 0, -body_z])
            difference() {
                sphere($fn=p, r=body_radius);
                translate([body_radius*neck_ratio, -body_radius, -body_radius])
                    cube([body_radius, 2*body_radius, 2*body_radius]);
            }
        }
}

module hair_line(p=high_poly, x=0, z=0, hair_radius=mane_radius, delta_x=body_x, delta_z=body_z) {
    translate([x, 0, z])
            difference() {
                hull() {
                    cylinder($fn=p, h=mane_thickness, r=hair_radius);
                    translate([delta_x, -delta_z, 0])
                        cylinder($fn=p, h=mane_thickness, r=hair_radius);
                }
                hull() {
                    cylinder($fn=p, h=mane_thickness, r=hair_radius - hair_spacing);
                    translate([delta_x, -delta_z, 0])
                        cylinder($fn=p, h=mane_thickness, r=hair_radius - hair_spacing);
                }
            }
}

module mane(p=high_poly) {
    translate([mane_x, mane_thickness/2, mane_height])
        rotate([90, 0, 0]) {
                hull() {
                    translate([0, 0, hair_thickness])
                    cylinder($fn=p, h=mane_thickness - 2*hair_thickness, r=mane_radius);
                    translate([body_x, -body_z, 0])
                       cylinder($fn=p, h=mane_thickness - 2*hair_thickness, r=mane_radius);
                }
              hair_line(p=p);
              hair_line(p=p, hair_radius = mane_radius - 2*hair_spacing);
        }
}

module body(p=high_poly) {
    translate([body_x, 0, -body_z])
        hull() {
            sphere($fn=p, r=body_radius);
            translate([body_length, 0, 0])
                sphere($fn=p, r=body_back_radius);
        }
}

module leg(p=high_poly, lengthwards=0, sideways=0, theta=20) {
    translate([body_x + lengthwards, sideways, -body_z])
        rotate([180 + theta, 0, 0]) {
        cylinder($fn=p, h=leg_length, r1=leg_radius, r2=leg_radius);
        }
}

module cute_leg(p=high_poly, lengthwards=0, sideways=0, downwards=0, theta=20, rise_angle=70) {
    translate([body_x + lengthwards, sideways, -body_z - downwards])
        rotate([180 + theta, rise_angle, 0]) {
            cylinder($fn=p, h=leg_length*cute_leg_first_ratio, r1=leg_radius, r2=leg_radius);
            translate([0, 0, leg_length*cute_leg_first_ratio])
                union() {
                    sphere($fn = 2*p, r=leg_radius);
                    rotate([0, 90, 0]) {
                        cylinder($fn=p, h=leg_length*cute_leg_second_ratio, r1=leg_radius, r2=leg_radius);
                    }
                    translate([leg_length*cute_leg_second_ratio, 0, 0])
                        union() {
                            sphere($fn=2*p, r=leg_radius);
                            rotate([0, 90 + rise_angle, 0]) {
                                cylinder($fn=p, h=leg_length*cute_leg_third_ratio, r1=leg_radius, r2=leg_radius);
                            }
                        }
                }
    }
}

module tail_outer_hair(p=high_poly) {
    translate([0, 0, -hair_thickness])
        difference() {
            hull() {
                cylinder($fn=p, h=tail_thickness, r=tail_radius);
                translate([body_x, -1.2*body_z, 0])
                    rotate([0, 0, 11]) {
                        cube([tail_tip_length, tail_tip_length, tail_thickness]);
                    }
            }
            hull() {
                cylinder($fn=p, h=tail_thickness, r=tail_radius - hair_spacing);
                translate([body_x + 2*hair_spacing, -1.2*body_z + hair_spacing, 0]) rotate([0, 0, 11]) {
                    cube([tail_tip_length - 2.8*hair_spacing, tail_tip_length - 2.8*hair_spacing, tail_thickness]);
                }
            }
        }
}

module tail_single_hair(p=high_poly, n=1) {
    translate([0, -4.5*n, -hair_thickness])
        rotate([0, 0, -15*n]) {
            difference() {
                hull() {
                    cylinder($fn=p, h=tail_thickness, r=tail_radius);
                    translate([body_x, -1.2*body_z, 0])
                        rotate([0, 0, 11]) {
                            cube([tail_tip_length, tail_tip_length, tail_thickness]);
                        }
                }
                union() {
                    hull() {
                        cylinder($fn=p, h=tail_thickness, r=tail_radius - hair_spacing);
                        translate([body_x + 2*hair_spacing, -1.2*body_z + hair_spacing, 0]) rotate([0, 0, 11]) {
                            cube([tail_tip_length - 2.8*hair_spacing, tail_tip_length - 2.8*hair_spacing, tail_thickness]);
                        }
                    }
                    rotate([50, 90, 0]) {
                        translate([-3*scale, -7*scale, 0]) cylinder($fn=p, r=6*scale, h=40*scale);
                    }
                }
            }
        }
}

module tail(p=high_poly) {
    translate([tail_x, tail_thickness/2 - hair_thickness, tail_height])
        rotate([90, 0, 0]) {
            intersection() {
                union() {
                    hull() {
                        cylinder($fn=p, h=tail_thickness - 2*hair_thickness, r=tail_radius);
                        translate([body_x, -1.2*body_z, 0])
                            rotate([0, 0, 11]) {
                               cube([tail_tip_length, tail_tip_length, tail_thickness - 2*hair_thickness]);
                            }
                    }
                    tail_outer_hair(p=p);
                    tail_single_hair(p=p, n=1);
                    tail_single_hair(p=p, n=2);
                }
                translate([0, 0, -hair_thickness])
                    cylinder($fn = 2*p, h=10*scale+tail_thickness, r=tail_tip_length*1.25);
            }
        }
}

module base(p=high_poly) {
    translate([body_x + 0.6*body_length, 0, -leg_length - body_z])
        minkowski() {
            cylinder($fn=p, h = base_thickness / 3, r = base_corner_radius);
            cube([base_length, base_width - 2*base_corner_radius, base_thickness/3], center = true);
        }
}

// Cadcorn, a parametric model of a 3D-printable unicorn
// ©2015 Paul Houghton, paul.houghton@futurice.com, CC-attribution-sharealike license, http://creativecommons.org/licenses/by-sa/4.0/
low_poly = 8;
high_poly = 64;
low_poly_joint = 16;
high_poly_joint = 64;

$fn=low_poly; // low_poly or high_poly
joint_poly = low_poly_joint; // low_poly_join or high_poly_joint
scale = 1;

head_big_radius = 10*scale;
head_small_radius = 4.5*scale;
head_length = 18*scale;
head_angle = 50;

horn_length = 20*scale;
horn_radius = 2.8*scale;

mane_thickness = 2*horn_radius;
mane_radius = head_big_radius;
mane_height = head_big_radius * 0.7;
mane_x = head_big_radius * 0.28;
mane_length_x = 10*scale;
mane_length_z = 20*scale;

hair_thickness = mane_thickness / 8;
hair_spacing = mane_thickness / 2;

neck_radius = 3*scale;
neck_ratio = .2; // Flattens the interface to the top body
neck_top_x = 3*scale;

body_x = 15*scale;
body_z = 28*scale;
body_radius = 14*scale;
body_back_radius = 12*scale;
body_length = 33*scale;

leg_length = (33*scale + body_radius);
leg_radius = 4*scale;

cute_leg_first_ratio = 0.5;
cute_leg_second_ratio = 0.25;
cute_leg_third_ratio = 0.11;

tail_thickness = mane_thickness;
tail_radius = 10 * hair_thickness;
tail_x = 2*body_x + body_length - tail_radius;
tail_height = -body_z + 1.7*tail_radius;
tail_tip_length = 29*scale;

base_thickness = 10*scale;
base_width = 40*scale;
base_corner_radius = 5*scale;
base_length = 100*scale;

module head() {
    rotate([0, -head_angle, 0]) {
        hull () {
            sphere(r=head_big_radius);
            translate([-head_length, 0, 0])
                sphere(r=head_small_radius);
        }
    }
}

module horn() {
    rotate([0, -head_angle, 0]) {
        translate([0, 0, head_big_radius - .2*scale])
        cylinder(h = horn_length, r1 = horn_radius, r2 = 0);
    }
}

module chili_horn() {
    rotate([0, -head_angle, 0]) {
        z = 1.1*scale + head_big_radius - .2*scale;
        translate([0, 0, z])
            hull() {
                sphere(r = horn_radius);
                translate([0, 0, horn_length/3])
                    sphere(r = horn_radius * .8);
            }
       translate([0, 0, z + horn_length/3])
            hull() {
                sphere(r = horn_radius * .8);
                rotate([0, -10, 0]) {
                    translate([0, 0, 3*horn_length/6])
                        sphere(r = horn_radius * .6);
                }
            }
    }
}

module neck() {
    hull() {
        translate([neck_top_x, 0, 0]) rotate([0, 180, 0]) {
            cylinder(h = head_big_radius - .2*scale, r1 = neck_radius, r2 = neck_radius);
        }
        translate([body_x, 0, -body_z])
            difference() {
                sphere(r = body_radius);
                translate([body_radius*neck_ratio, -body_radius, -body_radius])
                    cube([body_radius, 2*body_radius, 2*body_radius]);
            }
        }
}

module hair_line(x = 0, z = 0, hair_radius = mane_radius, delta_x = body_x, delta_z = body_z) {
    translate([x, 0, z])
            difference() {
                hull() {
                    cylinder(h = mane_thickness, r = hair_radius);
                    translate([delta_x, -delta_z, 0])
                        cylinder(h = mane_thickness, r = hair_radius);
                }
                hull() {
                    cylinder(h = mane_thickness, r = hair_radius - hair_spacing);
                    translate([delta_x, -delta_z, 0])
                        cylinder(h = mane_thickness, r = hair_radius - hair_spacing);
                }
            }
}

module mane() {
    translate([mane_x, mane_thickness/2, mane_height])
        rotate([90, 0, 0]) {
                hull() {
                    translate([0, 0, hair_thickness])
                    cylinder(h = mane_thickness - 2*hair_thickness, r = mane_radius);
                    translate([body_x, -body_z, 0])
                       cylinder(h = mane_thickness - 2*hair_thickness, r = mane_radius);
                }
              hair_line();
              hair_line(hair_radius = mane_radius - 2*hair_spacing);
        }
}

module body() {
    translate([body_x, 0, -body_z])
        hull() {
            sphere(r = body_radius);
            translate([body_length, 0, 0])
                sphere(r = body_back_radius);
        }
}

module leg(lengthwards=0, sideways=0, theta=20) {
    translate([body_x + lengthwards, sideways, -body_z])
        rotate([180 + theta, 0, 0]) {
        cylinder(h = leg_length, r1 = leg_radius, r2 = leg_radius);
        }
}

module cute_leg(lengthwards=0, sideways=0, downwards=0, theta=20, rise_angle=70) {
    translate([body_x + lengthwards, sideways, -body_z - downwards])
        rotate([180 + theta, rise_angle, 0]) {
            cylinder(h = leg_length*cute_leg_first_ratio, r1 = leg_radius, r2 = leg_radius);
            translate([0, 0, leg_length*cute_leg_first_ratio])
                union() {
                    sphere($fn = joint_poly, r = leg_radius);
                    rotate([0, 90, 0]) {
                        cylinder(h = leg_length*cute_leg_second_ratio, r1 = leg_radius, r2 = leg_radius);
                    }
                    translate([leg_length*cute_leg_second_ratio, 0, 0])
                        union() {
                            sphere($fn = joint_poly, r = leg_radius);
                            rotate([0, 90 + rise_angle, 0]) {
                                cylinder(h = leg_length*cute_leg_third_ratio, r1 = leg_radius, r2 = leg_radius);
                            }
                        }
                }
    }
}

module tail_outer_hair() {
    translate([0, 0, -hair_thickness])
        difference() {
            hull() {
                cylinder(h = tail_thickness, r = tail_radius);
                translate([body_x, -1.2*body_z, 0])
                    rotate([0, 0, 11]) {
                        cube([tail_tip_length, tail_tip_length, tail_thickness]);
                    }
            }
            hull() {
                cylinder(h = tail_thickness, r = tail_radius - hair_spacing);
                translate([body_x + 2*hair_spacing, -1.2*body_z + hair_spacing, 0]) rotate([0, 0, 11]) {
                    cube([tail_tip_length - 2.8*hair_spacing, tail_tip_length - 2.8*hair_spacing, tail_thickness]);
                }
            }
        }
}

module tail_single_hair(n=1) {
    translate([0, -4.5*n, -hair_thickness])
        rotate([0, 0, -15*n]) {
            difference() {
                hull() {
                    cylinder(h = tail_thickness, r = tail_radius);
                    translate([body_x, -1.2*body_z, 0])
                        rotate([0, 0, 11]) {
                            cube([tail_tip_length, tail_tip_length, tail_thickness]);
                        }
                }
                union() {
                    hull() {
                        cylinder(h = tail_thickness, r = tail_radius - hair_spacing);
                        translate([body_x + 2*hair_spacing, -1.2*body_z + hair_spacing, 0]) rotate([0, 0, 11]) {
                            cube([tail_tip_length - 2.8*hair_spacing, tail_tip_length - 2.8*hair_spacing, tail_thickness]);
                        }
                    }
                    rotate([50, 90, 0]) {
                        translate([-3*scale, -7*scale, 0]) cylinder(r = 6*scale, h = 40*scale);
                    }
                }
            }
        }
}

module tail() {
    translate([tail_x, tail_thickness/2 - hair_thickness, tail_height])
        rotate([90, 0, 0]) {
            intersection() {
                union() {
                    hull() {
                        cylinder(h = tail_thickness - 2*hair_thickness, r = tail_radius);
                        translate([body_x, -1.2*body_z, 0])
                            rotate([0, 0, 11]) {
                               cube([tail_tip_length, tail_tip_length, tail_thickness - 2*hair_thickness]);
                            }
                    }
                    tail_outer_hair();
                    tail_single_hair(n=1);
                    tail_single_hair(n=2);
                }
                translate([0, 0, -hair_thickness])
                    cylinder($fn = 16, h = 10*scale+tail_thickness, r = tail_tip_length*1.25);
            }
        }
}

module base() {
    translate([body_x + 0.6*body_length, 0, -leg_length - body_z])
        minkowski() {
            cylinder($fn = joint_poly, h = base_thickness / 3, r = base_corner_radius);
            cube([base_length, base_width - 2*base_corner_radius, base_thickness/3], center = true);
        }
}

union() { // difference() -> no base, or union() -> solid base
    union() {
        head();
//        horn();  // Uncomment either horn() or chili_horn or neither
        color("red") chili_horn();
        neck();
        mane();
        body();
        leg(theta=5, sideways=3*scale);
        cute_leg(theta=-5, sideways=-3*scale, downwards=3*scale);
        leg(lengthwards = body_length, sideways=2*scale, theta=15);
        leg(lengthwards = body_length, sideways=-2*scale, theta=-15);
        tail();
    }
    base();
}


parameterize the x and y scale

parameterize the x and y scale

use <../../../../shapes/open-cylinder/open-cylinder.scad>

use <../../lamp-shade.scad>

module legLampShade(squareLength,
                    outerRadius,
                    xScale,
                    yScale)
{
    bottomHeight = 5;

    union(outerRadius)
    {
        translate([0, 0, bottomHeight])
        legLamp_shade_top(squareLength = squareLength,
                          outerRadius = outerRadius,
                          xScale = xScale,
                          yScale = yScale);

        color("purple")
        legLamp_shade_bottom(height = bottomHeight, outerRadius = outerRadius * 2);
    }
}

module legLamp_shade_bottom(height, outerRadius)
{
    innerRadius = outerRadius - 1;

    openCylinder(height = height,
                 innerRadius = innerRadius,
                 outerRadius = outerRadius);
}

module legLamp_shade_top(squareLength, outerRadius, xScale, yScale)
{
    zTranslate = outerRadius * yScale;

    translate([0, 0, zTranslate])
    lampShade(outerRadius = outerRadius,
            squareLength = squareLength,
            xScale = xScale,
            yScale = yScale);
}

use <../../../../shapes/open-cylinder/open-cylinder.scad>

use <../../lamp-shade.scad>

module legLampShade(squareLength,
                    outerRadius,
                    xScale,
                    yScale)
{
    bottomHeight = 5;

    union(outerRadius)
    {
        translate([0, 0, bottomHeight])
        legLamp_shade_top(squareLength = squareLength,
                          outerRadius = outerRadius,
                          xScale = xScale,
                          yScale = yScale);

        color("purple")
        legLamp_shade_bottom(height = bottomHeight, outerRadius = outerRadius * 2);
    }
}

module legLamp_shade_bottom(height, outerRadius)
{
    innerRadius = outerRadius - 1;

    openCylinder(height = height,
                 innerRadius = innerRadius,
                 outerRadius = outerRadius);
}

module legLamp_shade_top(squareLength, outerRadius, xScale, yScale)
{
    zTranslate = outerRadius * 0.7;   // 2.0 ;// + ( 10 / 2.0 );

    translate([0, 0, zTranslate])
    lampShade(outerRadius = outerRadius,
            squareLength = squareLength,
            xScale = 0.3,
            yScale = 0.7);
}


spelling

spelling

//Simple Objects
module ring(r=5,d=1) {
	difference() {
		circle(r=r);
		circle(r=r-d);
	}
}
//Translation Modules
module tr_xy(x,y=0) {
	if(y==0) {
		for(i=[-1,1])for(j=[-1,1])translate([x*i,x*j])children();
	} else {
		for(i=[-1,1])for(j=[-1,1])translate([x*i,y*j])children();
	}
}
module rot_x(x=0,rotation=90,off=0) {
	for(i=[0:360/rotation-1])rotate(a=[0,0,rotation*i+off])translate([x,0])children();
}
//Support for Hollowed Models
module support(comb=false) {
    intersection() {
        if(comb==false)support_raw();
        if(comb==true)support_honeycomb();
        children();
    }
}
module support_raw(x=20,y=20,d=1.1,t=0.15) {
    for(i=[-1,1])for(j=[0:d:x/2])translate([i*j,0])square([t,y],center=true);
    for(i=[-1,1])for(j=[0:d:x/2])translate([0,i*j])square([x,t],center=true);
}
module support_honeycomb(x=10,y=10,r=0.7,d=0.1,fn=6) {
    for(k=[-1,1])for(l=[0:2*(r+r*sin(30)-d):x]){
        for(i=[1,-1])for(j=[0:2*r*cos(30)-d:y]) {
            translate([k*l,i*j])comb(r,d,fn);
            translate([k*(l+r+r*sin(30)-d),i*(j+cos(30)*r-0.5*d)])comb(r,d,fn);
        }
    }
}
module comb(r,d,fn) {
    difference() {
        circle(r=r,$fn=fn);
        circle(r=r-d,$fn=fn);
    }
}

//Simple Objects
module ring(r=5,d=1) {
	difference() {
		circle(r=r);
		circle(r=r-d);
	}
}
//Translation Modules
module tr_xy(x,y=0) {
	if(y==0) {
		for(i=[-1,1])for(j=[-1,1])translate([x*i,x*j])children();
	} else {
		for(i=[-1,1])for(j=[-1,1])translate([x*i,y*j])children();
	}
}
module rot_x(x=0,rotation=90,off=0) {
	for(i=[0:360/rotation-1])rotate(a=[0,0,rotation*i+off])translate([x,0])children();
}
//Support for Holowed Models
module support(comb=false) {
    intersection() {
        if(comb==false)support_raw();
        if(comb==true)support_honeycomb();
        children();
    }
}
module support_raw(x=20,y=20,d=1.1,t=0.15) {
    for(i=[-1,1])for(j=[0:d:x/2])translate([i*j,0])square([t,y],center=true);
    for(i=[-1,1])for(j=[0:d:x/2])translate([0,i*j])square([x,t],center=true);
}
module support_honeycomb(x=10,y=10,r=0.7,d=0.1,fn=6) {
    for(k=[-1,1])for(l=[0:2*(r+r*sin(30)-d):x]){
        for(i=[1,-1])for(j=[0:2*r*cos(30)-d:y]) {
            translate([k*l,i*j])comb(r,d,fn);
            translate([k*(l+r+r*sin(30)-d),i*(j+cos(30)*r-0.5*d)])comb(r,d,fn);
        }
    }
}
module comb(r,d,fn) {
    difference() {
        circle(r=r,$fn=fn);
        circle(r=r-d,$fn=fn);
    }
}


tow line blocker + additional wall thickness

eps = 0.1;
th0 = 2.4; // original thickness
dth = 4; // extra thickness for the model
th  = th0 + dth;
h = 10;

fi = 3.5; // fi of screw
x1 = 18.5;
y2 = 16.75;
x3 = 12.4;

// screw block
translate([0, -th, 0])
  difference()
  {
    cube([x1, th, h]);
    translate([x1 - 10.5 - fi/2, -eps, h/2])
      rotate([-90, 0, 0])
        cylinder(r=fi/2, h=th+2*eps, $fn=30);
  }

// connector
translate([x1-th, -y2, 0])
  cube([th, y2, h]);

// block
translate([-dth, 0, 0])
  translate([x1-th0, -y2-th+th0, 0])
    cube([x3+dth, th, h]);


preparing structure

preparing structure

use <projector_plate.scad>;
use <projector.scad>;
include <profile.scad>;

$detailed = false;

offset_depth = 50;

translate([0, 0, -offset_depth])
  center_projector() {
    Acer_Plate(200, 120, 60, 100);
    Acer_H6510BD(true);
  }

width = 480;
offset = 5;
height = 500;
beam_width = width - 2 * (20 + offset);

translate([0, 0, -offset_depth]) {
  translate([-beam_width/2,-60,-10])
    rotate([90,90,90])
      profile_20x60(beam_width);

  translate([-width/2,-height/2,-10])
    rotate([-90,0,0])
      profile_20x40(height);
  translate([width/2,-height/2,-10])
    rotate([-90,0,0])
      profile_20x40(height);
}

// base
base_depth = 400;
module base(width, depth, sections = 2) {
  profile_height = sections * 20;
  translate([-width/2,0,-base_depth/2])
    rotate([0,0,0])
      profile(sections, base_depth);

  translate([width/2,0,-base_depth/2])
    rotate([0,0,0])
      profile(sections, base_depth);

  lateral_beam_width = width - 20;
  translate([-lateral_beam_width/2,0,-base_depth/2+10])
    rotate([0,90,0])
      profile(sections, lateral_beam_width);

  translate([-lateral_beam_width/2,0,base_depth/2-10])
    rotate([0,90,0])
      profile(sections, lateral_beam_width);
}

bottom_sections = 4;
translate([0,-(height+bottom_sections*20)/2,0])
  base(width, base_depth, bottom_sections);

middle_sections = 2;
translate([0,(height+middle_sections*20)/2,0])
  base(width, base_depth, middle_sections);

// support towers
tower_pos = base_depth / 2 - 20;
translate([-width/2,-height/2,-tower_pos])
  rotate([-90,0,0])
    profile_20x40(height);
translate([width/2,-height/2,-tower_pos])
  rotate([-90,0,0])
    profile_20x40(height);

/*
len = 270;
translate([-20,60,-len])
  profile_20x20(len);
translate([-20,140,-len])
  profile_20x20(len);

translate([50, 0, 0])
  profile_20x40(100);

translate([100, 0, 0])
  profile_20x60(100);

translate([150, 0, 0])
  profile_20x80(100);
*/

use <projector_plate.scad>;
use <projector.scad>;
include <profile.scad>;

$detailed = false;

translate([0,0,0]) {
  Acer_Plate(200, 120, 60, 100);
  Acer_H6510BD(true);
}

/*
len = 270;
translate([-20,60,-len])
  profile_20x20(len);
translate([-20,140,-len])
  profile_20x20(len);

translate([50, 0, 0])
  profile_20x40(100);

translate([100, 0, 0])
  profile_20x60(100);

translate([150, 0, 0])
  profile_20x80(100);
*/


screw diamater - 1mm of spacing instead of 0.5mm, to make sure screwing it in will not deform hole and create weaknesses

eps=0.1;

module mount()
{
  wall=5;
  screw_d=3.5+1;
  ls_dim=[236+1, 162+1];
  ls_border=11.6-2;
  mount_len=60;
  mount_size=[30, 2*wall, mount_len+wall];

  module body_mount()
  {
    difference()
    {
      cube([ls_dim[0]+2*wall, ls_dim[1]+1*wall, mount_len+wall]);
      translate(wall*[1,1,1])
        cube([ls_dim[0], ls_dim[1]+eps, mount_len+eps]);
      translate(wall*[2,2,0]-[0,0,eps])
        cube([ls_dim[0]-2*wall, ls_dim[1]-1*wall+eps, wall+2*eps]);
    }
  }

  module screw_mount()
  {
    module screw()
    {
      rotate([-90, 0, 0])
        union()
        {
          $fn=50;
          cylinder(r1=(2*screw_d)/2, r2=screw_d/2, h=5);
          translate([0, 0, 5-eps])
            cylinder(r=screw_d/2, h=5+eps+10);
        }
    }

    translate([-mount_size[0], 0, 0])
      difference()
      {
        cube(mount_size);
        for(i=[-1,0,+1])
          translate([mount_size[0]/2, -eps, mount_size[2]/2+i*18])
            screw();
      }
  }

  body_mount();
  for(i=[0,1])
    translate([i*(ls_dim[0]+2*wall+mount_size[0]), ls_dim[1]-wall, 0])
      screw_mount();
}

mount();

eps=0.1;

module mount()
{
  wall=5;
  screw_d=4;
  ls_dim=[236+1, 162+1];
  ls_border=11.6-2;
  mount_len=60;
  mount_size=[30, 2*wall, mount_len+wall];

  module body_mount()
  {
    difference()
    {
      cube([ls_dim[0]+2*wall, ls_dim[1]+1*wall, mount_len+wall]);
      translate(wall*[1,1,1])
        cube([ls_dim[0], ls_dim[1]+eps, mount_len+eps]);
      translate(wall*[2,2,0]-[0,0,eps])
        cube([ls_dim[0]-2*wall, ls_dim[1]-1*wall+eps, wall+2*eps]);
    }
  }

  module screw_mount()
  {
    module screw()
    {
      rotate([-90, 0, 0])
        union()
        {
          $fn=50;
          cylinder(r1=(2*screw_d)/2, r2=screw_d/2, h=5);
          translate([0, 0, 5-eps])
            cylinder(r=screw_d/2, h=5+eps+10);
        }
    }

    translate([-mount_size[0], 0, 0])
      difference()
      {
        cube(mount_size);
        for(i=[-1,0,+1])
          translate([mount_size[0]/2, -eps, mount_size[2]/2+i*18])
            screw();
      }
  }

  body_mount();
  for(i=[0,1])
    translate([i*(ls_dim[0]+2*wall+mount_size[0]), ls_dim[1]-wall, 0])
      screw_mount();
}

mount();