Use Case:
Scenario 1:
You have closed polysurfaces exported from another CAD. Export them with IGES. Assume that is the only way and STEP is not supported from that other application.
You then import the IGES in Rhino. Polysurfaces are exploaded. If you try to use Python to find separate surfaces by name in order to join them into polysurfaces again the time it takes increases exponentially with the number of the polysurfaces. Due to waiting for mesh generation.
Scenario 2:
If you use STEP the join operation is executed upon import. Surfaces are joined really fast and the mesh generation happens after they are all joined.
Questions:
Why does it take so much time to do this with Python and not with STEP?
Not sure if this is the reason, unless you are doing this by scripting rs.Command(“Join”) and watching stuff happen onscreen…
You should be able to get a collection of all the surfaces with the same name in a list and then use something like rs.JoinSurfaces() or better, dive down into RhinoCommon and do JoinBreps(). However, one of the problems is that Rhino internally still joins stuff sequentially as far as I know, each time a new brep is added to an existing brep it creates a new brep object.
STEP files already have the join info in them, so I imagine the joining process may be handled directly by the importer which may be more efficient.
Dunno, the following takes 0.42 seconds here for the iges file you posted. What did I miss/do wrong?
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino, time
objs=rs.ObjectsByType(8)
tol=sc.doc.ModelAbsoluteTolerance
rs.EnableRedraw(False)
all_names=set([rs.ObjectName(obj) for obj in objs])
st=time.time()
for name in all_names:
ids=rs.ObjectsByName(name)
breps=[rs.coercebrep(obj) for obj in ids]
if breps:
joined=Rhino.Geometry.Brep.JoinBreps(breps,tol)
if joined:
new_ids=[sc.doc.Objects.AddBrep(jbrep) for jbrep in joined]
for new_id in new_ids: rs.ObjectName(new_id,name)
rs.DeleteObjects(ids)
print "Elapsed time is {:.2f}".format(time.time()-st)
Edit - sorry, forgot to re-name the new polysurfaces - now it’s 0.49 seconds
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino, time
objs=rs.ObjectsByType(8)
tol=sc.doc.ModelAbsoluteTolerance
rs.EnableRedraw(False)
all_names=set([rs.ObjectName(obj) for obj in objs])
st=time.time()
for name in all_names:
ids=rs.ObjectsByName(name)
joined=rs.JoinSurfaces(ids,False)
if joined:
rs.ObjectName(joined,name)
rs.DeleteObjects(ids)
print "Elapsed time is {:.2f}".format(time.time()-st)
0.54 seconds here.
The thing about using rs.JoinSurfaces() is that it returns only one object ID. If you have a collection of surfaces that are not all joinable, it will return None. Whereas with Rhino.Geometry.Brep.JoinBreps(), it will return everything it can join, that may be a list of more than one object.
I don’t quite understand why rs.JoinSurfaces() was deliberately limited in that way, there’s no real need for that, as it’s just calling Rhino.Geometry.Brep.JoinBreps() in the background anyway.
There are a lot of methods there that are weirdly developed like for example trim Curve it requires you to provide a float parameter or domain or something to show where to trim it instead of picking an object.
This is what lead me to creating this thread:
Another example is adding fillet. In RhinoCommon method you have a boolean that allows you to choose if you wanna trim the curves or extend them to make the fillet. And join them afterwards. In rhinoscriptsyntax you don’t have a choice you simply create an arc there no extend no trim no nothing. This is useless done like this. (to say the least)
To be fair it is in line with the documentation for JoinSurfaces(): “Joins two or more surface or polysurface objects together to form one polysurface object.” (emphasis by me).
Agreed, a new function would be better, maybe TryJoinSurfaces that returns all successful joins, even if there are more than one.
As long as the user can appreciate that the results aren’t necessarily what one would expect, like with JoinSurfaces()- either you get the one joined surface, or you don’t.