/* TransiDupe Duplicate tansmissive film. (We are running out of names for slide duplicators.) 5/29/2016 Version .9.024 Remixed from "DupliHood -- a slide copying attachment" by Hank Dietz http://www.thingiverse.com/thing:431624 http://www.instructables.com/id/3D-Printed-Slide-Copy-Attachment/ The code for making threads, and the springpart and diffuser modules are derived from Duplihood. All the rest is by Wayne Larmon. Modified to work with the PhotoSolve Xtend-a-Slide https://www.photosolve.com/main/product/xtendaslide/index.html TransiDupe is released under the Creative Commons - attribution license http://creativecommons.org/licenses/by/3.0/ (Just as Duplihood is.) Requires OpenSCAD version 2015.03, or newer. */ // mm = in/.039370 // 3.5 in = 88.9mm /* Global */ // Only partially Thingiverse Customizer compatible // ECHO: "id: 10.94 c_id 13.229 od: 16.229 ht: 13.9 nh: 5.4 bpt: 3.5" // ECHO: "id: 10.94 c_id 13.229 od: 16.229 ht: 13.9 nh: 5.4 bpt: 3.5" (PVC) // Which part do you want to make? // testmaghole diffuser exploded exploded_pvc springpart springpartsmall negativecarrier negativecarriersmall calslide part = "exploded"; // [pvcreartube:The tube that attaches to the step-up ring that is attached to the lens, pvcfronttube:The front tube,reartube:The tube that attaches to the step-up ring that is attached to the lens,slidecarrier:Slide carrier, springpart:Duplihood version of the slide carrier, springclamp:Clamp to hold the front slide/negativecarrier and front plate together,calslide:Blank slide for calibration, exploded:PVC tube version of exploded view of all three parts (for viewing, not printing), exploded_old: Duplihood parts and the non-PVC tube versions of the tubes] //,Negative carrier,negativecarriertop:, Negative carrier top part, negativecarrierboth: Both parts of the negative carrier (with rim removed--to check fit of both parts), fronttube:The front tube,reartube:The tube that attaches to the step-up ring that is attached to the lens, ,negativecarrier:, ,springpart:The spring cap that holds the slide,diffuser:The optional diffuser,exploded_old:Older version of exploded view of all three parts (for viewing, not printing),bothtubes:Like "exploded", but only prints the front and rear tubes,ruler:Ruler that shows how far the slide should be for the designated lengths of the tubes,thumbshell: Fits over a hose clamp screw so you don't need a screwdriver] // What is the slide format? (Anything other than "film6x6", exactly, means 35mm or 110 (Instamatic).) // We support both slides and negatives. "film6x6 is 6x6cm slides or 120 film negative // Not film6x6 could be either 35mm slides or negatives, or 110 (Instamatic) negative. film = "film6x6x"; // [film6x6:Mounted 6x6cm slides,film35:Mounted 35mm (135 format) slides] // outsideoffronttube must not be "true" if you use film6x6 and fronttube; // (outsideoffronttube was designed for the edge case of making a short front tube that fits on the outside // of a real Xtend-a-Slide. // // Well and for making PVC end brackets. So it isn't such an edge case after all. Sorry for the cross-confusion // The PVC code is only for 35mm and does does *not* support film6x6x (120 film) // (Not using PVC tube. fronttube, reartube) // How many sections? (each section is 23.5mm) // "2" (ea.) is typical for a P&S + closeup lens // "3" (ea.) works for an APS-C (crop) camera + 60mm macro lens for 35mm slides/negatives // "3" (ea.) works for an full frame camera + 100mm macro lens for 35mm slides/negatives // "5" (ea.) works for an APS-C (crop) camera + 100mm macro lens for 35mm slides/negatives // Sections are ~50mm in diameter. So probably shouldn't make more than 1 or 2 rear sections // for film6x6 (AKA 120 film) which has approx. 70mm diagonal. // 120 film: max of three Xtend-a-slide sections. Then 7.5 in" to 120 film frame. number_of_rear_sections=2.0; // [1:9] number_of_front_sections=2.0; // [1:9] // playpen1:For experimenting (currently, is about toruses (o-rings...)), xslidecarrier:Xtend-a-Slide slide carrier // Make the round plates on the tubes makeroundplate = "true"; // [true, false] // Make the tubes maketube = "true"; // [true, false] usenut="true"; // Add a retainer to hold a nut on the front tube. (Non-PVC version) magholes = "true"; // Add holes for magnets on carriers. For using with Xtend-a-Slide steel front plate. // 5/19/2016. Putting this aside for now. Too many interelated variables truncate = "true"; // Truncate carriers by removing unneeded portions (quicker printing...easier to grip.) is110 = "truex"; // [is110:Treat "35mm" film like 110 film (we have three choices of film size)] numfrontnuts=3; // Number of nut tubes on front end (PVC version only) numrearnuts=3; // Number of nut tubes on rear end (PVC version only) // If maketube is false, we make a crossbar across the center of the rear tube plate // (on the assumption that you will be manipulating the rear tube plate to see if it fits) // We *can* write whatever 'reardiskdiameter' is, but this takes time (+ ~17 seconds) // Non-PVC version only. Sorry. labelcrossbar = "truex"; // [true, false] // Set reardiskdiameter to the diameter of the step-up ring that is mounted on your lens. // Because plastic is soft, I suggest that you mount the rear tube to a step-up adapter *once* // and never remove the step-up adapter from the rear tube. // However you *can* set to the filter size on your lens, if you don't want to bother // with a step-up ring. // reardiskdiameter can't be smaller than 52mm. // 86 for PVC tube. We are now stressing PVC tube now so anything other than "86" // might cause things to break. FWIW. reardiskdiameter=77; // [52, 147] // 67 reardiskdiametertol=-.27; // Fudge factor to make threads fit. YMMV -.27 was too small reardiskdiametertol=0; // When using threads reardiskdiameternttol=-0; // 3/3/2016. Fudge factor for no threads/slitted disk -0.75 -0.07 reardiskdiameternttol=-.35; // 4/16/2016. Fudge factor for no threads/slitted disk -.30 -.45 -.4 reardiskdiameternttol=-0.45; // 5/22/2016 0 -0.35 makerearplateslits = "true"; // Make slits in rear plates (assumes makethreads != "true") // We are using this. I didn't have good luck with threads. // Make a rim on the front plate (and carriers)? Sort of deprecated. makerim = "truex"; /* [Hidden] */ // Should not need to adjust any variables below here /* I don't think that "exploded" is printable. It is handy to see all the parts together. You can load an .stl file into netfabb to see how many cubic centimeter of filiment that all the parts will use. */ // Cut mounting holes in plate cutplateholes=((reardiskdiameter >= 60) ? "true" : "false"); cutplateholes="false"; // For drilling holes in the step-up ring so you can use little nuts/bolts // We aren't using this right now. // Xtend-a-Slideish dimensions // Which we are still using as much as possible. Except for that PVC tube part. // PVC tube variation is_pvc_tube = "truex"; // Are we using a piece of 2" PVC tube? // Used for front and rear end brackets for pvctube if is_pvc_tube = "true" // These will fit on the ends of a piece of (existing) PVC tube tube_fudge=1.2; // Was 0.5. Then 1.1, then 1.8, then 1.2 tube_od_2in = 60.45 + tube_fudge; // 2 in. tube 60.44 tube_od_3in = 89.22 + tube_fudge; // 3 in. tube (Not really supported. Yet.) //tube_od=60.44+tube_fudge; // 2 inch PVC pipe tube_od=((film == "film6x6") ? tube_od_3in : tube_od_2in) ; // 6D to 120 film with 50mm macro lens is about 127mm. tube_wall=3; // How thick we want the tube we make to be (for PVC; pvcreartube, pvcfronttube) //tube_height=30; // How long we want this tube 30 for front tube front_tube_height = 30; //front_tube_height = 5; rear_tube_height = 30; // pvcreartube pvc_tube_ends(); with rearish parameters passed // pvcfronttube pvc_tube_ends() with frontish parameters passed // pvctube makes a length of tube the same size as real 2" PVC tube. pvctube_ht (below) sets length // End of PVC tube variation // Front tube large_front_dia = ((is_pvc_tube == "true") ? 115 : 130); // 120mm for 3" PVC pipe frontdiskdiameter=((film == "film6x6") ? large_front_dia : 88.93); // Was 87. 3 1/2" = 88.93mm // Debug is broke (for now.) Don't use it. // Debugging. "true" makes some parts thinner/shorter for making test prints // (to see if everything fits together.) // Anything other than "true" == false; "truex" == false // i.e., debug="truex" to make normal sized prints. // debug doesn't do very much with the pvctube version. Sorry. // And fails with the non-pvctube. Sorry. debug="truex"; // [true:Debug mode. Makes prints be shorter but the same diameter, false:Normal mode, truex: is the same as "false" (but is easier to type in the code.)] // Increases the inside diameter of the front tube. Increase this if the front tube can't fit over the back tube. // (Print both tubes in "debug" mode for testing this. And you don't need the plates to test how thes tube fit.) // Normal is = 1.00 (1.8) // ?? Doesn't do anything now front_tube_tol = 1.2; // [0,2] fdiskheight=2.25; // measured 3.3. 2016-03-07 Had been 2.0 for a while. 5/27 Then was 1.75 frontdiskheight=((debug == "true") ? 1 : fdiskheight ); //fronttubefrontindia=framex+front_tube_tol; fronttubethickness=3.9; // Measured 3.33 (then was 3.9) frontrimwall=3; //fronttubebackthickness=((film == "film6x6") ? fronttubethickness*3 : fronttubethickness); frontrimheight=((debug == "true") ? 3 : 15 ); //fronttubeoutdia=56.8; // Measured outer diameter of Xtend-a-Slide front tube was 56.3 fronttubeoutdia=((is_pvc_tube == "true" ) ? tube_od : 56.8 ); // Measured outer diameter of Xtend-a-Slide front tube was 56.3 // If you really want to 3D print an exact replica of a piece of PVC pipe. // It takes less than 15 minutes to saw a piece of real 2" PVC tube. Just saying' // 76.34mm = 3 in. // 134mm is about 5 1/2 Xtend-a-Tube sections // 109 is existing PVC tube that works with 35mm on Canon EF-S 60mm macro lens // Is just barely short enough. pvctube_ht = 105; // Rear tube // Set reardiskdiameter to the diameter of the step-up ring that is mounted on your lens. //reardiskdiameter=67; //reardiskheight=2; reardiskheight=((debug == "true") ? .9 : 2.1 ); reartubeoutdia=50; reartubethickness=3.5; // measured 2.35mm // Slide carrier cutoutfilmarea = "true"; // Cut out the film area on the Xtend-a-Slide slide carrier // Yes, if supplying your own diffusion // No, if you are printing the carrier in white and it will // be the diffuser. // length of notch to fish the slide out of the carrier with your finger xtol=4.9; // How far to move the slide up or down. - is down, + is up. stock is 1.2 // Then tried 3.2 (For droop compensation.) xtol=1.2; xslidefingernotchlength=31; xslidefingernotchwidth=22.5; xnotchdistance=((film == "film6x6") ? -1 : 17.0); // Distance finger notch is from the rim // diameter of slide carrier xslidedia=88; //xfrontdiskheight=((debug == "true") ? 1 : 2.7); xfrontdiskheight=2; outsideoffronttube="truex"; // Will our front tube be fitting onto an Xtend-a-slide front tube? // False (not true) means that it will be fitting on an Xtend-a-slide rear tube. // Leave 'number_of_front_sections=1;' if this is true. // Also see "is_pvc_tube"!!! (We now support using 2" PVC tube.) // Leave it "true" when using PVC tube. // Diameter for front tube that fits on an Extend-a-Slide rear tube //fronttubebackindia=reartubeoutdia+front_tube_tol; fronttubebackindia = ((outsideoffronttube == "true") ? fronttubeoutdia : reartubeoutdia+front_tube_tol ); // part = "diffuser" // One or both of these are needed to make finger room for the slide carrier. // Not so much for negative carrier. diffuser_finger_notch = "true"; // Cut out finger notch diffuser_flattop = "truex"; // Cut off flat top forward = 15; // Slide cutout this much from the center. 10. diffusor_type = "slide"; // Slide or negative. // Springclamp (for holding front carriers on.) springclamp_height = 4.2; // ht=4.4 works for slide carrier. 2.1 for rear plate(? No.) num_springclamps=1; // [1:4] springclamp_handle=14; // Length of handle springclamp_x=18; // Length of jaws springclamp_y=8; // Width of jaws (10 is same width as Home Depot 8863 panel clips) slidethickness=1.12; // For making test prints to see if the parts fit // (Shorter print time and use less filament.) num_rear_sections=((debug == "true") ? 1 : number_of_rear_sections); num_front_sections=((debug == "true") ? 1 : number_of_front_sections); // Make "sectionheight" be small (5) if you want // to make a test tube to check that the parts fit together properly // before you make the full size part. // 23.5mm is the height of an Xtend-a-slide section //sectionheight = 23.5; sectionheight=((debug == "true") ? 23.5/3 : 23.5 ); film35x=((is110 == "true") ? 18 : 36); film35y=((is110 == "true") ? 14 : 24); filmx=((film == "film6x6") ? 60 : film35x); filmy=((film == "film6x6") ? 60 : film35y); framex=((film == "film6x6") ? 70 : 50); framey=((film == "film6x6") ? 70 : 50); width35mm=((is110 == "true") ? 16.8 : 35.2); // "35mm" film is 110 film. For this computation. negwidth=((film == "film6x6") ? 61 : width35mm); negwidth=((film == "film6x6") ? 62.5 : width35mm); framez=((debug == "true") ? 0 : 3.25); frametol=1; lip=2; 6x6neg = "true"; // !"true" == slide diag_slide=sqrt(((framex+frametol)*(framex+frametol))+((framey+frametol)*(framey+frametol))); diag_negative=sqrt(((filmx+frametol)*(filmx+frametol))+((filmy+frametol)*(filmy+frametol))); diag=((6x6neg == "true") ? diag_negative : diag_slide); innertall=80; overlap=5; // Height of diffuser rim spring=1; echo(str("framex+front_tube_tol: ", framex+front_tube_tol, " diag: ", diag)); //fronttubefrontindia=framex+front_tube_tol; fronttubefrontindia = ((film == "film6x6") ? framex+front_tube_tol : fronttubebackindia); fronttubefrontindia = ((film == "film6x6") ? diag : fronttubebackindia); // Make threads on back plate of rear tube. (Slow...but see finishquality, below) // "Not true" (no threads) implies that you are going to glue the rear tube onto a step-up ring. // Need to print at least at standard quality on a FF Dreamer for threads to work makethreads = "truex"; // [true, false] makeplateslits = "true"; // Not needed at all? Should always be a local variable // Number of threads. Was 3 in original design numthreads=3; // [2,6] // Rendering threads is slow. However, you *must* use fine when printing for real. // (Rendering threads at "fine" adds almost a minute to rendering time.) finishquality="fine"; // [fine:use this when you are going to print for real,draftmode: use this when you are still developing.] // nutcapture() // 1/4"-20 nut_id=10.94; // 10.94 is the magic number for a 1/4-20 nut nut_nh = 5.4; // measured height of 1/4"-2nut nut_screwhole=6.7; // diameter of screw hole (6.5 for 1/4-20 bolt) nut_wall=3; // thickness of nut holder nut_ht=nut_nh+8.5; // height of nut holder 8.5 nut_facets=6; // 6 is the default nut_backplatethickness=3.5; /* // #10-32 nut_id=9.27; // 10.94 is the magic number for a 1/4-20 nut nut_nh = 3.20; // measured height of 1/4"-20 nut nut_screwhole=5.3; // diameter of screw hole (6.5 for 1/4-20 bolt) nut_wall=3; // thickness of nut holder nut_ht=nut_nh+10.5; // height of nut holder nut_facets=6; // 6 is the default nut_backplatethickness=3; */ // We are using nut capture tubes now. Anything with slits and tubes might cause things to break. // Number of slits in the tubes (Default is 10.) num_slits = 10; // [0:100] // Slit thickness in mm (Default is 2.) slit_thickness = 1.75; // mystep defines how fine to render the threads // The smaller mystep is, the longer it takes to render... // Should be = 5 for final part. // mystep = 5 takes about 53 seconds to render on my quadcore i7 // mystep = 30 takes about 8 seconds... // finishquality="fine" == mystep = 30 mystep=((finishquality == "fine") ? 5 : 30); // Must be a multiple of 5 $fn=((finishquality == "fine") ? 90 : 50); tol=0.25; // Increases the inside diameter of the springpart. // Increase this if the springpart can't fit over the front tube. td2dh_sp=0.025; // [0,2] // Increases the inside diameter of the diffuser. // Increase this if the diffuser can't fit over the springpart. td2dh_df=0.025; // [0,2] // What is the filter thread pitch? (Default is 75) thread_pitch = 75; // [50:Fine 0.5mm, 75:Standard 0.75mm, 100:Coarse 1.0mm, 150:Very coarse 1.5mm] // Tolerance to allow for inaccurate filament placement (usually extrusion diameter/2), in microns? // Default is 100. thread_tolerance = 100; // [0:500] // Thread rotation angle (to align slide mask with the camera)? // (Shouldn't need to change this.) thread_rotate = 45; // [0:359] //length_of_both_tubes = (num_rear_sections+num_front_sections)*sectionheight; length_of_both_tubes = (num_rear_sections*sectionheight)+(num_front_sections*sectionheight); //echo(str("lega: ", lega, ", legb: ", legb, ", legc: ", legc, ", num_front_sections*sectionheight: ", num_front_sections*sectionheight)); echo(str("film: ", film, ", sectionheight: ", sectionheight)); //-----------End of global variables-------- //------------Start of utility modules------------ // Modules must be defined before they are called. // Cuts slits into something. module makeslits(num=10, slitlength=50, slit_thickness=1.5, slitheight=10) { magic_1=1.9; //angle=40; translate([0,0,slitheight/2]) for (i=[0:360/num:360]) { rotate([0,0,i]) { cube([slitlength, slit_thickness, slitheight],center=true); } } } // Cuts angled slits into something. module make_angled_slits(num=10, slitlength=50, slit_thickness=1.5, slitheight=10, angle=0, angle_length=0) { magic_1=1.9; //angle=40; translate([0,0,slitheight/2]) for (i=[0:360/num:360]) { rotate([0,0,i]) { if (angle == 0) { cube([slitlength, slit_thickness, slitheight],center=true); } else { // Translate x needs work! angle_length doesn't scale translate([(slitlength/2)+(angle_length/3)-magic_1,angle_length*.29,0]) //translate([(slitlength-angle_length)/2-magic_1,angle_length*.24,0]) rotate([0,0,angle]) cube([angle_length+.1,slit_thickness, slitheight], center=true); } } } } // make_angled_slits2(num=22, slitlength=magdia*1.15, slit_thickness=1.0, slitheight=maght+1, angle=0, angle_length=0); module make_angled_slits2(num=10, slitlength=50, slit_thickness=1.5, slitheight=10, angle=0, angle_length=0) { magic_1=1.9; angle=40; translate([0,0,slitheight/2]) for (i=[0:360/num:360]) { rotate([0,0,i]) { if (angle == 0) { cube([slitlength, slit_thickness, slitheight],center=true); } else { // Translate x needs work! angle_length doesn't scale translate([(slitlength/2)+(angle_length/3)-magic_1,angle_length*.29,0]) //translate([(slitlength-angle_length)/2-magic_1,angle_length*.24,0]) rotate([0,0,angle]) cube([angle_length+.1,slit_thickness, slitheight], center=true); } } } } // Cuts nh holes in a cylinder (assumed to be used in a difference();) module round_holes_cutter(od=77, os=5, hs=3.5, nh=4, tk=3, start_rotation=45) { rotate([0,0,start_rotation]) for (i=[1:360/nh:360]) { //echo(str("i: ",i)); rotate([0,0,i]) translate([0,od/2-os,tk*.5]) cylinder(d=hs,h=tk+2,center=true); } } // Converts measure of the flat part of nut to the circular diameter (i.e., the farthest points) // https://gist.github.com/Stemer114/324c382a528d10b43759 function facet2dia(facet_dia=10.94, num_facets=6) = (facet_dia / 2 / cos(180 / num_facets) + 0.05)*2.078; // ?? I needed to add the "2.088") // #10-32 //module nutcapture (id=9.27, nh=3.20, ht=3.20+2, screwhole=4.9, facets=6, wall=2, backplatethickness=3) { // 1/4"-20 module nutcapture (id=10.94, nh=5.4, ht=5.4+2, screwhole=6.5, facets=6, wall=2, backplatethickness=3) { c_id = facet2dia(facet_dia = id, num_facets=facets); // I trialed-and-errored 13.25 to be the diameter of a 1/4"-2 nut (with $fn=6) echo(str("id: ", id, " c_id ",c_id, " od: ", od," ht: ",ht, " nh: ", nh, " bpt: ", backplatethickness)); od = c_id + wall; hole_adj=.6; // Enlarge the screw hole by this much .5 if (6 == 6) { //translate([0,0,backplatethickness*.5+ht-nh]) //cylinder(d=od,h=1,$fn=facets,center=true); nub_size=0.6; for (i=[1:360/facets:360]) { // Nut retainer (so it won't slide out.) //echo(str("i: ",i)); rotate([0,0,i-nub_size*4.5]) translate([c_id/2-.49,0,-nub_size*.99+nh+backplatethickness*.35]) cube([nub_size,nub_size,nub_size/2]); } } difference() { intersection() { translate([0,0,backplatethickness*.5]) // before printing! cube([od, od, backplatethickness], center=true) ; translate([0,0,backplatethickness*.0]) cylinder(d=od, h=backplatethickness/2+.1, $fn=facets, center=true) ; } translate([0,0,-ht/2+4]) cylinder(d=screwhole+hole_adj, h=ht+4,center=true); } difference() { translate([0,0,ht/2+backplatethickness*.1]) cylinder(d=od, h=ht+0, $fn=facets, center=true); translate([0,0,(ht)/2+backplatethickness*.5]) cylinder(d=c_id, h=ht+4, $fn=facets, center=true) ; translate([0,0,-ht/2+4]) cylinder(d=screwhole+hole_adj, h=ht+4,center=true) ; } } // nutcapture() // dia is Inside Diameter. Outside diameter is ID + wall // Is wrong and shouldn't be used. module maketube(dia = 50, hgt = 100, wall = 4, cnt=true) { difference() { cylinder(d = dia+wall, h = hgt, center=cnt); cylinder(d = dia, h = hgt*1.25, center=cnt); } } //diameter is outside diameter module maketube_od(dia = 50, hgt = 100, wall = 4, cnt=true) { difference() { cylinder(d = dia, h = hgt, center=cnt); cylinder(d = dia-wall*2, h = hgt*1.25, center=cnt); } } // dia is inside diameter module maketube_id(dia = 50, hgt = 100, wall = 4, cnt=true) { difference() { cylinder(d = dia+wall*2, h = hgt, center=cnt); cylinder(d = dia, h = hgt*1.25, center=cnt); } } module springclamp(len=springclamp_x*1, y=springclamp_y*1, ht=springclamp_height, hn=springclamp_handle) { magic_2 = -1.5; base_ht=0; thickness=2.5; magic_1 = thickness-.5; font_size=2.5; //y=10; translate([0,0,y/2]) rotate([90,0,0]) { translate([-len/1, -y/2,0]) // Bottom part cube([len+hn,y,thickness]); translate([-thickness,-y/2,magic_1]) // Upright part cube([thickness, y, thickness+ht+4+magic_1]); translate([0-.1,-y/2,thickness+ht+5.5]) // Top part of handle cube([hn+.1, y, thickness]); translate([hn/2-.01,-font_size*.5,thickness*2+ht*1+5.35]) linear_extrude(height= 0.7) { // Write the height (so we can tell different clips apart.) text(text = str(ht, "mm"), size=font_size, halign="center"); } translate([-2.6,-y/2,thickness+6+ht+magic_1]) // Angled down part rotate([0,135,0]) cube([8, y, thickness]); translate([-len-magic_2,-y/2,thickness+ht-.69]) // Upper slightly angled part. rotate([0,-5.5,0]) cube([len-8,y,thickness]); } } //------------End of utility modules------------ // Make a shell that fits over a hex hose clamp nut. So you don't need to use a screwdriver to adjust it. // id = 9.55 doesn't fit at all. 9.65 fits module thumbshell (od = 12.5, id = 9.67, ht = 18) { smoothness=18; // How many facets on the outside (tradeoff between increased grip and irritating fingers) slope=3; // Make the backside larger and easier to grip difference() { union() { translate([0,0,ht/2]) cylinder(d1=od, d2=od+slope, h=ht, $fn=smoothness, center=true); translate([0,0,ht*1]) sphere((od+slope)/2, $fn=smoothness); } union() { translate([0,0,ht/2]) cylinder(d=id, h = ht+2, $fn=6, center=true); translate([0,0,ht*1]) sphere((od+slope-6)/2, $fn=smoothness); } } } // thumbshell() // Calibration slide module calslide () { echo(str("Making calibration slide for ", film, ".")); echo(str("Slide Thickness = ", slidethickness, "mm, Frame size is ", filmy, "x", filmx, "mm" )); echo(str("Slide size = ", framex, "x", framey, "mm, ", framex * .04, " inches" )); union() { difference() { // difference() translate([0,0,slidethickness*.5]) cube([framex+frametol*0, framey+frametol*0, slidethickness], center=true); // Full slide translate([0,0,slidethickness*1.1]) // We are going to remove half the depth of the slide frame. // (So that the patterns within the slide frame will be in the center of the slide. // like real film is... (for focus accuracy.) cube([filmx,filmy, slidethickness], center=true); // punch out the slide frame //#cube([filmx+frametol, 5, slidethickness/2], center=true); crosshatch_thickness = slidethickness*.6; // Width of the slits in the crosshatches frame_cutout = slidethickness*.6; // Now punch out the calibration crosshatches offset = 1.5; // How far above the film frame should the crosshatches be? numsteps = 9; // How many crosshatches do we want (horizontally? stretch = 0; // Stretch calculation doesn't work yet. :-( start_x = (-filmx/2); // Position of the first crosshatch end_x = start_x+filmx; // Position of the last crosshatch step = (filmx/(numsteps-1)); // Increment each position by this much (in the loop) // film = "film6x6"; //step=((film == "film6x6") ? 9 : 3); y = (-filmy/2); // How high should the crosshatches be on the slide? start_y = y; end_y = (start_y+filmy); // Punch out slits around the outside of the slide flame translate([-start_x-.55, 1,-slidethickness*1]) // left top cube([frame_cutout,filmy/2-2,slidethickness*2]); // vertical translate([start_x-.0, 1,-slidethickness*1]) // left bottom cube([frame_cutout,filmy/2-2,slidethickness*2]); // vertical translate([-start_x-.55, start_y+1,-slidethickness*1]) // right top cube([frame_cutout,filmy/2-2,slidethickness*2]); // vertical translate([start_x+.0, start_y+1,-slidethickness*1]) // right bottom cube([frame_cutout,filmy/2-2,slidethickness*2]); // vertical translate([1,-start_y-.55, -slidethickness*1]) // right top cube([filmx/2-2,frame_cutout,slidethickness*2]); // horizontal translate([1,start_y-.55, -slidethickness*1]) // right bottom cube([filmx/2-2,frame_cutout,slidethickness*2]); // horizontal translate([start_x+1,-start_y-.55, -slidethickness*1]) // left bottom cube([filmx/2-2,frame_cutout,slidethickness*2]); // horizontal translate([start_x+1,start_y-.55, -slidethickness*1]) // left bottom cube([filmx/2-2,frame_cutout,slidethickness*2]); // horizontal // Punch out stuff within the slide frame //#cube([slidethickness*2, crosshatch_thickness, slidethickness*2], center=true); // Exact center //#cube([crosshatch_thickness, slidethickness*2, slidethickness*2], center=true); for (i=[start_x+step:step:end_x-step]) { translate ([i, start_y + offset*4, 0]) { // Below the film frame cube([slidethickness*2, crosshatch_thickness, slidethickness*2], center=true); cube([crosshatch_thickness, slidethickness*2, slidethickness*2], center=true); } translate ([i, 0, 0]) { // cube([slidethickness*2, crosshatch_thickness, slidethickness*2], center=true); cube([crosshatch_thickness, slidethickness*2, slidethickness*2], center=true); } translate ([i, (end_y - offset*4), 0]) { // Above the film frame cube([slidethickness*2, crosshatch_thickness, slidethickness*2], center=true); cube([crosshatch_thickness, slidethickness*2, slidethickness*2], center=true); } } echo (str("numsteps ",numsteps," step ",step, " start_x ",start_x," end_x ",end_x," start_y ",start_y, " end_y ", end_y)); for (i=[start_x:step:end_x]) { //echo(i ); translate ([i, y - offset, slidethickness*.5]) { // Below the film frame cube([slidethickness*2, crosshatch_thickness, slidethickness*2], center=true); cube([crosshatch_thickness, slidethickness*1, slidethickness*2], center=true); //cylinder(h=slidethickness*2,r=slidethickness,center=true); } translate ([i, 0 , .5]) { // On the center (Not needed anymore.) //cube([slidethickness*2, slidethickness/3, slidethickness*2], center=true); //cube([slidethickness/3, slidethickness*1, slidethickness*2], center=true); ////cylinder(h=slidethickness*2,r=slidethickness*1.1,center=true); //} } translate ([i, y-y-y+offset, slidethickness*.5]) { // Above the film frame cube([slidethickness*2, crosshatch_thickness, slidethickness*2], center=true); cube([crosshatch_thickness, slidethickness*1, slidethickness*2], center=true); } // translate () } // for (i=[start_x:step:end_x]) { } // difference } // union() } // module calslide() // Make a ruler to test measurements. // orientation = 90 stands upright to comparing in openSCAD. orientation = 0 is flat (for printing for real) // offset is the distance from 0. (so you can have an upright ruler standing next to the real model.) module makeruler(length = 100, width = 15, offset = 80, orientation = "upright", font_size = 5, print_length = "truex", print_text="true", the_text="Test text") { angle=((orientation == "upright") ? 90 : 0); xoffset=((orientation != "upright") ? length/2 : 0); ht = ((debug != "true") ? 1.4 : 1-.3); ext_ht = ((debug != "true") ? 0.5 : 0.4); echo(str("Ruler length: ", length, " ht: ", ht)); rotate([0,-angle,0]) translate([-xoffset,offset,0]){ cube([length, width, ht], center = false); if (print_length == "true") { translate([2,width/4,ht]) linear_extrude(height= ext_ht) { text(text = str(length, "mm"), size=5); } } else if (print_text == "true") { translate([length/2,width/4,ht]) linear_extrude(height= ext_ht) { text(text = str(the_text), size=font_size, halign="center"); } } } } // module makeruler() module make_nut_tube(num_nuts=2, tube_ht=5, od = tube_od, wall=tube_wall) { //nut_ht_offset=tube_ht-8.5; // For positioning the nut vertically nut_ht_offset=tube_ht-nut_id*.8; // For positioning the nut vertically nut_ht_comp=nut_ht+.5; // Nut hight + curvature of the tube. echo(str("make_nut_tube() od: ",od, "mm tube_ht: ", tube_ht, "mm")); //c_id = facet2dia(facet_dia = nut_id, num_facets=nut_facets); c_nut_id = facet2dia(facet_dia=nut_id, num_facets=nut_facets); for (i=[0:360/num_nuts:360]) { rotate([0,0,i]) difference() { union() { cylinder(d=od+wall, h=tube_ht); translate([-(od+nut_ht_comp)/2,0, nut_ht_offset]) rotate([0,90,0]) if (usenut == "true") { nutcapture(wall=nut_wall, id=nut_id, ht=nut_ht, facets=nut_facets, backplatethickness=nut_backplatethickness); // nutcapture() part one } } if (usenut == "true") { // nutcapture() part two :-( for (j=[0:360/num_nuts:360]) { rotate([0,0,j]) translate([-(od+wall-2)/2+.0,0, nut_ht_offset]) rotate([0,90,0]) cylinder(d=c_nut_id*.99, h=nut_ht/3, $fn=nut_facets, center=true); // d=c_nut_id*.98 } } translate([0,0,-4]) //#cylinder(d=tube_od, h=tube_height+8); //cylinder(d=52, h=tube_ht+8); if (is_pvc_tube == "true") { cylinder(d=framex+2, h=tube_ht+8); // 2016-03-06 } else { cylinder(d=od, h=tube_ht); } w = ((makeroundplate == "true") ? +2 : -2); translate([0,0,w]) cylinder(d=od, h=tube_ht-1); // +8 ; } // difference() } // for (i=... } // make_nut_tube() module make_slotted_tube (tube_od=tube_od, tube_height=tube_height, tube_wall=tube_wall, cnt=true) { translate([0,0,tube_height/2]) difference() { // dia is Inside Diameter. Outside diameter is ID + wall //module maketube(dia = 50, hgt = 100, wall = 4, cnt=true) maketube_od(dia = tube_od, hgt = tube_height, wall = tube_wall, cnt=true); translate([0,0,tube_height*.05]) // Raise (or lower) the slits makeslits(num=10, slitlength=tube_od + 8, slit_thickness=1.5, slitheight=tube_height/2); } } module make_slitted_disk (num_slits=80, dia=50, angle=60, ht=3, len_slits=0) { //len_slits=4.5; //dia=86; difference(){ translate([0,0,ht/2]) cylinder(d=dia, h=ht, center=true); translate([0,0,-5]) make_angled_slits(num=num_slits, slitlength=dia-8, slit_thickness=.7, angle=angle, angle_length=11) ; } translate([0,0,ht/2]) cylinder(d=dia-len_slits, h=ht, center=true); } module pvc_tube_ends(buildplate=makeroundplate, buildtube=maketube, diskheight=6, makethreads="false", makeplateslits="false", makefillet="false", cutplateholes=cutplateholes, diskdiameter=99, diskdiametertol=0, diskdiameternttol=0, num_nuttubes=2, tube_ht=20) { // diskdiametertol (threaded) // diskdiameternttol (not threaded) tol = ((makethreads == "true") ? diskdiametertol : diskdiameternttol); dia = diskdiameter + tol; //dia=diskdiameter+diskdiametertol; mag=((dia<49) ? 0.5 : 1); pitch=thread_pitch/100.0; ctol=thread_tolerance/1000.0; threadheight = numthreads * (pitch*.0002); echo(str("tube_od: ", tube_od, " tube_wall: ", tube_wall, " diskheight: ", diskheight, " buildplate: ", buildplate)); echo(str("tube_od+tube_wall: ", tube_od+tube_wall, "mm, diskdiameter: ",diskdiameter, "mm dia: ", dia, "mm tol:", tol)); filletsize=2.0; // For testing round_holes_cutter rhc_od=reardiskdiameter; // OD of the cylinder we will be cutting holes in rhc_tk=3.3; // How thick is the cylinder rhc_os=5.5; // How far from the outside edge should the center of the hold be rhc_hs=3; // What is the diameter of each hole? rhc_nh=4; //makethreads="truex"; //reardiskheight=2; // cylinder(d=dia,h=1); union() { if (buildplate == "true" ) { difference() { union() { if (makethreads != "true") { //cylinder(d=diskdiameter + diskdiametertol, h=diskheight, $fn=190); if (makeplateslits == "true") { make_slitted_disk(dia=dia, ht=diskheight, len_slits=5); } else { cylinder(d=dia, h=diskheight); } } else { difference() { translate([0,0,(threadheight)]) male_thread(pitch, dia-ctol, numthreads, 0.25); translate([0,0,diskheight]) cylinder(d=diskdiameter-3, 20) ; } } } // union() if (cutplateholes == "true") { round_holes_cutter(od=rhc_od, os=rhc_os, hs=rhc_hs, nh=rhc_nh, tk=rhc_tk); } translate([0,0,-4]) cylinder(d=tube_od, h = 8) ; } // difference() } if (buildtube == "true" ) { if (6 == 9) { make_slotted_tube(tube_height=tube_ht); } else { make_nut_tube(num_nuts=num_nuttubes,tube_ht=tube_ht); if (buildplate == "true" && makefillet == "true") { // Fake a fillet difference() { translate([0,0,diskheight-0.5]) cylinder(d1=tube_od+tube_wall+filletsize+0.5+1, d2=tube_od+tube_wall, h=filletsize) ; translate([0,0,-diskheight-0.5]) cylinder(d=tube_od, h = 8); } } } } } // union() } // module pvc_tube_ends() module fronttube( sections=3, buildplate="true", buildtube="true", slits="true") { echo(str("Making front tube for ", film, ".")); echo(str(sections, " sections, sectionheight ", sectionheight, "mm, total length: ",sections*sectionheight, "mm.")); // (Maybe) need Pythagorean Theorem here (for film6x6) (Not thus far.) // Used for calculating fronttube's dimensions // Is length of the cone (if filmx6x6 == true) shortsection=(film == "film6x6") ? (sections*sectionheight) : (sections*sectionheight); //slits="true"; start_straighttube_at=shortsection-(sectionheight*.05); start_straighttube_at=((number_of_front_sections >= 1) ? shortsection-(sectionheight*.05) : 0); straighttubeheight = ((number_of_front_sections > 1) ? sectionheight*number_of_front_sections : sectionheight*.8); straighttubeheight= sectionheight*.8; start_straighttube_at= (number_of_front_sections * sectionheight) - sectionheight; //start_straighttube_at=sectionheight; //straighttubeheight=3.1; // Debugging only!!!! fudgeif1=((sections == 1 && film == "film6x6") ? 1 : 0); // need to lower the straight section if sections == 1. //echo(str("Real length of the fronttube: ", shortsection, ".")); echo(str("Real length of the fronttube: ", start_straighttube_at + straighttubeheight, ".")); echo(str("fronttubebackindia: ", fronttubebackindia, " fronttubefrontindia: ", fronttubefrontindia, " tube_od: ", tube_od)); filletsize=2.5; if (buildplate == "true" && makerim == "true") { // Start with adding an outer rim on the front disk difference() { cylinder(d=frontdiskdiameter, h=frontrimheight) ; translate([0,0,-.5]) cylinder(d=frontdiskdiameter-frontrimwall, h=frontrimheight+1); } } difference() { // Temporarily change to "union()" to see what is subtracted // First build a solid front plate and tube union() { if (buildplate == "true" ) { cylinder(d=frontdiskdiameter, h=frontdiskheight); } // Then the tube. Solid, at this point if (buildtube == "true") { // cylinder(d1=(fronttubefrontindia+fronttubethickness), d2=(fronttubebackindia+fronttubethickness)-(fronttubethickness*(fudgeif1/5)), h=start_straighttube_at + fudgeif1); // shortsection-3.9 if (buildplate == "true" ) { translate([0,0,frontdiskheight-0.5]) // Fake a fillet cylinder(d1=fronttubefrontindia+fronttubethickness+filletsize+0.5+1, d2=fronttubefrontindia+fronttubethickness, h=filletsize+0.5); } } } // union() // Now difference() kicks in and eliminates these: // Eliminate the inner tube translate([0, 0, -1]) cylinder(r1=fronttubefrontindia/2, r2=fronttubebackindia/2, h=start_straighttube_at+1.01); } // difference() // For debugging. Uncomment to verify tube length calculations (ruler should == tube height) // Normally is commented out! (Prints a vertical "ruler" at one side of the tube.) //makeruler(offset=frontdiskdiameter/2 + 4,length=start_straighttube_at+straighttubeheight-1,orientation = "upright", print_length = "truex", print_text="truex"); // if (usenut == "true") { // Are now globals magic_height=10; if (slits == "true" && numfrontnuts <= 1) { // Straight section with a nutcapture (in addition to any other sections) // make slits by rotating a skinny rectangle around the tube (which are eliminated with "difference()") translate([0, 0, start_straighttube_at -1 - fudgeif1*0]) { difference() { // Normally is difference() if (buildtube == "true") { difference() { union() { if (usenut == "true") { translate([-(fronttubebackindia+fronttubethickness+nut_ht)/2,0,magic_height]) rotate([0,90,0]) nutcapture(id=nut_id, nh=nut_nh, ht=nut_ht, screwhole=nut_screwhole, facets=nut_facets, wall=nut_wall, backplatethickness=nut_backplatethickness); } cylinder(d=fronttubebackindia+fronttubethickness, h=straighttubeheight+1); } if (usenut == "true") { //cylinder(d=nut_id, h=nut_ht+0, $fn=nut_facets, center=true); //c_id = facet2dia(facet_dia = id, num_facets=facets); c_id = facet2dia(facet_dia = nut_id, num_facets=nut_facets); translate([-(fronttubebackindia+fronttubethickness-2)/2,0,magic_height]) rotate([0,90,0]) cylinder(d=c_id, h=nut_ht-6, $fn=nut_facets, center=true); } translate([0,0,-4]) cylinder(r=(fronttubebackindia)/2, h=straighttubeheight+18); } } //module makeslits(num=10, slitlength=200, slit_thickness=1.5, slitheight=10) { if (slits == "true" && buildtube == "true" && 0) { // Make the slits translate([0,0,+18]) // Raise (or lower) the slits makeslits(num=num_slits, slitlength=fronttubebackindia*1.3, slit_thickness=slit_thickness,slitheight=sectionheight*.6); } } } } else { // if (6 == 6) if (buildtube == "true") { // Add straight section translate([0, 0, start_straighttube_at -.1 - fudgeif1*0+0]) { xod = fronttubebackindia+(fronttubethickness*0); make_nut_tube(num_nuts=numfrontnuts,tube_ht=sectionheight+1, od = xod, wall=fronttubethickness); } } } } // module fronttube() module reartube(sections=3, buildplate="true", buildtube="true", slits="true") { // globals: reardiskdiametertol (threaded) // reardiskdiameternttol (not threaded) tol = ((makethreads == "true") ? reardiskdiametertol : reardiskdiameternttol); dia = reardiskdiameter + tol; mag=((dia<49) ? 0.5 : 1); pitch=thread_pitch/100.0; ctol=thread_tolerance/1000.0; threadheight = numthreads * (pitch*.0002); filletsize=3; echo(str("Making rear tube for ", film, ".")); //echo(str(sections, " sections.")); echo(str(sections, " sections, sectionheight of ", sectionheight, "mm, total length: ",sections*sectionheight, "mm.")); echo(str("reartubeoutdia ", reartubeoutdia, "mm, ",reardiskdiameter, "mm reardiskdiameter ", dia, "mm dia")); // For testing round_holes_cutter rhc_od=reardiskdiameter; // OD of the cylinder we will be cutting holes in rhc_tk=2; // How thick is the cylinder rhc_os=6; // How far from the outside edge should the center of the hole be rhc_hs=3; // What is the diameter of each hole? rhc_nh=4; // How many holes are we cutting? union() { difference() { // Temporarily change to "union()" to see what is subtracted union() { if (buildplate == "true" ) { difference() { if (makethreads != "true") { if (makeplateslits == "true") { make_slitted_disk(dia=dia, ht=reardiskheight, num_slits=70, len_slits=5.0); } else { cylinder(d=dia, h=reardiskheight); } } else { translate([0,0,(threadheight)]) male_thread(pitch, dia-ctol, numthreads, 0.25); } translate([0,0,reardiskheight]) cylinder(d=reardiskdiameter-3, 20) ; if (cutplateholes == "true") { round_holes_cutter(od=rhc_od, os=rhc_os, hs=rhc_hs, nh=rhc_nh, tk=rhc_tk); } } // difference() } if (buildtube == "true" ) { translate([0, 0, reardiskheight]) // Make the rear tube cylinder(r=reartubeoutdia/2, h=sections*sectionheight+1); translate([0,0,reardiskheight-0.5]) // Fake a fillet cylinder(d1=reartubeoutdia+filletsize+0.5+1, d2=reartubeoutdia, h=filletsize+0.5); } } // Eliminate the inner tube. translate([0, 0, (sections*sectionheight)/2]) cylinder(d=reartubeoutdia-reartubethickness*1.5, h=(sections*sectionheight)+20,center=true); if (buildtube == "true" ) { // How high should the slits start? translate([0, 0, (sections*sectionheight-sectionheight*.75) + (reardiskheight+1)]) { if (slits == "true" && buildtube == "true" && 0) { for (i=[1:360/num_slits:360]) { rotate([0,0,i]) cube([fronttubebackindia-(fronttubebackindia*.35), slit_thickness, sectionheight*1.1],center=false) ; } } } // translate() } // if (buildtube == "true" ) } // difference() if (buildtube != "true" && buildplate == "true" && labelcrossbar == "true") { thewidth=10; translate([0,-thewidth/2,0.25]) //makeruler(length = 50, width=thewidth, offset = 0, font_size = 4.7, orientation = "uprightx", print_length = "truex", print_text=labelcrossbar, the_text=str("Dia. ", reardiskdiameter, "mm")); makeruler(length = 50, width=thewidth, offset = 0, font_size = 3.7, orientation = "uprightx", print_length = "truex", print_text=labelcrossbar, the_text=str("", reardiskdiameter, "mm, tol. ", tol, "mm")); } } // union() } /* Measured: 1/2" == 12 x 3 .3" == 8 x 3 3/8" == 10 x 3 */ magd=12; // 12.60 magh=3; module testmaghole () { x = magd + 8; y = x; z = magh + 1.0; difference() { difference() { translate([0,0,z/2]) cube([x, y, z], center = true) ; translate([magd*.5, 0,0]) maghole(ang=0, magdia = magd, maght=magh, distance=0, top=z); } } } //module make_angled_slits(num=10, slitlength=50, slit_thickness=1.5, slitheight=10, angle=0, angle_length=0) module maghole(ang=120, distance = 0, magdia=12.45, maght=3.5, top=15) { //maght=8; magic1=0; magic2=1.1; // Thickness of lip magic2=.1; cx = (distance - magdia)/2; calc_start=(top - maght*1)+magic2; calc_start=(maght/2+top) - maght + .1; echo(str("maghole: maght: ", maght, " top: ", top, " cx: ", cx, " calc_start: ", calc_start )); dia_fudge=+0.09; // .65, .85 .75, .1 rotate ([0,0,ang]) difference() { union() { translate ([((distance - magdia)/2), 0, calc_start]) cylinder(d=magdia+dia_fudge, h=maght+magic2*1, center =true) ; translate([((distance - magdia)/2),0,maght/2-.3]) cylinder(d=magdia+dia_fudge-(magdia/2), h=maght+top*2, center=true) ; // Angled notches? /* translate ([((distance - magdia)/2)-magic1,0,maght/2-.1]) make_angled_slits2(num=24, slitlength=magdia*1.30, slit_thickness=1.7, slitheight=maght+1, angle=40, angle_length=.4); ; translate ([((distance - magdia)/2), 0, calc_start]) cylinder(d1=magdia+dia_fudge+1, d2=magdia+dia_fudge, h=maght+magic2*1, center =true) ; */ } } } // maghole() // AKA slide carrier ((mostly)from DupliHood) module springpart() { union() { echo(str("Making Spring Holder for ", film, ".")); echo(str("frontdiskdiameter = ", frontdiskdiameter+td2dh_sp, "mm. ")); //makerim = "true"; add_to_bottom = .9; // Add additional room at the bottom for the magnet holes. add_to_bottom = 0; translate([0,0,add_to_bottom]) { if (makerim == "true") { difference() { // outer rim cylinder(r=(frontdiskdiameter+td2dh_sp)/2+lip+lip, h=framez+spring+overlap+ add_to_bottom) ; //cylinder(r=(frontdiskdiameter+td2dh_sp)/2, h=framez+spring+overlap); // slide holder translate([0, 0, framez+spring]) cylinder(r=(frontdiskdiameter+td2dh_sp)/2+lip, h=1000) ; // slide removal access, shifted up as of 20140824 translate([0, 500-(framey/2)+frametol/4, 0]) cube([framex+frametol, 1000, 1000], center=true) // Cuts the slits beside the slide carrier. ; } } else { // No rim //magholes = "truex"; thicker=-.3; // or thinner. Of the entire front disk // .3 provides 0 tension for a standard cardboard mount // But it does have tension for a plastic mount // You might want to decrease (i.e., -.5) "thicker" if // you are only concerned with cardboard mounts and want // a bit of tension. thicker=((magholes == "true") ? -.4 : -.1); //thicker=0; frontdiskthickness = 4+thicker+slidethickness; holefudge = -0.8; // see add_to_bottom -- Sink the maghole this much //holefudge = -0.1; //holefudge=0; magd=12.45; magh=3.2; // 3.7 3.0 3.4 //magh=8.0; difference() { translate([0,0,-add_to_bottom]) cylinder(d=frontdiskdiameter, h=frontdiskthickness+add_to_bottom); //+slidethickness // slide holder // Make holes for magnets if (magholes == "true") { offset = 5; rotate([0,0,0]) { maghole(distance = frontdiskdiameter-offset, ang = 10, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); maghole(distance = frontdiskdiameter-offset, ang = 170, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); maghole(distance = frontdiskdiameter-offset, ang = 90+180, magdia=magd, maght=magh, top = frontdiskthickness + holefudge) ; /* // extra holes maghole(distance = frontdiskdiameter-offset, ang = -20, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); maghole(distance = frontdiskdiameter-offset, ang = 200, magdia=magd, maght=magh, top = frontdiskthickness) + holefudge; */ } } // magholes translate([0, 0, framez+spring+thicker]) cylinder(r=(frontdiskdiameter+td2dh_sp)/2+lip, h=1000) ; // slide removal access, shifted up as of 20140824 translate([0, 500-(framey/2)+frametol/4, 0]) cube([framex+frametol, 1000, 1000], center=true) // Cuts the slits beside the slide carrier. ; } // difference() } // makerim slit_thickness=.8; // .4 was fused--I had to use a box cutter (strongly) to free the slit. add_to_base=.2; // Make base where the bumps are be thicker add_to_base=0; difference() { union() { // spring translate([0, 0, (spring)/2-add_to_bottom/2]) cube([framex-slit_thickness, (framey+frametol)*1, spring+add_to_base], center=true); // bump on the spring, thicker as of 20140824 difference() { translate([0, filmy/7, -filmy*2+spring*3]) rotate([0, 90, 0]) if (debug == "true") { cylinder(r=filmy*1.923, h=framex-slit_thickness, center=true, $fn=80); } else { cylinder(r=filmy*2, h=framex-slit_thickness, center=true, $fn=180); } translate([0, 0, -500]) // Eliminate bottom of large bump cylinder cube([1000, 1000, 1000], center=true) ; } } // clear film area + double tolerance as of 20140824 translate([0, 500-(filmy+frametol)/2-frametol, 0]) cube([filmx+2*frametol, 1000, 1000], center=true) ; } // difference() } } // add_to_bottom } // module springpart() // Negative carrier muct be printed >= standard (because of slopes and curves.) // For negative carrier. // Move these to the top when they are done. diskthickness = 2.0; // Thickness of the negative carrier base plate platethickness = 3.5; // Thickness of Xtend-a-Slide round plate backpadding = 0.5; // Amount of (felt, etc.) padding on the top part of the neg carrier to provide some "give". /* rw=((film != "film6x6") ? 3.24 : 2.8); // 3.24mm = 1/8" railwidth=((is110 == "true" && film != "film6x6") ? 1.62 : rw); //railwidth = 3.24; */ railwidth=((film == "film6x6") ? 1.5 : 3.24); lrailwidth=((is110 == "true") ? 1.10 : railwidth); // 1.25 1.2 rrailwidth=((is110 == "true") ? 1.4 : railwidth); // 2.75 2.0 1.8 addrlthk = ((is110 == "true") ? 0.34 : 0); // Additional top rail thickness (not using Art tape) ?? .78 .54 addrllen = ((is110 == "true") ? 2.4 : -1.3); // Shrink rail length (not using Art tape) 2.8 5.8 4.3 negrailshrink=0.0; // May have to stick in a film6x6 falue...? lnegrailshrink=((is110 == "true") ? -0.74 : negrailshrink); // -.0.74 rnegrailshrink=((is110 == "true") ? -0.68 : negrailshrink); // -0.38 echo (str("film is ",film, " is110 is ", is110, " left railwidth: ", lrailwidth, "mm ", " right railwidth: ", rrailwidth, "mm ")); railthickness=1.1; // Thickness of the rails that the sprocket hole area rides on //railthickness=3; enlarge=((film == "film6x6" || is110 == "true") ? 0 : 5 ); // Enlarge the film frame by this much (to see part // of the sprocket hole area.) Only for 35mm. negframex=((film != "film6x6") ? framex : 75); // The size of the top negative carrier negframey=((film != "film6x6") ? framey : 75); // 2*2 inches for 35mm; yet to be determined for 120 film. negframex=((film != "film6x6") ? framex : 74.5); // The size of the top negative carrier negframey=((film != "film6x6") ? framey : 74.5); // 2*2 inches for 35mm; yet to be determined for 120 film. onetwentyfudge=((film != "film6x6") ? 0 : .5); // Fudge factor for 120 film ?? 2 make_neg_rails = "true"; // Make the negative support rails? (We might want to make them ourselves out of softer material.) makebaseplate = "true"; rimwall=4; negframetol=-0.252; // How much to shrink the part that is the size of a slide 0.4 magic_1=0.76; //magic_1=0; rail_len_magic=5; rail_len = (frontdiskdiameter+td2dh_sp)*.78+rail_len_magic; // 0.78 module negativecarriertop() { rotate([0,180,0]){ translate([0,0,-(railthickness+slidethickness)*magic_1]) { difference() { translate([0,0,railthickness*1.0]) // Make space for top negative carrier cube([negframex+negframetol, negframey+negframetol, slidethickness],center=true); cube([filmy+enlarge,filmx+enlarge, 50], center=true) // Cutout for image frame ; } if (make_neg_rails == "true") { // translate([(negwidth/2)-railwidth/2-lnegrailshrink,0,0]) // one rail //cube([railwidth, (frontdiskdiameter+td2dh_sp)*0.8,railthickness], center=true); makebeveledrail(lrailwidth, rail_len-addrllen,railthickness*1+addrlthk, up="upx"); translate([-(negwidth/2)+railwidth/2+rnegrailshrink,0,0]) // the other rail //cube([railwidth, (frontdiskdiameter+td2dh_sp)*0.7,railthickness], center=true); makebeveledrail(rrailwidth, rail_len-addrllen,railthickness*1+addrlthk, up="upx"); // Cover the top (bottom) of the part of the rails that are sticking out translate([-(negwidth/2-negrailshrink/2), (frontdiskdiameter+td2dh_sp)*0.293-1.7, railthickness/2]) cube([negwidth-negrailshrink,17.8,slidethickness]); mirror([0,1,0]) { translate([-(negwidth/2-negrailshrink/2), (frontdiskdiameter+td2dh_sp)*0.293-1.7, railthickness/2]) cube([negwidth-negrailshrink,17.8,slidethickness]); } } // if (make_neg_rails == "true") } } } // Create a rail with a bevel at each end (so film doesn't catch.) module makebeveledrail(wd=5, len=50, ht=1, rad=50, up="up") { ln = len-(rad*.2); // Needs work; it is kind of fragile and doesn't scale. ort=((up == "up") ? 0 : 180); // Should bevel be on top or bottom? shifter=((up == "up") ? 0 : -ht/2); // Flipping 180 degrees and compensating, depending. rotate([0,ort,0]) { // Flip 180 degrees (or not) translate([0,0,shifter]) { // Compensate for the 180 degree flip (or not) difference() { union() { translate([0,0,ht/2]) cube([wd,ln,ht],center=true); // Make the rail translate([-wd/2,(ln/2)-(wd/2),-rad+ht/1]) rotate([0,90,0]) // The bevels are created from a section of a cylinder cylinder(r=rad, h=wd, $fn=180); mirror([0,1,0]) // One cylinder for each end translate([-wd/2,(ln/2)-(wd/2),-rad+ht/1]) rotate([0,90,0]) cylinder(r=rad, h=wd, $fn=180); } translate([0,0,-200/2]) cube([200,200,200],center=true); // Whop off the large portion of the cylinders (leaving // just the bevels at the ends of the rail.) } } } } // negative carrier. module negativecarrier(makerim="truex") { //ourdiameter = frontdiskdiameter+td2dh_sp*4; ourdiameter = frontdiskdiameter; rimheight=diskthickness*1.2 + railthickness*2 + platethickness +5 ; echo(str("Making negative carrier for ", film, ".")); echo(str("ourdiameter = ", ourdiameter, "mm, rim height:", rimheight, "mm")); echo(str("Negative width = ", negwidth, "mm.")); makerim="truex"; if (makeroundplate == "true") { intersection() { negativeplate(dia=ourdiameter) ; cylinder(d=ourdiameter,h=100,center=true) // Make the square negative carrier be a circle //cube([framex+20,framey+20,100], center=true); ; } // intersection() } else { negativeplate(dia=ourdiameter/2); // Need some more thought } if (makebaseplate == "true" && makerim == "true") { difference() { translate([0,0,(rimheight)/2]) // outside rim maketube_od(dia=ourdiameter, hgt=rimheight, wall=rimwall); translate([0,0,diskthickness*2.5+backpadding+(railthickness*2.09)]) // dig a channel to mount on the front plate cylinder(d=ourdiameter-rimwall*1, h=platethickness, center=true); if (6 == 9) { // Unsupported slit (!) (Eventually replace with 45 degree triangle, maybe. Or an arch.) // (If needed for strength.) translate([0,0,diskthickness+railthickness*1.8]) // cut out slits in rim for negative cube([negwidth*1.0,frontdiskdiameter*1.5,(railthickness*2.49)],center=true); } else { // Cut it out all the way to the top of the rim (so nothing is unsupported.) translate([0,0,diskthickness+railthickness*(20/2) + railthickness]) // cut out slits in rim for negative cube([negwidth*1.0,frontdiskdiameter*1.5,(railthickness*20)],center=true); } } } } // negativecarrier() module negativeplate (dia = 100) { frontdiskdiameter=dia; //diskthickness=2; railslop=0.6; // Distance between top and bottom rails. 0.4 topplateheight = diskthickness + railthickness*2+railslop; magic_1=4.3+railthickness; // 4.3 is to top of rail magic_2=railthickness; plate_height=topplateheight + backpadding + slidethickness ; difference() { // baseplate translate([0,0,(plate_height)/2]) cube([frontdiskdiameter*1.1, frontdiskdiameter*1.1, plate_height],center=true); if (6 == 6) { // Cutout for image frame cube([filmy+enlarge,filmx+enlarge, 100], center=true); if (film == "film6x6") { translate([0,(filmx+enlarge)/2,2]) // Bevel the edges rotate([25,0,0]) cube([filmy+enlarge-3,6, 3], center=true); mirror([0,1,0]) { translate([0,(filmx+enlarge)/2,2]) // Bevel the edges rotate([25,0,0]) cube([filmy+enlarge-3,6, 3], center=true); } } } thicker=((magholes == "true") ? -.4 : -.1); thicker=0; frontdiskthickness = 4+thicker+slidethickness; frontdiskthickness = plate_height+.7; holefudge = -0.8; // see add_to_bottom -- Sink the maghole this much //holefudge = -0.1; //holefudge=0; magd=12.45; magh=3.1; // 3.7 3.0 3.4 3.2 if (magholes == "true") { offset = 3; // Distance offset2 = 25; // Angle away from 0 rotate([0,0,0]) { maghole(distance = frontdiskdiameter-offset, ang = offset2, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); maghole(distance = frontdiskdiameter-offset, ang = -offset2, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); maghole(distance = frontdiskdiameter-offset, ang = 180+offset2, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); maghole(distance = frontdiskdiameter-offset, ang = 180-offset2, magdia=magd, maght=magh, top = frontdiskthickness + holefudge); } } //translate([0,0,(diskthickness+topplateheight*4)/2+railthickness]) // Clear out space for the negative (and rails) translate([0,0,diskthickness+(topplateheight*2)]) // Clear out space for the negative (and rails) cube([negwidth,frontdiskdiameter*2,(topplateheight*4)],center=true) ; translate([0,0,topplateheight+magic_1]) // Make space for top negative carrier 4.89 cube([negframex+frametol, negframey+frametol, slidethickness*10],center=true) ; } // difference() (baseplate) if (make_neg_rails == "true") { difference() { union () { translate([(negwidth/2)-lrailwidth/2+onetwentyfudge ,0,diskthickness-.01+railthickness/2]) // one rail cube([lrailwidth, (frontdiskdiameter+td2dh_sp)*1.0,railthickness], center=true) ; translate([-(negwidth/2)+rrailwidth/2-onetwentyfudge ,0,diskthickness-.01+railthickness/2]) // the other rail cube([rrailwidth, (frontdiskdiameter+td2dh_sp)*1.0,railthickness], center=true) ; } xxx=((is110 == "true") ? 2 : 2); rot1=((film == "film6x6") ? 1.5 : xxx); echo(str("rot1: " , rot1)); rotate([0,rot1,90]) translate([(frontdiskdiameter/2),0,diskthickness+railthickness*2+.15]) cube([(frontdiskdiameter)/2,negwidth,diskthickness/2], center=true); mirror([0,1,0]) { rotate([0,rot1,90]) translate([(frontdiskdiameter/2),0,diskthickness+railthickness*2+.15]) cube([(frontdiskdiameter)/2,negwidth,diskthickness/2], center=true); } } } // if (make_neg_rails == "true") } // negativeplate() // Slide carrier for Xtend-a-Slide (35mm only) and TransiDupe tubes module slidecarrier () { roughnessadjust=0.4; // Ahh, adjust for the roughness of the front plate. So the slide will fit. // Nominally is the thickness of the slide. However... // .02 //frontdiskdiameteradj=frontdiskdiameter+td2dh_sp*4; frontdiatol= .5; frontdiskdiameteradj=frontdiskdiameter+frontdiatol; frontrimhgt=frontrimheight+xfrontdiskheight+slidethickness; totaldiskheight=xfrontdiskheight+slidethickness+roughnessadjust; echo(str("Making slide carrier for ", film, ".")); echo(str("frontdiskdiameter: ", frontdiskdiameter, " frontdiskdiameter (adjusted): ", frontdiskdiameteradj, ".")); echo(str("disk thickness is ", xfrontdiskheight, ", total disk height is ", totaldiskheight, ", rimwall is ", rimwall, ".")); echo(str("frontrimheight ", frontrimheight, ", frontrimhgt ", frontrimhgt, ".")); frametol=.5; if (makeroundplate == "true") { difference() { cylinder(d=frontdiskdiameteradj, h=totaldiskheight); // Bottom plate // Make holes for magnets if (magholes == "true") { offset = 5; rotate([0,0,0]) { maghole(distance = frontdiskdiameter-offset, ang = 90, top = totaldiskheight); maghole(distance = frontdiskdiameter-offset, ang = 180, top = totaldiskheight); maghole(distance = frontdiskdiameter-offset, ang = 90+180, top = totaldiskheight) ; } } // magholes if (cutoutfilmarea == "true") { translate([xtol/2,0,0]) cube([filmy+1, filmx+1, xfrontdiskheight+20], center=true); // Cut out the film area } translate([xslidedia/2-xnotchdistance+xtol/2,0,-5]) { // Make pieces for finger notch cylinder(r=xslidefingernotchwidth/2, h=xfrontdiskheight+20); translate([0,-xslidefingernotchwidth/2,0]) cube([xslidefingernotchlength,xslidefingernotchwidth,xfrontdiskheight+20],center=false); } translate([-(framex+frametol-xtol)/2, -(framex+frametol)/2, xfrontdiskheight]) // Cut out area for slide cube([(framex+frametol)*2, framey+frametol, xfrontdiskheight*1.1], center=false) ; // Add bevels to the end of the slide cutout. translate([framex/2,framey/5,xfrontdiskheight]) rotate([0,0,18]) cube([(framex+frametol)*.5, (framey+frametol)*.3, xfrontdiskheight*2.5], center=false); translate([framex/2,-framey*.5,xfrontdiskheight]) rotate([0,0,-15]) cube([(framex+frametol)*.5, (framey+frametol)*.3, xfrontdiskheight*2.5], center=false); } } channeldepth=rimwall*0.0; if (makerim == "true") { difference() { translate([0,0,xfrontdiskheight]) maketube_od(dia=frontdiskdiameteradj+4 , hgt = xfrontdiskheight+2, wall=1.5) ; translate([-(framex+frametol)/2, -(framex+frametol+3.9)/2, xfrontdiskheight*1.0]) // Cut out area for slide cube([(framex+frametol)*2, framey+frametol+5, xfrontdiskheight*11.1], center=false); translate([xslidedia/2-xnotchdistance+xtol/2,0,-5]) { // Make pieces for finger notch cylinder(r=xslidefingernotchwidth/2, h=xfrontdiskheight+20) ; translate([0,-xslidefingernotchwidth/2,0]) cube([xslidefingernotchlength,xslidefingernotchwidth,xfrontdiskheight+20],center=false); } } difference() { // Outside rim union() { // maketube: dia is Inside Diameter. OD = ID + wall translate([0,0,frontrimhgt/2]) maketube_od(dia=frontdiskdiameteradj*1.0, hgt=frontrimhgt, wall=rimwall-0) ; } translate([0,0,xfrontdiskheight+slidethickness+2.1]) // dig a channel to mount on the front plate cylinder(d=frontdiskdiameteradj+channeldepth, h=frontdiskheight-.1, center=true) ; //translate([0,0,frontrimhgt*.5]) translate([0,0,5]) // Slits start this high makeslits(num=11, slitlength=frontdiskdiameter*1.2, slit_thickness=1.15, slitheight=17); translate([-(framex+frametol)/2, -(framex+frametol+3.9)/2, xfrontdiskheight*1.0]) // Cut out area for slide cube([(framex+frametol)*2, framey+frametol+5, xfrontdiskheight*11.1], center=false); translate([xslidedia/2,0,xfrontdiskheight*.5]) cube([xslidefingernotchlength,xslidefingernotchwidth,xfrontdiskheight],center=true); } } } // slidecarrier () // Not from Duplihood module diffuser() { diffuser_rim = 2.5; // Height of rim above spacer diffuser_lip=2.5; // thickness of rim diffuser_thickness = 2.75; // diffuser_spacer = 6.5; // spacer height. 6.5mm == 1/4" diffuser_rimheight = diffuser_thickness+diffuser_spacer + diffuser_rim; diffuser_fudge=0.5; bot_killer=1; // Make >1 to kill the boottom (for debugging.) difference() { translate([0,0,diffuser_rimheight/2]) // First create rim cylinder(d=frontdiskdiameter+diffuser_lip+diffuser_fudge, h=diffuser_rimheight, center=true); translate([0,0,(diffuser_rimheight)/2+diffuser_spacer+.3]) // Remove area above spacer cylinder(d=frontdiskdiameter+diffuser_fudge, h=(diffuser_rimheight),center=true); translate([0,0,(diffuser_rimheight)/2+.2]) // Remove area down to the diffuser. cylinder(d=frontdiskdiameter-4+diffuser_fudge, h=(diffuser_rimheight-diffuser_thickness)*bot_killer,center=true); translate([0,0,(diffuser_thickness+diffuser_spacer)*.82]) makeslits(num=25, slitlength=frontdiskdiameter*1.5, slit_thickness=1.0, slitheight=diffuser_rim+5); // Cut out finger notch if (diffuser_finger_notch == "true" ) { rotate([0,0,90]) { translate([xslidedia/2-xnotchdistance+xtol/2,0,-5]) { // Make pieces for finger notch cylinder(r=xslidefingernotchwidth/2, h=xfrontdiskheight+20); translate([0,-xslidefingernotchwidth/2,0]) cube([xslidefingernotchlength,xslidefingernotchwidth,xfrontdiskheight+20],center=false); //} translate([-(framex+frametol-xtol)/2, -(framex+frametol)/2, xfrontdiskheight]) // Cut out area for slide cube([(framex+frametol)*2, framey+frametol, xfrontdiskheight*1.1], center=false) ; // Add bevels to the end of the slide cutout. translate([framex/2,framey/5,xfrontdiskheight]) rotate([0,0,18]) cube([(framex+frametol)*.5, (framey+frametol)*.3, xfrontdiskheight*2.5], center=false); translate([framex/2,-framey*.5,xfrontdiskheight]) rotate([0,0,-15]) cube([(framex+frametol)*.5, (framey+frametol)*.3, xfrontdiskheight*2.5], center=false); } } } if (diffuser_flattop == "true") { rotate([0,0,0]) { translate([framex/2+20,forward,(diffuser_thickness)/2+diffuser_spacer-.1-10]) rotate([0,0,90]) // Remove cut-out for slide. cube([framex*1,framey+40,diffuser_rim+15]); } } if (diffusor_type == "slide") { // Cutout for slides translate([framex/2+20,forward,(diffuser_thickness)/2+diffuser_spacer-.1]) rotate([0,0,90]) // Remove cut-out for slide. cube([framex*1,framey+40,diffuser_rim+5]); } else { // Cut out for negatives (eventually) translate([framex/2,-frontdiskdiameter/2-4,(diffuser_thickness)/2+diffuser_spacer-.05]) rotate([0,0,90]) // Remove cut-out for slide. cube([framex*2.5,framey+4,diffuser_rim+5]); } } } // Makes threads. Called from reartube() (from DupliHood) module male_thread(P, D_maj, Tall, tol=0, step=mystep) { // male thread is also called external thread echo(str("Step is ", step, " in male_thread() (360/step > 5 == coarse).")); echo(str("numthreads is ", Tall, ".")); H=sqrt(3)/2*P; fudge=0.0001; //assign(H=sqrt(3)/2*P) //assign(fudge=0.0001) intersection() { translate([0, 0, Tall/2]) cube([2*D_maj, 2*D_maj, Tall], center=true); for(k=[-P:P:Tall+P]) translate([0, 0, k]) for(i=[0:step:360-step]) hull() for(j = [0,step]) { rotate([0,0,(i+j)]) translate([D_maj/2, 0, (i+j)/360*P]) rotate([90, 0, 0]) linear_extrude(height=0.1, center=true, convexity=10) polygon(points=[ [-H*2/8-P/8-tol, 0], [P/2-H*2/8-P/8-tol, P/2], [-H*2/8-P/8-tol, P], [-D_maj/2-fudge, P], [-D_maj/2-fudge, 0]], paths=[[0,1,2,3,4]], convexity=10); } } } print_part(); // From Thingiverse Customizer docs. You must use "part" and "print_part()" to work on Customizer. // Colors only affect F5 (CGS) preview mode; // These colors go away after F6 (CGAL) render mode module print_part() { min_length = length_of_both_tubes - sectionheight; max_length = length_of_both_tubes - 10; if (is_pvc_tube != "true") { echo(str("length_of_both_tubes: ",length_of_both_tubes )); echo(str("Working length of both tubes is approx. ", min_length , "mm through ", max_length, "mm.")); } if (part == "fronttube") { color ("gray") fronttube(sections=num_front_sections, buildplate=makeroundplate, buildtube=maketube); } else if (part == "reartube") { color ("gray") reartube(sections=num_rear_sections, buildplate=makeroundplate, buildtube=maketube); } else if (part == "springpartxx") { color("white") springpart(); } else if (part == "springpartsmall") { // Make small (for test printing magnet holes) difference() { color("green") springpart(); sideways = 35; translate([sideways,0,0]) cube([50,100,10], center=true); translate([-sideways,0,0]) cube([50,100,10], center=true); } } else if (part == "testmaghole") { color("white") testmaghole(); } else if (part == "negativecarrier") { color("white") negativecarrier(); } else if (part == "springpart") { if (truncate == "true") { h = 10; intersection() { difference() { color("white") springpart(); translate([20,-frontdiskdiameter+45,h/2-.1]) cube([20,20,h], center=true); translate([-20,-frontdiskdiameter+45,h/2-.1]) cube([20,20,h], center=true); } union() { translate([0,6,h/2-.1]) cube([frontdiskdiameter+2,20,h], center=true); translate([0,0,h/2-.1]) cube([framex+10,frontdiskdiameter+2,h], center=true); } } } else { color("white") springpart(); } } else if (part == "negativecarriersmall") { intersection() { color("white") negativecarrier(); translate([0,0,0]) if (film == "film6x6") { cube([framex+15,framey+20,15], center = true); } else { cube([filmx+7,filmy+12,10], center = true); } } } else if (part == "negativecarriertop") { color("white") negativecarriertop(); } else if (part == "smallnegativecarriertop") { intersection() { color("white") negativecarriertop(); translate([0,0,10/2]) cube([40,40,10]); } } else if (part == "negativecarrierboth") { union() { color("white") negativecarrier(makerim="truex"); translate([0,0, diskthickness + railthickness*3.25]) color("green") rotate([0,180,0]) negativecarriertop() ; } // make_nut_tube() } else if (part == "makenuttube") { make_nut_tube(); } else if (part == "makeslottedtube") { make_slotted_tube(); } else if (part == "pvcreartube") { color("white") pvc_tube_ends(diskdiameter=reardiskdiameter, diskheight=reardiskheight, makethreads=makethreads, cutplateholes=cutplateholes, makeplateslits=makerearplateslits, makefillet="true", diskdiametertol=reardiskdiametertol, diskdiameternttol=reardiskdiameternttol, buildplate=makeroundplate, num_nuttubes=numrearnuts, tube_ht=rear_tube_height); } else if (part == "pvcfronttube") { color("white") // diskdiameter=frontdiskdiameter pvc_tube_ends(diskdiameter=frontdiskdiameter, diskheight=reardiskheight, makethreads="false", cutplateholes="false", makefillet="false", makeplateslits="false", buildplate=makeroundplate, num_nuttubes=numfrontnuts,tube_ht=front_tube_height); } else if (part == "pvctube") { ht = pvctube_ht; ht=10; color("white") translate([0,0,ht/2]) maketube_od(dia=60.36, hgt=ht , wall=4); } else if (part == "slidecarrier") { color("white") slidecarrier(); } else if (part == "xslidecarrier") { color("white") xslidecarrier(); } else if (part == "diffuser") { color ("white") diffuser(); } else if (part == "calslide") { color ("white") calslide(); //translate([0,0,5]) //calslide_2(); } else if (part == "thumbshell") { color("silver") thumbshell(); } else if (part == "springclamp" ) { num = num_springclamps; //num=3; //trans_x = (springclamp_handle+springclamp_x)/2+3; trans_x = ((num > 1) ? (springclamp_handle+springclamp_x+num*.5)/2+3 : 0); for (i=[0:360/num:360]) { rotate([0,0,i]) { translate([trans_x,0,0]) color("gray") springclamp(); } } } else if (part == "ruler") { rulerwidth=10; color ("white") echo(str("Ruler is ", length_of_both_tubes-(sectionheight/2), " (length_of_both_tubes-(sectionheight/2))")); translate([0,-rulerwidth*0.5,0]) makeruler(length = length_of_both_tubes-(sectionheight/2), width=rulerwidth, offset = 0, orientation = "uprightx", print_length = "true"); //makeruler(length = 50, width=rulerwidth, offset = 0, orientation = "uprightx", print_length = "truex", print_text="true", the_text="Test text"); } else if (part == "playpen1") { color ("white") playpen1(); } else if (part == "playpen2") { color ("gray") playpen2(); } else if (part == "bothtubes" || part == "bothtube") { union() { color("blue") fronttube(sections=num_front_sections, buildplate=makeroundplate, buildtube=maketube); color("green") translate([0,0,num_front_sections * sectionheight-1]) reartube(sections=num_rear_sections, buildplate=makeroundplate, buildtube=maketube); } } else if (part == "exploded_pvc") { union() { h=0; color("white") slidecarrier(); translate([0,0,h+8]) color("gray") negativecarrier(); translate([0,0,h+19]) rotate([180,0,0]) color("gray") negativecarriertop(); h0=22; // 22 translate([0,0,h0]) color("red") pvc_tube_ends(diskdiameter=frontdiskdiameter, diskheight=reardiskheight, makethreads="false", cutplateholes="false", makefillet="false", makeplateslits="false", buildplate=makeroundplate, num_nuttubes=numfrontnuts,tube_ht=front_tube_height); th=60; h00 = h0 + 0+ front_tube_height + reardiskheight ; color("white") translate([0,0,h00+ th/2]) //maketube_od(dia=60.30, hgt=th , wall=4); maketube_od(dia=tube_od, hgt=th , wall=4); h1=h00 + th +00 + reardiskheight + rear_tube_height; translate([0,0,h1+0]) rotate([180,0,0]) color("blue") pvc_tube_ends(diskdiameter=reardiskdiameter, diskheight=reardiskheight, makethreads=makethreads, cutplateholes=cutplateholes, makeplateslits=makerearplateslits, makefillet="true", diskdiametertol=reardiskdiametertol, diskdiameternttol=reardiskdiameternttol, buildplate=makeroundplate, num_nuttubes=numrearnuts, tube_ht=rear_tube_height); h2 = h1 + 8; translate([0,0,h2+0]) color("white") //calslide() ; } } else if (part == "exploded") { union() { /* color("white") diffuser(); */ translate([0, 0, 4 + (lip*1)]) union() { color("gray") springpart(); translate([0, 0, lip*7]) color("white") negativecarrier(); translate([0, 0, lip*12]) rotate([0,180,0]) color("white") negativecarriertop(); translate([0, 0, lip*16]) color("blue") fronttube(sections=num_front_sections, buildplate=makeroundplate, buildtube=maketube); translate([0, 0, (num_front_sections*sectionheight)*2+ 5+(sectionheight*.01)+lip*7]) rotate([0,180,0]) color("green") reartube(sections=num_rear_sections, buildplate=makeroundplate, buildtube=maketube); color("white") translate([0, 0, (num_rear_sections+num_front_sections)*sectionheight+(sectionheight*.1)+lip*8]) // So you can look down through the tubes in "exploded", in debug mode if (debug != "true") { //calslide(); } else { //calslide(); } ; } } } else { echo (str("Part '", part, "' is not defined.")); color("red") rotate([90,0,0]) linear_extrude(height= 0.7) { text(text = str("Part '", part, "' is not defined."), size=5, halign="center"); } } } // Experimental or unfinished modules go here. /////////////////////////////// module playpen1() { // Playing with rim and torus torheight=3; rimdiameter = frontdiskdiameter; //rimdiameter = 67; torus_dia = .065; torus_dia = 1; outerskin = torus_dia*1.95; innerskin = torus_dia*1; wall = torus_dia*.2; // 0 1 2 3 4 5 6 7 points = [ [0,0],[outerskin,0],[outerskin,outerskin],[outerskin-wall,outerskin,],[outerskin-wall,wall],[wall,wall],[wall, outerskin],[0,outerskin] ]; paths= [[0,1,2,3,4,5,6,7]]; //polygon(points, paths, 10); if (6 == 9) { // Rim + torus union() { echo(str("Playpen1 ", film, ".")); echo(str("rimdiameter = ", rimdiameter, ". ")); //translate([0, 500-(framey/2)+frametol/4, 0]) //color("red") //cube([framex+frametol, framex+frametol, 1.5], center=true) difference() { // outer rim cylinder(r=rimdiameter/2+lip+lip, h=framez+spring+overlap); //cylinder(r=rimdiameter/2+lip+lip, h=55); //cylinder(r=rimdiameter/2, h=framez+spring+overlap); // slide holder translate([0, 0, 0]) cylinder(r=rimdiameter/2+lip, h=1000) ; // slide removal access, shifted up as of 20140824 translate([0, 500-(framey/2)+frametol/4, 0]) //color("red") //cube([framex+frametol, 1000, 1000], center=true) ; translate([0,0,torheight]){ //torus(our_circle="coarse", location="inner"); translate([0,0,torheight*1.5]) //#torus(dia = rimdiameter+2, our_circle="up-channel", location = "outer" ) ; } } // difference translate([0,0,torheight*3.2]){ #torus(dia = rimdiameter+1, width=6, our_circle="square", location = "outer" ); } } // Union } else { // Just torus. translate([0,0,torheight*2.2]) //torus(dia = rimdiameter+2,our_circle="square",location="outer") belttorus(dia = rimdiameter+2,our_circle="square",location="outer") ; } } // playpen1() // Still needs works. The scaling doesn't scale. But it would work if you only needed one size of torus // and didn't mind fiddling with the assorted scaling parameters here. module torus (dia =frontdiskdiameter+2, width=5, our_circle="circlex", location = "outer" ) { //div=.26; // .25 for inner bevel, .26 for outer div=((location == "outer") ? .2659 : .25 ); //div=.25; //echo(str("our_circle ", our_circle, " div ", div)); torus_dia = .065; torus_dia = width*.01; scale([dia*div,dia*div,dia*div]) { // Don't really know how this works. translate([0,0,-.20]) rotate_extrude(convexity = 10, $fn = 190) translate([2, 0, 0]) if (our_circle == "true" ) { circle(r = torus_dia, $fn = 90); } else if (our_circle == "coarse" ) { // Namely for fast rendering speed. circle(r = torus_dia, $fn = 20); } else if (our_circle == "up-channel" ) { // channel-shaped polygon outerskin = torus_dia*2.95; wall = torus_dia*.5; // Plot paths counter-clockwise around the polygon // 0 1 2 3 4 5 6 7 points = [ [0,0],[outerskin,0],[outerskin,outerskin],[outerskin-wall,outerskin,],[outerskin-wall,wall],[wall,wall],[wall, outerskin],[0,outerskin] ]; paths= [[0,1,2,3,4,5,6,7]]; rotate([0,0,270]) // Outward facing //rotate([0,0,90]) // Inward facing polygon(points, paths, 10); } else { square([torus_dia*1.25,torus_dia*1.25], $fn = 90); } } // scale() (!) } // module torus() // Trying to make something to put on the edge of a plate for a rim to snap onto. // Will be used both convex (plate edge) and concave (rim that snaps onto the plate) // Not really, yet. As fragile as a sand castle on a skateboard. module belttorus (dia =frontdiskdiameter+2, wid=5, steps=1, slope=2, $fn=60) { width = wid/1; translate([0,0,-width*2+2]) { difference() { union() { for (i = [0:steps:width-1]) { translate([0,0,width-i/slope]) cylinder(d=dia+i-width+1,h=(width-i)/slope); translate([0,0,(i-width/slope)+steps]) cylinder(d=dia+i-width+1,h=(width-i)/slope); } } translate([0,0,-width*2]) cylinder(d=dia-width, h=width*5); } } }