I have 3D cells(Breps) sharing the same faces with their neighbors.
I like to find a fast way to get the cell topology that indicates a neighboring relationship.
By saying neighboring relationship I mean cells sharing the same faces(centers), not face edges.
That’s elementary via code. Notify if you want a C# that does that.
BTW: This appears to be some reverse engineering of some sort. I mean if you have a Graph on hand and you want to do things based on connectivity (VV, VE , EV and the likes) there’s various ways to cut the mustard the proper way. All that assuming that you know what connectivity (in general) is.
If performance is not an issue (otherwise it’s to go code as peter said), and if we can consider touching faces to be identical, so sharing an identical center, we can go like this:
this uses proximity 3D on face centers to generate a list of neighbors for each face, then -in a very convoluted way- struggles to rebuild a data tree where branch number is the index of the cell under examination and the ints in that branch are the index of neighbor cells
it uses metahopper wrap/unwrap list because I’m not smart enough to deal with those branches
Bottleneck navigator says DeconstructBrep and Area are the most intensive components
vanilla GH comes with a ‘Brep topology’ node that gives FF, FE and EF. And Parakeet also has a node with more extended options by the same name, and gives amongst other:
PF(Integer)
For each Point, Indices of Brep Faces connecting to it
Nice solution, inno.
… there is always something to learn!
I almost never used proximity component and practically I didn’t know its existence. Indeed it’s useful in this context.
I tried to make your def work with vanilla components:
never used Item Index before in my life and it’s awesome to generate a list of all indexes
and Longest List with repeat last instead of Stack Data is also a nice thing to keep in mind
I’ll dig into a bit more into it later because my brain shortcircuits at Sort List but I’ll get there after a couple of drinks
I use [item index] only to spare a component, but i think this is actually bad practice (and that component can probably be much more useful in other scenarios/uses).
Better use list length + series.
Then, the [sort list] is probably useless. I’m using it only to ensure the next step (set+member index+partitioning) works correctly. But probably values before sort list are already sorted enough for the script to work.
Then … do some LINQ or use RTrees or Point3dList and do the Conn Tree required (another 5 ms max). Even if you do the most stupid LINQ thing known to man like …
DataTree<int> conn = new DataTree<int>();
Point3dList taken = new Point3dList();
foreach(FINFO info in fInfo){
int bIdx = info.BIDX;
int fIdx = info.FIDX;
Point3d Cent = info.CENT;
if(taken.Contains(Cent)) continue;
taken.Add(Cent);
var Q = fInfo.Where(x => x.BIDX != bIdx && x.CENT.DistanceTo(Cent) < R).OrderBy(x => x.CENT.DistanceTo(Cent)).ToList();
if(!Q.Any()) continue;
int bIdx2 = Q.First().BIDX;
int fIdx2 = Q.First().FIDX;
taken.Add(Q.First().CENT);
if(!conn.PathExists(new GH_Path(bIdx, fIdx))){
conn.AddRange(new int[2]{bIdx2, fIdx2}, new GH_Path(bIdx, fIdx));
}
if(!conn.PathExists(new GH_Path(bIdx2, fIdx2))){
conn.AddRange(new int[2]{bIdx, fIdx}, new GH_Path(bIdx2, fIdx2));
}
}
OMG… I think I committed a crime, some solutions have even been updated to the 4th version, I am terribly sorry!
I just remembered there is a super fast cell topology component in Nautilus that can tell the neighboring relationship between touching Brep cells.
I promise I will read your solutions and try to learn from them.
The cells are made from the Iguana plugin(which can produce volumetric 3D mesh). I am trying to make 3D Voronoi by connecting all the neighboring volume centers, so I need the cell topology data.
I think this is a way of making 3D Voronoi without the Solid Intersection process.
If you have implemented the stupid LINQ posted above … well … that’s expected. As a challenge try to use RTrees (but how to relate points to class info ? you tell me) of Point3dLists.
I thought it was what you posted, that code. Sorry I couldn’t follow…
Yes, usually I haven’t seen the need for that, but I can understand how it could be handy. It make sense to have additional output when the cost difference is null…
Well … as I said … EVEN this stupid approach yields “OK” elapsed Time. Meaning that is the slowest imaginable way to cut the mustard.
Add an option then: explicit (2 dim paths: first the Brep idx, 2nd the Face idx, items: indices of adjacent Brep/Face) or “generic” (classic 1 dim paths: what Brep is adjacent to what).