discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

linear_extrude3d and an aside about OpenSCAD data vs geometry

BC
Bob Carlson
Sun, Nov 30, 2025 9:40 PM

I bought up this module in another discussion and Adrian suggested some simplification. I think it illustrates a point of OS that confuses me and probably a lot of other people too. Hopefully this explanation will allow people to get to this understanding faster than I did. 2D geometry seems like it is the same as 2D data, but it’s not. This module takes a 2D path (list of points) and returns 3D geometry.

The OS native modules like circle produce only geometry and once something is geometry its characteristics are pretty opaque. This module illustrates the difference pretty clearly. The argument path is a list of points in 3D space, that must be coplanar. Move, rot and path2d are all BOSL2 functions that work on data, so the result pathInXY is still data, a list of points, but now points in 2D space. The object of each function is put into an argument because functions don’t have children.

Polygon turns pathInXY into geometry. It can now be operated on by modules, which do take children. The BOSL2 modules rot and move are equivalent to the functions by the same name, but the object of each is a child and must be geometry.

One of the secrets to using BOSL2 is that it has a vast number of ways to manipulate data and the characteristics of the data are findable. Often staying in the data realm as long as possible is best. At some point, you start to turn your data into geometry. BOSL2s transformations are generally available in both realms, but the syntax will be sightly different. That shows clearly in the code. Two transformations are applied to the data, then they are reversed, but  reversed in the realm of geometry. Polygon_normal and centroid are examples of characteristics you can get from data that are unavailable in geometry AFAIK.

-Bob

include <BOSL2/std.scad>

module linear_extrude3d(path, h) {
d0 = assert(is_coplanar(path),
"Path Is Not Coplanar (from linear_extrude3d)");
r = polygon_normal(path);
c = centroid(path);

// Move the path to the XY plane centered on the origin
pathInXY = path2d(                        // remove Z
               rot(from = r, to = UP, p = // Rotate into XY
                   move(-c, p =           // Move centroid to origin
                       path)));

// Extrude it, then move it back
move(c)                        // Move the centroid back
    rot(from = UP, to = r)     // Rotate back to original angle
        linear_extrude(h)      // Do the extrusion
            polygon(pathInXY); // Make into a 2D shape

}

path = [[0, 0, 0], [0, 3, 4], [0, 3, 0]];
linear_extrude3d(path, 10);

p0 = move([4, -5, 2], p = path);
linear_extrude3d(p0, 10);

p1 = rot(from = RIGHT, to = UP + RIGHT + FRONT, p = p0);
linear_extrude3d(p1, 10);

I bought up this module in another discussion and Adrian suggested some simplification. I think it illustrates a point of OS that confuses me and probably a lot of other people too. Hopefully this explanation will allow people to get to this understanding faster than I did. 2D geometry seems like it is the same as 2D data, but it’s not. This module takes a 2D path (list of points) and returns 3D geometry. The OS native modules like circle produce only geometry and once something is geometry its characteristics are pretty opaque. This module illustrates the difference pretty clearly. The argument path is a list of points in 3D space, that must be coplanar. Move, rot and path2d are all BOSL2 functions that work on data, so the result pathInXY is still data, a list of points, but now points in 2D space. The object of each function is put into an argument because functions don’t have children. Polygon turns pathInXY into geometry. It can now be operated on by modules, which do take children. The BOSL2 modules rot and move are equivalent to the functions by the same name, but the object of each is a child and must be geometry. One of the secrets to using BOSL2 is that it has a vast number of ways to manipulate data and the characteristics of the data are findable. Often staying in the data realm as long as possible is best. At some point, you start to turn your data into geometry. BOSL2s transformations are generally available in both realms, but the syntax will be sightly different. That shows clearly in the code. Two transformations are applied to the data, then they are reversed, but reversed in the realm of geometry. Polygon_normal and centroid are examples of characteristics you can get from data that are unavailable in geometry AFAIK. -Bob include <BOSL2/std.scad> module linear_extrude3d(path, h) { d0 = assert(is_coplanar(path), "Path Is Not Coplanar (from linear_extrude3d)"); r = polygon_normal(path); c = centroid(path); // Move the path to the XY plane centered on the origin pathInXY = path2d( // remove Z rot(from = r, to = UP, p = // Rotate into XY move(-c, p = // Move centroid to origin path))); // Extrude it, then move it back move(c) // Move the centroid back rot(from = UP, to = r) // Rotate back to original angle linear_extrude(h) // Do the extrusion polygon(pathInXY); // Make into a 2D shape } path = [[0, 0, 0], [0, 3, 4], [0, 3, 0]]; linear_extrude3d(path, 10); p0 = move([4, -5, 2], p = path); linear_extrude3d(p0, 10); p1 = rot(from = RIGHT, to = UP + RIGHT + FRONT, p = p0); linear_extrude3d(p1, 10);