Skip to content

feat: support crosshair base for single magnet #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions gridfinity-rebuilt-baseplate.scad
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,15 @@ fity = 0; // [-1:0.1:1]
/* [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]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that screw together should be a separate feature, also because I would like to use S-04-02 magnets instead of screws :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, as screw together can be combined with multiple style plates.



// hole styles
style_hole = 2; // [0:none, 1:countersink, 2:counterbore]

// spoke width of crosshair
spoke_width = 3; // [2:1:24]

/* [Magnet Hole] */
// Baseplate will have holes for 6mm Diameter x 2mm high magnets.
enable_magnet = true;
Expand All @@ -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);


// ===== IMPLEMENTATION ===== //

color("tomato")
gridfinityBaseplate(gridx, gridy, l_grid, distancex, distancey, style_plate, hole_options, style_hole, fitx, fity);


// ===== CONSTRUCTION ===== //

module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, hole_options, sh, fitx, fity) {
Expand Down Expand Up @@ -109,9 +112,12 @@ module gridfinityBaseplate(gridx, gridy, length, dix, diy, sp, hole_options, sh,
else if (sp == 4)
translate([0,0,-5*(h_base+off)])
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();


hole_pattern(){
single_hole=sp==5||sp==6;
hole_pattern(l=l_grid, single_hole){
mirror([0, 0, 1])
block_base_hole(hole_options);

Expand All @@ -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);
}

}

function calculate_offset(style_plate, enable_magnet, style_hole) =
assert(style_plate >=0 && style_plate <=4)
let (screw_together = style_plate == 3 || style_plate == 4)
assert(style_plate >= 0 && style_plate <= 6)
let (screw_together = style_plate == 3 || style_plate == 4 || style_plate == 6)
screw_together ? 6.75 :
style_plate==0 ? 0 :
style_plate==1 ? bp_h_bot :
Expand Down Expand Up @@ -157,13 +162,6 @@ module cutter_weight() {
}
}
}
module hole_pattern(){
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made hole_pattern a utilility so it's moved to the utiliy.scad. The hole-pattern util is also used by bins

pattern_circular(4)
translate([l_grid/2-d_hole_from_side, l_grid/2-d_hole_from_side, 0]) {
render();
children();
}
}

module cutter_countersink(){
screw_hole(SCREW_HOLE_RADIUS + d_clear, 2*h_base,
Expand Down Expand Up @@ -192,12 +190,33 @@ module profile_skeleton() {
minkowski() {
square([l,l]);
circle(MAGNET_HOLE_RADIUS+r_skel+2);
}
}
}
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) {

screw(gx, gy);
Expand Down
4 changes: 3 additions & 1 deletion gridfinity-rebuilt-bins.scad
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ scoop = 1; //[0:0.1:1]
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)
div_base_y = 0;
// Base will have a single hole in the center (use with crosshair style base)
single_hole = false;

/* [Base Hole Options] */
// only cut magnet/screw holes at the corners of the bin to save uneccesary print time
Expand Down Expand Up @@ -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);
}
}
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);
}


Expand Down
52 changes: 35 additions & 17 deletions gridfinity-rebuilt-utility.scad
Original file line number Diff line number Diff line change
Expand Up @@ -210,33 +210,35 @@ 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];
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));
dbny = 1/(dy==0 ? len(dbnyt) > 0 ? dbnyt[0] : 1 : round(dy));
xx = gx*l-0.5;
yy = gy*l-0.5;

if (final_cut)
translate([0,0,h_base])
rounded_rectangle(xx+0.002, yy+0.002, h_bot/1.5, r_fo1+0.001);
if (final_cut) {
translate([0,0,h_base])
rounded_rectangle(xx+0.002, yy+0.002, h_bot/1.5, r_fo1+0.001);
}

intersection(){
if (final_cut)
translate([0,0,-1])
rounded_rectangle(xx+0.005, yy+0.005, h_base+h_bot/2*10, r_fo1+0.001);
if (final_cut) {
translate([0,0,-1])
rounded_rectangle(xx+0.005, yy+0.005, h_base+h_bot/2*10, r_fo1+0.001);
}

if(only_corners) {
difference(){
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([1, 0, 0]) {
translate([
(gx/2)*l_grid - d_hole_from_side,
(gy/2) * l_grid - d_hole_from_side,
(gx/2)*l_grid - (single_hole ? l_grid/2 : d_hole_from_side),
(gy/2)*l_grid - (single_hole ? l_grid/2 : d_hole_from_side),
0
])
block_base_hole(hole_options, off);
Expand All @@ -246,13 +248,29 @@ module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off
}
else {
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 gy
* @param l
Expand All @@ -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 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)
difference() {
block_base_solid(dbnx, dbny, l, off);

pattern_circular(abs(l-d_hole_from_side/2)<0.001?1:4)
translate([l/2-d_hole_from_side, l/2-d_hole_from_side, 0])
block_base_hole(hole_options, off);
hole_pattern(l, single_hole=single_hole) {
block_base_hole(hole_options, off);
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions tests/test_baseplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ def test_magnet_and_counterbored_screw_holes(self):
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'))

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__':
unittest.main()