Ejemplo n.º 1
0
def test_polyface3d_to_from_dict_hole():
    """Test the to/from dict of Polyface3D objects with a hole."""
    bound_pts = [Point3D(0, 0), Point3D(3, 0), Point3D(3, 3), Point3D(0, 3)]
    hole_pts = [Point3D(1, 1), Point3D(2, 1), Point3D(2, 2), Point3D(1, 2)]
    face = Face3D(bound_pts, None, [hole_pts])
    polyface = Polyface3D.from_offset_face(face, 1)

    polyface_dict = polyface.to_dict()
    new_polyface = Polyface3D.from_dict(polyface_dict)

    assert len(new_polyface.vertices) == 16
    assert len(new_polyface.face_indices) == 10
    assert len(new_polyface.faces) == 10
    assert len(new_polyface.edge_indices) == 24
    assert len(new_polyface.edges) == 24
    assert len(new_polyface.naked_edges) == 0
    assert len(new_polyface.non_manifold_edges) == 0
    assert len(new_polyface.internal_edges) == 24
    assert new_polyface.area == pytest.approx(32, rel=1e-3)
    assert new_polyface.volume == pytest.approx(8, rel=1e-3)
    assert new_polyface.is_solid

    assert new_polyface.faces[0].normal.z == pytest.approx(-1, rel=1e-3)
    assert new_polyface.faces[-1].normal.z == pytest.approx(1, rel=1e-3)
    assert new_polyface.faces[0].has_holes
    assert new_polyface.faces[-1].has_holes
    for face in polyface.faces:
        assert not face.is_clockwise
Ejemplo n.º 2
0
def test_group_by_orientation():
    """Test the group_by_orientation method."""
    pts_1 = (Point3D(0, 0), Point3D(15, 0), Point3D(10, 5), Point3D(5, 5))
    pts_2 = (Point3D(15, 0), Point3D(15, 15), Point3D(10, 10), Point3D(10, 5))
    pts_3 = (Point3D(0, 15), Point3D(5, 10), Point3D(10, 10), Point3D(15, 15))
    pts_4 = (Point3D(0, 0), Point3D(5, 5), Point3D(5, 10), Point3D(0, 15))
    pts_5 = (Point3D(5, 5), Point3D(10, 5), Point3D(10, 10), Point3D(5, 10))
    pf_1 = Polyface3D.from_offset_face(Face3D(pts_1), 3)
    pf_2 = Polyface3D.from_offset_face(Face3D(pts_2), 3)
    pf_3 = Polyface3D.from_offset_face(Face3D(pts_3), 3)
    pf_4 = Polyface3D.from_offset_face(Face3D(pts_4), 3)
    pf_5 = Polyface3D.from_offset_face(Face3D(pts_5), 3)
    room_1 = Room.from_polyface3d('Zone1', pf_1)
    room_2 = Room.from_polyface3d('Zone2', pf_2)
    room_3 = Room.from_polyface3d('Zone3', pf_3)
    room_4 = Room.from_polyface3d('Zone4', pf_4)
    room_5 = Room.from_polyface3d('Zone5', pf_5)

    rooms = [room_1, room_2, room_3, room_4, room_5]
    adj_info = Room.solve_adjacency(rooms, 0.01)
    grouped_rooms, core_rooms, orientations = Room.group_by_orientation(rooms)

    assert len(grouped_rooms) == 4
    assert len(core_rooms) == 1
    assert orientations == [0.0, 90.0, 180.0, 270.0]
def test_polyface3d_init_from_faces_tolerance():
    """Test the initialization of Polyface3D from_faces with a tolerance."""
    pts_1 = [Point3D(0, 0, 0), Point3D(0, 2, 0), Point3D(2, 2, 0), Point3D(2, 0, 0)]
    pts_2 = [Point3D(0, 0, 0), Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(0, 2, 0)]
    pts_3 = [Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(0, 0, 2)]
    pts_4 = [Point3D(2, 2, 0), Point3D(0, 2, 0), Point3D(0, 2, 2), Point3D(2, 2, 2)]
    pts_5 = [Point3D(2, 2, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(2, 2, 2)]
    pts_6 = [Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 0, 2)]
    pts_7 = [Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 0, 2.0001)]
    face_1 = Face3D(pts_1)
    face_2 = Face3D(pts_2)
    face_3 = Face3D(pts_3)
    face_4 = Face3D(pts_4)
    face_5 = Face3D(pts_5)
    face_6 = Face3D(pts_6)
    face_7 = Face3D(pts_7)
    polyface_1 = Polyface3D.from_faces(
        [face_1, face_2, face_3, face_4, face_5, face_6], 0.001)
    polyface_2 = Polyface3D.from_faces(
        [face_1, face_2, face_3, face_4, face_5, face_7], 0.001)
    polyface_3 = Polyface3D.from_faces(
        [face_1, face_2, face_3, face_4, face_5, face_7], 0.000001)

    assert polyface_1.is_solid
    assert polyface_2.is_solid
    assert not polyface_3.is_solid
Ejemplo n.º 4
0
def test_equality():
    """Test the equality of Polyface3D objects."""
    pts = [
        Point3D(0, 0, 0),
        Point3D(0, 2, 0),
        Point3D(2, 2, 0),
        Point3D(2, 0, 0),
        Point3D(0, 0, 2),
        Point3D(0, 2, 2),
        Point3D(2, 2, 2),
        Point3D(2, 0, 2)
    ]
    face_indices = [[(0, 1, 2, 3)], [(0, 4, 5, 1)], [(0, 3, 7, 4)],
                    [(2, 1, 5, 6)], [(2, 3, 7, 6)], [(4, 5, 6, 7)]]
    face_indices_2 = [[(0, 1, 2, 3)], [(0, 4, 5, 1)], [(0, 3, 7, 4)],
                      [(2, 1, 5, 6)], [(2, 3, 7, 6)]]
    polyface = Polyface3D(pts, face_indices)
    polyface_dup = polyface.duplicate()
    polyface_alt = Polyface3D(pts, face_indices_2)

    assert polyface is polyface
    assert polyface is not polyface_dup
    assert polyface == polyface_dup
    assert hash(polyface) == hash(polyface_dup)
    assert polyface != polyface_alt
    assert hash(polyface) != hash(polyface_alt)
def test_polyface3d_to_from_dict_with_overlap():
    """Test the to/from dict of Polyface3D objects with overlapping edges."""
    pts_1 = [Point3D(0, 0, 0), Point3D(0, 2, 0), Point3D(2, 2, 0), Point3D(2, 0, 0)]
    pts_2 = [Point3D(0, 0, 0), Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(0, 2, 0)]
    pts_3 = [Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(0, 0, 2)]
    pts_4 = [Point3D(2, 2, 0), Point3D(0, 2, 0), Point3D(0, 2, 2), Point3D(2, 2, 2)]
    pts_5 = [Point3D(2, 2, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(2, 2, 2)]
    pts_6 = [Point3D(0, 0, 2), Point3D(0, 1, 2), Point3D(2, 1, 2), Point3D(2, 0, 2)]
    pts_7 = [Point3D(0, 1, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 1, 2)]
    face_1 = Face3D(pts_1)
    face_2 = Face3D(pts_2)
    face_3 = Face3D(pts_3)
    face_4 = Face3D(pts_4)
    face_5 = Face3D(pts_5)
    face_6 = Face3D(pts_6)
    face_7 = Face3D(pts_7)
    polyface = Polyface3D.from_faces(
        [face_1, face_2, face_3, face_4, face_5, face_6, face_7], 0.01)
    new_polyface = polyface.merge_overlapping_edges(0.0001, 0.0001)
    assert new_polyface.is_solid
    assert len(new_polyface.naked_edges) == 0
    assert len(new_polyface.internal_edges) == 13

    polyface_dict = new_polyface.to_dict()
    dict_polyface = Polyface3D.from_dict(polyface_dict)
    assert isinstance(dict_polyface, Polyface3D)
    assert dict_polyface.to_dict() == polyface_dict
    assert dict_polyface.is_solid
    assert len(dict_polyface.naked_edges) == 0
    assert len(dict_polyface.internal_edges) == 13
def test_polyface3d_init_from_faces_coplanar():
    """Test the initialization of Polyface3D from_faces with two coplanar faces."""
    # this is an important case that must be solved
    # can be done by iterating through naked edges and finding colinear ones
    pts_1 = [Point3D(0, 0, 0), Point3D(0, 2, 0), Point3D(2, 2, 0), Point3D(2, 0, 0)]
    pts_2 = [Point3D(0, 0, 0), Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(0, 2, 0)]
    pts_3 = [Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(0, 0, 2)]
    pts_4 = [Point3D(2, 2, 0), Point3D(0, 2, 0), Point3D(0, 2, 2), Point3D(2, 2, 2)]
    pts_5 = [Point3D(2, 2, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(2, 2, 2)]
    pts_6 = [Point3D(0, 0, 2), Point3D(0, 1, 2), Point3D(2, 1, 2), Point3D(2, 0, 2)]
    pts_7 = [Point3D(0, 1, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 1, 2)]
    face_1 = Face3D(pts_1)
    face_2 = Face3D(pts_2)
    face_3 = Face3D(pts_3)
    face_4 = Face3D(pts_4)
    face_5 = Face3D(pts_5)
    face_6 = Face3D(pts_6)
    face_7 = Face3D(pts_7)
    polyface = Polyface3D.from_faces(
        [face_1, face_2, face_3, face_4, face_5, face_6, face_7], 0.01)
    polyface_2 = Polyface3D.from_faces(
        [face_1, face_2, face_3, face_4, face_5, face_7], 0.01)

    assert not polyface.is_solid
    assert len(polyface.naked_edges) != 0

    new_polyface = polyface.merge_overlapping_edges(0.0001, 0.0001)
    assert new_polyface.is_solid
    assert len(new_polyface.naked_edges) == 0
    assert len(new_polyface.internal_edges) == 13

    new_polyface_2 = polyface_2.merge_overlapping_edges(0.0001, 0.0001)
    assert not new_polyface_2.is_solid
    assert len(new_polyface_2.naked_edges) != 0
Ejemplo n.º 7
0
def test_floor_mesh_grid():
    """Test the generation of a mesh grid from the floor of a box."""
    polyface = Polyface3D.from_box(5, 10, 3)
    floor_grid = polyface.faces[0].get_mesh_grid(1, 1, 1, True)
    assert len(floor_grid.faces) == 50

    angle = -1 * math.radians(45)
    x_axis = Vector3D(1, 0, 0).rotate_xy(angle)
    base_plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 0), x_axis)
    polyface = Polyface3D.from_box(5, 10, 3, base_plane)
    floor_grid = polyface.faces[0].get_mesh_grid(1, 1, 1, True)
    assert len(floor_grid.faces) == 50
Ejemplo n.º 8
0
def test_compute_bounding_box_extents_complex():
    """Test the bounding box extents of ladybug_geometry."""
    # South Room 1: 21 x 10.5 x 3
    szone1 = Face3D(
        [Point3D(0, 0),
         Point3D(21, 0),
         Point3D(21, 10.5),
         Point3D(0, 10.5)])
    sroom1 = Room.from_polyface3d('SouthRoom1',
                                  Polyface3D.from_offset_face(szone1, 3))

    # North Room 1: 21 x 10.5 x 3
    nzone1 = Face3D(
        [Point3D(0, 10.5),
         Point3D(21, 10.5),
         Point3D(21, 21),
         Point3D(0, 21)])
    nroom1 = Room.from_polyface3d('NorthRoom1',
                                  Polyface3D.from_offset_face(nzone1, 3))

    # South Room 2: 21 x 10.5 x 3
    szone2 = Face3D([
        Point3D(0, 0, 3),
        Point3D(21, 0, 3),
        Point3D(21, 10.5, 3),
        Point3D(0, 10.5, 3)
    ])
    sroom2 = Room.from_polyface3d('SouthRoom2',
                                  Polyface3D.from_offset_face(szone2, 3))

    # North Room 2: 21 x 10.5 x 3
    nzone2 = Face3D([
        Point3D(0, 10.5, 3),
        Point3D(21, 10.5, 3),
        Point3D(21, 21, 3),
        Point3D(0, 21, 3)
    ])
    nroom2 = Room.from_polyface3d('NorthRoom2',
                                  Polyface3D.from_offset_face(nzone2, 3))

    rooms = [sroom1, nroom1, sroom2, nroom2]
    model = Model('Four_Zone_Simple', rooms)

    # Rotate the buildings
    theta = 30.0
    model.rotate_xy(theta, rooms[0].geometry.vertices[-1])
    geoms = [room.geometry for room in model.rooms]
    xx, yy, zz = bounding_box_extents(geoms, math.radians(theta))

    assert xx == pytest.approx(21, abs=1e-10)
    assert yy == pytest.approx(21, abs=1e-10)
    assert zz == pytest.approx(6, abs=1e-10)
def test_min_max_center():
    """Test the Face3D min, max and center."""
    polyface_1 = Polyface3D.from_box(2, 4, 2)
    polyface_2 = Polyface3D.from_box(math.sqrt(2), math.sqrt(2), 2, Plane(
        Vector3D(0, 0, 1), Point3D(1, 0, 0), Vector3D(1, 1, 0)))

    assert polyface_1.min == Point3D(0, 0, 0)
    assert polyface_1.max == Point3D(2, 4, 2)
    assert polyface_1.center == Point3D(1, 2, 1)
    assert polyface_1.volume == pytest.approx(16, rel=1e-3)

    assert polyface_2.min == Point3D(0, 0, 0)
    assert polyface_2.max == Point3D(2, 2, 2)
    assert polyface_2.center == Point3D(1, 1, 1)
    assert polyface_2.volume == pytest.approx(4, rel=1e-3)
def test_overlapping_bounding_boxes():
    """Test the Polyface3D overlapping_bounding_boxes method."""
    polyface_1 = Polyface3D.from_box(1, 1, 1, Plane(o=Point3D(1, 1, 2)))
    polyface_2 = Polyface3D.from_box(1, 1, 1, Plane(o=Point3D(1, 1, 1)))
    polyface_3 = Polyface3D.from_box(1, 1, 1, Plane(o=Point3D(2, 1, 2)))
    polyface_4 = Polyface3D.from_box(1, 1, 1, Plane(o=Point3D(1, 2, 2)))
    polyface_5 = Polyface3D.from_box(1, 1, 1, Plane(o=Point3D(0, 0, 0)))

    assert Polyface3D.overlapping_bounding_boxes(polyface_1, polyface_2, 0.01)
    assert Polyface3D.overlapping_bounding_boxes(polyface_1, polyface_3, 0.01)
    assert Polyface3D.overlapping_bounding_boxes(polyface_1, polyface_4, 0.01)
    assert not Polyface3D.overlapping_bounding_boxes(polyface_1, polyface_5, 0.01)
Ejemplo n.º 11
0
def test_polyface3d_init_from_offset_face():
    """Test the initalization of Poyface3D from_offset_face."""
    face = Face3D.from_rectangle(2, 2)
    polyface = Polyface3D.from_offset_face(face, 2)

    assert len(polyface.vertices) == 8
    assert len(polyface.face_indices) == 6
    assert len(polyface.faces) == 6
    assert len(polyface.edge_indices) == 12
    assert len(polyface.edges) == 12
    assert len(polyface.naked_edges) == 0
    assert len(polyface.non_manifold_edges) == 0
    assert len(polyface.internal_edges) == 12
    assert polyface.area == 24
    assert polyface.volume == 8
    assert polyface.is_solid

    for f in polyface.faces:
        assert f.is_clockwise is False
    for e in polyface.edges:
        assert e.length == 2

    assert polyface.faces[0].normal.z == pytest.approx(-1, rel=1e-3)
    assert polyface.faces[-1].normal.z == pytest.approx(1, rel=1e-3)
    for face in polyface.faces:
        assert not face.is_clockwise
def test_polyface3d_init_solid():
    """Test the initialization of Polyface3D and basic properties of solid objects."""
    pts = [Point3D(0, 0, 0), Point3D(0, 2, 0), Point3D(2, 2, 0), Point3D(2, 0, 0),
           Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(2, 2, 2), Point3D(2, 0, 2)]
    face_indices = [[(0, 1, 2, 3)], [(0, 4, 5, 1)], [(0, 3, 7, 4)],
                    [(2, 1, 5, 6)], [(2, 3, 7, 6)], [(4, 5, 6, 7)]]
    polyface = Polyface3D(pts, face_indices)

    assert len(polyface.vertices) == 8
    assert len(polyface.face_indices) == 6
    assert len(polyface.faces) == 6
    assert len(polyface.edge_indices) == 12
    assert len(polyface.edges) == 12
    assert len(polyface.naked_edges) == 0
    assert len(polyface.non_manifold_edges) == 0
    assert len(polyface.internal_edges) == 12
    assert polyface.area == 24
    assert polyface.volume == 8
    assert polyface.is_solid

    for face in polyface.faces:
        assert face.area == 4
        assert face.is_clockwise is False
    assert polyface.faces[0].normal == Vector3D(0, 0, -1)
    assert polyface.faces[1].normal == Vector3D(-1, 0, 0)
    assert polyface.faces[2].normal == Vector3D(0, -1, 0)
    assert polyface.faces[3].normal == Vector3D(0, 1, 0)
    assert polyface.faces[4].normal == Vector3D(1, 0, 0)
    assert polyface.faces[5].normal == Vector3D(0, 0, 1)
def test_polyface3d_init_from_faces_open():
    """Test the initialization of Polyface3D from_faces with an open object."""
    pts_1 = [Point3D(0, 0, 0), Point3D(0, 2, 0), Point3D(2, 2, 0), Point3D(2, 0, 0)]
    pts_2 = [Point3D(0, 0, 0), Point3D(0, 0, 2), Point3D(0, 2, 2), Point3D(0, 2, 0)]
    pts_3 = [Point3D(0, 0, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(0, 0, 2)]
    pts_4 = [Point3D(2, 2, 0), Point3D(0, 2, 0), Point3D(0, 2, 2), Point3D(2, 2, 2)]
    pts_5 = [Point3D(2, 2, 0), Point3D(2, 0, 0), Point3D(2, 0, 2), Point3D(2, 2, 2)]
    face_1 = Face3D(pts_1)
    face_2 = Face3D(pts_2)
    face_3 = Face3D(pts_3)
    face_4 = Face3D(pts_4)
    face_5 = Face3D(pts_5)
    polyface = Polyface3D.from_faces([face_1, face_2, face_3, face_4, face_5], 0.01)

    assert len(polyface.vertices) == 8
    assert len(polyface.face_indices) == 5
    assert len(polyface.faces) == 5
    assert len(polyface.edge_indices) == 12
    assert len(polyface.edges) == 12
    assert len(polyface.naked_edges) == 4
    assert len(polyface.non_manifold_edges) == 0
    assert len(polyface.internal_edges) == 8
    assert polyface.area == 20
    assert polyface.volume == 0
    assert polyface.is_solid is False

    for face in polyface.faces:
        assert face.area == 4
        assert face.is_clockwise is False
Ejemplo n.º 14
0
def test_to_dict_air_walls():
    """Test the Model to_dict method with a multi-zone house."""
    pts_1 = [Point3D(0, 0), Point3D(30, 0), Point3D(20, 10), Point3D(10, 10)]
    pts_2 = [Point3D(0, 0), Point3D(10, 10), Point3D(10, 20), Point3D(0, 30)]
    pts_3 = [Point3D(10, 20), Point3D(20, 20), Point3D(30, 30), Point3D(0, 30)]
    pts_4 = [Point3D(30, 0), Point3D(30, 30), Point3D(20, 20), Point3D(20, 10)]
    verts = [pts_1, pts_2, pts_3, pts_4]
    rooms = []
    for i, f_vert in enumerate(verts):
        pface = Polyface3D.from_offset_face(Face3D(f_vert), 3)
        room = Room.from_polyface3d('PerimeterRoom{}'.format(i), pface)
        room.properties.energy.program_type = office_program
        room.properties.energy.add_default_ideal_air()
        rooms.append(room)
    rooms.append(Room.from_box('CoreRoom', 10, 10, 3, origin=Point3D(10, 10)))
    adj_info = Room.solve_adjacency(rooms, 0.01)
    for face_pair in adj_info['adjacent_faces']:
        face_pair[0].type = face_types.air_boundary
        face_pair[1].type = face_types.air_boundary

    model = Model('CorePerimeterOfficeFloor', rooms)
    model_dict = model.to_dict()
    assert model_dict['rooms'][-1]['faces'][1]['face_type'] == 'AirBoundary'
    new_model = Model.from_dict(model_dict)
    air_face_type = new_model.rooms[-1].faces[1]
    assert air_face_type.type == face_types.air_boundary
    assert isinstance(air_face_type.properties.energy.construction, AirBoundaryConstruction)

    model_idf_str = model.to.idf(model)
    assert model_idf_str.count('Construction:AirBoundary') == 1
    assert model_idf_str.count('ZoneMixing') == 16
Ejemplo n.º 15
0
def test_envelope_components_by_type():

    zone_pts = Face3D([
        Point3D(0, 0, 0),
        Point3D(20, 0, 0),
        Point3D(20, 10, 0),
        Point3D(0, 10, 0)
    ])
    room = Room.from_polyface3d('SouthRoom',
                                Polyface3D.from_offset_face(zone_pts, 3))

    door_pts = [
        Point3D(2, 10, 0.01),
        Point3D(4, 10, 0.01),
        Point3D(4, 10, 2.50),
        Point3D(2, 10, 2.50)
    ]
    door = Door('FrontDoor', Face3D(door_pts))
    room[3].add_door(door)  # Door to north face
    room[1].apertures_by_ratio(0.3)  # Window on south face

    ext_faces, int_faces = room.properties.energy.envelope_components_by_type()

    walls, roofs, floors, apertures, doors = ext_faces

    assert len(walls) == 4
    assert len(roofs) == 1
    assert len(floors) == 0
    assert len(apertures) == 1
    assert len(doors) == 1

    for types in int_faces:
        assert len(types) == 0
Ejemplo n.º 16
0
    def __init__(self, identifier, faces, tolerance=0, angle_tolerance=0):
        """Initialize Room."""
        _BaseWithShade.__init__(self, identifier)  # process the identifier

        # process the zone volume geometry
        if not isinstance(faces, tuple):
            faces = tuple(faces)
        for face in faces:
            assert isinstance(face, Face), \
                'Expected honeybee Face. Got {}'.format(type(face))
            face._parent = self

        if tolerance == 0:
            self._faces = faces
            self._geometry = None  # calculated later from faces or added by classmethods
        else:
            # try to get a closed volume between the faces
            room_polyface = Polyface3D.from_faces(
                tuple(face.geometry for face in faces), tolerance)
            if not room_polyface.is_solid and angle_tolerance != 0:
                ang_tol = math.radians(angle_tolerance)
                room_polyface = room_polyface.merge_overlapping_edges(
                    tolerance, ang_tol)
            # replace honeybee face geometry with versions that are facing outwards
            if room_polyface.is_solid:
                for i, correct_face3d in enumerate(room_polyface.faces):
                    faces[i]._geometry = correct_face3d
            self._faces = faces
            self._geometry = room_polyface

        self._multiplier = 1  # default value that can be overridden later
        self._story = None  # default value that can be overridden later
        self._properties = RoomProperties(self)  # properties for extensions
Ejemplo n.º 17
0
def test_polyface3d_init_from_polyface():
    """Test the initalization of room from a Poyface3D."""
    bound_pts = [Point3D(0, 0), Point3D(3, 0), Point3D(3, 3), Point3D(0, 3)]
    hole_pts = [
        Point3D(1, 1, 0),
        Point3D(2, 1, 0),
        Point3D(2, 2, 0),
        Point3D(1, 2, 0)
    ]
    face = Face3D(bound_pts, None, [hole_pts])
    polyface = Polyface3D.from_offset_face(face, 3)
    room = Room.from_polyface3d('Donut Zone', polyface)

    assert room.name == 'DonutZone'
    assert room.display_name == 'Donut Zone'
    assert isinstance(room.geometry, Polyface3D)
    assert len(room.geometry.vertices) == 16
    assert len(room) == 10
    assert room.center == Point3D(1.5, 1.5, 1.5)
    assert room.volume == 24
    assert room.floor_area == 8
    assert room.exposed_area == 56
    assert room.exterior_wall_area == 48
    assert room.exterior_aperture_area == 0
    assert room.average_floor_height == 0
    assert not room.has_parent
    assert room.check_solid(0.01, 1)
Ejemplo n.º 18
0
 def geometry(self):
     """Get a ladybug_geometry Polyface3D object representing the room."""
     if self._geometry is None:
         self._geometry = Polyface3D.from_faces(
             tuple(face.geometry for face in self._faces),
             0)  # use 0 tolerance
     return self._geometry
Ejemplo n.º 19
0
    def check_solid(self,
                    tolerance=0.01,
                    angle_tolerance=1,
                    raise_exception=True):
        """Check whether the Room is a closed solid to within the input tolerances.

        Args:
            tolerance: tolerance: The maximum difference between x, y, and z values
                at which face vertices are considered equivalent. This is used in
                determining whether the faces form a closed volume. Default: 0.01,
                suitable for objects in meters.
            angle_tolerance: The max angle difference in degrees that vertices are
                allowed to differ from one another in order to consider them colinear.
                Default: 1 degree.
            raise_exception: Boolean to note whether a ValueError should be raised
                if the room geometry does not form a closed solid.
        """
        if self._geometry is not None and self.geometry.is_solid:
            return True
        face_geometries = tuple(face.geometry for face in self._faces)
        self._geometry = Polyface3D.from_faces(face_geometries, tolerance)
        if self.geometry.is_solid:
            return True
        ang_tol = math.radians(angle_tolerance)
        self._geometry = self.geometry.merge_overlapping_edges(
            tolerance, ang_tol)
        if self.geometry.is_solid:
            return True
        if raise_exception:
            raise ValueError(
                'Room "{}" is not closed to within {} tolerance and {} angle '
                'tolerance.'.format(self.display_name, tolerance,
                                    angle_tolerance))
        return False
Ejemplo n.º 20
0
def model_complete_office_floor(directory):
    pts_1 = [Point3D(0, 0), Point3D(30, 0), Point3D(20, 10), Point3D(10, 10)]
    pts_2 = [Point3D(0, 0), Point3D(10, 10), Point3D(10, 20), Point3D(0, 30)]
    pts_3 = [Point3D(10, 20), Point3D(20, 20), Point3D(30, 30), Point3D(0, 30)]
    pts_4 = [Point3D(30, 0), Point3D(30, 30), Point3D(20, 20), Point3D(20, 10)]
    verts = [pts_1, pts_2, pts_3, pts_4]
    rooms = []
    for i, f_vert in enumerate(verts):
        pface = Polyface3D.from_offset_face(Face3D(f_vert), 3)
        room = Room.from_polyface3d('PerimeterRoom{}'.format(i), pface)
        room.properties.energy.program_type = prog_type_lib.office_program
        room.properties.energy.add_default_ideal_air()
        rooms.append(room)
    rooms.append(Room.from_box('CoreRoom', 10, 10, 3, origin=Point3D(10, 10)))
    adj_info = Room.solve_adjacency(rooms, 0.01)
    for face_pair in adj_info['adjacent_faces']:
        face_pair[0].type = face_types.air_boundary
        face_pair[1].type = face_types.air_boundary
    for room in rooms:
        for face in room:
            if isinstance(face.type, (Floor, RoofCeiling)):
                face.boundary_condition = boundary_conditions.adiabatic

    model = Model('Core_Perimeter_Office_Floor', rooms)

    dest_file = os.path.join(directory, 'model_complete_office_floor.json')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(), fp, indent=4)
Ejemplo n.º 21
0
def to_polyface3d(geo, meshing_parameters=None):
    """A Ladybug Polyface3D object from a Rhino Brep.

    Args:
        geo: A Rhino Brep, Surface or Mesh that will be converted into a single
            Ladybug Polyface3D.
        meshing_parameters: Optional Rhino Meshing Parameters to describe how
            curved faces should be converted into planar elements. If None,
            Rhino's Default Meshing Parameters will be used.
    """
    mesh_par = meshing_parameters or rg.MeshingParameters.Default  # default
    if not isinstance(
            geo, rg.Mesh) and _planar.has_curved_face(geo):  # keep solidity
        return Polyface3D.from_faces(_planar.curved_solid_faces(geo, mesh_par),
                                     tolerance)
    return Polyface3D.from_faces(to_face3d(geo, mesh_par), tolerance)
Ejemplo n.º 22
0
    def find_adjacency(rooms, tolerance=0.01):
        """Get a list with all adjacent pairs of Faces between input rooms.

        Note that this method does not change any boundary conditions of the input
        rooms or mutate them in any way. It's purely a geometric analysis of the
        faces between rooms.

        Args:
            rooms: A list of rooms for which adjacencies will be solved.
            tolerance: The minimum difference between the coordinate values of two
                faces at which they can be considered centered adjacent. Default: 0.01,
                suitable for objects in meters.

        Returns:
            A list of tuples with each tuple containing 2 objects for Faces that
            are adjacent to one another.
        """
        adj_faces = []  # lists of adjacencies to track
        for i, room_1 in enumerate(rooms):
            try:
                for room_2 in rooms[i + 1:]:
                    if not Polyface3D.overlapping_bounding_boxes(
                            room_1.geometry, room_2.geometry, tolerance):
                        continue  # no overlap in bounding box; adjacency impossible
                    for face_1 in room_1._faces:
                        for face_2 in room_2._faces:
                            if face_1.geometry.is_centered_adjacent(
                                    face_2.geometry, tolerance):
                                adj_faces.append((face_1, face_2))
                                break
            except IndexError:
                pass  # we have reached the end of the list of zones
        return adj_faces
Ejemplo n.º 23
0
def test_intersect_line_ray():
    """Test the Polyface3D intersect_line_ray method."""
    pts = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 1, 2),
           Point3D(1, 1, 2), Point3D(1, 2, 2), Point3D(0, 2, 2))
    plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2))
    face = Face3D(pts, plane)
    polyface = Polyface3D.from_offset_face(face, 1)
    ray_1 = Ray3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 1))
    ray_2 = Ray3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, -1))
    ray_3 = Ray3D(Point3D(1.5, 1.5, 0), Vector3D(0, 0, 1))
    ray_4 = Ray3D(Point3D(-1, -1, 0), Vector3D(0, 0, 1))
    line_1 = LineSegment3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 3))
    line_2 = LineSegment3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 1))

    assert polyface.does_intersect_line_ray_exist(ray_1) is True
    assert polyface.does_intersect_line_ray_exist(ray_2) is False
    assert polyface.does_intersect_line_ray_exist(ray_3) is False
    assert polyface.does_intersect_line_ray_exist(ray_4) is False
    assert polyface.does_intersect_line_ray_exist(line_1) is True
    assert polyface.does_intersect_line_ray_exist(line_2) is False

    assert polyface.intersect_line_ray(ray_1) == [
        Point3D(0.5, 0.5, 2), Point3D(0.5, 0.5, 3)
    ]
    assert polyface.intersect_line_ray(ray_2) == []
    assert polyface.intersect_line_ray(ray_3) == []
    assert polyface.intersect_line_ray(ray_4) == []
    assert polyface.intersect_line_ray(line_1) == [
        Point3D(0.5, 0.5, 2), Point3D(0.5, 0.5, 3)
    ]
    assert polyface.intersect_line_ray(line_2) == []
Ejemplo n.º 24
0
def test_reflect():
    """Test the Polyface3D reflect method."""
    polyface = Polyface3D.from_box(1, 1, 1, Plane(o=Point3D(1, 1, 2)))

    origin_1 = Point3D(1, 0, 2)
    normal_1 = Vector3D(1, 0, 0)
    normal_2 = Vector3D(-1, -1, 0).normalize()

    test_1 = polyface.reflect(normal_1, origin_1)
    assert test_1[0].x == pytest.approx(1, rel=1e-3)
    assert test_1[0].y == pytest.approx(1, rel=1e-3)
    assert test_1[0].z == pytest.approx(2, rel=1e-3)
    assert test_1[2].x == pytest.approx(0, rel=1e-3)
    assert test_1[2].y == pytest.approx(2, rel=1e-3)
    assert test_1[2].z == pytest.approx(2, rel=1e-3)

    test_1 = polyface.reflect(normal_2, Point3D(0, 0, 2))
    assert test_1[0].x == pytest.approx(-1, rel=1e-3)
    assert test_1[0].y == pytest.approx(-1, rel=1e-3)
    assert test_1[0].z == pytest.approx(2, rel=1e-3)
    assert test_1[2].x == pytest.approx(-2, rel=1e-3)
    assert test_1[2].y == pytest.approx(-2, rel=1e-3)
    assert test_1[2].z == pytest.approx(2, rel=1e-3)

    test_2 = polyface.reflect(normal_2, origin_1)
    assert test_2[0].x == pytest.approx(0, rel=1e-3)
    assert test_2[0].y == pytest.approx(0, rel=1e-3)
    assert test_2[0].z == pytest.approx(2, rel=1e-3)
    assert test_2[2].x == pytest.approx(-1, rel=1e-3)
    assert test_2[2].y == pytest.approx(-1, rel=1e-3)
    assert test_2[2].z == pytest.approx(2, rel=1e-3)
Ejemplo n.º 25
0
def test_rotate():
    """Test the Polyface3D rotate method."""
    polyface = Polyface3D.from_box(2, 2, 2, Plane(o=Point3D(0, 0, 2)))
    origin = Point3D(0, 0, 0)
    axis = Vector3D(1, 0, 0)

    test_1 = polyface.rotate(axis, math.pi, origin)
    assert test_1[0].x == pytest.approx(0, rel=1e-3)
    assert test_1[0].y == pytest.approx(0, rel=1e-3)
    assert test_1[0].z == pytest.approx(-2, rel=1e-3)
    assert test_1[2].x == pytest.approx(2, rel=1e-3)
    assert test_1[2].y == pytest.approx(-2, rel=1e-3)
    assert test_1[2].z == pytest.approx(-2, rel=1e-3)
    assert polyface.area == test_1.area
    assert polyface.volume == test_1.volume
    assert len(polyface.vertices) == len(test_1.vertices)

    test_2 = polyface.rotate(axis, math.pi / 2, origin)
    assert test_2[0].x == pytest.approx(0, rel=1e-3)
    assert test_2[0].y == pytest.approx(-2, rel=1e-3)
    assert test_2[0].z == pytest.approx(0, rel=1e-3)
    assert test_2[2].x == pytest.approx(2, rel=1e-3)
    assert test_2[2].y == pytest.approx(-2, rel=1e-3)
    assert test_2[2].z == pytest.approx(2, rel=1e-3)
    assert polyface.area == test_2.area
    assert polyface.volume == test_1.volume
    assert len(polyface.vertices) == len(test_2.vertices)
Ejemplo n.º 26
0
def test_polyface3d_init_open():
    """Test the initalization of Poyface3D and basic properties of open objects."""
    pts = [
        Point3D(0, 0, 0),
        Point3D(0, 2, 0),
        Point3D(2, 2, 0),
        Point3D(2, 0, 0),
        Point3D(0, 0, 2),
        Point3D(0, 2, 2),
        Point3D(2, 2, 2),
        Point3D(2, 0, 2)
    ]
    face_indices = [[(0, 1, 2, 3)], [(0, 4, 5, 1)], [(0, 3, 7, 4)],
                    [(2, 1, 5, 6)], [(2, 3, 7, 6)]]
    polyface = Polyface3D(pts, face_indices)

    assert len(polyface.vertices) == 8
    assert len(polyface.face_indices) == 5
    assert len(polyface.faces) == 5
    assert len(polyface.edge_indices) == 12
    assert len(polyface.edges) == 12
    assert len(polyface.naked_edges) == 4
    assert len(polyface.non_manifold_edges) == 0
    assert len(polyface.internal_edges) == 8
    assert polyface.area == 20
    assert polyface.volume == 0
    assert polyface.is_solid is False

    for face in polyface.faces:
        assert face.area == 4
        assert face.is_clockwise is False
Ejemplo n.º 27
0
def test_bounding_rectangle():
    """Test the bounding_rectangle methods with arrays of 3D objects."""
    plane1 = Plane(o=Point3D(-5, 0, 0))
    plane2 = Plane(o=Point3D(0, -4, 4))
    plane3 = Plane(o=Point3D(2, 2, -4))
    polyface1 = Polyface3D.from_box(2, 4, 2, plane1)
    polyface2 = Polyface3D.from_box(2, 4, 2, plane2)
    polyface3 = Polyface3D.from_box(2, 4, 2, plane3)

    min_pt, max_pt = bounding_rectangle([polyface1, polyface2, polyface3])
    assert min_pt == Point2D(-5, -4)
    assert max_pt == Point2D(4, 6)

    x_dom, y_dom = bounding_rectangle_extents(
        [polyface1, polyface2, polyface3])
    assert x_dom == 9
    assert y_dom == 10
Ejemplo n.º 28
0
def test_afn_plenum_zone():
    """Test case where no infiltration load exists."""
    zone_pts = Face3D(
        [Point3D(0, 0),
         Point3D(20, 0),
         Point3D(20, 10),
         Point3D(0, 10)])
    room = Room.from_polyface3d('PlenumRoom',
                                Polyface3D.from_offset_face(zone_pts, 1))
    room.properties.energy.program_type = prog_type_lib.plenum_program

    # Make model
    model = Model('PlenumSimple', [room])

    # generate afn, w/ average leakage
    afn.generate(model.rooms,
                 leakage_type='Medium',
                 use_room_infiltration=True)
    faces = model.faces

    # check ext wall
    crack = faces[1].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_medium_cracks']['wall_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_medium_cracks']['wall_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[1].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)

    # check roof
    crack = faces[5].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_medium_cracks']['roof_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_medium_cracks']['roof_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[5].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)

    # generate afn, w/ tight leakage
    afn.generate(model.rooms,
                 leakage_type='Excellent',
                 use_room_infiltration=False)
    faces = model.faces

    # check ext wall
    crack = faces[1].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_excellent_cracks']['wall_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_excellent_cracks']['wall_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[1].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)

    # check roof
    crack = faces[5].properties.energy.vent_crack
    chk_cof = CRACK_TEMPLATE_DATA['external_excellent_cracks']['roof_flow_cof']
    chk_exp = CRACK_TEMPLATE_DATA['external_excellent_cracks']['roof_flow_exp']
    assert crack.flow_coefficient == pytest.approx(chk_cof * faces[5].area,
                                                   abs=1e-10)
    assert crack.flow_exponent == pytest.approx(chk_exp, abs=1e-10)
Ejemplo n.º 29
0
def model_complete_holes(directory):
    bound_pts = [Point3D(0, 0), Point3D(9, 0), Point3D(9, 9), Point3D(0, 9)]
    hole_pts = [
        Point3D(3, 3, 0),
        Point3D(6, 3, 0),
        Point3D(6, 6, 0),
        Point3D(3, 6, 0)
    ]
    face = Face3D(bound_pts, None, [hole_pts])
    polyface = Polyface3D.from_offset_face(face, 3)
    room = Room.from_polyface3d('DonutZone', polyface)

    ap_bound_pts = [
        Point3D(0.5, 0, 0.5),
        Point3D(2.5, 0, 0.5),
        Point3D(2.5, 0, 2.5),
        Point3D(0.5, 0, 2.5)
    ]
    ap_hole_pts = [
        Point3D(1, 0, 1),
        Point3D(2, 0, 1),
        Point3D(2, 0, 2),
        Point3D(1, 0, 2)
    ]
    ap_face = Face3D(ap_bound_pts, None, [ap_hole_pts])
    ap = Aperture('HoleAperture', ap_face)
    for face in room.faces:
        if face.geometry.is_sub_face(ap_face, 0.01, 1.0):
            face.add_aperture(ap)

    shd_bound_pts = [
        Point3D(0, 0, 6),
        Point3D(9, 0, 6),
        Point3D(9, 9, 6),
        Point3D(0, 9, 6)
    ]
    shd_hole_pts1 = [
        Point3D(2, 2, 6),
        Point3D(4, 2, 6),
        Point3D(4, 4, 6),
        Point3D(2, 4, 6)
    ]
    shd_hole_pts2 = [
        Point3D(5, 5, 6),
        Point3D(7, 5, 6),
        Point3D(7, 7, 6),
        Point3D(5, 7, 6)
    ]
    s_face = Face3D(shd_bound_pts, None, [shd_hole_pts1, shd_hole_pts2])
    shd = Shade('Canopy', s_face)

    model = Model('Donut_Building', [room], orphaned_shades=[shd])

    dest_file = os.path.join(directory, 'model_complete_holes.json')
    with open(dest_file, 'w') as fp:
        json.dump(model.to_dict(), fp, indent=4)
Ejemplo n.º 30
0
def test_bounding_rectangle_angle():
    """Test the bounding_rectangle methods with an axis_angle."""
    plane1 = Plane(o=Point3D(-5, 0, 0))
    plane2 = Plane(o=Point3D(0, -4, 4))
    plane3 = Plane(o=Point3D(2, 2, -4))
    polyface1 = Polyface3D.from_box(2, 4, 2, plane1)
    polyface2 = Polyface3D.from_box(2, 4, 2, plane2)
    polyface3 = Polyface3D.from_box(2, 4, 2, plane3)

    min_pt, max_pt = bounding_rectangle([polyface1, polyface2, polyface3], 45)
    assert min_pt.x == pytest.approx(1.45, rel=1e-2)
    assert min_pt.y == pytest.approx(-4.89, rel=1e-2)
    assert max_pt.x == pytest.approx(-1.62, rel=1e-2)
    assert max_pt.y == pytest.approx(9.47, rel=1e-2)

    x_dom, y_dom = bounding_rectangle_extents(
        [polyface1, polyface2, polyface3], 45)
    assert x_dom == pytest.approx(10.6103, rel=1e-2)
    assert y_dom == pytest.approx(10.1589, rel=1e-2)