// Modules operating on edges use two arguments to describe the edge set they will use: The `edges` argument
// is a list of edge set descriptors to include in the edge set and the `except` argument is a list of
// edge set descriptors to remove from the edge set. If either argument is just a single edge set
// descriptor it can be passed directly rather than in a singleton list.
// Each edge set descriptor must be one of:
// - A vector pointing towards an edge, indicating that single edge.
// - A vector pointing towards a face, indicating all edges surrounding that face.
// - A vector pointing towards a corner, indicating all edges touching that corner.
// - The string `"X"`, indicating all X axis aligned edges.
// - The string `"Y"`, indicating all Y axis aligned edges.
// - The string `"Z"`, indicating all Z axis aligned edges.
// - The string `"ALL"`, indicating all edges.
// - The string `"NONE"`, indicating no edges at all.
// - A 3x4 array, where each entry corresponds to one of the 12 edges and is set to 1 if that edge is included and 0 if the edge is not. The edge ordering is:
// ```
// [
// [Y-Z-, Y+Z-, Y-Z+, Y+Z+],
// [X-Z-, X+Z-, X-Z+, X+Z+],
// [X-Y-, X+Y-, X-Y+, X+Y+]
// ]
// ```
// You can specify edge descriptors directly by giving a vector, or you can use sums of the
// named direction vectors described above. Below we show all of the edge sets you can
// describe with sums of the direction vectors.
// Figure(3D,Big): Vectors pointing toward an edge select that single edge
// ydistribute(50) {
// xdistribute(30) {
// _show_edges(edges=BOT+RIGHT);
// _show_edges(edges=BOT+BACK);
// _show_edges(edges=BOT+LEFT);
// _show_edges(edges=BOT+FRONT);
// }
// xdistribute(30) {
// _show_edges(edges=FWD+RIGHT);
// _show_edges(edges=BACK+RIGHT);
// _show_edges(edges=BACK+LEFT);
// _show_edges(edges=FWD+LEFT);
// }
// xdistribute(30) {
// _show_edges(edges=TOP+RIGHT);
// _show_edges(edges=TOP+BACK);
// _show_edges(edges=TOP+LEFT);
// _show_edges(edges=TOP+FRONT);
// }
// }
// Figure(3D,Med): Vectors pointing toward a face select all edges surrounding that face.
// ydistribute(50) {
// xdistribute(30) {
// _show_edges(edges=LEFT);
// _show_edges(edges=FRONT);
// _show_edges(edges=RIGHT);
// }
// xdistribute(30) {
// _show_edges(edges=TOP);
// _show_edges(edges=BACK);
// _show_edges(edges=BOTTOM);
// }
// }
// Figure(3D,Big): Vectors pointing toward a corner select all edges surrounding that corner.
// ydistribute(50) {
// xdistribute(30) {
// _show_edges(edges=FRONT+LEFT+TOP);
// _show_edges(edges=FRONT+RIGHT+TOP);
// _show_edges(edges=FRONT+LEFT+BOT);
// _show_edges(edges=FRONT+RIGHT+BOT);
// }
// xdistribute(30) {
// _show_edges(edges=TOP+LEFT+BACK);
// _show_edges(edges=TOP+RIGHT+BACK);
// _show_edges(edges=BOT+LEFT+BACK);
// _show_edges(edges=BOT+RIGHT+BACK);
// }
// }
// Figure(3D,Med): Named Edge Sets
// ydistribute(50) {
// xdistribute(30) {
// _show_edges(edges="X");
// _show_edges(edges="Y");
// _show_edges(edges="Z");
// }
// xdistribute(30) {
// _show_edges(edges="ALL");
// _show_edges(edges="NONE");
// }
// }
// Next are some examples showing how you can combine edge descriptors to obtain different edge sets.
// The default value for `edges` is `"ALL"`, the set of all edges. The default value for `except` is the
// empty set, meaning no edges are removed.
// Figure(3D,Big): You can specify the top front edge with a numerical vector or by combining the named direction vectors. If you combine them as a list you get all the edges around the front or top faces. Adding `except` removes an edge.
// Figure(3D,Big): Using `except=BACK` removes the four edges surrounding the back face if they are present in the edge set. In the first example only one edge needs to be removed. In the second example we remove two of the Z-aligned edges. The third example removes all four back edges from the default edge set of all edges. You can explicitly give `edges="ALL"` but it is not necessary, since this is the default. In the fourth example, the edge set of Y-aligned edges contains no back edges, so the `except` parameter has no effect.
// Figure(3D,Big): On the left `except` is a list to remove two edges. In the center we show a corner edge set defined by a numerical vector, and at the right we remove that same corner edge set with named direction vectors.
// You can specify corner descriptors directly by giving a vector, or you can use sums of the
// named direction vectors described above. Below we show all of the corner sets you can
// describe with sums of the direction vectors.
// Figure(3D,Big): Vectors pointing toward a corner select that corner.
// ydistribute(55) {
// xdistribute(35) {
// _show_corners(corners=FRONT+LEFT+TOP);
// _show_corners(corners=FRONT+RIGHT+TOP);
// _show_corners(corners=FRONT+LEFT+BOT);
// _show_corners(corners=FRONT+RIGHT+BOT);
// }
// xdistribute(35) {
// _show_corners(corners=TOP+LEFT+BACK);
// _show_corners(corners=TOP+RIGHT+BACK);
// _show_corners(corners=BOT+LEFT+BACK);
// _show_corners(corners=BOT+RIGHT+BACK);
// }
// }
// Figure(3D,Big): Vectors pointing toward an edge select the corners and the ends of the edge.
// ydistribute(55) {
// xdistribute(35) {
// _show_corners(corners=BOT+RIGHT);
// _show_corners(corners=BOT+BACK);
// _show_corners(corners=BOT+LEFT);
// _show_corners(corners=BOT+FRONT);
// }
// xdistribute(35) {
// _show_corners(corners=FWD+RIGHT);
// _show_corners(corners=BACK+RIGHT);
// _show_corners(corners=BACK+LEFT);
// _show_corners(corners=FWD+LEFT);
// }
// xdistribute(35) {
// _show_corners(corners=TOP+RIGHT);
// _show_corners(corners=TOP+BACK);
// _show_corners(corners=TOP+LEFT);
// _show_corners(corners=TOP+FRONT);
// }
// }
// Figure(3D,Med): Vectors pointing toward a face select the corners of the face.
// ydistribute(55) {
// xdistribute(35) {
// _show_corners(corners=LEFT);
// _show_corners(corners=FRONT);
// _show_corners(corners=RIGHT);
// }
// xdistribute(35) {
// _show_corners(corners=TOP);
// _show_corners(corners=BACK);
// _show_corners(corners=BOTTOM);
// }
// }
// Figure(3D,Med): Corners by name
// xdistribute(35) {
// _show_corners(corners="ALL");
// _show_corners(corners="NONE");
// }
// Next are some examples showing how you can combine corner descriptors to obtain different corner sets.
// The default value for `corners` is `"ALL"`, the set of all corners. The default value for `except` is the
// empty set, meaning no corners are removed.
// Figure(3D,Big): You can specify corner sets numerically or by adding together named directions. The third example shows a list of two corner specifications, giving all the corners on the front face or the right face.
// Figure(3D,Big): Corners for one edge, two edges, and all the edges except the two on one edge. Note that since the default is all edges, you only need to give the except argument in this case:
// Figure(3D,Big): The first example shows a single corner removed from the top corners using a numerical vector. The second one shows removing a set of two corner descriptors from the implied set of all corners.