OpenSCAD 挺有趣的。
OpenSCAD is kinda neat

原始链接: https://nuxx.net/blog/2025/12/20/openscad-is-kinda-neat/

该项目详细介绍了使用OpenSCAD重新创建最初在Autodesk Fusion 360中创建的参数化电池座设计。作者旨在通过重新实现一个简单、可定制的电池整理器来学习OpenSCAD——一种基于代码的CAD工具。 OpenSCAD脚本(`battery_holder_generator.scad`)生成AA或AAA电池的座,尺寸根据用户定义的行数、列数和电池类型进行调整。它的工作原理是创建一个实体盒子,然后使用嵌套循环和`difference()`函数减去电池形状的空隙。 作者强调代码的简单性——基本上是绘制一个盒子并切割孔洞——并指出在循环中使用`let()`函数存在学习曲线。虽然承认OpenSCAD可能不适合复杂设计,但他们预见它在创建快速、实用的零件(如垫片和轴承漂移器)方面具有用处。这表明了转向一种轻量级的CAD解决方案,用于简单的几何形状。

## OpenSCAD:一种参数化3D建模工具 最近的Hacker News讨论强调了OpenSCAD,一种基于代码的3D建模软件,及其在实际项目中的持续实用性,例如为家庭定制3D打印。用户报告利用ChatGPT协助进行复杂设计,通常在第一次尝试时就能取得成功。 虽然OpenSCAD因其参数化设计能力而受到赞扬——允许通过代码而非手动调整轻松修改——但它也并非没有缺点。有人对该语言笨拙的语法、复杂几何体带来的性能问题(导致渲染时间缓慢)以及缺乏高级运算符表示担忧。 尽管最后一次官方发布是在2021年,但GitHub仓库显示近期仍有活动,表明存在持续的(或许是非正式的)维护。一些用户认为其稳定性可能抵消了频繁更新的需求。
相关文章

原文

Earlier this year I designed a very basic box/organizer for AA and AAA batteries in Autodesk Fusion, making it parameterized so that by changing a few variables one could adjust the battery type/size, rows/columns, etc. This worked well, and after uploading it to Printables earlier today I realized that reimplementing it would probably be a good way to learn the basics of OpenSCAD.

OpenSCAD is a rather different type of CAD tool, one in which you write code to generate objects. Because my battery holder is very simple (just a box with a pattern of cutouts) and uses input parameters, I figured it’d be a good intro to a new language / tool. And in the future might even be better than firing up Fusion for such simple designs.

After going through part of the tutorial and an hour or so of poking, here’s the result: battery_holder_generator.scad

By changing just a few variables — numRows and numColumns and batteryType — one can render a customized battery holder which can then be plopped into a slicer and printed. No heavy/expensive CAD software needed and the output is effectively the same.

Without comments or informative output, this is the meat of the code:

AA = 15;
AAA = 11;
heightCompartment = 19;
thicknessWall = 1;
numRows = 4;
numColumns = 10;
batteryType = AA;

widthBox = (numRows * batteryType) + ((numRows + 1) * thicknessWall);
lengthBox = (numColumns * batteryType) + ((numColumns + 1) * thicknessWall);
depthBox = heightCompartment + thicknessWall;

difference() {
    cube([lengthBox, widthBox, depthBox]);
    for (c = [ 1 : numColumns ])
        for (r = [ 1 : numRows ])
            let (
                startColumn = ((c * thicknessWall) + ((c - 1) * batteryType)),
                startRow = ((r * thicknessWall) + ((r - 1) * batteryType))
            )
            {
                translate([startColumn, startRow, thicknessWall])
                cube([batteryType, batteryType, heightCompartment + 1]);
            }
};

Simply, it draws a box and cuts out the holes. (The first cube() draws the main box, then difference() subtracts the battery holes via the second cube() as their quantity and location (via translate()) is iterated.

That’s it. Pretty neat, eh?

(One part that confused me is how I needed to use let() to define startColumn and startRow inside the loop. I don’t understand this…)

While this probably won’t be very helpful for more complicated designs, I can see this being super useful for bearing drifts, spacers, and other similar simple (yet incredibly useful in real life) geometric shapes.

联系我们 contact @ memedata.com