// dependency: https://github.com/revarbat/BOSL use // outside config width=60; height=15; depth=100; tape_height=5; tape_z=4; // local config frame=5; head_frame=2; head_size=[14, 10, tape_height+head_frame*2]; head_pos=[width/2, -frame+2, tape_z-head_frame]; laser_size=[10, 2, tape_height]; laser_pos=[head_pos.x, head_pos.y + 10 + head_size.y, tape_z]; laser_tower_size=[laser_size.x+2, laser_size.y+1, 15]; module reader() { module laser(corner=0.1) { up(laser_size.z/2) up(corner) color("Red") minkowski() { s=[laser_size.x, laser_size.y, laser_size.z-corner*2]; cube(s, center=true); sphere(corner); } } module laser_tower(corner=2) { color("DarkSlateBlue") back(laser_tower_size.y-laser_size.y) difference() { minkowski() { s=[laser_tower_size.x, laser_tower_size.y, laser_tower_size.z-corner*2]; up(laser_size.z/2) cube(s, center=true); sphere(corner); } fwd(laser_tower_size.y) scale(1.05) laser(); } } module head_space() { stube=[head_size.x-head_frame*2, head_size.y+head_frame*3, head_size.z-head_frame*2]; up(head_size.z/4 + head_frame) cube(stube, center=true); } module head(corner=0.5) { up(corner) back(head_size.y/2) color("DarkSlateBlue") minkowski() { s=[head_size[0], head_size[1] + frame, head_size[2]-corner*2]; difference() { up(head_size.z/2) cube(s, center=true); head_space(); } sphere(corner); } } translate(head_pos) head(); translate(laser_pos) { laser(); laser_tower(); } color("DarkSlateBlue") { difference() { fwd(frame) cube([width, frame, height]); translate(head_pos) head_space(); } fwd(frame) down(frame) cube([width, depth + frame, frame]); } } reader();