generative modeling for Rhino
Ive been trying to create a python script that takes a set of meshes and create a boolean difference with another input mesh. Like puncturing holes in a mesh surfaces.
I want to see if multi threading speeds up the process, because if you go above 500 'holes' it gets super slow (like 4 minutes, and 10 minutes for 600). I checked out Steve's blog post: http://python.rhino3d.com/entries/607-Multithreaded-Python and created my own version but i keep on having the error: 'Aggregate exception: various errors are produced'.
attached is the grasshopper file (with the python component)
Thanks in advance!
gh def: meshboolean.ghx
Are you trying to punch holes into a single mesh from multiple threads? If so, forget about it. It'll never work.
Haha David :)
I'm afraid that is the case... I use a for loop where I use my initial mesh and iterate one by one trough my boolean meshes re-using the mesh that comes out as the input,
tMesh = mesh #big surface where the hole are going to be punctured in
meshes #the boolean meshes that are sticking trough the mesh
for i in meshes:
---tMesh = rs.meshBooleanDifference(tMesh,i,True)
I was hoping i could spread the actions in the for loop over multiple threads, check out the link I posted, I believe Steve did something similar, only with a plane/brep intersection- for loop.
Steve said in the post and I qoute :'This set of classes and functions makes it relatively easy to write things like parallel for loops in which every iteration of the loop may be processed on different threads'. The 'relatively easy' sounded quite appealing haha, but i guess it is more complex.
Plane|Brep intersection is fine because neither of those should affect the state of the data operated on*. However, you're modifying a mesh simultaneously from multiple threads, there's bound to be conflicts. The only way to solve this is to create a lock on the mesh object during one boolean operation, which sort of ruins the whole idea of multi-threading.
If you were punching holes in multiple meshes, you could solve one per thread, but a single mesh... nah. Just nah.
* this is actually not really true. It's possible that there are caches and trees that will be constructed the first time you call a Brep intersection functions, but this only needs to happen once so a thread lock during cache construction is not that big a sacrifice.
Thanks David for the clear explanation! I guess back to the drawing board...
To speed things up you can either subdivide the surface or mesh into smaller pieces before trimming the holes or you could create a bitmap image through grasshopper to use as a transparency texture for rendering.
The latter Im using now for the renders. The thing is that the guys that render are kind of 'lazy' , they asked me if it would be possible to create the holes (so they wouldnt have to make the textures for rendering). But I think given the time the texture option is the one we're going for.
Maybe later ill try to subdivide the mesh first into smaller parts so i can spread those over multiple threads. Lets see.
Even if you don't use multiple threads, it will still be much faster.
Some time ago I made a definition that given a set of surfaces for each surface it created a transparency texture, a material, assigned the transparency texture to the material and assigned the material to the surface, all within the definition.
I rendered it inside Rhino. If you are rendering in another software i think there are some file formats that can export materials but i haven't tested it.
Ah that sounds pretty cool! They use 3Dmax + vray, I think the .fbx (motionbuilder) exports the material, so that might be an option. But we're out of time to experiment unfortunatley. They're already almost finished doing the textures. Thanks!