Got the design done... Not a big fan of it, but to each their own

// Program by Ankur Gupta
// www.github.com/agupta231
// Jan 2017

/**
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.
**/

init_size = 50;
iteration_multiplier = 0.75;
iterations = 3;

echo(version());

module aux_cubes(current_iter, starting_pos) {
    iter_size = init_size * pow(iteration_multiplier, current_iter);
    displacement = (init_size * (pow(iteration_multiplier, current_iter) + pow(iteration_multiplier, current_iter - 1))) / 2;

    for(i = [[displacement, 0, 0], [-displacement, 0, 0], [0, displacement, 0], [0, -displacement, 0], [0, 0, displacement], [0, 0, -displacement]]) {
        new_pos = i + starting_pos;

        translate(i + starting_pos) {
            cube(iter_size, center = true);
        }

        if(current_iter < iterations) {
            aux_cubes(current_iter + 1, new_pos);
        }
    }
}

total_length = ((init_size * iteration_multiplier) * (1 - pow(iteration_multiplier, iterations - 1))) / (1 - iteration_multiplier) * 2 + init_size - 5;

difference() {
    cube(total_length, center = true);

    union() {
        cube(init_size, center = true);

        aux_cubes(1, [0, 0, 0]);
    }
}

// Program by Ankur Gupta
// www.github.com/agupta231
// Jan 2017

/**
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.
**/

init_size = 50;
iteration_multiplier = 0.5;
iterations = 5;

echo(version());

module aux_cubes(current_iter, starting_pos) {
    iter_size = init_size * pow(iteration_multiplier, current_iter);
    displacement = (init_size * (pow(iteration_multiplier, current_iter) + pow(iteration_multiplier, current_iter - 1))) / 2;

    for(i = [[displacement, 0, 0], [-displacement, 0, 0], [0, displacement, 0], [0, -displacement, 0], [0, 0, displacement], [0, 0, -displacement]]) {
        new_pos = i + starting_pos;

        translate(i + starting_pos) {
            cube(iter_size, center = true);
        }

        if(current_iter < iterations) {
            aux_cubes(current_iter + 1, new_pos);
        }
    }
}

union() {
    cube(init_size, center = true);

    aux_cubes(1, [0, 0, 0]);
}


Readme: example-007 - update

Readme: example-007 - update

include <../lasercut.scad>;

thickness = 3.1;
x = 50;
y = 100;
r = thickness*2;
lasercutoutSquare(thickness=thickness, x=x, y=y,
    finger_joints=[
            [UP, 1, 4],
            [DOWN, 1, 4]
        ],
    circles_add = [
            [r, x+thickness, y/5],
        ],
    circles_remove = [
            [r, x/2, y/2],
            [1.5, x/2, y*2/3], // Screw-hole
        ],
    slits = [
            [RIGHT,x,y/2,10]
        ],
    cutouts = [
            [x/6, y/6, thickness*5, thickness*2]
        ]
    );

include <../lasercut.scad>;

thickness = 3.1;
x = 50;
y = 100;
r = thickness*2;
lasercutoutSquare(thickness=thickness, x=x, y=y,
    finger_joints=[
            [UP, 1, 4],
            [DOWN, 1, 4]
        ],
    circles_add = [
            [r, x+thickness, y/5],
        ],
    circles_remove = [
            [r, x/2, y/2],
            [1.5, x/2, y*2/3], // Screw-hole
        ],
    slits = [
            [RIGHT,x,y/2,10]
        ]
    );


made inner gear a bit thicker to reduce rattling

include <Parametric_Involute__Bevel_and_Spur_Gears/parametric_involute_gear_v5.0.scad>

$fn=50;
mm = 1;
inch = 25.4 * mm;

ACRYLIC_THICKNESS = 5. * mm;
ACRYLIC_TOL = .5 * mm;
PITCH = 360 * mm;
PRESSURE_ANGLE = 28;

RIM_THICKNESS = 2 * mm;
EXTRA_RIM_R = 3 * mm;

module hex(r, h){
  rotate(a=30, v=[0, 0, 1])
  linear_extrude(height=h)
    polygon(points=[[r,0],
		    [r * cos(60),r * sin(60)],
		    [r * cos(120),r * sin(120)],
		    [r * cos(180),r * sin(180)],
		    [r * cos(240),r * sin(240)],
		    [r * cos(300),r * sin(300)],
		    ],paths=[ [0, 1, 2, 3, 4, 5] ]);
}

module stepper_gear(N_TEETH=6){
  PITCH_R = N_TEETH * PITCH / 360.;
  PITCH_D = 2 * PITCH_R;
  PITCH_DIAMETRIAL = N_TEETH / PITCH_D;
  // Addendum: Radial distance from pitch circle to outside circle.
  ADDENDUM = 1 / PITCH_DIAMETRIAL;

  thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL;// + RIM_THICKNESS;
  //Outer Circle
  OUTER_RADIUS = PITCH_R + ADDENDUM;
  difference(){
    union(){
      rotate(a=360/6/2., v=[0, 0, 1])
      gear (number_of_teeth=6,
	    circular_pitch = PITCH,
	    gear_thickness = thickness,
	    rim_thickness = thickness,
	    hub_thickness = thickness,
	    bore_diameter=0. * mm,
	    circles=4,
	    pressure_angle=28
	    );
      translate([0, 0, -RIM_THICKNESS])cylinder(r=OUTER_RADIUS, h=RIM_THICKNESS);
      // translate([0, 0, 6.5*mm])cylinder(r=OUTER_RADIUS, h=RIM_THICKNESS);
      translate([0, 0, -2 * RIM_THICKNESS])cylinder(r=OUTER_RADIUS + EXTRA_RIM_R, h=RIM_THICKNESS);
    }
    translate([0, 0, -1])cylinder(r=3 * mm/2, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);
  }
}

module outer_gear(N_TEETH=66){
  PITCH_R = N_TEETH * PITCH / 360.;
  PITCH_D = 2 * PITCH_R;
  PITCH_DIAMETRIAL = N_TEETH / PITCH_D;
  // Addendum: Radial distance from pitch circle to outside circle.
  ADDENDUM = 1 / PITCH_DIAMETRIAL;

  //Outer Circle
  OUTER_RADIUS = PITCH_R + ADDENDUM;
  OUTER_DIAMETER = 2 * OUTER_RADIUS;

  MARGIN = 1 * inch;
  difference(){
    cylinder(r=OUTER_RADIUS  +  MARGIN, h=ACRYLIC_THICKNESS + ACRYLIC_TOL);
    translate([0, 0, -1])
    gear (number_of_teeth=N_TEETH,
	  circular_pitch = PITCH,
	  gear_thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL + 2,
	  rim_thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL + 2,
	  hub_thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL + 2,
	  bore_diameter=0. * mm,
	  circles=0,
	  pressure_angle=28
	  );
  }
}

module inner_gear(minute, N_TEETH=30){
  PITCH_R = N_TEETH * PITCH / 360.;
  PITCH_D = 2 * PITCH_R;
  PITCH_DIAMETRIAL = N_TEETH / PITCH_D;
  // Addendum: Radial distance from pitch circle to outside circle.
  ADDENDUM = 1 / PITCH_DIAMETRIAL;

  //Outer Circle
  OUTER_RADIUS = PITCH_R + ADDENDUM;
  OUTER_DIAMETER = 2 * OUTER_RADIUS;
  rad = 10 * mm;
  d1 = (rad + .0) * [1,0,0];
  d2 = (rad + .0) * [sin(30), cos(30), 0];
  translate([0, 36  * mm, 0])
    rotate(a=360/30/4 - 66./30 * minute/60 * 360 + minute/60.*720, v=[0, 0,1])
    difference(){
    intersection(){
      cylinder(r1=40, r2=26.5, h=ACRYLIC_THICKNESS); // taper the teeth
      scale([1, 1, 1])gear (number_of_teeth=N_TEETH,
	    circular_pitch = PITCH,
			    gear_thickness = ACRYLIC_THICKNESS/2,
			    rim_thickness = ACRYLIC_THICKNESS, //   - ACRYLIC_TOL,
			    hub_thickness = ACRYLIC_THICKNESS, //  - ACRYLIC_TOL,
	    bore_diameter=0. * mm,
	    circles=0,
	    pressure_angle=28
	    );
    }
    translate([0, 0, -1])cylinder(r=6 * mm/2, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);

    // lighten the load
    for(i=[0:4]){
      rotate(a=360/5 * i, v=[0, 0, 1])translate([0, 16, -1])cylinder(r=6 * mm, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);
      // scale([1, 1, .3])translate([0, 0, ])rotate(a=360/5 * i, v=[0, 0, 1])translate([0, 18, -1])sphere(r=11 * mm);
    }
  }
  // add in rim strip to support hour hand
  translate([0, 0, 1])
    union(){
    difference(){
      translate([0, 36*mm, 0])cylinder(r = 1*inch, h=ACRYLIC_THICKNESS);
      translate([0, 36*mm, -1])cylinder(r = 7 * inch/8, h=ACRYLIC_THICKNESS+2);
    }
    difference(){
      translate([0, 36*mm, 0])cylinder(r = 8*mm, h=ACRYLIC_THICKNESS);
      translate([0, 36*mm, -1])cylinder(r = 4*mm, h=ACRYLIC_THICKNESS+2);
    }
  }
}

module minute_hand(r=65*mm, w=21.5*mm, h=RIM_THICKNESS - 0.5*mm,filagree=false){
//linear_extrude(height = 2, center=true)
//polygon(points=[[-5*mm/2, 0], [0, 65*mm], [5*mm/2, 0]]);
  difference(){
    union(){
      stepper_gear(N_TEETH=6);
      translate([0, 2*mm, -2*RIM_THICKNESS])
	linear_extrude(height=h)

        if (filagree){

            translate([0,8.2,0])scale([1.3,1,1])import("filagreeminute.dxf");

        }

        else
            polygon(points=[[-w/2, 0], [0, r], [w/2, 0]]);
    }
    translate([0, 0, -50])cylinder(r=3 * mm/2, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);
    // translate([0, r - 15 * mm, -50])cylinder(h=100, r=3.00/2*mm); //hole for hall effect magnet
  }
}

module hour_hand(r=50*mm, w=21.5*mm, h=1.5*mm, filagree = false){
  difference(){
    union(){
      translate([0, RIM_THICKNESS, -RIM_THICKNESS])
	linear_extrude(height=h)

        if (filagree){

            translate([0,8.2,0])scale([1.3,1,1])import("filagreehour.dxf");

        }else
	polygon(points=[[-w/2, 0], [0, r], [w/2, 0]]);
      // translate([0, 36, -RIM_THICKNESS])cylinder(r=5.5 * mm/2, h=ACRYLIC_THICKNESS + RIM_THICKNESS + .5*mm);
      translate([0, 36, -RIM_THICKNESS])cylinder(r=5.5 * mm/2, h=ACRYLIC_THICKNESS + RIM_THICKNESS + 1);
      translate([0, 36, ACRYLIC_THICKNESS + .75*mm])scale([1, .8, 1])cylinder(r1=7/2. * mm, r2=3.2*mm, h=1.5*mm); // clip
      translate([0, 0, -RIM_THICKNESS])cylinder(r=11, h=h);
    }
    translate([0, 0, -RIM_THICKNESS - 1])cylinder(r=8.25, h=2*h);
    translate([-.5 * mm, 36 * mm-5 * mm, 2])cube([1 * mm, 10 * mm, 10 * mm]); // slot
    //translate([0, r - 10 * mm, -50])cylinder(h=100, r=3.00/2*mm); // hall effect magnet slot
  }
}

HOUR = 9;
MINUTE = $t * 60;
//MINUTE = HOUR * 60 + 15;
// translate([0,0, 2])rotate(v=[0, 1, 0], a=180)
translate([0, -0, -RIM_THICKNESS])rotate(a=MINUTE/720 * 360, v=[0, 0, 1])color([.1, 1, 0])inner_gear(MINUTE);
// color([.1, .1, 1])outer_gear();
translate([0, 0, -1.5*mm])rotate(a=MINUTE/720 * 360, v=[0, 0, 1])color([1, 0, 0])rotate(a=0, v=[0, 0, 1])hour_hand(w=11,filagree=true);
translate([0, 0, -RIM_THICKNESS])translate([0, 0, 0])rotate(a=MINUTE/60 * 360, v=[0, 0, 1])minute_hand(w=12,filagree=true);

// cylinder(r=50*mm, h=100*mm); // for scale

include <Parametric_Involute__Bevel_and_Spur_Gears/parametric_involute_gear_v5.0.scad>

$fn=50;
mm = 1;
inch = 25.4 * mm;

ACRYLIC_THICKNESS = 5. * mm;
ACRYLIC_TOL = .5 * mm;
PITCH = 360 * mm;
PRESSURE_ANGLE = 28;

RIM_THICKNESS = 2 * mm;
EXTRA_RIM_R = 3 * mm;

module hex(r, h){
  rotate(a=30, v=[0, 0, 1])
  linear_extrude(height=h)
    polygon(points=[[r,0],
		    [r * cos(60),r * sin(60)],
		    [r * cos(120),r * sin(120)],
		    [r * cos(180),r * sin(180)],
		    [r * cos(240),r * sin(240)],
		    [r * cos(300),r * sin(300)],
		    ],paths=[ [0, 1, 2, 3, 4, 5] ]);
}

module stepper_gear(N_TEETH=6){
  PITCH_R = N_TEETH * PITCH / 360.;
  PITCH_D = 2 * PITCH_R;
  PITCH_DIAMETRIAL = N_TEETH / PITCH_D;
  // Addendum: Radial distance from pitch circle to outside circle.
  ADDENDUM = 1 / PITCH_DIAMETRIAL;

  thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL;// + RIM_THICKNESS;
  //Outer Circle
  OUTER_RADIUS = PITCH_R + ADDENDUM;
  difference(){
    union(){
      rotate(a=360/6/2., v=[0, 0, 1])
      gear (number_of_teeth=6,
	    circular_pitch = PITCH,
	    gear_thickness = thickness,
	    rim_thickness = thickness,
	    hub_thickness = thickness,
	    bore_diameter=0. * mm,
	    circles=4,
	    pressure_angle=28
	    );
      translate([0, 0, -RIM_THICKNESS])cylinder(r=OUTER_RADIUS, h=RIM_THICKNESS);
      // translate([0, 0, 6.5*mm])cylinder(r=OUTER_RADIUS, h=RIM_THICKNESS);
      translate([0, 0, -2 * RIM_THICKNESS])cylinder(r=OUTER_RADIUS + EXTRA_RIM_R, h=RIM_THICKNESS);
    }
    translate([0, 0, -1])cylinder(r=3 * mm/2, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);
  }
}

module outer_gear(N_TEETH=66){
  PITCH_R = N_TEETH * PITCH / 360.;
  PITCH_D = 2 * PITCH_R;
  PITCH_DIAMETRIAL = N_TEETH / PITCH_D;
  // Addendum: Radial distance from pitch circle to outside circle.
  ADDENDUM = 1 / PITCH_DIAMETRIAL;

  //Outer Circle
  OUTER_RADIUS = PITCH_R + ADDENDUM;
  OUTER_DIAMETER = 2 * OUTER_RADIUS;

  MARGIN = 1 * inch;
  difference(){
    cylinder(r=OUTER_RADIUS  +  MARGIN, h=ACRYLIC_THICKNESS + ACRYLIC_TOL);
    translate([0, 0, -1])
    gear (number_of_teeth=N_TEETH,
	  circular_pitch = PITCH,
	  gear_thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL + 2,
	  rim_thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL + 2,
	  hub_thickness = ACRYLIC_THICKNESS + ACRYLIC_TOL + 2,
	  bore_diameter=0. * mm,
	  circles=0,
	  pressure_angle=28
	  );
  }
}

module inner_gear(minute, N_TEETH=30){
  PITCH_R = N_TEETH * PITCH / 360.;
  PITCH_D = 2 * PITCH_R;
  PITCH_DIAMETRIAL = N_TEETH / PITCH_D;
  // Addendum: Radial distance from pitch circle to outside circle.
  ADDENDUM = 1 / PITCH_DIAMETRIAL;

  //Outer Circle
  OUTER_RADIUS = PITCH_R + ADDENDUM;
  OUTER_DIAMETER = 2 * OUTER_RADIUS;
  rad = 10 * mm;
  d1 = (rad + .0) * [1,0,0];
  d2 = (rad + .0) * [sin(30), cos(30), 0];
  translate([0, 36  * mm, 0])
    rotate(a=360/30/4 - 66./30 * minute/60 * 360 + minute/60.*720, v=[0, 0,1])
    difference(){
    intersection(){
      cylinder(r1=40, r2=26.5, h=ACRYLIC_THICKNESS); // taper the teeth
      scale([1, 1, 1])gear (number_of_teeth=N_TEETH,
	    circular_pitch = PITCH,
			    gear_thickness = ACRYLIC_THICKNESS/2,
	    rim_thickness = ACRYLIC_THICKNESS - ACRYLIC_TOL,
	    hub_thickness = ACRYLIC_THICKNESS - ACRYLIC_TOL,
	    bore_diameter=0. * mm,
	    circles=0,
	    pressure_angle=28
	    );
    }
    translate([0, 0, -1])cylinder(r=6 * mm/2, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);

    // lighten the load
    for(i=[0:4]){
      rotate(a=360/5 * i, v=[0, 0, 1])translate([0, 16, -1])cylinder(r=6 * mm, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);
      // scale([1, 1, .3])translate([0, 0, ])rotate(a=360/5 * i, v=[0, 0, 1])translate([0, 18, -1])sphere(r=11 * mm);
    }
  }
  // add in rim strip to support hour hand
  translate([0, 0, 1])
    union(){
    difference(){
      translate([0, 36*mm, 0])cylinder(r = 1*inch, h=ACRYLIC_THICKNESS);
      translate([0, 36*mm, -1])cylinder(r = 7 * inch/8, h=ACRYLIC_THICKNESS+2);
    }
    difference(){
      translate([0, 36*mm, 0])cylinder(r = 8*mm, h=ACRYLIC_THICKNESS);
      translate([0, 36*mm, -1])cylinder(r = 4*mm, h=ACRYLIC_THICKNESS+2);
    }
  }
}

module minute_hand(r=65*mm, w=21.5*mm, h=RIM_THICKNESS - 0.5*mm,filagree=false){
//linear_extrude(height = 2, center=true)
//polygon(points=[[-5*mm/2, 0], [0, 65*mm], [5*mm/2, 0]]);
  difference(){
    union(){
      stepper_gear(N_TEETH=6);
      translate([0, 2*mm, -2*RIM_THICKNESS])
	linear_extrude(height=h)

        if (filagree){

            translate([0,8.2,0])scale([1.3,1,1])import("filagreeminute.dxf");

        }

        else
            polygon(points=[[-w/2, 0], [0, r], [w/2, 0]]);
    }
    translate([0, 0, -50])cylinder(r=3 * mm/2, h=ACRYLIC_THICKNESS + ACRYLIC_TOL + 2 + 100);
    // translate([0, r - 15 * mm, -50])cylinder(h=100, r=3.00/2*mm); //hole for hall effect magnet
  }
}

module hour_hand(r=50*mm, w=21.5*mm, h=1.5*mm, filagree = false){
  difference(){
    union(){
      translate([0, RIM_THICKNESS, -RIM_THICKNESS])
	linear_extrude(height=h)

        if (filagree){

            translate([0,8.2,0])scale([1.3,1,1])import("filagreehour.dxf");

        }else
	polygon(points=[[-w/2, 0], [0, r], [w/2, 0]]);
      // translate([0, 36, -RIM_THICKNESS])cylinder(r=5.5 * mm/2, h=ACRYLIC_THICKNESS + RIM_THICKNESS + .5*mm);
      translate([0, 36, -RIM_THICKNESS])cylinder(r=5.5 * mm/2, h=ACRYLIC_THICKNESS + RIM_THICKNESS + 1);
      translate([0, 36, ACRYLIC_THICKNESS + .75*mm])scale([1, .8, 1])cylinder(r1=7/2. * mm, r2=3.2*mm, h=1.5*mm); // clip
      translate([0, 0, -RIM_THICKNESS])cylinder(r=11, h=h);
    }
    translate([0, 0, -RIM_THICKNESS - 1])cylinder(r=8.25, h=2*h);
    translate([-.5 * mm, 36 * mm-5 * mm, 2])cube([1 * mm, 10 * mm, 10 * mm]); // slot
    //translate([0, r - 10 * mm, -50])cylinder(h=100, r=3.00/2*mm); // hall effect magnet slot
  }
}

HOUR = 9;
MINUTE = $t * 60;
//MINUTE = HOUR * 60 + 15;
// translate([0,0, 2])rotate(v=[0, 1, 0], a=180)
translate([0, -0, -RIM_THICKNESS])rotate(a=MINUTE/720 * 360, v=[0, 0, 1])color([.1, 1, 0])inner_gear(MINUTE);
// color([.1, .1, 1])outer_gear();
translate([0, 0, -1.5*mm])rotate(a=MINUTE/720 * 360, v=[0, 0, 1])color([1, 0, 0])rotate(a=0, v=[0, 0, 1])hour_hand(w=11,filagree=true);
// translate([0, 0, -RIM_THICKNESS])translate([0, 0, 0])rotate(a=MINUTE/60 * 360, v=[0, 0, 1])minute_hand(w=12,filagree=true);

// cylinder(r=50*mm, h=100*mm); // for scale


added oring slot for sliding rocket

added oring slot for sliding rocket

use <m3d/fn.scad>

module nozzle()
{
  module oring(d_in, d_r)
  {
    rotate_extrude(angle=360, convexity=20, $fn=fn(120))
      translate([d_in/2+d_r/2, 0, 0])
        circle(d=d_r, $fn=fn(40));
  }

  module body()
  {
    h = 15;
    cylinder(d=26.5, h=h, $fn=fn(100));
    translate([0,0,h])
    {
      h = 24.5;
      cylinder(d=32, h=h, $fn=fn(120));
      translate([0,0,h])
      {
        h = 5;
        cylinder(d1=32, d2=21, h=h, $fn=fn(200));
        translate([0,0,h])
        {
          difference()
          {
            cylinder(d1=21, d2=20, h=10, $fn=fn(200));
            translate([0, 0, 6])
              oring(d_in=17+1.5, d_r=2.5+0.5);
          }
        }
      }
    }
  }

  difference()
  {
    body();
    translate([0,0,-1])
      cylinder(d=9, h=60, $fn=fn(50));
  }
}

rotate([180, 0, 0])
  nozzle();


refactor and add a customizer for the internal cutout bottom radius

// originially from:
// Sine Cube Vase 1 by @Chompworks
// Original at: https://www.thingiverse.com/thing:2666281
// Released under the Creative Commons CC - BY 3.0 licence
// Details here: https://creativecommons.org/licenses/by/3.0/
// customizer modifications by Roberto Marquez
//                              https://www.thingiverse.com/onebeartoe/designs

cubeOrCylinder = "cylinder"; // [cube, cylinder]

internalCutout_bottomRadius = 43; // [30 : 1 : 45]

/* [Hidden] */

step=4; // number of degrees to step for each cuboid element

maxlayers=100; // max number of layers. More layers slows down compilation on [F6], but makes the vase taller

basewidth=50; // basic length of a cuboid

difference() // Take away the two parts at the bottom
{
    union() // this stitches all the cuboids together
    {
        translate([0,0,-80])
        for (layers=[1:maxlayers]) // make each slice
        {
            for (angle=[1:step:360])
            {
                translate([0,0,layers*2]) // move the cuboid up to where it needs to be!
                rotate([0,0,angle]) // rotate the cuboid
                rotate([45,-45,0]) // rotate the cuboid for the best effect
                translate([0,-1,0]) // move the cuboid. This minus 1 offset just worked well!

                if(cubeOrCylinder == "cylinder")
                {
                    cylinderHeight = basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8);

	                cylinder(r=2, h=cylinderHeight, $fn=20);
                }
                else
                {
                    cube_xLength = basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8);

    				cube([cube_xLength, 4, 4]);

                        // lets explain this!
                        // make a 4x4 square
                        // then extrude it by:
                            // basewidth - a constant. this is the minimum length of any cuboid
                            // PLUS
                            // (layers/maxlayers*30) - this makes the vase taper outward as it gets taller. A sine function on this could make it act more like a pot/urn [Thin, Fat, Thin]
                            // PLUS
                            // 10*cos(layers*15)*sin(angle*8) - this is a nasty bit of trig at first!
                            // the sine function controls the bumps. Multiplying the angle by 8 means that rather than 1 bump, there are 8 for any given layer
                            // the cosine function (layers*15) makes the bumps also occur in the Z axis as they go up. If you removed this, the vase becomes very straight
                }
            }
        }
    }

    //this removes the cone base and leaves a flat base for the vase
    translate([-500,-500,-100])
    cube([1000,1000,100]);

    // this adds an internal hollow, 5mm up from the base
    internalCutout_TopRadius = internalCutout_bottomRadius + 15;
    translate([0,0,5])
    cylinder(r1 = internalCutout_bottomRadius, r2 = internalCutout_TopRadius, h = maxlayers * 2, $fn = 360/step);
}

// originially from:
// Sine Cube Vase 1 by @Chompworks
// Original at: https://www.thingiverse.com/thing:2666281
// Released under the Creative Commons CC - BY 3.0 licence
// Details here: https://creativecommons.org/licenses/by/3.0/
// customizer modifications by Roberto Marquez
//                              https://www.thingiverse.com/onebeartoe/designs

cubeOrCylinder = "cube"; // [cube, cylinder]

/* [Hidden] */

step=4; // number of degrees to step for each cuboid element
maxlayers=100; // max number of layers. More layers slows down compilation on [F6], but makes the vase taller
basewidth=50; // basic length of a cuboid

difference() // Take away the two parts at the bottom
{
    union() // this stitches all the cuboids together
    {
        translate([0,0,-80])
        for (layers=[1:maxlayers]) // make each slice
        {
            for (angle=[1:step:360])
            {
                translate([0,0,layers*2]) // move the cuboid up to where it needs to be!
                rotate([0,0,angle]) // rotate the cuboid
                rotate([45,-45,0]) // rotate the cuboid for the best effect
                translate([0,-1,0]) // move the cuboid. This minus 1 offset just worked well!

                if(cubeOrCylinder == "cylinder")
                {
	                cylinder(r=2, h=basewidth + (layers/maxlayers*30) + 10*cos(layers*15)
								                *sin(angle*8), $fn=20);
                }
                else
                {
    				cube([basewidth + (layers/maxlayers*30) + 10*cos(layers*15) * sin(angle*8),
                          4,
                          4]);

                        // lets explain this!
                        // make a 4x4 square
                        // then extrude it by:
                            // basewidth - a constant. this is the minimum length of any cuboid
                            // PLUS
                            // (layers/maxlayers*30) - this makes the vase taper outward as it gets taller. A sine function on this could make it act more like a pot/urn [Thin, Fat, Thin]
                            // PLUS
                            // 10*cos(layers*15)*sin(angle*8) - this is a nasty bit of trig at first!
                            // the sine function controls the bumps. Multiplying the angle by 8 means that rather than 1 bump, there are 8 for any given layer
                            // the cosine function (layers*15) makes the bumps also occur in the Z axis as they go up. If you removed this, the vase becomes very straight
                }
            }
        }
    }

    //this removes the cone base and leaves a flat base for the vase
    translate([-500,-500,-100])
    cube([1000,1000,100]);

    // this adds an internal hollow, 5mm up from the base
    translate([0,0,5])
    cylinder(r1=30,r2=45,h=maxlayers*2, $fn=360/step);
}


put the caster back together

put the caster back together

include <../config/config.scad>
UseSTL=false;
UseVitaminSTL=true;
DebugConnectors=true;
DebugCoordinateFrames=true;

translate([0, 0, GroundClearance]) {

            // Default Design Elements
            // -----------------------

            // Base
            LogoBotBase_STL();

            // Caster

            attach(LogoBot_Con_Caster, MarbleCaster_Con_Default, ExplodeSpacing=15) {

                MarbleCasterAssembly();

            }

            attach(offsetConnector(invertConnector(LogoBot_Con_Caster), [0,0,dw]), MarbleCaster_Con_Default, ExplodeSpacing=15)
                    pintack(side=false, h=dw+0.6+2+1.5, lh=2, bh=2);

        }

MarbleCasterAssembly();

include <../config/config.scad>
UseSTL=false;
UseVitaminSTL=true;
DebugConnectors=true;
DebugCoordinateFrames=true;

translate([0, 0, GroundClearance]) {

            // Default Design Elements
            // -----------------------

            // Base
            LogoBotBase_STL();

            // Caster

            attach(LogoBot_Con_Caster, MarbleCaster_Con_Default, ExplodeSpacing=15) {

                MarbleCasterAssembly();

            }

            attach(LogoBot_Con_Caster, MarbleCaster_Con_Default, ExplodeSpacing=15)
                    pintack(side=false, h=dw+0.6+2+1.5, lh=2, bh=2);

        }

MarbleCasterAssembly();


Save basic ring for the bar sensor

Save basic ring for the bar sensor

projection()  ring();
module ring(){difference(){
cylinder(r=15, h=1, center=true);
cylinder(r=10, h=2, center=true);
}
}

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


The stand was fleshed out some more.

The stand was fleshed out some more.

use <../basic-wall-mounted-stand.scad>

mount_cube_xLength = 4;  // [ 2 :  20]
mount_cube_yLength = 50; // [20 : 150]
mount_cube_zLength = 45; // [20 : 150]

platform_height = 6; // [5 : 50]
platform_segmentCount = 60; // [3 : 130]
platform_topRadius = 50; // [25: 100]

support_xLength = 60; // [50 : 100]
support_zLength = 59; // [20 : 250]

basicWallMountedStand(mount_cube_xLength = mount_cube_xLength,
					  mount_cube_yLength = mount_cube_yLength,
					  mount_cube_zLength = mount_cube_zLength,
					  platform_height = platform_height,
					  platform_segmentCount = platform_segmentCount,
				  	  platform_topRadius = platform_topRadius,
					  support_xLength = support_xLength,
				  	  support_zLength = support_zLength);

use <../basic-wall-mounted-stand.scad>

mount_cube_yLength = 40; // [20 : 150]

platform_height = 6; // [5 : 50]
platform_segmentCount = 60; // [3 : 130]
platform_topRadius = 50; // [25: 100]

support_height = 50; // [20 : 250]

basicWallMountedStand(mount_cube_yLength = mount_cube_yLength,
					  platform_height = platform_height,
					  platform_segmentCount = platform_segmentCount,
				  	  platform_topRadius = platform_topRadius,
				  	  support_height = support_height);


triangles: add triangles scad from thing:220868

/*
   Triangles.scad
Author: Tim Koopman
https://github.com/tkoopman/Delta-Diamond/blob/master/OpenSCAD/Triangles.scad

angleCA
/|\
a / H \ c
/  |  \
angleAB ------- angleBC
b

Standard Parameters
center: true/false
If true same as centerXYZ = [true, true, true]

centerXYZ: Vector of 3 true/false values [CenterX, CenterY, CenterZ]
center must be left undef

height: The 3D height of the Triangle. Ignored if heights defined

heights: Vector of 3 height values heights @ [angleAB, angleBC, angleCA]
If CenterZ is true each height will be centered individually, this means
the shape will be different depending on CenterZ. Most times you will want
CenterZ to be true to get the shape most people want.
 */

/*
   Triangle
a: Length of side a
b: Length of side b
angle: angle at point angleAB
 */
module Triangle(
        a, b, angle, height=1, heights=undef,
        center=undef, centerXYZ=[false,false,false])
{
    // Calculate Heights at each point
    heightAB = ((heights==undef) ? height : heights[0])/2;
    heightBC = ((heights==undef) ? height : heights[1])/2;
    heightCA = ((heights==undef) ? height : heights[2])/2;
    centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCA);

    // Calculate Offsets for centering
    offsetX = (center || (center==undef && centerXYZ[0]))?((cos(angle)*a)+b)/3:0;
    offsetY = (center || (center==undef && centerXYZ[1]))?(sin(angle)*a)/3:0;

    pointAB1 = [-offsetX,-offsetY, centerZ-heightAB];
    pointAB2 = [-offsetX,-offsetY, centerZ+heightAB];
    pointBC1 = [b-offsetX,-offsetY, centerZ-heightBC];
    pointBC2 = [b-offsetX,-offsetY, centerZ+heightBC];
    pointCA1 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ-heightCA];
    pointCA2 = [(cos(angle)*a)-offsetX,(sin(angle)*a)-offsetY, centerZ+heightCA];

    polyhedron(
            points=[	pointAB1, pointBC1, pointCA1,
            pointAB2, pointBC2, pointCA2 ],
            triangles=[
            [0, 1, 2],
            [3, 5, 4],
            [0, 3, 1],
            [1, 3, 4],
            [1, 4, 2],
            [2, 4, 5],
            [2, 5, 0],
            [0, 5, 3] ] );
}

/*
   Isosceles Triangle
   Exactly 2 of the following paramaters must be defined.
   If all 3 defined H will be ignored.
b: length of side b
angle: angle at points angleAB & angleBC.
 */
module Isosceles_Triangle(
        b, angle, H=undef, height=1, heights=undef,
        center=undef, centerXYZ=[true, false, false])
{
    valid = 	(angle!=undef)?((angle < 90) && (b!=undef||H!=undef)) : (b!=undef&&H!=undef);
    ANGLE = (angle!=undef) ? angle : atan(H / (b/2));
    a = (b==undef)?(H/sin((180-(angle*2))/2)) :
        (b / cos(ANGLE))/2;
    B = (b==undef)? (cos(angle)*a)*2:b;
    if (valid)
    {
        Triangle(a=a, b=B, angle=ANGLE, height=height, heights=heights,
                center=center, centerXYZ=centerXYZ);
    } else {
        echo("Invalid Isosceles_Triangle. Must specify any 2 of b, angle and H, and if angle used angle must be less than 90");
    }
}

/*
   Right Angled Triangle
   Create a Right Angled Triangle where the hypotenuse will be calculated.

   |\
   a| \
   |  \
   ----
   b
a: length of side a
b: length of side b
 */
module Right_Angled_Triangle(
        a, b, height=1, heights=undef,
        center=undef, centerXYZ=[false, false, false])
{
    Triangle(a=a, b=b, angle=90, height=height, heights=heights,
            center=center, centerXYZ=centerXYZ);
}

/*
   Wedge
   Is same as Right Angled Triangle with 2 different heights, and rotated.
   Good for creating support structures.
 */
module Wedge(a, b, w1, w2)
{
    rotate([90,0,0])
        Right_Angled_Triangle(a, b, heights=[w1, w2, w1], centerXYZ=[false, false, true]);
}

/*
   Equilateral Triangle
   Create a Equilateral Triangle.

l: Length of all sides (a, b & c)
H: Triangle size will be based on the this 2D height
When using H, l is ignored.
 */
module Equilateral_Triangle(
        l=10, H=undef, height=1, heights=undef,
        center=undef, centerXYZ=[true,false,false])
{
    L = (H==undef)?l:H/sin(60);
    Triangle(a=L,b=L,angle=60,height=height, heights=heights,
            center=center, centerXYZ=centerXYZ);
}

/*
   Trapezoid
   Create a Basic Trapezoid (Based on Isosceles_Triangle)

   d
   /----\
   /  |   \
   a  /   H    \ c
   /    |     \
   angle ------------ angle
   b

b: Length of side b
angle: Angle at points angleAB & angleBC
H: The 2D height at which the triangle should be cut to create the trapezoid
heights: If vector of size 3 (Standard for triangles) both cd & da will be the same height, if vector have 4 values [ab,bc,cd,da] than each point can have different heights.
 */
module Trapezoid(
        b, angle=60, H, height=1, heights=undef,
        center=undef, centerXYZ=[true,false,false])
{
    validAngle = (angle < 90);
    adX = H / tan(angle);

    // Calculate Heights at each point
    heightAB = ((heights==undef) ? height : heights[0])/2;
    heightBC = ((heights==undef) ? height : heights[1])/2;
    heightCD = ((heights==undef) ? height : heights[2])/2;
    heightDA = ((heights==undef) ? height : ((len(heights) > 3)?heights[3]:heights[2]))/2;

    // Centers
    centerX = (center || (center==undef && centerXYZ[0]))?0:b/2;
    centerY = (center || (center==undef && centerXYZ[1]))?0:H/2;
    centerZ = (center || (center==undef && centerXYZ[2]))?0:max(heightAB,heightBC,heightCD,heightDA);

    // Points
    y = H/2;
    bx = b/2;
    dx = (b-(adX*2))/2;

    pointAB1 = [centerX-bx, centerY-y, centerZ-heightAB];
    pointAB2 = [centerX-bx, centerY-y, centerZ+heightAB];
    pointBC1 = [centerX+bx, centerY-y, centerZ-heightBC];
    pointBC2 = [centerX+bx, centerY-y, centerZ+heightBC];
    pointCD1 = [centerX+dx, centerY+y, centerZ-heightCD];
    pointCD2 = [centerX+dx, centerY+y, centerZ+heightCD];
    pointDA1 = [centerX-dx, centerY+y, centerZ-heightDA];
    pointDA2 = [centerX-dx, centerY+y, centerZ+heightDA];

    validH = (adX < b/2);

    if (validAngle && validH)
    {
        polyhedron(
                points=[	pointAB1, pointBC1, pointCD1, pointDA1,
                pointAB2, pointBC2, pointCD2, pointDA2 ],
                triangles=[
                [0, 1, 2],
                [0, 2, 3],
                [4, 6, 5],
                [4, 7, 6],
                [0, 4, 1],
                [1, 4, 5],
                [1, 5, 2],
                [2, 5, 6],
                [2, 6, 3],
                [3, 6, 7],
                [3, 7, 0],
                [0, 7, 4]	] );
    } else {
        if (!validAngle) echo("Trapezoid invalid, angle must be less than 90");
        else echo("Trapezoid invalid, H is larger than triangle");
    }
}

// Examples
Triangle(a=5, b=15, angle=33, centerXYZ=[true,false,false]);
translate([20,0,0]) Right_Angled_Triangle(a=5, b=20, centerXYZ=[false,true,false]);
translate([45,0,0]) Wedge(a=5, b=20, w1=10, w2=5);
translate([-20,0,0]) Trapezoid(b=20, angle=33, H=4, height=5, centerXYZ=[true,false,true]);

translate([0,10,0]) Isosceles_Triangle(b=20, angle=33);
translate([30,10,0]) Isosceles_Triangle(b=20, H=5);
translate([-30,10,0]) Isosceles_Triangle(angle=33, H=5, center=true);

translate([15,-25,0]) Equilateral_Triangle(l=20);
translate([-15,-25,0]) Equilateral_Triangle(H=20);

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


Initial OpenScad commit

Initial OpenScad commit

Only a wheel so far

/*  _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _
 * / \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \
 * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
 *
 * Hub to mount a 12mm hex RC car wheel to a Micro Metal Gear Motor
 * you will need to pause the print to place the M4 nut inside
 * the height will be shown in the console
 *
 * 	          visit
 * 		www.ideahex.com
 *
 * Written by Damian Kleiss
 *  _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _
 * / \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \
 * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \*/

 // HUB MOTOR END //
 shaftMountOuterWidth = 13.5;
 shaftDia = 3.6;        // Diameter of the motor shaft
 shaftLength = 8.1;     // Length of motor shaft
 shaftFlat = 2.9;       // This is the flat part of the motor shaft
 shaftNutWidth = 5.9;   // distance across flats of shaft nuts
 shaftnutHeight = 2.8;  // height of shaft nut
 shaftBoltDia   = 3.5;  // Required hole for grub screw

 // HUBWHEEL END //
 hexWidth = 12.1;       // width between flats of the Wheel Hex
 hexLength = 6.2;       // Length of the hex that goes into the wheel
 wheelNutWidth = 7.7;   // Width between flats of the nut that the wheel is held on with
 wheelNutHeight = 3.9;  // Height of the nut that holds the wheel on
 wheelBoltDia = 3.5;    // Diameter of the hole

 // ORING  //
 oringInnerDia   = 50;
 oringThickness  = 5;

 // WHEEL //
 wheelDia = oringInnerDia+oringThickness;
 wheelThickness = oringThickness;

 // GENERIC //
 minWallThickness = 0.9;    // This is only used between the shaft nut and shaft
 smidge = 0.01; // small value used to get manifold geometry

 $fn = 100;  // number of facets that make up round things

 // ASSMBLY //

translate([0,0,wheelThickness/2])
{
  Wheel(hubShape = "Round", shaft = "D");
  Oring(id = oringInnerDia, thickness = oringThickness);
}

//color("blue")
// rotate([180,0,0])
//HubHoles(shape = "Hex");
//color("red")
//
//Hub(shape = "Round");

 module Wheel(hubShape = "Round", shaft = "D")
 {
    color("red")
    difference()
    {
        union()
        {
             translate([0,0,shaftLength/2+1])
             Hub(shape = hubShape);
             Rim();
        }
        translate([0,0,shaftLength/2+1])
        rotate([180,0,0])
        HubHoles(shape = shaft);
    }
}

 module Rim()
 {
     difference()
     {
        cylinder(d=wheelDia,h=wheelThickness,center=true);
        Oring(id = oringInnerDia, thickness = oringThickness);
     }
 }

module Oring(id = 50, thickness = 5)
{
    color("DimGray")
    rotate_extrude(convexity = 10)
    {
        translate([(id+thickness)/2,0,0])
        circle(r=thickness/2);
    }
}

module Hub(shape = "Hex")
{
        rotate([0,0,30])
    if(shape == "Hex")
    {
        cylinder(r =  shaftMountOuterWidth / 2 / cos(180/6), h = shaftLength, $fn=6, center = true); // Motor End
    }
    else if(shape == "Round")
    {
        cylinder(r =  shaftMountOuterWidth / 2 / cos(180/6), h = shaftLength, center = true); // Motor End
    }

}

module HubHoles(shape = "D")
{
          // Shaft Mount Holes
        color("red")

    if (shape == "D")
    {
        union()
        {
            rotate([0,90,0])
            {
                translate([0,0,shaftDia-shaftFlat+minWallThickness])
                hull()      // Hull two nuts so we can slip a nut in after the hub has been printed
                {
                    cylinder(r = shaftNutWidth / 2 / cos(180/6), h = shaftnutHeight, $fn=6); // ShaftNut Hole
                    translate([shaftLength/2,0,0])
                    cylinder(r = shaftNutWidth / 2 / cos(180/6), h = shaftnutHeight, $fn=6); // ShaftNut Hole
                }
                translate([0,0,hexWidth/2])
                cylinder(r = shaftBoltDia /2, h=hexWidth,center = true,$fn=100);            // Shaft Bolt hole
            }

            // Shaft Hole
            difference()
            {
                cylinder(r=shaftDia/2,h=shaftLength+smidge,center = true, $fn = 100);
                translate([(shaftDia-(shaftDia-shaftFlat)),0,0])
                cube([shaftDia,shaftDia,shaftLength+(smidge*2)],center=true);       // Shaft Flat
            }
        }
    }
    else if (shape == "Hex")
    {
        cylinder(r = shaftDia / 2 / cos(180/6), h = shaftLength+smidge,center = true, $fn=6); // ShaftNut Hole
        translate([0,0,shaftLength/2 + wheelThickness/2])
        cylinder(r = wheelBoltDia, h = wheelThickness,center = true); // ShaftNut Hole
    }

}

// echo("Pause at Z height of ",shaftLength+wheelNutHeight, " mm");

/*
 difference() // Uncomment for cross section view
 {
     union()
     {

         // WHEEL END //
         translate([0,0,shaftLength])
         translate([0,0,hexLength/2])
         rotate([0,0,30])       // Rotate so it lines up with shaft end
         difference()
         {
             cylinder(r =  hexWidth / 2 / cos(180/6), h = hexLength, $fn=6, center = true); // Wheel Hex End
             color("red")
             union()
             {
                 translate([0,0,-(hexLength+smidge)/2])  // Move nut hole to end of Hex
                 cylinder(r =  wheelNutWidth / 2 / cos(180/6), h = wheelNutHeight, $fn=6 ); // Wheel nut hole

                 cylinder(r=wheelBoltDia/2,h=hexLength+smidge,center=true,$fn=100); // wheel bolt hole
             }
         }

         // MOTOR END //
         translate([0,0,shaftLength/2])
         difference()
         {
            rotate([0,0,30])
            cylinder(r =  shaftMountOuterWidth / 2 / cos(180/6), h = shaftLength, $fn=6, center = true); // Motor End

            // Shaft Mount Holes
            color("red")
            union()
            {
                rotate([0,90,0])
                {
                    translate([0,0,shaftDia-shaftFlat+minWallThickness])
                    hull()      // Hull two nuts so we can slip a nut in after the hub has been printed
                    {
                        cylinder(r = shaftNutWidth / 2 / cos(180/6), h = shaftnutHeight, $fn=6); // ShaftNut Hole
                        translate([shaftLength/2,0,0])
                        cylinder(r = shaftNutWidth / 2 / cos(180/6), h = shaftnutHeight, $fn=6); // ShaftNut Hole
                    }
                    translate([0,0,hexWidth/2])
                    cylinder(r = shaftBoltDia /2, h=hexWidth,center = true,$fn=100);            // Shaft Bolt hole
                }

                // Shaft Hole
                difference()
                {
                    cylinder(r=shaftDia/2,h=shaftLength+smidge,center = true, $fn = 100);
                    translate([(shaftDia-(shaftDia-shaftFlat)),0,0])
                    cube([shaftDia,shaftDia,shaftLength+(smidge*2)],center=true);       // Shaft Flat
                }
            }
        }
    }
    translate([-shaftMountOuterWidth,0,-smidge/2])
    cube([shaftMountOuterWidth*2,shaftMountOuterWidth*2,shaftLength+hexLength+smidge],center=false);
}
*/

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


Correct typo

Correct typo

// Mockup of OmmatiDiag
/*
 * The mockup was done after the first crude drawing with
 * [Tinkrecad](https://tinkercad.com/things/3utMiKsZhx9) proved to be too
 * inflexible.
 * The basic unit of the detector will be the scintillator size, which we
 * chose to be 17" x 17" translating to 430 x 430 mm in SI units.
*/

// Basic length variables [mm]
unitlength = 430;
padding = 20;
height = 100;
semitransparent = 0.618;
nearlytransparent = 0.309;

// dimlines.scad is used to easily draw dimensional measurements
// http://www.cannymachines.com/entries/9/openscad_dimensioned_drawings
include <dimlines.scad>

DIM_LINE_WIDTH = .025 * unitlength;
DIM_SPACE = .1 * unitlength;

//~ translate([unitlength + 50 , padding/2, 0])
//~ rotate([0,0,90])
  //~ dimensions(unitlength, line_width=DIM_LINE_WIDTH, loc=0);

// Housing
module Housing()
  color ("gray", semitransparent) {
    // box bottom
    cube([unitlength + padding, unitlength + padding,1]);
    // box back walls
    cube([unitlength + padding, 1, height]);
    cube([1, unitlength + padding, height]);
    // box front walls, can (and should be turned off for increased visibility)
    translate(v = [0, unitlength + padding, 0]) {
      cube([unitlength + padding, 1, height]);
    }
    translate(v = [unitlength + padding, 0, 0]) {
      cube([1, unitlength + padding, height]); //
    }
    }
Housing();

// Scintillator
module Scintillator()
  translate([padding/2, padding/2, 1]) {
    color ("green", 1) {
      cube([unitlength,unitlength,1]);
      }
    }
Scintillator();

// CMOS Backplate
module Backplate()
  translate([(unitlength+padding)/2 + 5, (unitlength+padding)/2 + 5, height-15]) {
    color ("red", semitransparent) {
      cube([350,320,1],center=true);
      }
    }
Backplate();

// Ommatidium
module Ommatidium() {
  // FOV of one Ommatidium
  FOVSize = ([unitlength/4, unitlength/3]);
  module FOV()
    color("pink",0.5) cube([FOVSize[0], FOVSize[1], 1], center=true);

  // CMOS (Aptina AR0130)
  CMOSSize = ([1280, 960]);
  pixelsize = 3.75 / 1000; // [um]
  module CMOS()
    color ("blue")
      cube([CMOSSize[0] * pixelsize, CMOSSize[1] * pixelsize, 0.5], center=true);
  translate ([0,0,0]) CMOS();

  // Ommatidium back plate
  module Ommatidiumplate()
    color ("red", semitransparent)
      cube([15, 20, 1], center=true);
  translate ([5,7,0]) Ommatidiumplate();

  // FOV CMOS
  d_cmos_lens = 15;
  d_lens_scintillator = height - d_cmos_lens - 15;
  module CMOSCone()
      color("orange", nearlytransparent)
      cylinder(h = d_cmos_lens,
                r1 = CMOSSize[0] * pixelsize / 2 ,
                r2 = lensdiameter * 2, center=true);
  module CMOSCross() {
    color("red", 1)
    polyhedron(
      points=[ [0, 0, 0], //origin
        [-CMOSSize[0]*pixelsize/2, 0, d_cmos_lens],     // horizontal_1
        [CMOSSize[0]*pixelsize/2, 0,d_cmos_lens],       // horizontal_2
        [0, -CMOSSize[1] * pixelsize / 2,d_cmos_lens],  // vertical_1
        [0,  CMOSSize[1] * pixelsize / 2,d_cmos_lens]], // vertical_2
      triangles=[[0,1,2], [0,3,4]]);
    }

  mirror([0,0,1]) translate([0,0,-d_cmos_lens])CMOSCross();
  translate([0,0,d_cmos_lens/2]) CMOSCone();

  // Lens
  lensdiameter = 4;
  module Lens()
    // the lens is a squashed sphere: http://is.gd/4H9sZf
    scale([2,2,0.5]) sphere(lensdiameter, $fn=50, center=true);
  translate([0, 0, d_cmos_lens]) Lens();

  // FOV Lens
  module LensCone()
    color("orange",nearlytransparent)
    scale([1, 4/3, 1])
    cylinder(h = d_lens_scintillator,
              r1 = lensdiameter * 2,
              r2 = FOVSize[1]/2 * 1.2);
  module LensCross() {
    color("red", 1) polyhedron(
      points=[ [0, 0, 0], //origin
        [-FOVSize[0]/2, 0, d_lens_scintillator],   // horizontal_1
        [FOVSize[0]/2, 0,d_lens_scintillator],     // horizontal_2
        [0, -FOVSize[1]/2 ,d_lens_scintillator],   // vertical_1
        [0,  FOVSize[1]/2 ,d_lens_scintillator]],  // vertical_2
      triangles=[[0,1,2], [0,3,4]]);
    }
  translate([0,0,d_cmos_lens]) LensCross();
  translate([0,0,d_cmos_lens]) LensCone();
  translate([0,0,d_cmos_lens + d_lens_scintillator]) FOV();
}

translate([unitlength/4/2 + padding/2, unitlength/3/2 + padding/2, height-14])
mirror([0,0,1])
for (xpos=[0:3], ypos = [0:2]) // iterate over x and y
  translate([xpos*unitlength/4, ypos*unitlength/3, 0]) Ommatidium();

// Mockup of OmmatiDiag
/*
 * The mockup was done after the first crude drawing with
 * [Tinkrecad](https://tinkercad.com/things/3utMiKsZhx9) proved to be too
 * inflexible.
 * The basic unit of the detecotor will be the scintillator size, which we
 * chose to be 17" x 17" translating to 430 x 430 mm in SI units.
*/

// Basic length variables [mm]
unitlength = 430;
padding = 20;
height = 100;
semitransparent = 0.618;
nearlytransparent = 0.309;

// dimlines.scad is used to easily draw dimensional measurements
// http://www.cannymachines.com/entries/9/openscad_dimensioned_drawings
include <dimlines.scad>

DIM_LINE_WIDTH = .025 * unitlength;
DIM_SPACE = .1 * unitlength;

//~ translate([unitlength + 50 , padding/2, 0])
//~ rotate([0,0,90])
  //~ dimensions(unitlength, line_width=DIM_LINE_WIDTH, loc=0);

// Housing
module Housing()
  color ("gray", semitransparent) {
    // box bottom
    cube([unitlength + padding, unitlength + padding,1]);
    // box back walls
    cube([unitlength + padding, 1, height]);
    cube([1, unitlength + padding, height]);
    // box front walls, can (and should be turned off for increased visibility)
    translate(v = [0, unitlength + padding, 0]) {
      cube([unitlength + padding, 1, height]);
    }
    translate(v = [unitlength + padding, 0, 0]) {
      cube([1, unitlength + padding, height]); //
    }
    }
Housing();

// Scintillator
module Scintillator()
  translate([padding/2, padding/2, 1]) {
    color ("green", 1) {
      cube([unitlength,unitlength,1]);
      }
    }
Scintillator();

// CMOS Backplate
module Backplate()
  translate([(unitlength+padding)/2 + 5, (unitlength+padding)/2 + 5, height-15]) {
    color ("red", semitransparent) {
      cube([350,320,1],center=true);
      }
    }
Backplate();

// Ommatidium
module Ommatidium() {
  // FOV of one Ommatidium
  FOVSize = ([unitlength/4, unitlength/3]);
  module FOV()
    color("pink",0.5) cube([FOVSize[0], FOVSize[1], 1], center=true);

  // CMOS (Aptina AR0130)
  CMOSSize = ([1280, 960]);
  pixelsize = 3.75 / 1000; // [um]
  module CMOS()
    color ("blue")
      cube([CMOSSize[0] * pixelsize, CMOSSize[1] * pixelsize, 0.5], center=true);
  translate ([0,0,0]) CMOS();

  // Ommatidium back plate
  module Ommatidiumplate()
    color ("red", semitransparent)
      cube([15, 20, 1], center=true);
  translate ([5,7,0]) Ommatidiumplate();

  // FOV CMOS
  d_cmos_lens = 15;
  d_lens_scintillator = height - d_cmos_lens - 15;
  module CMOSCone()
      color("orange", nearlytransparent)
      cylinder(h = d_cmos_lens,
                r1 = CMOSSize[0] * pixelsize / 2 ,
                r2 = lensdiameter * 2, center=true);
  module CMOSCross() {
    color("red", 1)
    polyhedron(
      points=[ [0, 0, 0], //origin
        [-CMOSSize[0]*pixelsize/2, 0, d_cmos_lens],     // horizontal_1
        [CMOSSize[0]*pixelsize/2, 0,d_cmos_lens],       // horizontal_2
        [0, -CMOSSize[1] * pixelsize / 2,d_cmos_lens],  // vertical_1
        [0,  CMOSSize[1] * pixelsize / 2,d_cmos_lens]], // vertical_2
      triangles=[[0,1,2], [0,3,4]]);
    }

  mirror([0,0,1]) translate([0,0,-d_cmos_lens])CMOSCross();
  translate([0,0,d_cmos_lens/2]) CMOSCone();

  // Lens
  lensdiameter = 4;
  module Lens()
    // the lens is a squashed sphere: http://is.gd/4H9sZf
    scale([2,2,0.5]) sphere(lensdiameter, $fn=50, center=true);
  translate([0, 0, d_cmos_lens]) Lens();

  // FOV Lens
  module LensCone()
    color("orange",nearlytransparent)
    scale([1, 4/3, 1])
    cylinder(h = d_lens_scintillator,
              r1 = lensdiameter * 2,
              r2 = FOVSize[1]/2 * 1.2);
  module LensCross() {
    color("red", 1) polyhedron(
      points=[ [0, 0, 0], //origin
        [-FOVSize[0]/2, 0, d_lens_scintillator],   // horizontal_1
        [FOVSize[0]/2, 0,d_lens_scintillator],     // horizontal_2
        [0, -FOVSize[1]/2 ,d_lens_scintillator],   // vertical_1
        [0,  FOVSize[1]/2 ,d_lens_scintillator]],  // vertical_2
      triangles=[[0,1,2], [0,3,4]]);
    }
  translate([0,0,d_cmos_lens]) LensCross();
  translate([0,0,d_cmos_lens]) LensCone();
  translate([0,0,d_cmos_lens + d_lens_scintillator]) FOV();
}

translate([unitlength/4/2 + padding/2, unitlength/3/2 + padding/2, height-14])
mirror([0,0,1])
for (xpos=[0:3], ypos = [0:2]) // iterate over x and y
  translate([xpos*unitlength/4, ypos*unitlength/3, 0]) Ommatidium();


x/ends: use dual bearings

x/ends: use dual bearings

use <thing_libutils/misc.scad>
use <thing_libutils/bearing.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/timing-belts.scad>
use <thing_libutils/bearing-linear.scad>

include <thing_libutils/bearing_data.scad>
include <thing_libutils/pulley.scad>
include <thing_libutils/materials.scad>

include <x-end.h>

module xaxis_end_body(part, with_motor, beltpath_index=0, nut_top=false, with_xrod_adjustment=true)
{
    nut_h = zaxis_nut[4];
    bearing_sizey = zaxis_bearing_OD + 5*mm;

    xaxis_end_xrod_offset_z = xaxis_rod_l/2 - (main_width/2 + zmotor_mount_rod_offset_x);
    xaxis_rod_d_support = xaxis_rod_d+5*mm;
    xaxis_rod_l_support = xaxis_end_xrod_offset_z + 8*mm + (with_xrod_adjustment?8*mm:0);

    if(part==undef)
    {
        difference()
        {
            xaxis_end_body(part="pos", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end_body(part="neg", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end_body(part="vit", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);
            for(x=[-1,1])
            for(z=[-1,1])
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                translate([x*screw_dist/2, 0, z*screw_dist/2])
                cylindera(d=lookup(ThreadSize,xaxis_motor_thread)+4*mm, h=motor_mount_wall_thick, orient=Y, align=[0,-1,0], round_r=2);
            }
        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            // main nut support
            rcylindera(h=zaxis_nut[4], d=zaxis_nut[0]+5*mm, align=Z);

            // nut screw holes support
            rotate(Z*90)
            for(x=[-1,1])
            translate([x*zaxis_nut[5], 0, 0])
            rcylindera(h=zaxis_nut[4], d=lookup(ThreadSize, zaxis_nut[6])+5*mm, align=Z);

            // lead screw
            // ensure some support for the leadscrew cutout all the way to the top
            /*rcylindera(h=xaxis_end_wz, d=zaxis_nut[2]*2, align=Z);*/
        }

        // x axis rod holders
        for(z=[-1,1])
        translate([0,0,z*(xaxis_rod_distance/2)])
        rcylindera(h=xaxis_end_width(with_motor), d=xaxis_rod_d_support, extra_h=3*mm, extra_align=-X, orient=X, align=X);

        // endstops mount support
        if(xaxis_endstop_type == "SWITCH")
        {
            t(xaxis_endstop_pos(with_motor))
            rcubea(xaxis_endstop_size_switch, align=-XAXIS-ZAXIS);
        }
        else if(xaxis_endstop_type == "SN04")
        {
            t(xaxis_endstop_pos(with_motor))
            translate(xaxis_endstop_offset_SN04)
            rcubea(xaxis_endstop_size_SN04, align=-XAXIS-ZAXIS);
        }

        // belt idler screw cut support
        for(z=[-1,1])
        for(y=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0,y*-xaxis_beltpath_width/2,0])
            cylindera(orient=Y, d=15*mm, h=7*mm, align=-y*Y);
        }
    }
    else if(part=="neg")
    {
        for(z=[-1,1])
        translate([0,0*mm,z*(xaxis_rod_distance/2)])
        {
            xoff = - xaxis_end_xrod_offset_z -(with_xrod_adjustment?6:0)*mm;
            translate([xoff,0,0])
            cylindera(h=abs(xoff)+xaxis_end_width(with_motor)+1,d=xaxis_rod_d+.5*mm, orient=X, align=X);

            if(with_xrod_adjustment)
            {
                tx(-5*mm)
                nut_trap_cut(nut=NutHexM4, trap_offset=8*mm, screw_l=12*mm, screw_offset=2*mm, trap_axis=Y, cut_screw=true, orient=X, align=X);
            }
        }
    }
    else if(part=="vit")
    {
    }
}

module xaxis_end(part, with_motor=false, stop_x_rods=true, beltpath_index=0, show_motor=false, nut_top=false, show_nut=false, show_rods=false, show_bearings=false, with_xrod_adjustment=false)
{
    nut_h = zaxis_nut[4];
    extra_size = with_motor?0*mm:0*mm;
    extra_align = 1;

    if(part==undef)
    {
        difference()
        {
            xaxis_end(part="pos", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end(part="neg", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end(part="vit", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    {
        // projection against z, ensure easy print
        material(Mat_Plastic)
        proj_extrude_axis(axis=Z, offset=xaxis_end_wz/2)
        {
            xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

            // z smooth bearing mounts support
            translate(-xaxis_zaxis_distance_y*Y)
            for(z=[-1,1])
            translate(-z*Z*(xaxis_end_wz/2))
            {
                linear_bearing_mount(
                    part=part,
                    bearing=zaxis_bearing,
                    ziptie_type=ziptie_type,
                    ziptie_bearing_distance=ziptie_bearing_distance,
                    orient=Z*z,
                    align=Z*z,
                    with_zips=true,
                    offset_flange=true,
                    mount_dir_align=xaxis_z_bearing_mount_dir,
                    mount_style=xaxis_z_bearing_mount_style
                    );
            }

        }
    }
    else if(part=="neg")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        // belt idler screw cut
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw_cut(nut=NutHexM5, h=xaxis_beltpath_width+13*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        //endstop mount screw cuts
        if(xaxis_endstop_type == "SWITCH")
        {
            t(xaxis_endstop_pos(with_motor))
            translate(xaxis_endstop_screw_offset_switch)
            for(y=[-1,1])
            translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
            {
                screw_cut(nut=NutHexM2_5, h=10*mm, head_embed=false, with_head=true, with_nut=false, orient=-Z, align=-Z);
            }
        }
        else if(xaxis_endstop_type == "SN04")
        {
            t(xaxis_endstop_pos(with_motor))
            translate(xaxis_endstop_screw_offset_SN04)
            for(y=[-1,1])
            translate([-0*mm,y*10.5*mm/2,xaxis_endstop_size_SN04[2]])
            {
                translate(xaxis_endstop_offset_SN04)
                screw_cut(nut=NutHexM3, h=20*mm, head_embed=false, with_head=true, with_nut=false, orient=-Z, align=-Z);
            }
        }

        xaxis_end_beltpath(height=xaxis_beltpath_height_body, width=xaxis_beltpath_width);

        // z smooth bearing mounts cut
        translate(-xaxis_zaxis_distance_y*Y)
        for(z=[-1,1])
        translate(-z*Z*(xaxis_end_wz/2))
        {
            linear_bearing_mount(
                part=part,
                bearing=zaxis_bearing,
                ziptie_type=ziptie_type,
                ziptie_bearing_distance=ziptie_bearing_distance,
                orient=Z*z,
                align=Z*z,
                with_zips=true,
                offset_flange=true,
                mount_dir_align=xaxis_z_bearing_mount_dir,
                mount_style=xaxis_z_bearing_mount_style
                );
        }

        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);

            // axle
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                round_d=1.1*lookup(NemaRoundExtrusionDiameter, xaxis_motor);
                translate([0, .1, 0])
                translate(Y)
                teardrop(d=round_d,h=motor_mount_wall_thick, orient=Y, align=-Y, roll=90, truncate=0.9);

                // motor axle
                translate([0, .1, 0])
                cylindera(d=1.2*lookup(NemaAxleDiameter, xaxis_motor), h=lookup(NemaFrontAxleLength, xaxis_motor)+3*mm, orient=Y, align=Y);

                // bearing for offloading force on motor shaft
                translate([0, -2.5*mm-xaxis_pulley[1]-.1, 0])
                scale(1.03)
                cylindera(d=bearing_MR105[1], h=6*mm, orient=Y, align=[0,-1,0]);

                for(x=[-1,1])
                for(z=[-1,1])
                translate([0,-xaxis_end_motor_offset[1],0])
                translate([x*screw_dist/2, -(xaxis_beltpath_width/2+3*mm), z*screw_dist/2])
                {
                    if(!(x==1 && z == (beltpath_index==0?1:-1)))
                    screw_cut(xaxis_motor_nut, h=25, with_nut=false, orient=Y, align=Y);
                }
            }

        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        rotate(90*Z)
        {
            union()
            {
                translate([0,0,-.1])
                {
                    // nut
                    cylindera(h=nut_h+1, d=zaxis_nut[0]*1.05, align=Z);

                    // lead screw
                    translate([0,0,-.1])
                    cylindera(h=lookup(NemaFrontAxleLength,zaxis_motor), d=zaxis_nut[2]*1.5, align=Z);

                    for(i=[-1,1])
                    translate([i*zaxis_nut[5], 0, -zaxis_nut[3]])
                    screw_cut(thread=zaxis_nut[6], h=16*mm, with_nut=false, orient=Z, align=Z);
                }
            }
        }
    }
    else if(part=="vit")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        translate(-xaxis_zaxis_distance_y*Y)
        for(z=[-1,1])
        translate(-z*Z*(xaxis_end_wz/2))
        {
            linear_bearing_mount(
                part=part,
                bearing=zaxis_bearing,
                ziptie_type=ziptie_type,
                ziptie_bearing_distance=ziptie_bearing_distance,
                orient=Z*z,
                align=Z*z,
                with_zips=true,
                offset_flange=true,
                mount_dir_align=xaxis_z_bearing_mount_dir,
                mount_style=xaxis_z_bearing_mount_style
                );
        }

        if(with_motor)
        {
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                // 1mm due to motor offset
                translate([0,-1*mm,0])
                {
                    // 1mm between pulley and motor
                    translate([0,-1*mm,0])
                    pulley(xaxis_pulley, flip=false, orient=Y, align=[0,-1,0]);

                    if(show_motor)
                    {
                        motor(model=xaxis_motor, size=NemaMedium, dual_axis=false, orient=-Y);
                    }
                }
            }
        }

        //endstop
        if($show_vit)
        {
            if(xaxis_endstop_type == "SWITCH")
            {
                t(xaxis_endstop_pos(with_motor))
                difference()
                {
                    material(Mat_PlasticBlack)
                    rcubea(xaxis_endstop_size_switch, align=[-1,0,1]);

                    translate(xaxis_endstop_screw_offset_switch)
                    for(y=[-1,1])
                    translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
                    screw(nut=NutHexM2_5, with_nut=false, h=10*mm, orient=[0,0,-1], align=[0,0,-1]);
                }
            }
            else if(xaxis_endstop_type == "SN04")
            {
                t(xaxis_endstop_pos(with_motor))
                translate(xaxis_endstop_offset_SN04)
                translate([-36,-9,0])
                rotate(ZAXIS*-90)
                import("stl/SN04-N_Inductive_Proximity_Sensor_3528_0.stl");
            }
        }

        // belt idler pulley screw
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw(nut=NutHexM5, h=25*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            pulley(xaxis_idler_pulley, orient=Y);
        }

        if(show_nut)
        {
            mirror([0,0,nut_top?1:0])
            translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2-zaxis_nut[3]])
            xaxis_end_znut();
        }

        if(show_rods)
        {
            for(z=[-1,1])
                translate([0,0,z*xaxis_rod_distance/2])
                translate([0, -xaxis_zaxis_distance_y, 0])
                cylindera(d=zaxis_rod_d, h=zaxis_rod_l, orient=Z);
        }
    }
}

module xaxis_end_beltpath(height, width, length = 1000, align=N, orient=X)
{
    hull()
    for(z=[-1,1])
    translate([0,0,z*height/2])
    teardrop(h=length, d=width, orient=orient, align=align, roll=-180*min(0,z), truncate=1);
}

module xaxis_end_znut()
{
    difference()
    {
        material(zaxis_nut_mat)
        union()
        {
            cylindera(d=zaxis_nut[1], h=zaxis_nut[3], orient=Z, align=Z);
            cylindera(d=zaxis_nut[0], h=zaxis_nut[4], orient=Z, align=Z);
        }

        translate([0,0,-.1])
        cylindera(d=zaxis_nut[2], h=zaxis_nut[4]+.2, orient=Z, align=Z);
    }
}

if(false)
{
    // x axis
    /*translate([0,0,axis_pos_z])*/
    {
        /*if(!$preview_mode)*/
        {
            zrod_offset = zmotor_mount_rod_offset_x;
            for(z=xaxis_beltpath_z_offsets)
            tz(z)
            ty(xaxis_zaxis_distance_y)
            tx(-sign(z)*(-main_width/2-zrod_offset+xaxis_end_motor_offset[0]))
            rotate(90*X)
            belt_path(
                len=main_width+xaxis_end_motor_offset[0],
                belt_width=xaxis_belt_width,
                belt=xaxis_belt,
                pulley_d=xaxis_pulley_inner_d,
                orient=X, align=-sign(z)*X);
        }

        /*translate([axis_pos_x,0,0])*/
        /*{*/
            // x carriage
            /*attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],N])*/
            /*{*/
                /*x_carriage_full();*/
            /*}*/
        /*}*/

        // x smooth rods
        color(color_rods)
        for(z=[-1,1])
        translate([xaxis_rod_offset_x,xaxis_zaxis_distance_y,z*(xaxis_rod_distance/2)])
        cylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=X);

        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        translate([x*(zmotor_mount_rod_offset_x),0,0])
        cylindera(h=zaxis_rod_l,d=zaxis_rod_d, orient=Z, align=N);

        for(x=[-1,1])
        {
            translate([x*(main_width/2), 0, 0])
            {
                translate([0, xaxis_zaxis_distance_y, 0])
                translate([x*zmotor_mount_rod_offset_x, 0, 0])
                mirror([max(0,x),0,0])
                {
                    xaxis_end(with_motor=true, beltpath_index=max(0,x), show_nut=true, show_motor=true, show_nut=true);
                }
            }
        }
    }

}

if(false)
{
    for(x=[-1,1])
    translate([x*100*mm,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    {
        xaxis_end(with_motor=true, beltpath_index=max(0,x), show_motor=false, show_nut=false, show_bearings=false, with_xrod_adjustment=true);
    }
}

module part_x_end_right()
{
    x=1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}

module part_x_end_left()
{
    x=-1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}

use <thing_libutils/misc.scad>
use <thing_libutils/bearing.scad>
use <thing_libutils/screws.scad>
use <thing_libutils/timing-belts.scad>
use <thing_libutils/bearing-linear.scad>

include <thing_libutils/bearing_data.scad>
include <thing_libutils/pulley.scad>
include <thing_libutils/materials.scad>

include <x-end.h>

module xaxis_end_body(part, with_motor, beltpath_index=0, nut_top=false, with_xrod_adjustment=true)
{
    nut_h = zaxis_nut[4];
    bearing_sizey = zaxis_bearing_OD + 5*mm;

    xaxis_end_xrod_offset_z = xaxis_rod_l/2 - (main_width/2 + zmotor_mount_rod_offset_x);
    xaxis_rod_d_support = xaxis_rod_d+5*mm;
    xaxis_rod_l_support = xaxis_end_xrod_offset_z + 8*mm + (with_xrod_adjustment?8*mm:0);

    if(part==undef)
    {
        difference()
        {
            xaxis_end_body(part="pos", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end_body(part="neg", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end_body(part="vit", with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    material(Mat_Plastic)
    {
        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);
            for(x=[-1,1])
            for(z=[-1,1])
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                translate([x*screw_dist/2, 0, z*screw_dist/2])
                cylindera(d=lookup(ThreadSize,xaxis_motor_thread)+4*mm, h=motor_mount_wall_thick, orient=Y, align=[0,-1,0], round_r=2);
            }
        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        {
            // main nut support
            rcylindera(h=zaxis_nut[4], d=zaxis_nut[0]+5*mm, align=Z);

            // nut screw holes support
            rotate(Z*90)
            for(x=[-1,1])
            translate([x*zaxis_nut[5], 0, 0])
            rcylindera(h=zaxis_nut[4], d=lookup(ThreadSize, zaxis_nut[6])+5*mm, align=Z);

            // lead screw
            // ensure some support for the leadscrew cutout all the way to the top
            /*rcylindera(h=xaxis_end_wz, d=zaxis_nut[2]*2, align=Z);*/
        }

        // x axis rod holders
        for(z=[-1,1])
        translate([0,0,z*(xaxis_rod_distance/2)])
        rcylindera(h=xaxis_end_width(with_motor), d=xaxis_rod_d_support, extra_h=3*mm, extra_align=-X, orient=X, align=X);

        // endstops mount support
        if(xaxis_endstop_type == "SWITCH")
        {
            t(xaxis_endstop_pos(with_motor))
            rcubea(xaxis_endstop_size_switch, align=-XAXIS-ZAXIS);
        }
        else if(xaxis_endstop_type == "SN04")
        {
            t(xaxis_endstop_pos(with_motor))
            translate(xaxis_endstop_offset_SN04)
            rcubea(xaxis_endstop_size_SN04, align=-XAXIS-ZAXIS);
        }

        // belt idler screw cut support
        for(z=[-1,1])
        for(y=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0,y*-xaxis_beltpath_width/2,0])
            cylindera(orient=Y, d=15*mm, h=7*mm, align=-y*Y);
        }
    }
    else if(part=="neg")
    {
        for(z=[-1,1])
        translate([0,0*mm,z*(xaxis_rod_distance/2)])
        {
            xoff = - xaxis_end_xrod_offset_z -(with_xrod_adjustment?6:0)*mm;
            translate([xoff,0,0])
            cylindera(h=abs(xoff)+xaxis_end_width(with_motor)+1,d=xaxis_rod_d+.5*mm, orient=X, align=X);

            if(with_xrod_adjustment)
            {
                tx(-5*mm)
                nut_trap_cut(nut=NutHexM4, trap_offset=8*mm, screw_l=12*mm, screw_offset=2*mm, trap_axis=Y, cut_screw=true, orient=X, align=X);
            }
        }
    }
    else if(part=="vit")
    {
    }
}

module xaxis_end(part, with_motor=false, stop_x_rods=true, beltpath_index=0, show_motor=false, nut_top=false, show_nut=false, show_rods=false, show_bearings=false, with_xrod_adjustment=false)
{
    nut_h = zaxis_nut[4];
    extra_size = with_motor?0*mm:0*mm;
    extra_align = 1;

    if(part==undef)
    {
        difference()
        {
            xaxis_end(part="pos", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
            xaxis_end(part="neg", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
        }
        %xaxis_end(part="vit", with_motor=with_motor, stop_x_rods=stop_x_rods, beltpath_index=beltpath_index, show_motor=show_motor, nut_top=nut_top, show_nut=show_nut, show_rods=show_rods, show_bearings=show_bearings, with_xrod_adjustment=with_xrod_adjustment);
    }
    else if(part=="pos")
    {
        // projection against z, ensure easy print
        material(Mat_Plastic)
        proj_extrude_axis(axis=Z, offset=xaxis_end_wz/2)
        {
            xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

            // z smooth bearing mounts support
            translate(-xaxis_zaxis_distance_y*Y)
            translate(-Z*(xaxis_end_wz/2))
            {
                linear_bearing_mount(
                    part=part,
                    bearing=zaxis_bearing,
                    ziptie_type=ziptie_type,
                    ziptie_bearing_distance=ziptie_bearing_distance,
                    orient=Z,
                    align=Z,
                    with_zips=true,
                    offset_flange=true,
                    mount_dir_align=xaxis_z_bearing_mount_dir,
                    mount_style=xaxis_z_bearing_mount_style
                    );
            }

        }
    }
    else if(part=="neg")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        // belt idler screw cut
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw_cut(nut=NutHexM5, h=xaxis_beltpath_width+13*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        //endstop mount screw cuts
        if(xaxis_endstop_type == "SWITCH")
        {
            t(xaxis_endstop_pos(with_motor))
            translate(xaxis_endstop_screw_offset_switch)
            for(y=[-1,1])
            translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
            {
                screw_cut(nut=NutHexM2_5, h=10*mm, head_embed=false, with_head=true, with_nut=false, orient=-Z, align=-Z);
            }
        }
        else if(xaxis_endstop_type == "SN04")
        {
            t(xaxis_endstop_pos(with_motor))
            translate(xaxis_endstop_screw_offset_SN04)
            for(y=[-1,1])
            translate([-0*mm,y*10.5*mm/2,xaxis_endstop_size_SN04[2]])
            {
                translate(xaxis_endstop_offset_SN04)
                screw_cut(nut=NutHexM3, h=20*mm, head_embed=false, with_head=true, with_nut=false, orient=-Z, align=-Z);
            }
        }

        xaxis_end_beltpath(height=xaxis_beltpath_height_body, width=xaxis_beltpath_width);

        // z smooth bearing mounts cut
        translate(-xaxis_zaxis_distance_y*Y)
        translate(-Z*(xaxis_end_wz/2))
        {
            linear_bearing_mount(
                part=part,
                bearing=zaxis_bearing,
                ziptie_type=ziptie_type,
                ziptie_bearing_distance=ziptie_bearing_distance,
                orient=Z,
                align=Z,
                with_zips=true,
                offset_flange=true,
                mount_dir_align=xaxis_z_bearing_mount_dir,
                mount_style=xaxis_z_bearing_mount_style
                );
        }

        if(with_motor)
        {
            screw_dist = lookup(NemaDistanceBetweenMountingHoles, xaxis_motor);

            // axle
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                round_d=1.1*lookup(NemaRoundExtrusionDiameter, xaxis_motor);
                translate([0, .1, 0])
                translate(Y)
                teardrop(d=round_d,h=motor_mount_wall_thick, orient=Y, align=-Y, roll=90, truncate=0.9);

                // motor axle
                translate([0, .1, 0])
                cylindera(d=1.2*lookup(NemaAxleDiameter, xaxis_motor), h=lookup(NemaFrontAxleLength, xaxis_motor)+3*mm, orient=Y, align=Y);

                // bearing for offloading force on motor shaft
                translate([0, -2.5*mm-xaxis_pulley[1]-.1, 0])
                scale(1.03)
                cylindera(d=bearing_MR105[1], h=6*mm, orient=Y, align=[0,-1,0]);

                for(x=[-1,1])
                for(z=[-1,1])
                translate([0,-xaxis_end_motor_offset[1],0])
                translate([x*screw_dist/2, -(xaxis_beltpath_width/2+3*mm), z*screw_dist/2])
                {
                    if(!(x==1 && z == (beltpath_index==0?1:-1)))
                    screw_cut(xaxis_motor_nut, h=25, with_nut=false, orient=Y, align=Y);
                }
            }

        }

        // nut mount
        mirror([0,0,nut_top?1:0])
        translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2])
        rotate(90*Z)
        {
            union()
            {
                translate([0,0,-.1])
                {
                    // nut
                    cylindera(h=nut_h+1, d=zaxis_nut[0]*1.05, align=Z);

                    // lead screw
                    translate([0,0,-.1])
                    cylindera(h=lookup(NemaFrontAxleLength,zaxis_motor), d=zaxis_nut[2]*1.5, align=Z);

                    for(i=[-1,1])
                    translate([i*zaxis_nut[5], 0, -zaxis_nut[3]])
                    screw_cut(thread=zaxis_nut[6], h=16*mm, with_nut=false, orient=Z, align=Z);
                }
            }
        }
    }
    else if(part=="vit")
    {
        xaxis_end_body(part=part, with_motor=with_motor, beltpath_index=beltpath_index, nut_top=nut_top, with_xrod_adjustment=with_xrod_adjustment);

        translate(-xaxis_zaxis_distance_y*Y)
        translate(-Z*(xaxis_end_wz/2))
        {
            linear_bearing_mount(
                part=part,
                bearing=zaxis_bearing,
                ziptie_type=ziptie_type,
                ziptie_bearing_distance=ziptie_bearing_distance,
                orient=Z,
                align=Z,
                with_zips=true,
                offset_flange=true,
                mount_dir_align=xaxis_z_bearing_mount_dir,
                mount_style=xaxis_z_bearing_mount_style
                );
        }

        if(with_motor)
        {
            translate([0,0,xaxis_beltpath_z_offsets[beltpath_index]])
            translate(xaxis_end_motor_offset)
            {
                // 1mm due to motor offset
                translate([0,-1*mm,0])
                {
                    // 1mm between pulley and motor
                    translate([0,-1*mm,0])
                    pulley(xaxis_pulley, flip=false, orient=Y, align=[0,-1,0]);

                    if(show_motor)
                    {
                        motor(model=xaxis_motor, size=NemaMedium, dual_axis=false, orient=-Y);
                    }
                }
            }
        }

        //endstop
        if($show_vit)
        {
            if(xaxis_endstop_type == "SWITCH")
            {
                t(xaxis_endstop_pos(with_motor))
                difference()
                {
                    material(Mat_PlasticBlack)
                    rcubea(xaxis_endstop_size_switch, align=[-1,0,1]);

                    translate(xaxis_endstop_screw_offset_switch)
                    for(y=[-1,1])
                    translate([-5*mm,y*9.5*mm/2,xaxis_endstop_size_switch[2]])
                    screw(nut=NutHexM2_5, with_nut=false, h=10*mm, orient=[0,0,-1], align=[0,0,-1]);
                }
            }
            else if(xaxis_endstop_type == "SN04")
            {
                t(xaxis_endstop_pos(with_motor))
                translate(xaxis_endstop_offset_SN04)
                translate([-36,-9,0])
                rotate(ZAXIS*-90)
                import("stl/SN04-N_Inductive_Proximity_Sensor_3528_0.stl");
            }
        }

        // belt idler pulley screw
        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            translate([0, -xaxis_beltpath_width/2 - 7*mm, 0])
            {
                screw(nut=NutHexM5, h=25*mm, with_nut=true, orient=Y, align=Y);
            }
        }

        for(z=[-1,1])
        translate([xaxis_end_pulley_offset,0,-xaxis_beltpath_z_offsets[max(0,beltpath_index)]])
        {
            pulley(xaxis_idler_pulley, orient=Y);
        }

        if(show_nut)
        {
            mirror([0,0,nut_top?1:0])
            translate([zaxis_rod_screw_distance_x, -xaxis_zaxis_distance_y, -xaxis_end_wz/2-zaxis_nut[3]])
            xaxis_end_znut();
        }

        if(show_rods)
        {
            for(z=[-1,1])
                translate([0,0,z*xaxis_rod_distance/2])
                translate([0, -xaxis_zaxis_distance_y, 0])
                cylindera(d=zaxis_rod_d, h=zaxis_rod_l, orient=Z);
        }
    }
}

module xaxis_end_beltpath(height, width, length = 1000, align=N, orient=X)
{
    hull()
    for(z=[-1,1])
    translate([0,0,z*height/2])
    teardrop(h=length, d=width, orient=orient, align=align, roll=-180*min(0,z), truncate=1);
}

module xaxis_end_znut()
{
    difference()
    {
        material(zaxis_nut_mat)
        union()
        {
            cylindera(d=zaxis_nut[1], h=zaxis_nut[3], orient=Z, align=Z);
            cylindera(d=zaxis_nut[0], h=zaxis_nut[4], orient=Z, align=Z);
        }

        translate([0,0,-.1])
        cylindera(d=zaxis_nut[2], h=zaxis_nut[4]+.2, orient=Z, align=Z);
    }
}

if(false)
{
    // x axis
    /*translate([0,0,axis_pos_z])*/
    {
        /*if(!$preview_mode)*/
        {
            zrod_offset = zmotor_mount_rod_offset_x;
            for(z=xaxis_beltpath_z_offsets)
            tz(z)
            ty(xaxis_zaxis_distance_y)
            tx(-sign(z)*(-main_width/2-zrod_offset+xaxis_end_motor_offset[0]))
            rotate(90*X)
            belt_path(
                len=main_width+xaxis_end_motor_offset[0],
                belt_width=xaxis_belt_width,
                belt=xaxis_belt,
                pulley_d=xaxis_pulley_inner_d,
                orient=X, align=-sign(z)*X);
        }

        /*translate([axis_pos_x,0,0])*/
        /*{*/
            // x carriage
            /*attach(xaxis_carriage_conn, [[0,-xaxis_zaxis_distance_y,0],N])*/
            /*{*/
                /*x_carriage_full();*/
            /*}*/
        /*}*/

        // x smooth rods
        color(color_rods)
        for(z=[-1,1])
        translate([xaxis_rod_offset_x,xaxis_zaxis_distance_y,z*(xaxis_rod_distance/2)])
        cylindera(h=xaxis_rod_l,d=xaxis_rod_d, orient=X);

        for(x=[-1,1])
        translate([x*(main_width/2), 0, 0])
        translate([x*(zmotor_mount_rod_offset_x),0,0])
        cylindera(h=zaxis_rod_l,d=zaxis_rod_d, orient=Z, align=N);

        for(x=[-1,1])
        {
            translate([x*(main_width/2), 0, 0])
            {
                translate([0, xaxis_zaxis_distance_y, 0])
                translate([x*zmotor_mount_rod_offset_x, 0, 0])
                mirror([max(0,x),0,0])
                {
                    xaxis_end(with_motor=true, beltpath_index=max(0,x), show_nut=true, show_motor=true, show_nut=true);
                }
            }
        }
    }

}

if(false)
{
    for(x=[-1,1])
    translate([x*100*mm,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    {
        xaxis_end(with_motor=true, beltpath_index=max(0,x), show_motor=false, show_nut=false, show_bearings=false, with_xrod_adjustment=true);
    }
}

module part_x_end_right()
{
    x=1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}

module part_x_end_left()
{
    x=-1;
    translate([0,0,xaxis_end_wz/2])
    mirror([max(0,x),0,0])
    xaxis_end(with_motor=true, beltpath_index=max(0,x), with_xrod_adjustment=true);
}


config: yaxis belt path offset reduced

config: yaxis belt path offset reduced

include <MCAD/stepper.scad>
include <screws.scad>
include <pulley.scad>
include <thing_libutils/bearing_data.scad>
include <thing_libutils/metric-thread-data.scad>
include <thing_libutils/metric-hexnut-data.scad>
include <thing_libutils/misc.scad>

e=0.01;

// minimum size of a fragment
// resolution of any round object (segment length)
// Because of this variable very small circles have a smaller number of fragments than specified using $fa.
// The default value is 2.
$fs = 2;

// minimum angle for a fragment.
// The default value is 12 (i.e. 30 fragments for a full circle)
$fa = 12;

//hq
if(false)
{
    $fs= 0.5;
    $fa = 4;
}

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

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;

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

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

// for tapped ends
extrusion_end_nut = MHexNutM6;

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

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_type = [1.2*mm, 2.8*mm];
ziptie_thickness = ziptie_type[0];
ziptie_width = ziptie_type[1]+0.6*mm;
ziptie_bearing_distance=3*mm;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_rod_offset_x = 0*mm;
xaxis_bearing=bearing_sf1_1010;
/*xaxis_bearing=bearing_igus_rj4jp_01_10;*/

xaxis_pulley = pulley_2GT_20T;
xaxis_pulley_inner_d = xaxis_pulley[2];
xaxis_idler_pulley = pulley_2GT_20T_idler;
xaxis_idler_pulley_inner_d = xaxis_idler_pulley[2];
xaxis_idler_pulley_outer_d = xaxis_idler_pulley[3];

xaxis_belt_width = 6*mm;
xaxis_beltpath_height = xaxis_pulley_inner_d+5*mm;
xaxis_beltpath_width = max(xaxis_belt_width+3*mm, xaxis_pulley[0]+2*mm);
xaxis_beltpath_z_offset_pulley = xaxis_pulley_inner_d/2;
/*xaxis_beltpath_z_offsets = [xaxis_beltpath_z_offset_pulley];*/
xaxis_beltpath_z_offsets = [-2*mm-xaxis_beltpath_z_offset_pulley, 2*mm+xaxis_beltpath_z_offset_pulley];

xaxis_carriage_bearing_offset_y = ziptie_thickness+3*mm;
xaxis_carriage_beltpath_offset_y = xaxis_carriage_bearing_offset_y+xaxis_bearing[1]/2;

xaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);

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=bearing_sf1_1212;
yaxis_bearing_distance_y = 7*cm;

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

yaxis_pulley = pulley_2GT_20T;
yaxis_pulley_inner_d = yaxis_pulley[2];
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_inner_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 10*mm;

yaxis_idler_pulley = pulley_2GT_20T_idler;
yaxis_idler_pulley_inner_d = yaxis_idler_pulley[2];
yaxis_idler_pulley_outer_d = yaxis_idler_pulley[3];
yaxis_idler_pulley_h = yaxis_idler_pulley[0];
yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_inner_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_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;*/
zaxis_bearing=bearing_sf1_1212;

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

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);

// inner_d, outer_d, thread, outer_h, full_h
zaxis_nut = [20*mm, 36*mm, 8*mm, 5*mm, 23*mm];

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

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);
zmotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
zmotor_mount_width = zmotor_w+zmotor_mount_thickness*2 + zmotor_mount_thread_dia*8;
zmotor_mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

zmotor_mount_clamp_dist = zaxis_rod_d*2.5;
zmotor_mount_clamp_thread = ThreadM4;
zmotor_mount_clamp_nut = MHexNutM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(MHexNutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(MHexNutThickness, zmotor_mount_clamp_nut);
zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;

xaxis_zaxis_distance_y_ = max(xaxis_rod_d/2 + zaxis_bearing[1]/2, zaxis_nut[1]/2 - xaxis_rod_d/2);
xaxis_zaxis_distance_y = xaxis_zaxis_distance_y_ + ziptie_type[0]+.5*mm + 1*mm;

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_rod_d/2 + 1*mm;

// offset between Z motor screw and z rod
// place z rod as close as possible (depends on z nut and also motor etc)
zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + zmotor_w/2 + 1*mm);

// z rod offset from lower extrusion (outer)
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

// z screw offset from lower extrusion (outer)
zmotor_mount_screw_offset_x = zmotor_mount_rod_offset_x - zaxis_rod_screw_distance_x ;

color_extrusion = "DimGray";
color_rods = "CornflowerBlue";
color_part = "DarkRed";
color_gantry_connectors = "OliveDrab";

// 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 <screws.scad>
include <pulley.scad>
include <thing_libutils/bearing_data.scad>
include <thing_libutils/metric-thread-data.scad>
include <thing_libutils/metric-hexnut-data.scad>
include <thing_libutils/misc.scad>

e=0.01;

// minimum size of a fragment
// resolution of any round object (segment length)
// Because of this variable very small circles have a smaller number of fragments than specified using $fa.
// The default value is 2.
$fs = 2;

// minimum angle for a fragment.
// The default value is 12 (i.e. 30 fragments for a full circle)
$fa = 12;

//hq
if(false)
{
    $fs= 0.5;
    $fa = 4;
}

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

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;

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

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

// for tapped ends
extrusion_end_nut = MHexNutM6;

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

gantry_connector_thickness = 5;

rod_fit_tolerance=1.01;

ziptie_type = [1.2*mm, 2.8*mm];
ziptie_thickness = ziptie_type[0];
ziptie_width = ziptie_type[1]+0.6*mm;
ziptie_bearing_distance=3*mm;

xaxis_rod_distance = 60*mm;
xaxis_rod_d = 9.975*mm;
xaxis_rod_l = 500*mm;
xaxis_rod_offset_x = 0*mm;
xaxis_bearing=bearing_sf1_1010;
/*xaxis_bearing=bearing_igus_rj4jp_01_10;*/

xaxis_pulley = pulley_2GT_20T;
xaxis_pulley_inner_d = xaxis_pulley[2];
xaxis_idler_pulley = pulley_2GT_20T_idler;
xaxis_idler_pulley_inner_d = xaxis_idler_pulley[2];
xaxis_idler_pulley_outer_d = xaxis_idler_pulley[3];

xaxis_belt_width = 6*mm;
xaxis_beltpath_height = xaxis_pulley_inner_d+5*mm;
xaxis_beltpath_width = max(xaxis_belt_width+3*mm, xaxis_pulley[0]+2*mm);
xaxis_beltpath_z_offset_pulley = xaxis_pulley_inner_d/2;
/*xaxis_beltpath_z_offsets = [xaxis_beltpath_z_offset_pulley];*/
xaxis_beltpath_z_offsets = [-2*mm-xaxis_beltpath_z_offset_pulley, 2*mm+xaxis_beltpath_z_offset_pulley];

xaxis_carriage_bearing_offset_y = ziptie_thickness+3*mm;
xaxis_carriage_beltpath_offset_y = xaxis_carriage_bearing_offset_y+xaxis_bearing[1]/2;

xaxis_motor = dict_replace(Nema17, NemaFrontAxleLength, 22*mm);

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=bearing_sf1_1212;
yaxis_bearing_distance_y = 7*cm;

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

yaxis_pulley = pulley_2GT_20T;
yaxis_pulley_inner_d = yaxis_pulley[2];
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_inner_d/2;
yaxis_belt_path_offset_z = yaxis_motor_offset_z + 15*mm;

yaxis_idler_pulley = pulley_2GT_20T_idler;
yaxis_idler_pulley_inner_d = yaxis_idler_pulley[2];
yaxis_idler_pulley_outer_d = yaxis_idler_pulley[3];
yaxis_idler_pulley_h = yaxis_idler_pulley[0];
yaxis_idler_mount_thickness = 5;
yaxis_idler_pulley_tight_len = 20*mm;
yaxis_idler_pulley_offset_y = yaxis_idler_mount_thickness + yaxis_pulley_inner_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_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;*/
zaxis_bearing=bearing_sf1_1212;

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

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);

// inner_d, outer_d, thread, outer_h, full_h
zaxis_nut = [20*mm, 36*mm, 8*mm, 5*mm, 23*mm];

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

zmotor_w = lookup(NemaSideSize,zaxis_motor);
zmotor_h = lookup(NemaLengthLong,zaxis_motor);
zmotor_mount_thread_dia = lookup(ThreadSize, extrusion_thread);
zmotor_mount_width = zmotor_w+zmotor_mount_thickness*2 + zmotor_mount_thread_dia*8;
zmotor_mount_h = main_lower_dist_z+extrusion_size+zaxis_motor_offset_z;

zmotor_mount_clamp_dist = zaxis_rod_d*2.5;
zmotor_mount_clamp_thread = ThreadM4;
zmotor_mount_clamp_nut = MHexNutM4;
zmotor_mount_clamp_thread_dia = lookup(ThreadSize, zmotor_mount_clamp_thread);
zmotor_mount_clamp_nut_dia = lookup(MHexNutWidthMin, zmotor_mount_clamp_nut);
zmotor_mount_clamp_nut_thick = lookup(MHexNutThickness, zmotor_mount_clamp_nut);
zmotor_mount_clamp_width = zmotor_mount_clamp_dist+zmotor_mount_clamp_thread_dia*3;

xaxis_zaxis_distance_y_ = max(xaxis_rod_d/2 + zaxis_bearing[1]/2, zaxis_nut[1]/2 - xaxis_rod_d/2);
xaxis_zaxis_distance_y = xaxis_zaxis_distance_y_ + ziptie_type[0]+.5*mm + 1*mm;

zaxis_nut_mount_outer = zaxis_nut[1]/2 + zaxis_rod_d/2 + 1*mm;

// offset between Z motor screw and z rod
// place z rod as close as possible (depends on z nut and also motor etc)
zaxis_rod_screw_distance_x = max(zaxis_nut_mount_outer, zaxis_rod_d/2 + zmotor_w/2 + 1*mm);

// z rod offset from lower extrusion (outer)
zmotor_mount_rod_offset_x = zmotor_w/2+zaxis_rod_screw_distance_x+zmotor_mount_motor_offset;

// z screw offset from lower extrusion (outer)
zmotor_mount_screw_offset_x = zmotor_mount_rod_offset_x - zaxis_rod_screw_distance_x ;

color_extrusion = "DimGray";
color_rods = "CornflowerBlue";
color_part = "DarkRed";
color_gantry_connectors = "OliveDrab";

// 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;


через телефон менял позицию буквы в плоскости


Add demo for the pipe shape

Add demo for the pipe shape

/**
 * Samples using the camelSCAD library.
 *
 * A simple parametric pipe.
 *
 * @author jsconan
 * @license CC0-1.0
 */

// As we need to use some shapes, use the right entry point of the library
use <../shapes.scad>

// We will render the object using the specifications of this mode
renderMode = "prod";

// Defines the dimensions of the pipe
height = 50;
width = 1;
innerDiameter = 9.5;
outerDiameter = innerDiameter + width * 2;

// Sets the minimum facet angle and size using the defined render mode.
$fa = facetAngle(renderMode);
$fs = facetSize(renderMode);

// And draw the pipe accordingly
pipe(d=outerDiameter, h=height, w=width);

error: pathspec 'samples/simple-tube.scad' did not match any file(s) known to git