Untitled
unknown
plain_text
15 hours ago
14 kB
5
Indexable
// // Dog Wheelchair (OpenSCAD) — mm, Customizer-ready (v2025-08-22c) // - Selectable support rule: add the bar if weight >= threshold (default) or <= threshold. // - Wheels are aligned to the axle hole of the supports (reuse Part E’s transform chain). // - all_parts arranged in a grid with mirrored versions and print-friendly orientations. // - Extra-long through holes for straps/screws. // // ------------------------------------------------------------ /* [View Mode] */ part = "wheelchair_sim"; // [wheelchair_sim:Wheelchair Simulation,part_a:Part A,part_b:Part B,part_b2:Part B2,part_c:Part C,part_d:Part D,part_e:Part E,all_parts:All Parts] /* [Dog - Dimensions (mm)] */ // Body width (side-to-side) dog_width = 152; // ~6" // Hind height dog_height = 203; // ~8" // Belly to tail dog_length = 356; // ~14" /* [Wheels & Hardware (mm)] */ wheel_diameter = 102; // ~4" screw_diameter = 6.35; // 1/4" tube_outer_diameter = 19.7; // 0.776" (tube OD) /* [Frame] */ wheel_angle = 0; // Rear upright tilt (deg): 0..15 wheel_axle_back_offset = 90; // Axle distance behind front crossbar (mm) clearance_back = 50; // Shorten simulated frame at the back (mm) ground_clearance_allowance = 25; // Ground clearance allowance (mm) /* [Support Bar] */ auto_support = true; // enable rule support_rule = "heavier"; // [heavier:Add bar if weight >= threshold, lighter:Add bar if weight <= threshold] dog_weight_kg = 5.0; support_threshold_kg = 4.5; force_extra_support_bar = false; // force the bar regardless of rule /* [Joints / Bends] */ fit = 0.25; // tube->socket clearance (mm) joint_wall = 5; // radial wall thickness (mm) joint_cyl_length = 25; // straight cylinder length (mm) bend_radius = 1; // torus path radius (mm) angle_1 = -30; // lower bend arm (deg) angle_2 = 60; // upper bend arm (deg) /* [Quality] */ $fa = 6; // max facet angle $fs = 0.5; // min facet size /* [Colors] */ col_parts = "chartreuse"; col_frame = "lightgrey"; col_wheels = "dimgray"; /* [Hidden / Derived] */ tube_radius = tube_outer_diameter/2; inner_radius = tube_radius + fit; // socket radius for tube outer_radius = inner_radius + joint_wall; cyllength = joint_cyl_length; wheel_radius = wheel_diameter/2; screw_radius = screw_diameter/2; // Simulated frame geometry chair_length = dog_length - clearance_back; chair_width = dog_width; chair_height = max(5, dog_height - wheel_radius - ground_clearance_allowance); ang = wheel_angle; // OpenSCAD uses degrees // Support rule bar = force_extra_support_bar || (auto_support ? (support_rule == "heavier" ? (dog_weight_kg >= support_threshold_kg) : (dog_weight_kg <= support_threshold_kg)) : false); // Axle position along Y (negative is backward) chairwheeldistance = wheel_axle_back_offset; // Grid spacing for "all_parts" grid_dx = 160; grid_dy = 110; /* ---------- Utilities ---------- */ module drill_z(r, h, center=false){ cylinder(r=r, h=h, center=center); } module drill_x(r, h, center=false){ rotate(90, [0,1,0]) cylinder(r=r, h=h, center=center); } module drill_y(r, h, center=false){ rotate(90, [1,0,0]) cylinder(r=r, h=h, center=center); } /* ---------- Wheel (disc) ---------- */ module wheel_disc_raw(){ // flat disc without extra transforms color(col_wheels) scale([1,1,0.25]) sphere(r=wheel_radius); } /* ---------- Bends (hex section) ---------- */ module bend(){ difference(){ rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) circle(r=outer_radius, $fn=6); } rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) circle(r=inner_radius); } rotate([0,0,angle_1]) translate([-100,-100,-50]) cube([300,100,100]); rotate([0,0,angle_2]) translate([-100, 0,-50]) cube([300,100,100]); } } module bend2(){ intersection(){ rotate([0,0,-30]) translate([0,0,-50]) cube([100,100,100]); difference(){ rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) rotate([0,0,90]) circle(r=outer_radius, $fn=6); } rotate_extrude(){ translate([bend_radius + outer_radius, 0, 0]) circle(r=inner_radius); } rotate([0,0,angle_1]) translate([-100,-100,-50]) cube([300,100,100]); rotate([0,0,angle_2]) translate([-100, 0,-50]) cube([300,100,100]); } } } /* ---------- Strap blocks + through-holes ---------- */ module strapholes(){ translate([-15,33,-50]) drill_z(screw_radius, 200); } module straps1(){ difference(){ union(){ translate([-25.38,28.9,-10]) cube([20,20,20]); } union(){ rotate(-30,[1,0,0]) translate([-40,-100,20.926]) cube([200,200,20]); rotate( 30,[1,0,0]) translate([-40,-100,-43.63]) cube([200,200,22.7]); translate([-40,39,-20]) cube([200,200,50]); } rotate( 10,[1,0,0]) strapholes(); } } module straps2(){ difference(){ union(){ translate([-25.38,28.9,-10]) cube([12,20,20]); } union(){ rotate(-30,[1,0,0]) translate([-40,-100,20.926]) cube([200,200,20]); rotate( 30,[1,0,0]) translate([-40,-100,-43.63]) cube([200,200,22.7]); } translate([-40,39,-20]) cube([200,200,50]); rotate(90,[0,1,0]) translate([0,33,-50]) drill_z(screw_radius, 400); } } module straps3(){ difference(){ union(){ translate([-25.38,28.9,-10]) cube([20,20,20]); } union(){ rotate(-30,[1,0,0]) translate([-40,-100,20.926]) cube([200,200,20]); rotate( 30,[1,0,0]) translate([-40,-100,-43.63]) cube([200,200,22.7]); translate([-40,39,-20]) cube([200,200,50]); } rotate(-10,[1,0,0]) strapholes(); } } /* ---------- Printable parts (A..E, B2) ---------- */ module partA(){ color(col_parts) union(){ rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,90,0]) difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength+5); } rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-0.02,0]) rotate([-90,90,0]) difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength+5); } bend2(); rotate(-30,[0,0,1]) straps1(); } } module partB_common(_use_straps3=false){ color(col_parts) union(){ rotate(120,[0,0,1]) union(){ rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,0,ang]) difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-10]) cylinder(r=inner_radius, h=cyllength+15); } rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-38,0]) rotate([-90,0,0]) difference(){ cylinder(r=outer_radius, h=cyllength*1.75, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5); } difference(){ bend(); rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-40,0]) rotate([-90,0,0]) translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5); } } rotate(90,[0,1,0]) rotate(-90,[0,0,1]) translate([-12.62,-15.95,-15.95]){ if(_use_straps3) straps3(); else straps1(); } } } module partB(){ partB_common(false); } module partB2(){ mirror([1,0,0]) partB_common(true); } module partC(){ color(col_parts) difference(){ rotate(120,[0,0,1]) rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,0,0]) rotate([0,0,90]) difference(){ cylinder(r=outer_radius, h=cyllength-5.4, $fn=6); translate([0,0,-10]) cylinder(r=inner_radius, h=cyllength+60); } } translate([25.36,0,0]) straps1(); } module partD(){ color(col_parts) difference(){ rotate(120,[0,0,1]) rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,0,0]) rotate([0,0,90]) difference(){ cylinder(r=outer_radius, h=cyllength+20, $fn=6); translate([0,0,10]) cylinder(r=inner_radius, h=cyllength+25); } } translate([50.76,0,0]) straps1(); translate([25.36,0,0]) straps2(); } module partE(){ color(col_parts) translate([0,0,-tan(ang)*2.2]) rotate(ang,[1,0,0]) difference(){ rotate(120,[0,0,1]) union(){ if(bar){ rotate([0,0,angle_1]) translate([bend_radius+outer_radius,0.02,0]) rotate([90,90,0]) difference(){ cylinder(r=outer_radius, h=cyllength, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength+5); } } rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-43,0]) rotate([-90,90,0]) difference(){ cylinder(r=outer_radius, h=cyllength*1.75 + 25.4, $fn=6); translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5); // axle hole (very long) translate([0,50,60]) rotate(90,[1,0,0]) drill_z(screw_radius, 400); } if(bar){ difference(){ bend2(); rotate([0,0,angle_2]) translate([bend_radius+outer_radius,-40,0]) rotate([-90,0,0]) translate([0,0,-1]) cylinder(r=inner_radius, h=cyllength*2+5); } } } } } /* ---------- Wheels from Part E pose ---------- */ // reproduces the same transforms to the axle, then places the disc module wheel_from_partE_local(){ translate([0,0,-tan(ang)*2.2]) rotate(ang,[1,0,0]) rotate(120,[0,0,1]) rotate([0,0,angle_2]) translate([bend_radius + outer_radius, -43, 0]) rotate([-90,90,0]) translate([0,50,60]) rotate(90,[1,0,0]) wheel_disc_raw(); } module wheels_from_partE_pair(){ // right translate([outer_radius , -chairwheeldistance, -chair_height - outer_radius]) rotate(90,[1,0,0]) wheel_from_partE_local(); // left (mirrored; same chain as the assembly of Part E) mirror([1,0,0]) translate([-chair_width + outer_radius , -chairwheeldistance, -chair_height - outer_radius]) rotate(90,[1,0,0]) wheel_from_partE_local(); } /* ---------- Simulated frame ---------- */ module wheelchair(){ union(){ // side rails translate([ chair_width, 0 ,0]) rotate(90,[1,0,0]) cylinder(r=inner_radius, h=chair_length); translate([ 0, 0 ,0]) rotate(90,[1,0,0]) cylinder(r=inner_radius, h=chair_length); // front crossbar rotate(90,[0,1,0]) cylinder(r=inner_radius, h=chair_width); // rear uprights (angled) rotate(ang,[1,0,0]) translate([ 0, -chairwheeldistance , -chair_height]) cylinder(r=inner_radius, h=chair_height); mirror([1,0,0]) rotate(ang,[1,0,0]) translate([ -chair_width, -chairwheeldistance , -chair_height]) cylinder(r=inner_radius, h=chair_height); // extra support bar (if enabled) if(bar){ rotate(90,[0,1,0]) translate([ chair_height, -chairwheeldistance , 0]) cylinder(r=inner_radius, h=chair_width); } } // wheels aligned to Part E axle wheels_from_partE_pair(); } /* ---------- Print orientations (used by all_parts) ---------- */ module orient_A(){ rotate(-90,[1,0,0]) translate([-80,-30,25]) rotate(120,[0,0,1]) partA(); } module orient_A_m(){ rotate(-90,[1,0,0]) translate([-80,-30,25]) rotate(120,[0,0,1]) mirror([1,0,0]) partA(); } module orient_B(){ translate([-90,-20,13]) rotate(180,[1,0,0]) partB(); } module orient_B2(){ translate([-90,-20,13]) rotate(180,[1,0,0]) partB2(); } module orient_C(){ translate([-40,10,-3]) rotate(90,[1,0,0]) partC(); } module orient_C_m(){ translate([-40,10,-3]) rotate(90,[1,0,0]) mirror([1,0,0]) partC(); } module orient_D(){ translate([30,-35,-3]) rotate(90,[1,0,0]) partD(); } module orient_D_m(){ translate([30,-35,-3]) rotate(90,[1,0,0]) mirror([1,0,0]) partD(); } module orient_E(){ translate([-10,-35,29]) rotate(90,[0,0,1]) rotate(-90,[0,1,0]) partE(); } module orient_E_m(){ translate([-10,-35,29]) rotate(90,[0,0,1]) rotate(-90,[0,1,0]) mirror([1,0,0]) partE(); } /* ---------- RENDER (selector) ---------- */ print_part(); module print_part(){ if (part == "wheelchair_sim"){ union(){ // part A + mirror translate([outer_radius,-outer_radius,0]) rotate(120,[0,0,1]) partA(); mirror([1,0,0]) translate([outer_radius - chair_width,-outer_radius,0]) rotate(120,[0,0,1]) partA(); // part B + mirror translate([0, -chairwheeldistance - outer_radius , -outer_radius]) rotate(90,[0,1,0]) partB(); mirror([1,0,0]) translate([ -chair_width, -chairwheeldistance - outer_radius , -outer_radius]) rotate(90,[0,1,0]) partB(); // part C + mirror translate([outer_radius , -chairwheeldistance - 80 , 0]) rotate(90,[0,0,1]) partC(); mirror([1,0,0]) translate([-chair_width + outer_radius , -chairwheeldistance - 80 , 0]) rotate(90,[0,0,1]) partC(); // part D + mirror translate([outer_radius , -chair_length , 0]) rotate(90,[0,0,1]) partD(); mirror([1,0,0]) translate([-chair_width + outer_radius , -chair_length , 0]) rotate(90,[0,0,1]) partD(); // part E + mirror translate([outer_radius , -chairwheeldistance , -chair_height - outer_radius]) rotate(90,[1,0,0]) partE(); mirror([1,0,0]) translate([ -chair_width + outer_radius , -chairwheeldistance , -chair_height - outer_radius]) rotate(90,[1,0,0]) partE(); // simulated frame color(col_frame) wheelchair(); } } else if (part == "part_a"){ orient_A(); } else if (part == "part_b"){ orient_B(); } else if (part == "part_b2"){ orient_B2(); } else if (part == "part_c"){ orient_C(); } else if (part == "part_d"){ orient_D(); } else if (part == "part_e"){ orient_E(); } else if (part == "all_parts"){ union(){ // row 1 translate([0, 0,0]) orient_A(); translate([grid_dx, 0,0]) orient_A_m(); // row 2 translate([0, -grid_dy,0]) orient_B(); translate([grid_dx, -grid_dy,0]) orient_B2(); // row 3 translate([0, -2*grid_dy,0]) orient_C(); translate([grid_dx, -2*grid_dy,0]) orient_C_m(); // row 4 translate([0, -3*grid_dy,0]) orient_D(); translate([grid_dx, -3*grid_dy,0]) orient_D_m(); // row 5 translate([0, -4*grid_dy,0]) orient_E(); translate([grid_dx, -4*grid_dy,0]) orient_E_m(); } } }
Editor is loading...
Leave a Comment