# Enveloping 3D Solids

I have many solid stacks in Revit and want to find the enveloping solids. In this sample model, I want to get 4 enveloping solids/geometries that contain these solids. Something like bounding box, but they are just cuboids.
I want to ultimately extract these simplified 4 enveloping solids out of Revit to conduct some study.

Please note that these can be like Tetris blocks, so I can’t just use the bottom/footprint (or top) layer to extrude the into enveloping solids.

BoxEnvelope.sat (5.3 MB)

Hello,
1/ Sort in z these elements from their centroid
2/ order them by x and y
3/ for a column xi with yi min and yimax and
create a solid for this row put it in a container
4/ and so on
then unify all the solids in the container at the end

there will probably be better ideas
edit: In Mr. Chuongmep’s openmep package, you have an algorithm to get around the cube points of a floor which can save you valuable time

Cordially
christian.stan

1 Like

Thanks for the suggestion. Can you explain the unification process for individual columns?

I can also think of scaling up the solids just enough to make them intersect and get the 4 solid unions. Then perhaps I can scale them down. I’ll try but geometry.intersection proves to be heavy work.

1 Like

Looks like a programming study, so I’m going to assume that there could be gaps in the Z direction as well (ie: one of these could sit somewhere above the other, but so far that you wouldn’t want to merge them).

Since everything is an axis aligned cuboid, you can readily scale them up to ‘close the distance’ which would facilitate a merger, union the upscaled solids, separate the union into discrete containers, and test the containers for intersection with each cube.

Something like this:

1. Define the vector for the offset X, Y, and Z distance which you’d want to encapsulate.
2. Get the bounding box of each cube.
3. Move the max point of each bounding box by the offset vector (step 1), and the min point of each bounding box by the reverse of the offset vector (step 1)
4. Build a new bounding box from the moved min and max points, and convert to a cuboid, giving you a slightly larger geometry than before. Graphically you should still be able to confirm the discrete parts; if not your offset for the X, Y or Z is too large.
5. Union the scaled cubes into a single solid with a Solid.ByUnion node, and pull out the discrete parts using a Solid.Separate node. You should see the individual ‘clumps’ which are larger than the previous cubes.
6. Test each cube for intersection with the separated solids; filter the initial list by that test and you’ve got your cubes sorted into groups by adjacency.

Give it a shot and if you’re stuck let me know and I’ll post something later today.

2 Likes

Here is an example but the way adopted here is too artisanal not adaptable enough to a condition of existence of neighboring blocks or hollow blocks (in short I got a little too carried away before thinking)

sorry if this conditions you a loss of time

cordially
christian.stan

2 Likes

I like this method.

1 Like

another approach

code block:

``````res==3?
Cuboid.ByLengths(pt_,1.4,1,1):
Cuboid.ByLengths(pt_,1,1,1);
``````

your ‘‘idea’’ (rather process) must be more optimized for certain

Cordially
christian.stan

1 Like

My method implemented 3 ways, showing results and run times (you’ll have to decipher which method took what amount to run):

And the actual graph image for those looking to build it:

2 Likes

Thank you for the feedback, there is a weird thing on the same node (Geometry.ImportFromSatWithUnits) even if in global variation it does not change significantly locally twice it peaks at 600ms and once at 450ms, it comes HDD quality? eternal learner

Cordially
christian.stan

The difference of 0.2 seconds could be related to file access limits. The HDD can only read the file once at a time, and was passing the path 3x…

Either way, a best practice would be to read the file once, so technically that slowdown would be my bad.

1 Like

Thanks for sharing all these different methods to segregate the solids. But my goal was to get the enveloping solids instead of grouping the smaller boxes.

Also, I would prefer to have solid container of fused (watertight) geometries to export as stl, step, or sat format.

Exploding a unioned solid reveals it’s made up of hundreds of surfaces instead of just a dozen or fewer.

Here’s how a directshape unioned solid looks in Revit

Ah. I don’t know if removing the lines is doable, but you could try subtracting a solid from above and below, eating away some of the added Z height.

Could also clean this manually.

1 Like

My way of scaling up grids of boxes and scaling down the enveloping solid (container) is not perfect at all. The centroid of the container makes it tricky to scale it down uniformly in all directions since there can be jutting edges (farther from the centroid shrinks more) like for L shape.

Thinking on this further, I wonder if you could group the faces (the topology objects, not the surface geometry) by their normals, and use some Python on each groups to get them sub grouped by common edges, netting you a group of groups of co-planar faces. From there you could union surfaces in each nested group, flatten the list, build a polysurface from those, and convert those to a solid…

1 Like

Hello Mr. Jacob, how do you get this information menu on the calculation times of each node, is it a package or personal production?
christian.stan

TuneUp view extension, which can be found on package manager.

1 Like

Thanks a lot

Cordially
christian.stan

1 Like

Hola amigos, buenas. I like the aproach of my friend @christian.stan, get the centroids, organize them and create surfaces and then solids by loft or similar, would be an option, I leave you my script maybe it will give you some ideas!

Enveloping Solid sandbox.dyn (45.1 KB)

1 Like