I have two sets of entities. Set A has 1 entity, typically larger than the rest in volume. Set B may or may not have more than one entity and may or may not be continuous (i.e., not a single entity, as shown in the image). All entities are closed polysurfaces that were created as solids. What I ultimately want is to determine the intersection volumes.
This is what I’ve tried:
Select the sets as two breps (A and B), use Solid Intersect and compute the volume of the result → did not work because Set B has more than one entity
Select the sets as two breps (A and B), mesh the breps, use Mesh Intersect and compute the volume of the result → despite the mesh being an approximation due to the element size, it is more than fine for what I need. However, it was quite slow to compute the results. In fact, when Set B has a large amount of entities (much more than 2), Rhino crashed.
Without a specific code example or more detail it’s hard to see exactly what the issue is?
Does this suffice for your needs?
You can graft the cylinders input to get the volume for each intersection or trim the tree one depth and use mass addition to get the total volume for all intersecting cylinders.
If you need a speed increase, grab the C# component here which supports multi-threading:
@maje90 I’m now really thinking about getting into scripting because I’m bumping into walls that come from the fact that grasshopper works “linearly” and does not allow for loops or recursiveness. I’m not sure if this is the way though…
After re-thinking what I actually need to compute, this is a brief summary of it: I have two main layers: Compartments and Pipes. Inside each, I have sub-layers. Sub-layers contain either closed polysurfaces, closed surfaces or a closed meshes. The main goal is to go through the objects in each pipe sub-layer and determine the intersecting volume with the objects in each compartment sub-layer.
I was able to do this partially, by inputting the list of layers and selecting a pair à priori to compute the intersection (see below and attachments).
However, this does not cover the full scope of the problem. My brain map is telling me that I need to somehow compute a matrix with all combinations first, go through them in a loop and obtain the intersecting volumes. I need this output to be organized because I need to be able to trace back from the results matrix and determine which pipe - compartment pair generated each result.
Based on your outline and layer structure I don’t see a need for looping here, although you are correct that scripting can give you some capabilities that Vanilla Grasshopper will not.
Since you already have your pipes and your compartments organized in layers, effectively you have a DataTree already…
You have a list containing nested lists.
Therefore, you can work on it like a data tree and then get relevant information such as “which layer aka compartment” is this pipe intersection volume on?
I’ll see if I can come back with a gh script here demonstrating this… one moment.
Here it is. I it is working properly. My only concern has to do with the fact that my model mixes meshes with surfaces/polysurfaces. Hence the current warnings when computing volumes and Mesh intersect. I used Mesh intersect because Solid Intersect was not working with mesh objects, whereas Mesh Intersect works with solid objects.
It looked like there were discrepancies between volume between my version and the version you shared. Maybe that was because of how I was processing your data void of the plugins initially? I create duplicate sets of pipes here to compare against each individual compartment if that makes sense?
One another note, thinking about efficiency and time… I was wondering how I could speed this for bigger models (larger number of layers and objects for example)… Particularly the Mesh Intersect and Volume commands are the slowest. So, if I could avoid running them on objects like Pipe A and Compartment B (see image below), which do not even touch each other, that could save processing time I guess. Tomorrow I will try comparing bounding box extents to filter unnecessary intersect operations. Other suggestions are also welcome!
Hi @Filipe_Belga, I recommend pre filtering components for intersection logic by first using the Clash component. This component is fast and you can use it to group the clashing objects into data tree branches so that you then only run the intersection logic on “known” clashes.
This should substantially improve performance on large models and you can set limits on the component as well.
I actually was working on his exact thing for you but scrapped it when I ran out of time.
EDIT: interesting on the missing compartments. Possibly a failed mesh conversion, layer issue, or oversight elsewhere on my part. I’ll take a look when I’m in the studio again
@michaelvollrath sure, I’m coming back to this tomorrow as well. Anyway, I found out that the missing geometry is somehow invalid/null but I’m not sure why as it is a “normal” closed solid polysurface like many others…
Anyway, I will also try your tip on using clash component for performance.
Finally, for reference, the plugin I’m using is elefront for filtering objects by layers.
I believe the clash component compares everything as meshes anyways for quicker detection so my guess would be mesh will win out for clash and physics computations… but I’m certainly not well enough versed on the differences for the actual boolean operators and would think mileage may vary based on the complexity of the geometry in question? Like a super dense mesh with many faces vs a brep representation of that same object with all faces merged would, I assume, be faster to operate on despite the overall volume/form of it being similar.
With rendering stuff it seems like mesh typically wins out in speed because my (limited) understanding is GPU wants everything as triangles for rendering anyways… and you can get performance gains by “merging meshes” to be less draw calls but I have no idea how booleans which I think are CPU computations compare in mesh vs brep.
Hopefully another user can weigh in on this, I know there are some boolean wizards in these forums lurking about
One small note regarding Clash component. I just tested it a few moments ago and it seems it doesn’t recognize 1 object fully inside another as a “clash” and this detail is quite important in my algorithm.
Perhaps you could get the bounding box points of set A and then check for “PointInBrep” of set B.
To speed this up I would use bounding boxes for A and B.
If any of the A.bbox vertices are inside B.bbox brep shape, that means there is potentially an overlap.
Then you could more specifically check with the A set by using DeconstructBrep or get the Mesh vertices and compare again so that its not the generic bounds of an object but more specifically a piece o the geometry itself is inside of the other object (the vertex or vertices of A in this example)
I did some testes with DeMesh (Deconstruct Mesh) + Read the vextex coordinates + MInc (Test a Point for Mesh inclusion) and it seems to have worked quite well also! I basically run through it what did not pass the Clash Detection test to check if there are no clash at all or if there are objects/pipes “fully inside” any compartment. However, this increased the processing time quite a bit… Therefore, since in most of the cases there are no pipe route that pass through single compartments, i.e. is “fully inside”, I will most likely bypass this with a stream filter so that it only runs when I want it too.