Irregular Results with Adjacent Faces

Hi all,

I am running into some funny results with my geometry that I wonder if anyone can shed some light on for me? I’m modeling a fairly complex form and having some issues with finding adjacent faces. Mostly its all working great, but in a very irregular/unpredictable way I am having some items fail to recognize their adjacent room face? I can’t quite figure our whats causing this and it seems to happen in a fairly ‘random’ fashion?

I am being very, very careful in my geometry creation and splitting faces carefully. If I ‘remodel’ the offending face(s), sometimes it works, sometimes not. Very odd?

As example - on a small bit of the building (just pulled out two rooms as an example here) I would like my Honeybee model to recognize this highlighted face as a ‘Surface’ BC / interface floor:

The trouble I am running into is that sometimes the ‘Solve Adjacency’ works great, but then sometimes not so much… for instance, in the example here with just these two rooms, I can get it to work correctly at first, but if I do something as simple as make a ‘copy’ of the room geometry (keyboard ‘Alt’ and click/drag) then with that new geometry, now it does not recognize the intersection face any longer?

I think I have tried to track down the difference between the two cases here, since I know they are identical geometry (a direct copy) and the best I can find - the only difference occurs in the ‘ub’ calculation within the ‘does_intersection_exist_line2d’ method (as a part of the face’s is_centered_adjacent() / intersect_line_ray() evaluation.

The basic adjacent face checks are all the same in both cases: Is there an overlapping bounding-box, are the face center-points equivalent, is the face area difference within the tolerance value: Those are all ‘True’ for both cases. It’s only the ‘Test-Ray’ intersection check that seems to show any difference between the two.

For my ‘original’ version, that ‘does_intersection_exist_line2d’ check results in a negative value of -3.91993656526e-15, and then the ‘copy’ geometry calculates a result of +3.91993656526e-15 (positive). This seems to cause the face.is_point_inside() check to return a second True value, which then causes the adjacency check to not actually find the adjacent face. (I think… a lot of nested methods there and I certainly don’t understand what the does_intersection_exist_line2d() math is trying to solve for there, so might be totally wrong on all that).

So I definitely don’t understand what the ua and ub are checking for - but it seems to me that the difference between -3.91993656526e-15 and +3.91993656526e-15 might just be some sort of tolerance / rounding issue, not an actual difference in the geometry? I wonder if there should be some sort of tolerance added to the line._u_in() method or the ua / ub calculation itself?

I wonder if anyone can shed some light on that? Is there something else that is actually ‘different’ in the two cases here that I’m not seeing? In general, as I noted: I’m getting some fairly irregular results from this adjacency finder and would be great to understand a bit more about the ‘proper’ way to model these sorts of complex geometries (I know, simplify whenever I can. Can’t always though)? Is there some sort of tolerance value that can be set globally or something that might make this a bit simpler?

as always - any advice is always appreciated!
thanks so much. (files attached if you like).
@edpmay (52.1 KB)
face_adjacency.3dm (495.7 KB)

If i understood well your issue (you want the intermediate floor to be recognized as a ‘surface’), just opening your file works fine for me on both geometries. My default tolerance is 0.001, but they work also when changing it to higher/lower values.
I also made a copy of the geometry and it works too.
Maybe it is related to the Rhino version? I’m using the latest 7.2.21012.


Hi @edpmay,

Try the workflow below (You will need the Human pluginn)

2d block input.3dm (49.3 KB) (62.6 KB)

thanks @AbrahamYezioro, @Erikbeeren

wow - thats so peculiar? It definitely is not working for me. I wonder what the difference is?

I’m using Rhino 7.2.21021.7001 on Windows 10 Home edition - running on Parallels on my MacBook. I have double checked and the tolerance is set to 0.001m

Interestingly, if I change the tolerance setting in Rhino - no change occurs in the Grasshopper, model no matter what I set it to. If I set it to 0.1m or 0.01m or 0.0000001m I always get the same result (even after a GH ‘Recompute’):

BUT: if I set the Rhino doc tolerance to a different value (say: 0.01m), save the Rhino file and close everything, then reopen - now I do get a different result (the ‘Surface’ is no longer recognized on the ‘original’ but DOES get recognized o the copy now…) Again: not changing anything about the geom, just the tolerance setting, save, close and reopen:

If I do all that again: set Rhino tolerance to 0.1m, save, close, reopen, now I get yet another result - in that case both surfaces are recognized correctly?

again - nothing at all changes until I save and reopen the file in any of these cases, even when I ‘recompute’ the GH scene?

That seems odd, doesn’t it? Is there a certain tolerance it ‘should’ be set to for LBT to work best that you know of?

regardless, thanks so much for taking a look! Really appreciate it.
@edpmay (46.3 KB)
face_adjacency.3dm (508.2 KB)

I think its 0.0001, I’m semi sure I remember from HB THERM stuff.
Setting doc at 0.0001, alt+gumball drag; apply troubleshooting rig to new geom returned the ‘Surface’ surface attr. Saved, reopened, all was well: alt+gumball dragged again and checked with tsRig and the ‘Surface’ surface attr returned in test rig again.

I think that’s why I’ve developed a compulsive habit to always run rhino on .0001… :sweat_smile: always be prepared for HB THERM is what my brain thinks apparently

Incase I’m missing something (Which we know is definitely within the realm of possibility)
This is the reload \ try again portion of the aforementioned:

funky tolerance from Trevor Fedyna on Vimeo.


I love that 2d based workflow btw - thanks so much for sharing.

Using that process I can mostly get a single floor to work ok now. It seems to recognize all the divisions and split all the geometry really well:

but I still run into trouble when I try and add multiple floors. The interface floors do not reliably get tagged as ‘surface’ (although they do get created correctly - the split-faces seems to be working as I’d expect):

It just doesn’t recognize their ‘Surface’ BC all of the time, and instead tags them all as ‘Roof’ once and a while. It occurs for me sort of ‘randomly’ - if I try and tweak any of the lines, some surfaces pop in or out of ‘Surface’ BC type.

Do you see anything here I’d doing incorrectly that might be causing this to occur?

thanks so much for the advice!

2d_workflow_example.3dm (194.3 KB) (46.5 KB)

One last thing: for what it’s worth: my geometry here does seem to get recognized and handled properly when using the ‘Legacy’ tools. If I just copy/paste the same geom, and run it through the old tools, it seems to (so far) find all the adjacencies where the LBT1 does not:

Legacy_Adjacency.3dm (158.9 KB) (134.4 KB)


Hi @edpmay,

I used the blocks so I can model each floor on the base plane. This avoids inaccuracy in the Z-direction.
Which is probably the case in your file. Tiny inaccuracies can already generate this problem, and they are hard discover.

@Erikbeeren, Ah - I see - that makes sense: I didn’t realize that at first. Slick!

Unfortunately though no: that does not solve the issue. Using the blocks and your exact set up, I still get irregular missing ‘Surface’ assignments here and there throughout the model:

When I made the blocks, I used ‘ProjectToCPlane’ to make sure that all the line work is flat, and I double checked the lines are all intersecting using ‘Trim’ command on all.

As I noted before, if I ‘move’ the geometry in the scene, some faces come ‘on’ or ‘off’ as ‘Surface’ type as well. (30.4 KB)
face_adjacency_2d_EM.3dm (53.7 KB)

Hi @edpmay,

If you start from scratch, and model each floor on the base plane (z=0), then make blocks of them and put each floor (block) on the right height, I think your problem is solved. Keep the insertion points on the same place! You can use the groundfloor for tracing the 1st floor and so on.

Thanks @Erikbeeren - I appreciate all your advice here. In this case I gave up (ran out of time on this particular project) and went back and used the old Legacy tools - they all worked perfectly with my geometry. I’ll give this new method another try when I have more time to devote to it on the next project.

thanks so much!

1 Like


It saved me a lot of time and frustration, using this method.

This is by design. Changing the tolerance of a Rhino model to something other than what the geometry was created in produces a lot of strange behavior. Surfaces that were curved can become planar, volumes that were open can become closed, and a whole manner of other properties about the geometry become mis-matched with the processing of that geometry.

Suffice it to say that, if you are going to change your Model tolerance, you should probably recreate the geometry in that new tolerance if you want it to be valid. Changing the units is fine and you’ll be able to recompute the canvas as you normally would in that case. But trying to take “the tolerance shortcut” with bad geometry usually doesn’t end well in my expereince.

Another suggestion if your rooms are just extruded floor plates, you can use Dragonfly to build your honeybee energy model instead of Honeybee. All building geometry consists of extruded floor plates in dragonfly and so it tends to be a lot easier to clean your input geometry. See the sample file that’s included in the Food4Rhino download of the LBT plugin for an example.

Also, I ran your file from 4 days ago and it seems to have correctly solved adjacencies:

I’m using the Rhino 7 build form 1/21/2021. Perhaps you have an older build of Rhino 7 with a bug?

FYI @edpmay ,
It occurred to me that you could be experiencing this bug that was in the LBT 1.1.0 stable release but is fixed in the development version:

If you run the “LB Versioner” and the “LB Sync Grasshopper File” components, it’s possible that may solve it on your end.

@chris Ah!!! that was it! Thanks a million, as always. Works perfectly for me now after running the ‘LB Versioner’ update.

thanks so much!

1 Like