mirror of
https://github.com/kennetek/gridfinity-rebuilt-openscad.git
synced 2024-11-29 11:33:56 +00:00
feat: support crosshair base for single magnet
This commit is contained in:
parent
3f2c6e28c5
commit
f8a623d6b4
4 changed files with 83 additions and 34 deletions
|
@ -48,12 +48,15 @@ fity = 0; // [-1:0.1:1]
|
||||||
/* [Styles] */
|
/* [Styles] */
|
||||||
|
|
||||||
// baseplate styles
|
// baseplate styles
|
||||||
style_plate = 0; // [0: thin, 1:weighted, 2:skeletonized, 3: screw together, 4: screw together minimal]
|
style_plate = 0; // [0: thin, 1:weighted, 2:skeletonized, 3: screw together, 4: screw together minimal, 5:crosshair, 6:screw together crosshair]
|
||||||
|
|
||||||
|
|
||||||
// hole styles
|
// hole styles
|
||||||
style_hole = 2; // [0:none, 1:countersink, 2:counterbore]
|
style_hole = 2; // [0:none, 1:countersink, 2:counterbore]
|
||||||
|
|
||||||
|
// spoke width of crosshair
|
||||||
|
spoke_width = 3; // [2:1:24]
|
||||||
|
|
||||||
/* [Magnet Hole] */
|
/* [Magnet Hole] */
|
||||||
// Baseplate will have holes for 6mm Diameter x 2mm high magnets.
|
// Baseplate will have holes for 6mm Diameter x 2mm high magnets.
|
||||||
enable_magnet = true;
|
enable_magnet = true;
|
||||||
|
@ -64,12 +67,12 @@ chamfer_holes = true;
|
||||||
|
|
||||||
hole_options = bundle_hole_options(refined_hole=false, magnet_hole=enable_magnet, screw_hole=false, crush_ribs=crush_ribs, chamfer=chamfer_holes, supportless=false);
|
hole_options = bundle_hole_options(refined_hole=false, magnet_hole=enable_magnet, screw_hole=false, crush_ribs=crush_ribs, chamfer=chamfer_holes, supportless=false);
|
||||||
|
|
||||||
|
|
||||||
// ===== IMPLEMENTATION ===== //
|
// ===== IMPLEMENTATION ===== //
|
||||||
|
|
||||||
color("tomato")
|
color("tomato")
|
||||||
gridfinityBaseplate(gridx, gridy, l_grid, distancex, distancey, style_plate, hole_options, style_hole, fitx, fity);
|
gridfinityBaseplate(gridx, gridy, l_grid, distancex, distancey, style_plate, hole_options, style_hole, fitx, fity);
|
||||||
|
|
||||||
|
|
||||||
// ===== CONSTRUCTION ===== //
|
// ===== CONSTRUCTION ===== //
|
||||||
|
|
||||||
module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, hole_options, sh, fitx, fity) {
|
module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, hole_options, sh, fitx, fity) {
|
||||||
|
@ -109,9 +112,12 @@ module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, hole_options, sh,
|
||||||
else if (sp == 4)
|
else if (sp == 4)
|
||||||
translate([0,0,-5*(h_base+off)])
|
translate([0,0,-5*(h_base+off)])
|
||||||
rounded_square(length-2*r_c2-2*r_c1, 10*(h_base+off), r_fo3);
|
rounded_square(length-2*r_c2-2*r_c1, 10*(h_base+off), r_fo3);
|
||||||
|
else if (sp == 5 || sp == 6)
|
||||||
|
linear_extrude(10*(h_base+off), center = true)
|
||||||
|
profile_crosshair();
|
||||||
|
|
||||||
|
single_hole=sp==5||sp==6;
|
||||||
hole_pattern(){
|
hole_pattern(l=l_grid, single_hole){
|
||||||
mirror([0, 0, 1])
|
mirror([0, 0, 1])
|
||||||
block_base_hole(hole_options);
|
block_base_hole(hole_options);
|
||||||
|
|
||||||
|
@ -121,15 +127,14 @@ module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, hole_options, sh,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
screw_together = sp == 3 || sp == 4;
|
screw_together = sp == 3 || sp == 4 || sp == 6;
|
||||||
if (screw_together) cutter_screw_together(gx, gy, off);
|
if (screw_together) cutter_screw_together(gx, gy, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculate_offset(style_plate, enable_magnet, style_hole) =
|
function calculate_offset(style_plate, enable_magnet, style_hole) =
|
||||||
assert(style_plate >=0 && style_plate <=4)
|
assert(style_plate >= 0 && style_plate <= 6)
|
||||||
let (screw_together = style_plate == 3 || style_plate == 4)
|
let (screw_together = style_plate == 3 || style_plate == 4 || style_plate == 6)
|
||||||
screw_together ? 6.75 :
|
screw_together ? 6.75 :
|
||||||
style_plate==0 ? 0 :
|
style_plate==0 ? 0 :
|
||||||
style_plate==1 ? bp_h_bot :
|
style_plate==1 ? bp_h_bot :
|
||||||
|
@ -157,13 +162,6 @@ module cutter_weight() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module hole_pattern(){
|
|
||||||
pattern_circular(4)
|
|
||||||
translate([l_grid/2-d_hole_from_side, l_grid/2-d_hole_from_side, 0]) {
|
|
||||||
render();
|
|
||||||
children();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module cutter_countersink(){
|
module cutter_countersink(){
|
||||||
screw_hole(SCREW_HOLE_RADIUS + d_clear, 2*h_base,
|
screw_hole(SCREW_HOLE_RADIUS + d_clear, 2*h_base,
|
||||||
|
@ -192,12 +190,33 @@ module profile_skeleton() {
|
||||||
minkowski() {
|
minkowski() {
|
||||||
square([l,l]);
|
square([l,l]);
|
||||||
circle(MAGNET_HOLE_RADIUS+r_skel+2);
|
circle(MAGNET_HOLE_RADIUS+r_skel+2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
circle(r_skel);
|
circle(r_skel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module profile_crosshair() {
|
||||||
|
l_grid_inner = l_grid - 2*r_c2 - 2*r_c1; // l without chamfers
|
||||||
|
l_grid_inner_minkowski = l_grid_inner / 2 - r_f1;
|
||||||
|
|
||||||
|
// sqrt 2 because of 45 degree angle
|
||||||
|
spoke_offset=sqrt(2)*spoke_width/2;
|
||||||
|
|
||||||
|
pattern_circular(4)
|
||||||
|
difference() {
|
||||||
|
minkowski() {
|
||||||
|
polygon([
|
||||||
|
[spoke_offset, 0],
|
||||||
|
[l_grid_inner_minkowski, l_grid_inner_minkowski - spoke_offset],
|
||||||
|
[l_grid_inner_minkowski, -l_grid_inner_minkowski + spoke_offset],
|
||||||
|
]);
|
||||||
|
circle(r_f1);
|
||||||
|
}
|
||||||
|
circle(MAGNET_HOLE_RADIUS+r_skel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module cutter_screw_together(gx, gy, off) {
|
module cutter_screw_together(gx, gy, off) {
|
||||||
|
|
||||||
screw(gx, gy);
|
screw(gx, gy);
|
||||||
|
|
|
@ -78,6 +78,8 @@ scoop = 1; //[0:0.1:1]
|
||||||
div_base_x = 0;
|
div_base_x = 0;
|
||||||
// number of divisions per 1 unit of base along the Y axis. (default 1, only use integers. 0 means automatically guess the right division)
|
// number of divisions per 1 unit of base along the Y axis. (default 1, only use integers. 0 means automatically guess the right division)
|
||||||
div_base_y = 0;
|
div_base_y = 0;
|
||||||
|
// Base will have a single hole in the center (use with crosshair style base)
|
||||||
|
single_hole = false;
|
||||||
|
|
||||||
/* [Base Hole Options] */
|
/* [Base Hole Options] */
|
||||||
// only cut magnet/screw holes at the corners of the bin to save uneccesary print time
|
// only cut magnet/screw holes at the corners of the bin to save uneccesary print time
|
||||||
|
@ -111,7 +113,7 @@ gridfinityInit(gridx, gridy, height(gridz, gridz_define, style_lip, enable_zsnap
|
||||||
cutCylinders(n_divx=cdivx, n_divy=cdivy, cylinder_diameter=cd, cylinder_height=ch, coutout_depth=c_depth, orientation=c_orientation, chamfer=c_chamfer);
|
cutCylinders(n_divx=cdivx, n_divy=cdivy, cylinder_diameter=cd, cylinder_height=ch, coutout_depth=c_depth, orientation=c_orientation, chamfer=c_chamfer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gridfinityBase(gridx, gridy, l_grid, div_base_x, div_base_y, hole_options, only_corners=only_corners);
|
gridfinityBase(gridx, gridy, l_grid, div_base_x, div_base_y, hole_options, only_corners=only_corners, single_hole=single_hole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ module profile_base() {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off=0, final_cut=true, only_corners=false) {
|
module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off=0, final_cut=true, only_corners=false, single_hole=false) {
|
||||||
dbnxt = [for (i=[1:5]) if (abs(gx*i)%1 < 0.001 || abs(gx*i)%1 > 0.999) i];
|
dbnxt = [for (i=[1:5]) if (abs(gx*i)%1 < 0.001 || abs(gx*i)%1 > 0.999) i];
|
||||||
dbnyt = [for (i=[1:5]) if (abs(gy*i)%1 < 0.001 || abs(gy*i)%1 > 0.999) i];
|
dbnyt = [for (i=[1:5]) if (abs(gy*i)%1 < 0.001 || abs(gy*i)%1 > 0.999) i];
|
||||||
dbnx = 1/(dx==0 ? len(dbnxt) > 0 ? dbnxt[0] : 1 : round(dx));
|
dbnx = 1/(dx==0 ? len(dbnxt) > 0 ? dbnxt[0] : 1 : round(dx));
|
||||||
|
@ -218,25 +218,27 @@ module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off
|
||||||
xx = gx*l-0.5;
|
xx = gx*l-0.5;
|
||||||
yy = gy*l-0.5;
|
yy = gy*l-0.5;
|
||||||
|
|
||||||
if (final_cut)
|
if (final_cut) {
|
||||||
translate([0,0,h_base])
|
translate([0,0,h_base])
|
||||||
rounded_rectangle(xx+0.002, yy+0.002, h_bot/1.5, r_fo1+0.001);
|
rounded_rectangle(xx+0.002, yy+0.002, h_bot/1.5, r_fo1+0.001);
|
||||||
|
}
|
||||||
|
|
||||||
intersection(){
|
intersection(){
|
||||||
if (final_cut)
|
if (final_cut) {
|
||||||
translate([0,0,-1])
|
translate([0,0,-1])
|
||||||
rounded_rectangle(xx+0.005, yy+0.005, h_base+h_bot/2*10, r_fo1+0.001);
|
rounded_rectangle(xx+0.005, yy+0.005, h_base+h_bot/2*10, r_fo1+0.001);
|
||||||
|
}
|
||||||
|
|
||||||
if(only_corners) {
|
if(only_corners) {
|
||||||
difference(){
|
difference(){
|
||||||
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
||||||
block_base(gx, gy, l, dbnx, dbny, 0, off);
|
block_base(gx, gy, l, dbnx, dbny, [], off);
|
||||||
|
|
||||||
copy_mirror([0, 1, 0]) {
|
copy_mirror([0, 1, 0]) {
|
||||||
copy_mirror([1, 0, 0]) {
|
copy_mirror([1, 0, 0]) {
|
||||||
translate([
|
translate([
|
||||||
(gx/2)*l_grid - d_hole_from_side,
|
(gx/2)*l_grid - (single_hole ? l_grid/2 : d_hole_from_side),
|
||||||
(gy/2) * l_grid - d_hole_from_side,
|
(gy/2)*l_grid - (single_hole ? l_grid/2 : d_hole_from_side),
|
||||||
0
|
0
|
||||||
])
|
])
|
||||||
block_base_hole(hole_options, off);
|
block_base_hole(hole_options, off);
|
||||||
|
@ -246,13 +248,29 @@ module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
pattern_linear(gx/dbnx, gy/dbny, dbnx*l, dbny*l)
|
||||||
block_base(gx, gy, l, dbnx, dbny, hole_options, off);
|
block_base(gx, gy, l, dbnx, dbny, hole_options, off, single_hole=single_hole);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A single Gridfinity base. With holes (if set).
|
* @brief Apply hole pattern to children
|
||||||
|
* @param l
|
||||||
|
* @param single_hole Use a single hole, default = false
|
||||||
|
*/
|
||||||
|
module hole_pattern(l, single_hole=false){
|
||||||
|
hole_offset = single_hole ? 0 : l/2 - d_hole_from_side;
|
||||||
|
steps= (single_hole || abs(l - d_hole_from_side/2) < 0.001) ? 1 : 4;
|
||||||
|
|
||||||
|
pattern_circular(steps)
|
||||||
|
translate([hole_offset, hole_offset, 0]) {
|
||||||
|
render();
|
||||||
|
children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A single Gridfinity base. With holes (if set).
|
||||||
* @param gx
|
* @param gx
|
||||||
* @param gy
|
* @param gy
|
||||||
* @param l
|
* @param l
|
||||||
|
@ -261,14 +279,14 @@ module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off
|
||||||
* @param hole_options @see block_base_hole.hole_options
|
* @param hole_options @see block_base_hole.hole_options
|
||||||
* @param off
|
* @param off
|
||||||
*/
|
*/
|
||||||
module block_base(gx, gy, l, dbnx, dbny, hole_options, off) {
|
module block_base(gx, gy, l, dbnx, dbny, hole_options, off, single_hole=false) {
|
||||||
render(convexity = 2)
|
render(convexity = 2)
|
||||||
difference() {
|
difference() {
|
||||||
block_base_solid(dbnx, dbny, l, off);
|
block_base_solid(dbnx, dbny, l, off);
|
||||||
|
|
||||||
pattern_circular(abs(l-d_hole_from_side/2)<0.001?1:4)
|
hole_pattern(l, single_hole=single_hole) {
|
||||||
translate([l/2-d_hole_from_side, l/2-d_hole_from_side, 0])
|
block_base_hole(hole_options, off);
|
||||||
block_base_hole(hole_options, off);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,16 @@ class TestBasePlateHoles(unittest.TestCase):
|
||||||
self.scad_runner.camera_arguments = self.scad_runner.camera_arguments.with_rotation(CameraRotations.AngledTop)
|
self.scad_runner.camera_arguments = self.scad_runner.camera_arguments.with_rotation(CameraRotations.AngledTop)
|
||||||
self.scad_runner.create_image([], Path('magnet_and_counterbored_screw_holes_top.png'))
|
self.scad_runner.create_image([], Path('magnet_and_counterbored_screw_holes_top.png'))
|
||||||
|
|
||||||
|
def test_crosshair_with_magnet(self):
|
||||||
|
vars = self.scad_runner.parameters
|
||||||
|
vars["enable_magnet"] = True
|
||||||
|
vars["chamfer_holes"] = False
|
||||||
|
vars["crush_ribs"] = False
|
||||||
|
vars["style_plate"] = 5
|
||||||
|
self.scad_runner.create_image([], Path('crosshair_with_magnet_bottom.png'))
|
||||||
|
self.scad_runner.camera_arguments = self.scad_runner.camera_arguments.with_rotation(CameraRotations.AngledTop)
|
||||||
|
self.scad_runner.create_image([], Path('crosshair_with_magnet_top.png'))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in a new issue