def add_door(door, points, vectors):
    """Add Door normals."""
    points.append(from_point3d(door.center))
    vectors.append(from_vector3d(door.normal))
    for shd in door.shades:
        points.append(from_point3d(shd.center))
        vectors.append(from_vector3d(shd.normal))
def add_aperture(aperture, points, vectors):
    """Add Aperture normals."""
    points.append(from_point3d(aperture.center))
    vectors.append(from_vector3d(aperture.normal))
    for shd in aperture.shades:
        points.append(from_point3d(shd.center))
        vectors.append(from_vector3d(shd.normal))
def add_face(face, points, vectors):
    """Add Face normals."""
    points.append(from_point3d(face.center))
    vectors.append(from_vector3d(face.normal))
    for ap in face.apertures:
        add_aperture(ap, points, vectors)
    for dr in face.doors:
        add_door(ap, points, vectors)
    for shd in face.shades:
        points.append(from_point3d(shd.center))
        vectors.append(from_vector3d(shd.normal))
def add_room(room, points, vectors):
    """Add Room normals."""
    for face in room.faces:
        add_face(face, points, vectors)
    for shd in room.shades:
        points.append(from_point3d(shd.center))
        vectors.append(from_vector3d(shd.normal))
def add_model(model, points, vectors):
    """Add Model normals."""
    for room in model.rooms:
        add_room(room, points, vectors)
    for face in model.orphaned_faces:
        add_face(face, points, vectors)
    for ap in model.orphaned_apertures:
        add_aperture(ap, points, vectors)
    for dr in model.orphaned_doors:
        add_door(door, points, vectors)
    for shd in model.orphaned_shades:
        points.append(from_point3d(shd.center))
        vectors.append(from_vector3d(shd.normal))
Ejemplo n.º 6
0
def build_window_meshes(_window_surface, _grid_size, _mesh_params):
    """Create the Ladybug Mesh3D grided mesh for the window being analysed
    
    Arguments:
        _window_surface: (Brep) A single window Brep from the scene
        _grid_size: (float)
        _mesh_params: (Rhino.Geometry.MeshingParameters)
    Returns: (tuple)
        points: (list: Ladybug Point3D) All the analysis points on the window
        normals: (list: Ladybug Normal) All the normals for the analysis points
        window_mesh: (ladybug_geometry.geometry3d.Mesh3D) The window
        window_back_mesh: (ladybug_geometry.geometry3d.Mesh3D) A copy of the window shifted 'back'
        just a little bit (0.1 units). Used when solving the 'unshaded' situation.
    """

    # create the gridded mesh for the window surface
    #---------------------------------------------------------------------------
    offset_dist = 0.001
    window_mesh = to_joined_gridded_mesh3d([_window_surface], _grid_size,
                                           offset_dist)
    window_rh_mesh = from_mesh3d(window_mesh)
    points = [from_point3d(pt) for pt in window_mesh.face_centroids]

    # Create a 'back' for the window
    #---------------------------------------------------------------------------
    # Mostly this is done so it can be passed to the ladybug_rhino.intersect.intersect_mesh_rays()
    # solver as a surfce which is certain to *not* shade the window at all
    window_back_mesh = None
    for sr in _window_surface.Surfaces:
        window_normal = sr.NormalAt(0.5, 0.5)
        window_normal.Unitize()
        window_normal = window_normal * -1 * 0.1

        window_back = _window_surface.Duplicate()
        window_back.Translate(window_normal)
        window_back_mesh = Rhino.Geometry.Mesh.CreateFromBrep(
            window_back, _mesh_params)[0]

    normals = [from_vector3d(vec) for vec in window_mesh.face_normals]

    return points, normals, window_mesh, window_back_mesh, window_rh_mesh
Ejemplo n.º 7
0
def deconstruct_sky_matrix(_sky_mtx):
    """Copied from Ladybug 'IncidentRadiation' Component
    
    Arguments:
        _sky_mtx: A Ladybug Sky Matrix for the season
    Returns: (tuple)
        sky_vecs: (list: _ )
        total_sky_rad: (list: _ )
    """

    mtx = de_objectify_output(_sky_mtx)
    total_sky_rad = [
        dir_rad + dif_rad for dir_rad, dif_rad in izip(mtx[1], mtx[2])
    ]
    lb_vecs = view_sphere.tregenza_dome_vectors if len(total_sky_rad) == 145 \
        else view_sphere.reinhart_dome_vectors
    if mtx[0][0] != 0:  # there is a north input for sky; rotate vectors
        north_angle = math.radians(mtx[0][0])
        lb_vecs = [vec.rotate_xy(north_angle) for vec in lb_vecs]
    sky_vecs = [from_vector3d(vec) for vec in lb_vecs]

    return sky_vecs, total_sky_rad
Ejemplo n.º 8
0
    _offset_dist_ = _offset_dist_ if _offset_dist_ is not None \
        else 0.1 / conversion_to_meters()

    # create the gridded mesh from the geometry
    study_mesh = to_joined_gridded_mesh3d(_geometry, _grid_size)
    points = [
        from_point3d(pt.move(vec * _offset_dist_))
        for pt, vec in zip(study_mesh.face_centroids, study_mesh.face_normals)
    ]
    hide_output(ghenv.Component, 1)

    # mesh the geometry and context
    shade_mesh = join_geometry_to_mesh(_geometry + context_)

    # get the study points and reverse the sun vectors (for backward ray-tracting)
    rev_vec = [from_vector3d(to_vector3d(vec).reverse()) for vec in _vectors]
    normals = [from_vector3d(vec) for vec in study_mesh.face_normals]

    # intersect the rays with the mesh
    int_matrix, angles = intersect_mesh_rays(shade_mesh,
                                             points,
                                             rev_vec,
                                             normals,
                                             parallel=parallel_)

    # compute the results
    int_mtx = objectify_output('Sun Intersection Matrix', int_matrix)
    if _timestep_ and _timestep_ != 1:  # divide by the timestep before output
        results = [sum(int_list) / _timestep_ for int_list in int_matrix]
    else:  # no division required
        results = [sum(int_list) for int_list in int_matrix]
Ejemplo n.º 9
0
    hide_output(ghenv.Component, 1)

    # mesh the geometry and context
    shade_mesh = join_geometry_to_mesh(_geometry + context_)

    # deconstruct the matrix and get the sky dome vectors
    mtx = de_objectify_output(_sky_mtx)
    total_sky_rad = [
        dir_rad + dif_rad for dir_rad, dif_rad in zip(mtx[1], mtx[2])
    ]
    lb_vecs = view_sphere.tregenza_dome_vectors if len(total_sky_rad) == 145 \
        else view_sphere.reinhart_dome_vectors
    if mtx[0][0] != 0:  # there is a north input for sky; rotate vectors
        north_angle = math.radians(mtx[0][0])
        lb_vecs = [vec.rotate_xy(north_angle) for vec in lb_vecs]
    sky_vecs = [from_vector3d(vec) for vec in lb_vecs]

    # intersect the rays with the mesh
    normals = [from_vector3d(vec) for vec in study_mesh.face_normals]
    int_matrix_init, angles = intersect_mesh_rays(shade_mesh,
                                                  points,
                                                  sky_vecs,
                                                  normals,
                                                  parallel=parallel_)

    # compute the results
    results = []
    int_matrix = []
    for int_vals, angles in zip(int_matrix_init, angles):
        pt_rel = [ival * math.cos(ang) for ival, ang in zip(int_vals, angles)]
        int_matrix.append(pt_rel)
Ejemplo n.º 10
0
        hoys_ = list(data_hoys.intersection(set(hoys_)))

    # initialize sunpath based on location
    sp = Sunpath.from_location(_location, north_, dl_saving_)

    # process all of the input hoys into altitudes, azimuths and vectors
    altitudes, azimuths, datetimes, moys, hoys, vectors, suns = [], [], [], [], [], [], []
    for hoy in hoys_:
        sun = sp.calculate_sun_from_hoy(hoy, solar_time_)
        if sun.is_during_day:
            altitudes.append(sun.altitude)
            azimuths.append(sun.azimuth)
            datetimes.append(sun.datetime)
            moys.append(sun.datetime.moy)
            hoys.append(sun.datetime.hoy)
            vectors.append(from_vector3d(sun.sun_vector))
            suns.append(sun)

    if len(data_) > 0 and len(
            hoys_) > 0:  # build a sunpath for each data collection
        title, all_sun_pts, all_analemma, all_daily, all_compass, all_col_pts, all_legends = \
            [], [], [], [], [], [], []
        for i, data in enumerate(data_):
            try:  # sense when several legend parameters are connected
                lpar = legend_par_[i]
            except IndexError:
                lpar = None if len(legend_par_) == 0 else legend_par_[-1]

            # move the center point so sun paths are not on top of one another
            fac = i * radius * 3
            center_pt_i = Point2D(center_pt.x + fac, center_pt.y)
Ejemplo n.º 11
0
    from ladybug_rhino.intersect import join_geometry_to_brep, bounding_box_extents, \
        trace_ray, normal_at_point
    from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree, \
        hide_output
except ImportError as e:
    raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))

if all_required_inputs(ghenv.Component):
    # check the _bounce_count_
    _bounce_count_ = 0 if _bounce_count_ is None else _bounce_count_ - 1
    assert _bounce_count_ >= 0, 'The input _bounce_count_ must be greater '  \
        'than zero. Got {}.'.format(_bounce_count_ + 1)
    # process the input sun vector
    lb_vec = to_vector3d(_vector).normalize()
    neg_lb_vec = -lb_vec
    vec = from_vector3d(lb_vec)

    # convert all of the _source_geo and contex into a single Brep for ray tracing
    rtrace_brep = join_geometry_to_brep(_source_geo + context_)

    # autocompute the first and last bounce length if it's unspecified
    if _first_length_ is None or _last_length_ is None:
        max_pt, min_pt = (to_point3d(p)
                          for p in bounding_box_extents(rtrace_brep))
        diag_dist = max_pt.distance_to_point(min_pt)
        _first_length_ = diag_dist if _first_length_ is None else _first_length_
        _last_length_ = diag_dist if _last_length_ is None else _last_length_

    # create the gridded mesh from the _source_geo and set up the starting rays
    study_mesh = to_joined_gridded_mesh3d(_source_geo, _grid_size)
    move_vec = neg_lb_vec * _first_length_
        human_points.extend(hpts)
        human_line.append(hlin)

    if _run:
        # mesh the context for the intersection calculation
        shade_mesh = join_geometry_to_mesh(_context)

        # generate the sun vectors for each sun-up hour of the year
        sp = Sunpath.from_location(_location, north_)
        sun_vecs = []
        day_pattern = []
        for hoy in range(8760):
            sun = sp.calculate_sun_from_hoy(hoy)
            day_pattern.append(sun.is_during_day)
            if sun.is_during_day:
                sun_vecs.append(from_vector3d(sun.sun_vector_reversed))

        # intersect the sun vectors with the context and compute fraction exposed
        sun_int_matrix, angles = intersect_mesh_rays(shade_mesh,
                                                     human_points,
                                                     sun_vecs,
                                                     cpu_count=workers)
        fract_body_exp = []
        for i in range(0, len(human_points), _pt_count_):
            fract_body_exp.append(
                fract_exposed_from_mtx(sun_int_matrix[i:i + _pt_count_],
                                       day_pattern))

        # generate the vectors and weights for sky exposure
        sky_vecs = [
            from_vector3d(vec) for vec in view_sphere.tregenza_dome_vectors
    for dr in model.orphaned_doors:
        add_door(door, points, vectors)
    for shd in model.orphaned_shades:
        points.append(from_point3d(shd.center))
        vectors.append(from_vector3d(shd.normal))


if all_required_inputs(ghenv.Component):
    # list of rhino geometry to be filled with content
    points = []
    vectors = []

    # loop through all objects and add them
    for hb_obj in _hb_objs:
        if isinstance(hb_obj, Room):
            add_room(hb_obj, points, vectors)
        elif isinstance(hb_obj, Face):
            add_face(hb_obj, points, vectors)
        elif isinstance(hb_obj, Aperture):
            add_aperture(hb_obj, points, vectors)
        elif isinstance(hb_obj, Door):
            add_door(hb_obj, points, vectors)
        elif isinstance(hb_obj, Shade):
            points.append(from_point3d(hb_obj.center))
            vectors.append(from_vector3d(hb_obj.normal))
        elif isinstance(hb_obj, Model):
            add_model(hb_obj, points, vectors)
        else:
            raise TypeError(
                'Unrecognized honeybee object type: {}'.format(type(hb_obj)))
Ejemplo n.º 14
0
    sky_type = 1 if len(direct) == 145 else 2  # i for tregenza; 2 for reinhart
    total = [dirr + difr
             for dirr, difr in zip(direct, diffuse)]  # total radiation

    # override the legend default min and max to make sense for domes
    l_par = legend_par_.duplicate(
    ) if legend_par_ is not None else LegendParameters()
    if l_par.min is None:
        l_par.min = 0
    if l_par.max is None:
        l_par.max = max(total)

    # output patch patch vectors
    patch_vecs_lb = view_sphere.tregenza_dome_vectors if len(total) == 145 \
        else view_sphere.reinhart_dome_vectors
    patch_vecs = [from_vector3d(vec) for vec in patch_vecs_lb]

    # create the dome meshes
    if not show_comp_:  # only create the total dome mesh
        mesh, compass, legend, title, mesh_values = \
            draw_dome(total, center_pt3d, 'Total', l_par)
        patch_values = total
    else:  # create domes for total, direct and diffuse
        # loop through the 3 radiation types and produce a dome
        mesh, compass, legend, title, mesh_values = [], [], [], [], []
        rad_types = ('Total', 'Direct', 'Diffuse')
        rad_data = (total, direct, diffuse)
        for dome_i in range(3):
            cent_pt = Point3D(center_pt3d.x + radius * 3 * dome_i,
                              center_pt3d.y, center_pt3d.z)
            dome_mesh, dome_compass, dome_legend, dome_title, dome_values = \
        try:
            x_axis = to_vector3d(quad_only_)
            lb_faces = [
                Face3D(f.boundary, Plane(f.normal, f[0], x_axis), f.holes)
                for f in lb_faces
            ]
        except AttributeError:
            pass  # no plane connected; juse use default orientation
        lb_meshes = [
            geo.mesh_grid(_grid_size, offset=_offset_dist_) for geo in lb_faces
        ]
        if len(lb_meshes) == 1:
            lb_mesh = lb_meshes[0]
        elif len(lb_meshes) > 1:
            lb_mesh = Mesh3D.join_meshes(lb_meshes)
    else:  # use Rhino's default meshing
        try:  # assume it's a Rhino Brep
            lb_mesh = to_gridded_mesh3d(_geometry, _grid_size, _offset_dist_)
        except TypeError:  # assume it's a Rhino Mesh
            try:
                lb_mesh = to_mesh3d(_geometry)
            except TypeError:  # unidientified geometry type
                raise TypeError(
                    '_geometry must be a Brep or a Mesh. Got {}.'.format(
                        type(_geometry)))

    # generate the test points, vectors, and areas.
    points = [from_point3d(pt) for pt in lb_mesh.face_centroids]
    vectors = [from_vector3d(vec) for vec in lb_mesh.face_normals]
    face_areas = lb_mesh.face_areas
    mesh = from_mesh3d(lb_mesh)
    # deconstruct the matrix and get the sky dome vectors
    mtx = de_objectify_output(_sky_mtx)
    total_sky_rad = [
        dir_rad + dif_rad for dir_rad, dif_rad in zip(mtx[1], mtx[2])
    ]
    ground_rad = [(sum(total_sky_rad) / len(total_sky_rad)) * mtx[0][1]
                  ] * len(total_sky_rad)
    all_rad = total_sky_rad + ground_rad
    lb_vecs = view_sphere.tregenza_dome_vectors if len(total_sky_rad) == 145 \
        else view_sphere.reinhart_dome_vectors
    if mtx[0][0] != 0:  # there is a north input for sky; rotate vectors
        north_angle = math.radians(mtx[0][0])
        lb_vecs = tuple(vec.rotate_xy(north_angle) for vec in lb_vecs)
    lb_grnd_vecs = tuple(vec.reverse() for vec in lb_vecs)
    all_vecs = [from_vector3d(vec) for vec in lb_vecs + lb_grnd_vecs]

    # intersect the rays with the mesh
    normals = [from_vector3d(vec) for vec in study_mesh.face_normals]
    int_matrix_init, angles = intersect_mesh_rays(shade_mesh,
                                                  points,
                                                  all_vecs,
                                                  normals,
                                                  cpu_count=workers)

    # compute the results
    results = []
    int_matrix = []
    for int_vals, angles in zip(int_matrix_init, angles):
        pt_rel = [ival * math.cos(ang) for ival, ang in zip(int_vals, angles)]
        int_matrix.append(pt_rel)
Ejemplo n.º 17
0
    # get the view vectors based on the view type
    patch_wghts = None
    if vt_str == 'Horizontal Radial':
        lb_vecs = view_sphere.horizontal_radial_vectors(30 * _resolution_)
    elif vt_str == 'Horizontal 30-Degree Offset':
        patch_mesh, lb_vecs = view_sphere.horizontal_radial_patches(
            30, _resolution_)
        patch_wghts = view_sphere.horizontal_radial_patch_weights(
            30, _resolution_)
    elif vt_str == 'Spherical':
        patch_mesh, lb_vecs = view_sphere.sphere_patches(_resolution_)
        patch_wghts = view_sphere.sphere_patch_weights(_resolution_)
    else:
        patch_mesh, lb_vecs = view_sphere.dome_patches(_resolution_)
        patch_wghts = view_sphere.dome_patch_weights(_resolution_)
    view_vecs = [from_vector3d(pt) for pt in lb_vecs]

    # mesh the geometry and context
    shade_mesh = join_geometry_to_mesh(_geometry + context_) if _geo_block_ \
        else join_geometry_to_mesh(context_)

    # intersect the rays with the mesh
    if vt_str == 'Sky View':  # account for the normals of the surface
        normals = [from_vector3d(vec) for vec in study_mesh.face_normals]
        int_matrix, angles = intersect_mesh_rays(shade_mesh,
                                                 points,
                                                 view_vecs,
                                                 normals,
                                                 parallel=parallel_)
    else:
        int_matrix, angles = intersect_mesh_rays(shade_mesh,
            apply_mask_to_base_mask(strategy_pattern, over_pattern,
                                    orient_pattern)
            apply_mask_to_sky(sky_pattern, over_pattern)
        if left_fin_proj_ or right_fin_proj_:
            f_pattern = view_sphere.fin_pattern(direction, left_fin_proj_,
                                                right_fin_proj_, view_vecs)
            apply_mask_to_base_mask(strategy_pattern, f_pattern,
                                    orient_pattern)
            apply_mask_to_sky(sky_pattern, f_pattern)

# account for any input context
context_pattern = None
if len(context_) != 0:
    shade_mesh = join_geometry_to_mesh(context_)  # mesh the context
    points = [from_point3d(center_pt3d)]
    view_vecs = [from_vector3d(pt) for pt in view_vecs]
    int_matrix, angles = intersect_mesh_rays(shade_mesh, points, view_vecs)
    context_pattern = [val == 0 for val in int_matrix[0]]
    apply_mask_to_sky(sky_pattern, context_pattern)

# get the weights for each patch to be used in view factor calculation
weights = view_sphere.dome_radial_patch_weights(az_count, alt_count)
if direction is not None:
    weights = [
        wgt * abs(math.cos(ang)) * 2 for wgt, ang in zip(weights, dir_angles)
    ]

# create meshes for the masks and compute any necessary view factors
gray, black = Color(230, 230, 230), Color(0, 0, 0)
context_view, orient_view, strategy_view = 0, 0, 0
if context_pattern is not None: