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] */
|
||||
|
||||
// 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
|
||||
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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 :
|
||||
|
@ -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(){
|
||||
screw_hole(SCREW_HOLE_RADIUS + d_clear, 2*h_base,
|
||||
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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];
|
||||
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));
|
||||
|
@ -218,25 +218,27 @@ module gridfinityBase(gx, gy, l, dx, dy, hole_options=bundle_hole_options(), off
|
|||
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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.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()
|
||||
|
|
Loading…
Reference in a new issue