Hello,
I took a look at your model and the main issue is exactly what was mentioned earlier: most of the geometry consists of open surfaces rather than closed solids, which is why it’s failing for 3D printing.
I went through your file and used a couple of small Python scripts in Rhino to both analyze and partially repair the geometry.
First, I checked all objects and identified which ones are not closed. In your case, almost everything is made of individual surfaces, so they need to be fixed before they can be used for printing.
Then I analyzed the open elements based on their naked edges (these are edges that are not connected to another surface). This helps understand how each object is “broken” internally.
-
If an object had a simple opening (4 naked edges forming a loop), I was able to automatically fix it by recreating the missing surface (similar to the EdgeSrf command) and joining it back to the object. These are now closed solids and should work for 3D printing.
-
If an object had more complex edge conditions (multiple openings, non-planar boundaries, or irregular topology), I did not fix it automatically to avoid creating incorrect geometry.
To make things easier to review, I organized the model into three layers:
-
Not impacted elements → already closed solids (Left Group)
-
Problematic elements → automatically fixed and now usable (Middle Group)
-
Complex/not solved elements → require manual cleanup (Right Group)
Even if some elements look simple visually, their internal topology can be more complex, which is why they fall into the last category.
I’ve uploaded the processed file here:
https://drive.google.com/file/d/18UYOmfmVwtl_A0Pnspv44-LfA36BiWe4/view?usp=sharing
If you want to try the same approach, you can try this using OkPy Agent console from Orkestra Online.
Here is the script I used to identify and classify the problematic geometry:
import Rhinofrom Rhino.Geometry import *
doc = currentdoc
open_ids = fixable_ids = complex_ids =
for obj in doc.Objects:geo = obj.Geometry
if not isinstance(geo, Brep):
continue
if geo.IsSolid:
continue
open_ids.append(obj.Id)
# Count naked edges
naked_count = sum(
1 for e in geo.Edges if e.Valence == EdgeAdjacency.Naked
)
if naked_count == 4:
fixable_ids.append(obj.Id)
else:
complex_ids.append(obj.Id)
# Select ALL problematic geometry
doc.Objects.UnselectAll()
for oid in open_ids:doc.Objects.Select(oid)
doc.Views.Redraw()
print(“🔍 ANALYSIS RESULT”)print(“Open Breps:”, len(open_ids))print(“Fixable (4-edge):”, len(fixable_ids))print(“Complex cases:”, len(complex_ids))
# Output for chaining if needed
out = {“open”: open_ids,“fixable”: fixable_ids,“complex”: complex_ids}
And this is the script used to fix the simple cases:
import Rhino
from Rhino.Geometry import *
from System.Collections.Generic import List
doc = __currentdoc__
fixed = 0
failed = 0
for obj in doc.Objects:
geo = obj.Geometry
if not isinstance(geo, Brep):
continue
if geo.IsSolid:
continue
# Count naked edges
naked_edges = [
e for e in geo.Edges if e.Valence == EdgeAdjacency.Naked
]
if len(naked_edges) != 4:
continue # skip complex cases
curves = List[Curve]()
for e in naked_edges:
curves.Add(e.DuplicateCurve())
surface = Brep.CreateEdgeSurface(curves)
if not surface:
failed += 1
continue
joined_input = List[Brep]()
joined_input.Add(geo)
joined_input.Add(surface)
joined = Brep.JoinBreps(joined_input, 0.01)
if joined and len(joined) > 0 and joined[0].IsSolid:
doc.Objects.Replace(obj.Id, joined[0])
fixed += 1
else:
failed += 1
doc.Views.Redraw()
print("đź› FIX RESULT")
print("Fixed:", fixed)
print("Failed:", failed)
__out__ = {
"fixed": fixed,
"failed": failed
}
Let me know if this helps! 