diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 023de2c..b69698e 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -39,7 +39,7 @@ jobs:
just paths
- name: Generate site
- uses: yawkat/web-openscad-editor@35cd9bbb2bdec1fe98462d853833ea4c3058f89f # main
+ uses: yawkat/web-openscad-editor@323ca329f12ea210428ed6407f57f870fba548b7 # main
with:
config: editor.toml
output: out
diff --git a/LICENSE b/LICENSE
index 0865ffd..e04f7ab 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,7 @@
This repository is dual-licensed under MIT and CC-BY 4.0.
+Some models in opengrid/ are licenes under CC-BY 4.0 by https://www.printables.com/@DavidD and https://www.printables.com/@mitufy .
+
CC-BY 4.0: https://creativecommons.org/licenses/by/4.0/
MIT License
diff --git a/README.md b/README.md
index 3d5274a..950b19a 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,10 @@ For inserting magnets, check out [the jig](#jig).
- [Top plate wall](#top-plate-wall)
- [Bottom plate wall](#bottom-plate-wall)
- [Variable wall height](#variable-wall-height)
+ - [openGrid Adapter](#opengrid-adapter)
+ - [Adapter types](#adapter-types)
+ - [Standard openGrid](#standard-opengrid)
+ - [openConnect](#openconnect)
- [Vertical Screws](#vertical-screws)
- [Screw dimensions](#screw-dimensions)
- [Screw locations](#screw-locations)
@@ -564,6 +568,67 @@ The top and bottom wall height can also be adjusted individually for each corner
> [!NOTE]
> Variable height does not currently render correctly with segmented baseplates.
+## openGrid Adapter
+
+**[Customizer with recommended openConnect layout](https://gridflock.yawk.at/#eyJwbGF0ZV9zaXplIjpbNDIsNDJdLCJwbGF0ZV93YWxsX3RoaWNrbmVzcyI6WzAsMSw0LDFdLCJwbGF0ZV93YWxsX2Fib3ZlIjpbMTQsMCwwLDE0XSwiYWRhcHRlcl9ub3J0aCI6dHJ1ZSwiYWRhcHRlcl9lYXN0Ijp0cnVlLCJhZGFwdGVyX3NvdXRoIjp0cnVlLCJhZGFwdGVyX3dlc3QiOnRydWV9)**
+
+You can use GridFlock to generate Gridfinity "shelves" that can be attached to an [openGrid](https://www.opengrid.world/) system. Configure a plate wall of sufficient height, and then enable `adapter_north`, `adapter_east`, `adapter_west`, or `adapter_south`. For example, the following shelf has been generated with `plate_wall_thickness=[0,1,1,1]` (1mm wall everywhere except north) and `plate_wall_above=[20,0,0,20]` (20mm wall at south-east and south-west corners):
+
+
+
+
+Note that openConnect is preferred over directly printing openGrid snaps, see below.
+
+The wall will automatically be filled with as many adapters as possible:
+
+
+
+
+> [!NOTE]
+> Adapters do not render correctly with segmented baseplates.
+
+### Adapter types
+
+GridFlock offers various adapter variants.
+
+#### Standard openGrid
+
+You can print the standard openGrid connector directly onto the wall. Normal and lite, directional and non-directional variants are available. There is also a "vertical" variant of each which cuts a 45° angle from the bottom of each connector which makes printing without supports possible, but reduces strength.
+
+> [!NOTE]
+> The printability vs strength tradeoff is substantial with this adapter. The vertical variants don't stay in place nearly as well, but the non-vertical type is very difficult to print. The openConnect system described below is the preferred option for connecting to openGrid.
+
+The standard connector works with standard openGrid plates, but not lite plates:
+
+
+
+
+The lite connector works with all openGrid plates, but has reduced strength:
+
+
+
+
+The directional connector has increased strength:
+
+
+
+
+The vertical variants make the connector actually printable:
+
+
+
+
+#### openConnect
+
+[openConnect](https://www.printables.com/model/1559478-openconnect-opengrids-own-connector-system) is a system that adds a separately printed connector in between GridFlock and openGrid. This makes vertical printing a breeze without compromising attachment strength.
+
+Since the GridFlock side of the connector is recessed, this requires a thicker wall of ~4mm, but vertical height can be lower.
+
+
+
+
+There is also a "lock" variant that increases the connection strength to the openConnect interconnect. This connection is so strong that you may need a hammer to install the interconnect. This is my preferred option.
+
## Vertical Screws
Vertical screws are inserted at cell intersections. They can be used to screw down the plate. Screws can be placed at various positions depending on use case.
diff --git a/docs/images/adapter-multi.png b/docs/images/adapter-multi.png
new file mode 100644
index 0000000..de16056
Binary files /dev/null and b/docs/images/adapter-multi.png differ
diff --git a/docs/images/adapter-simple.png b/docs/images/adapter-simple.png
new file mode 100644
index 0000000..127aafe
Binary files /dev/null and b/docs/images/adapter-simple.png differ
diff --git a/docs/images/openconnect-standard.png b/docs/images/openconnect-standard.png
new file mode 100644
index 0000000..b0e8e05
Binary files /dev/null and b/docs/images/openconnect-standard.png differ
diff --git a/docs/images/opengrid-directional.png b/docs/images/opengrid-directional.png
new file mode 100644
index 0000000..de38ed9
Binary files /dev/null and b/docs/images/opengrid-directional.png differ
diff --git a/docs/images/opengrid-lite.png b/docs/images/opengrid-lite.png
new file mode 100644
index 0000000..7a31144
Binary files /dev/null and b/docs/images/opengrid-lite.png differ
diff --git a/docs/images/opengrid-standard.png b/docs/images/opengrid-standard.png
new file mode 100644
index 0000000..7b6ca4b
Binary files /dev/null and b/docs/images/opengrid-standard.png differ
diff --git a/docs/images/opengrid-vertical.png b/docs/images/opengrid-vertical.png
new file mode 100644
index 0000000..4ce532f
Binary files /dev/null and b/docs/images/opengrid-vertical.png differ
diff --git a/editor.toml b/editor.toml
index eafe9f0..781855b 100644
--- a/editor.toml
+++ b/editor.toml
@@ -17,7 +17,7 @@ description-extra-html = """
You have enabled both the edge and intersection puzzle connectors. While technically possible, it is better to focus on and tune one connector type.
"""
umami-track-render = []
-umami-track-export = ["magnets", "magnet_style", "connector_intersection_puzzle", "connector_edge_puzzle", "bed_size", "click", "click_style", "filler_x", "filler_y", "stacked_print"]
+umami-track-export = ["magnets", "magnet_style", "connector_intersection_puzzle", "connector_edge_puzzle", "bed_size", "click", "click_style", "filler_x", "filler_y", "stacked_print", "adapter_mode"]
[model.param-metadata.bed_size.presets]
text = "Printer Presets"
@@ -153,6 +153,21 @@ help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#plate-wall"
[model.param-metadata.plate_wall_height]
help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#plate-wall"
+[model.tab-metadata.openGrid]
+help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#opengrid-adapter"
+collapsed = true
+[model.param-metadata.adapter_north]
+help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#opengrid-adapter"
+[model.param-metadata.adapter_east]
+help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#opengrid-adapter"
+[model.param-metadata.adapter_south]
+help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#opengrid-adapter"
+[model.param-metadata.adapter_west]
+help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#opengrid-adapter"
+[model.param-metadata.adapter_mode]
+help-link = "https://github.com/yawkat/GridFlock/blob/main/README.md#adapter-types"
+display-condition = {js = "adapter_north || adapter_east || adapter_south || adapter_west"}
+
[model.tab-metadata."Vertical Screws"]
collapsed = true
[model.param-metadata.vertical_screw_diameter]
diff --git a/gridflock.scad b/gridflock.scad
index b9a406b..44ceaae 100644
--- a/gridflock.scad
+++ b/gridflock.scad
@@ -134,6 +134,19 @@ plate_wall_above = [0, 0, 0, 0];
// Variable wall height, below the plate. Specified for each corner individually. Corners are SW, NW, NE, SE.
plate_wall_below = [0, 0, 0, 0];
+/* [openGrid] */
+
+// Generate openGrid adapters on the north wall. Requires a plate wall of sufficient height/thickness on that side
+adapter_north = false;
+// Generate openGrid adapters on the east wall. Requires a plate wall of sufficient height/thickness on that side
+adapter_east = false;
+// Generate openGrid adapters on the south wall. Requires a plate wall of sufficient height/thickness on that side
+adapter_south = false;
+// Generate openGrid adapters on the west wall. Requires a plate wall of sufficient height/thickness on that side
+adapter_west = false;
+// Style of the openGrid adapter. The plain openGrid connectors can be printed directly, in normal or 'lite' strength, and in a directional or non-directional variant. The 'vertical' variants of each cut a 45° angle to allow printing without supports, at the cost of reduced strength. The openConnect variants instead cut a slot for a separately printed openConnect connector, which is the recommended option
+adapter_mode = 11; // [0:openGrid, 1:openGrid/lite, 2:openGrid/directional, 3:openGrid/lite/directional, 4:openGrid/vertical, 5:openGrid/lite/vertical, 6:openGrid/directional/vertical, 7:openGrid/lite/directional/vertical, 10:openConnect Slot, 11:openConnect Slot w/ Lock]
+
/* [Vertical Screws] */
// Radius of vertical screws
@@ -243,6 +256,14 @@ assert(!magnets || magnet_frame_style != _MAGNET_SOLID || magnet_style != _MAGNE
assert(!thumbscrews || solid_base > 0 || (magnets && magnet_frame_style == _MAGNET_SOLID), "Thumbscrew holes require some sort of solid base, such as magnet_style solid, or an explicit solid_base.");
+_OPENGRID_LITE = 1;
+_OPENGRID_DIRECTIONAL = 2;
+_OPENGRID_VERTICAL = 4;
+_OPENGRID_MAX = 7;
+
+_ADAPTER_SLOT_OPENCONNECT = 10;
+_ADAPTER_SLOT_OPENCONNECT_LOCK = 11;
+
$fn=40;
// dimensions of the magnet extraction slot
@@ -951,6 +972,53 @@ module chamfer_triangle() {
polygon([[-extend, -extend], [1 + extend, -extend], [-extend, 1 + extend]]);
}
+module adapter_side(side, size) {
+ min_below = min(plate_wall_below[(side+1)%4], plate_wall_below[(side+2)%4]);
+ min_above = min(plate_wall_above[(side+1)%4], plate_wall_above[(side+2)%4]);
+ height_side = _total_height + plate_wall_height[0] + plate_wall_height[1] + min_below + min_above;
+ area = [
+ size[side == _WEST || side == _EAST ? 1 : 0] - plate_corner_radius*2,
+ height_side
+ ];
+ connector_size =
+ adapter_mode <= _OPENGRID_MAX ? [24.6, 24.6] :
+ adapter_mode == _ADAPTER_SLOT_OPENCONNECT || adapter_mode == _ADAPTER_SLOT_OPENCONNECT_LOCK ? [26, 18] :
+ assert(false);
+ count = [for (i = [0,1]) floor((area[i] + 28 - connector_size[i]) / 28)];
+ for (xi = [0:count.x-1], yi = [0:count.y-1]) translate([(-count.x/2+xi+0.5)*28, size[side == _WEST || side == _EAST ? 0 : 1]/2, (-count.y/2+yi+0.5)*28 - _extra_height - plate_wall_height[1] - min_below + height_side / 2]) {
+ if (adapter_mode <= _OPENGRID_MAX) {
+ depth = (adapter_mode & _OPENGRID_LITE) == 0 ? 6.8 : 3.4;
+ translate([0, depth, 0]) rotate([90, 0, 0]) {
+ difference() {
+ if ((adapter_mode & _OPENGRID_DIRECTIONAL) == 0) {
+ if ((adapter_mode & _OPENGRID_LITE) == 0) import("opengrid/opengrid-bare-snap.3mf");
+ else import("opengrid/opengrid-bare-lite-snap.3mf");
+ } else {
+ if ((adapter_mode & _OPENGRID_LITE) == 0) import("opengrid/opengrid-bare-directional-snap-v21.3mf");
+ else import("opengrid/opengrid-bare-directional-lite-snap-v2.3mf");
+ }
+ if ((adapter_mode & _OPENGRID_VERTICAL) != 0) translate([0, -12.3, 0]) rotate([0, -90, 0]) linear_extrude(h=28, center=true) polygon([[0, -depth], [depth, -depth], [depth, 0], [0, depth]]);
+ }
+ }
+ } else if (adapter_mode == _ADAPTER_SLOT_OPENCONNECT || adapter_mode == _ADAPTER_SLOT_OPENCONNECT_LOCK) {
+ rotate([90, 0, 180]) translate([0, 0, -2.7]) {
+ if (adapter_mode == _ADAPTER_SLOT_OPENCONNECT) import("opengrid/openconnect_slot_negative.3mf");
+ else import("opengrid/openconnect_slot_negative_lock.3mf");
+ }
+ }
+ }
+}
+
+module adapter(size, connector, negative) {
+ mode_negative = adapter_mode == _ADAPTER_SLOT_OPENCONNECT || adapter_mode == _ADAPTER_SLOT_OPENCONNECT_LOCK;
+ if (negative == mode_negative) {
+ if (adapter_north && !connector[_NORTH]) adapter_side(_NORTH, size);
+ if (adapter_east && !connector[_EAST]) rotate([0,0,-90]) adapter_side(_EAST, size);
+ if (adapter_south && !connector[_SOUTH]) rotate([0,0,180]) adapter_side(_SOUTH, size);
+ if (adapter_west && !connector[_WEST]) rotate([0,0,90]) adapter_side(_WEST, size);
+ }
+}
+
function compute_segment_size(trace, padding) = [
BASEPLATE_DIMENSIONS.x * cumulate(trace.x)[len(trace.x)] + padding[_EAST] + padding[_WEST],
BASEPLATE_DIMENSIONS.y * cumulate(trace.y)[len(trace.y)] + padding[_NORTH] + padding[_SOUTH],
@@ -1085,6 +1153,8 @@ module segment(trace=[[1], [1]], padding=[0, 0, 0, 0], connector=[false, false,
}
}
}
+
+ adapter(size, connector, negative=false);
if (connector_intersection_puzzle) translate([0, 0, -_extra_height]) linear_extrude(height = _total_height) segment_intersection_connectors(true, trace, size, padding, connector);
if (connector_edge_puzzle) {
@@ -1103,6 +1173,8 @@ module segment(trace=[[1], [1]], padding=[0, 0, 0, 0], connector=[false, false,
}
}
}
+ adapter(size, connector, negative=true);
+
if (connector_edge_puzzle) {
translate([0, 0, -_extra_height]) linear_extrude(height = _extra_height+edge_puzzle_height_female) segment_edge_connectors(false, trace, size, padding, connector);
}
diff --git a/opengrid/openconnect_slot_negative.3mf b/opengrid/openconnect_slot_negative.3mf
new file mode 100644
index 0000000..cd05963
Binary files /dev/null and b/opengrid/openconnect_slot_negative.3mf differ
diff --git a/opengrid/openconnect_slot_negative_lock.3mf b/opengrid/openconnect_slot_negative_lock.3mf
new file mode 100644
index 0000000..f4d0968
Binary files /dev/null and b/opengrid/openconnect_slot_negative_lock.3mf differ
diff --git a/opengrid/opengrid-bare-directional-lite-snap-v2.3mf b/opengrid/opengrid-bare-directional-lite-snap-v2.3mf
new file mode 100644
index 0000000..ab7adc8
Binary files /dev/null and b/opengrid/opengrid-bare-directional-lite-snap-v2.3mf differ
diff --git a/opengrid/opengrid-bare-directional-snap-v21.3mf b/opengrid/opengrid-bare-directional-snap-v21.3mf
new file mode 100644
index 0000000..76fce66
Binary files /dev/null and b/opengrid/opengrid-bare-directional-snap-v21.3mf differ
diff --git a/opengrid/opengrid-bare-lite-snap.3mf b/opengrid/opengrid-bare-lite-snap.3mf
new file mode 100644
index 0000000..080424d
Binary files /dev/null and b/opengrid/opengrid-bare-lite-snap.3mf differ
diff --git a/opengrid/opengrid-bare-snap.3mf b/opengrid/opengrid-bare-snap.3mf
new file mode 100644
index 0000000..decf8c3
Binary files /dev/null and b/opengrid/opengrid-bare-snap.3mf differ