Solve adjacency script does not find all floor/ceiling adjacencies

Hi everyone and @chris,
I am trying to write a script to automatically take the buildings in the Rhino scene and create an honeybee model. I have to create the model from solids so I start with DF and then I convert to an HB model. I am experiencing an issue for some floors, in which the solve_adjacencies function does not detects the adjacency between ceiling/floor. I cannot leave it to adiabatic because I want to change the boundary condition of the ground floor and the roof, which are defined as adiabatic, to ground and outdoors respectively. I also change the surface in contact with adjacent buildings to adiabatic.
I am trying to implement this on a building in contact with others. I am experiencing this issue between the ground, first and second floor of this building.
This is the code I wrote so far, up to the boundary condition change.

# set to True to get all geometries defined by the "Buildings" layer
if getBuildings == True:
    buildingsNames = []
    buildingsBreps = []
    # take buildings
    buildings = Rhino.RhinoDoc.ActiveDoc.Objects.FindByLayer("Buildings")
    for building in buildings:
        # if a name is defined take it and append it to the names list
        if building.Attributes.Name != None:
            buildingsNames.append(building.Attributes.Name)
        else:
            # otherwise write to give name to all buildings and change building layer to highlight it
            print("Give name to all buildings and change back the layer to Buildings")
            building.Attributes.LayerIndex = 7
            Rhino.RhinoDoc.ActiveDoc.Objects.ModifyAttributes(building, building.Attributes, True)
        # convert the building geometries to brep in order to work with them
        buildingsBreps.append(building.Geometry.ToBrep()) # I need to convert the geometry to Brep, if I take it like this it is an extrusion, for the intersection I need Breps so I put .ToBrep()

# set to True to cut the surfaces of the buildings touching each other
if intersectSolids == True:
    # generate bounding boxes for all inputs
    boundingBoxes = [buildingBrep.GetBoundingBox(False) for buildingBrep in buildingsBreps]
    # intersect drawn breps
    intersectedBuildings = intersect_solids(buildingsBreps, boundingBoxes)

# set to True to create simulation files based on geometry and inputs
if createSimulationFiles == True:
    allModels = []
    dfBuildings = []
    for building in range(len(intersectedBuildings)):
        # find min and max z coordinate of the building
        min, max = geo_min_max_height(intersectedBuildings[building])
        # find the heights of each floor and the corresponding floor-to-floor height
        floor_heights, interpreted_f2f = interpret_floor_height_subdivide(definedFloorHeight, max, min)
        # create the floors for the building massing
        floor_breps = split_solid_to_floors(intersectedBuildings[building], floor_heights)
        floor_faces = []
        for flr in floor_breps:
            story_faces = []
            for rm_face in flr:
                story_faces.extend(to_face3d(rm_face))
            floor_faces.append(story_faces)
        # from the floors and floors heights create stories
        dfBuilding = Building.from_all_story_geometry(buildingsNames[building], floor_faces, interpreted_f2f, tolerance = tolerance) # if I want to do core-perimeter zones I have to do it here
        dfBuildings.append(dfBuilding)
    dfModel = dragonfly.model.Model(identifier = modelName, buildings = dfBuildings, tolerance = tolerance)
    # convert DF model into HB model
    hbModel = dfModel.to_honeybee(object_per_model = "District", use_multiplier=False, tolerance = tolerance) # if it is True I get just one room, here I get one room for each floor
    # get rooms from the entire HB model
    rooms = hbModel[0].rooms # have to put [0] because the result is a list of one element and I have to use the model not the list
    # solve adjacnency
    adj_rooms = [room.duplicate() for room in rooms] # duplicate the initial objects
    adj_info = Room.solve_adjacency(adj_rooms, tolerance) # double the tolerance value to be sure to detect adjacencies for floor/ceiling
    # add windows based on ratio, same ratio for every orientation and set correct boundary conditions
    for room in adj_rooms:
        for face in room.faces:
            if isinstance(face.boundary_condition, Outdoors) and isinstance(face.type, Wall): # windows
                face.apertures_by_ratio(wwr)
            if isinstance(face.boundary_condition, Adiabatic) and isinstance(face.type, Floor): # ground floor
                face.boundary_condition = boundary_conditions.ground
            if isinstance(face.boundary_condition, Adiabatic) and isinstance(face.type, RoofCeiling): # roof
                face.boundary_condition = boundary_conditions.outdoors
            if isinstance(face.boundary_condition, Surface) and isinstance(face.type, Wall): # surface in contact with adjacent buildings
                face.boundary_condition = boundary_conditions.adiabatic

As you can see from the following picture between the ground and the first floor it is not detecting any adjacency, it sets it as outdoors because it is an adiabatic RoofCeiling:

Accordingly, the first floor floor is set to ground as boundary condition.


The same thing occurs between first and second floor. For the other floors it is correct.
However, if I double the tolerance in the solve_adjacency function (2*tolerance, as written in that line comment) I am able to solve this issue only between the first and second floor. I still have the problem between the ground and the first floor.
It is strange because when I try to do the same thing with the components I don’t have this issue, it is perfectly able to find the adjacencies. Therefore, it has to be something in my code but I couldn’t find a way to solve it.
I attach the two files, in the gh file there is the python script I employed so far.
FloorCeilingAdjacency.3dm (50.8 KB)FloorCeilingAdjacency.gh (17.0 KB)

@fbattini,

FYI, your component is working correctly for me, with the default tolerance, in Rhino 6:


image

The absolute tolerance in my Rhino is 0.01, what is it on yours?

1 Like

Hi @SaeranVasanthakumar! Thank you very much for your reply. I work in meters, so my tolerance is the same as yours 0.01.
Actually, I never try to close Rhino and Grasshopper and run the script again. It is working for me too, now :man_facepalming:. Sometimes the easy solution is the best one. I had some other script opened and maybe I had some conflict that caused the problem.
I am happy it is solved and thank you a lot for you help :grinning:

1 Like