Parametric Model Maker - Model Times out - help?

I’ve been developing a model for Maker World, using OpenSCAD and BOSL2 libraries, and while it works on smaller versions of the model, it times out when the model gets larger.

Is there a way to figure out what all can be done to optimize a model so that it completes within what appears to be the 10 second timeout limit on Parametric Model Maker?

Here is the specific model in question:

If you generate that model with default parameters, it will work, however if you instead change the parameters as follows:

frame_width = 635
frame_height = 937
led_face_outwards = true

Here is the full file that times out: frame_led_channel_parts_timeout.scad · GitHub

Then the model will timeout on the web generator and never fully complete. With these inputs it should generate 4 plates worth of print assets, and when generating them locally on an M2 Macbook Air with OpenSCAD 2025.10.27 it is rendered in about 16 seconds. If I run the default parameters, then the render completes locally in about 9.7 seconds.

Any ideas? Thanks!

delete line 543:547
you are not allowed to call mw_plate_X() or the model maker will break.
same for mw_assembly_view().

1 Like

Nice catch! You are absolutely right, those calls aren’t allowed in the model maker. However, I also made a mistake when creating the gist, since those calls aren’t found on the actual code uploaded for the model in question. I had added those lines for my local testing so that I could see how long it would take to render multiple plates when just using OpenSCAD locally, and then I forgot to remove them when uploading the code to the gist for sharing. I have now fixed the gist, so those lines aren’t listed, but unfortunately that’s not the root cause of the problem.

Updated gist here: frame_led_channel_parts_timeout.scad · GitHub (should be same as original link)

I’m leaning towards a solution where I just upload 3 separate .scad files that each do about 1/3 of the objects, and thus should render in about 1/3 the amount of time. That is probably the fastest way to solve this. Or maybe there is some way to cache and reuse the same objects that I’m generating multiple times in different locations, so that it doesn’t take longer just to have multiple copies of the same object?

I receive these console log issues when running plate 1.

Parsing design (AST generation)…
Compiling design (CSG Tree generation)…
Rendering Polygon Mesh using Manifold…
WARNING: PolySet → Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh…
WARNING: PolySet → Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh…
WARNING: PolySet → Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh…
WARNING: PolySet → Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh…
WARNING: PolySet → Manifold conversion failed: NotManifold
Trying to repair and reconstruct mesh…

Interesting. What version of OpenSCAD are you running locally? I’m running OpenSCAD version 2025.10.27 (git aa785fe4a) and this is the output I get when just doing plate 1:

Loaded design '/Users/justinwagner/projects/open-scad-projects/frame_led_channel_parts.scad'.
Compiling design (CSG Tree generation)...
ECHO: "width_after_margin", 587
ECHO: "height_after_margin", 889
ECHO: "width_ch_length", 195.667
ECHO: "height_ch_length", 177.8
ECHO: "total_width_pieces", 6
ECHO: "total_height_pieces", 10
ECHO: "total_channels", 16
Compiling design (CSG Products generation)...
Geometries in cache: 11
Geometry cache size in bytes: 22664
CGAL Polyhedrons in cache: 0
CGAL cache size in bytes: 0
Compiling design (CSG Products normalization)...
Normalized tree has 192 elements!
Compile and preview finished.
Total rendering time: 0:00:05.209

And this is the version (git commit) of BOSL2 I’m usually locally:

Commit: 7a1e243dfddaf1c3ef8644fe2dd843b781f22dcd
Parents: 11af3b662c9fce7b782806f0c3ae1666ce37bfee, b506db99785a31cde2d543d076bb7fb5e6f52324
Author: adrianVmariano <avm4@cornell.edu>
Committer: GitHub <noreply@github.com>
Date: Mon Oct 27 2025 18:49:17 GMT-0600 (Mountain Daylight Time)
 

Merge pull request #1699 from coryrc/issue1679

Change $slop docs and tester

Ignore me, I had loaded an old version of OpenSCAD (too many versions on my Mac).

I took the opportunity to grab the 2025-12-12 release and no such issue as I noted above.

1 Like

Its slow not because the geometry is complex, but because BOSL2 features are expensive.
Use BOSL only where it actually adds value and go bare metal OpenSCAD elsewhere.
Avoid global fn, it massively hurts performance on small parts.
Instead, assign fn per part and derive it from a target resolution.
If using difference with more than two operands, wrap the union in render to reduce CSG overhead.

resolution = 0.2;
function fn(r,d) = floor(2*(r?r:d?d/2:1)*PI/resolution);
module fncircle(r=undef, d=undef, resolution=resolution) {
  radius = (r!=undef)?r:(d!=undef)?d/2:1;
  facets = floor(2*radius*PI/resolution);
  circle(r=radius,$fn=facets);
}
// circle(d=5,$fn=fn(d=5));
// fncircle(d=5);
// fncircle(d=5,resolution=1);

Whoa, nice tips @Professional3D ! I’m going to work through them one by one to fully comprehend and determine just how much speedup each ends up getting on this problem.

Tip 1) Don’t use global $fn, but rather only use it where it’s required. Sub-tip: derive it from a resolution.

It’s not clear to my why deriving this from a resolution would improve performance, but perhaps it’s just to have the number expressed in a way such that lower numbers create smoother circles? @Professional3D can you elaborate on this sub tip a bit more, I’d like to understand the reasoning here better.

I went ahead and did some performance benchmarking to see just how much benefit this particular problem would get from this tip relating to global use of $fn, and I did see some speedup. However, the speedup was all less than 1%, so this optimization alone certainly won’t be the sole fix to this problem. For each iteration of the code changes, I ran 5x previews, and 5x renders and took their average time. I captured all data here: OpenSCAD Benchmarking - Google Sheets

And the snapshot of these tests are:

I’ve committed this improvement to my repo, and next will chew on the other 2 tips and how I can incorporate them to address this problem. Here is the git commit with the changes made: Optimize usage of $fn · jrwagz/open-scad-projects@8a1f1db · GitHub

In my approach, resolution represents the physical length of each polygon segment, analogous to the XY resolution of a 3D printer. Why drive a crazy $fn if the user cannot see it and the printer cannot print it?

A global fn forces the same high segment count onto every circle, cylinder sphere, linear_extrude, rotate_extrude and offset, regardless of size.
circle(d=1, $fn=200) costs essentially the same as circle(d=2000, $fn=200), even though the small one gains nothing visually.

Deriving $fn from a target resolution keeps segment length roughly constant, so small features use few segments and large ones only get more where needed.
That cuts polygon count early, before CSG evaluation, which is where OpenSCAD actually gets slow.
Nothing becomes magically smoother, you are just expressing smoothness in physical units instead of an arbitrary global number.