def polygon_to_brep(polygon, z_height): """Convert a ladybug Polygon2D or list of polygon2D into Rhino breps.""" if isinstance(polygon, list): # face with holes verts = [] for poly in polygon: verts.append([Point3D(pt.x, pt.y, z_height) for pt in poly]) return from_face3d(Face3D(verts[0], holes=verts[1:])) else: verts = [Point3D(pt.x, pt.y, z_height) for pt in polygon] return from_face3d(Face3D(verts))
def _inset_floor_surfaces( _floor_surface, _inset_dist, _ghenv ): '''Shrinks/Insets the surface by the specified amount ''' try: rh_srfc = from_face3d(_floor_surface.geometry) except Exception as e: msg = 'Error. Can not convert floor surface: "{}" to Rhino geometry?'.format( _floor_surface ) _ghenv.Component.AddRuntimeMessage(ghK.GH_RuntimeMessageLevel.Remark, msg) return None if _inset_dist < 0.001: return rh_srfc #----------------------------------------------------------------------- srfcPerim = ghc.JoinCurves( ghc.BrepEdges(rh_srfc)[0], preserve=False ) # Get the inset Curve srfcCentroid = Rhino.Geometry.AreaMassProperties.Compute(rh_srfc).Centroid plane = ghc.XYPlane(srfcCentroid) srfcPerim_Inset_Pos = ghc.OffsetCurve(srfcPerim, _inset_dist, plane, 1) srfcPerim_Inset_Neg = ghc.OffsetCurve(srfcPerim, _inset_dist*-1, srfcCentroid, 1) # Choose the right Offset Curve. The one with the smaller area srfcInset_Pos = ghc.BoundarySurfaces( srfcPerim_Inset_Pos ) srfcInset_Neg = ghc.BoundarySurfaces( srfcPerim_Inset_Neg ) area_Pos = ghc.Area(srfcInset_Pos).area area_neg = ghc.Area(srfcInset_Neg).area if area_Pos < area_neg: return srfcInset_Pos else: return srfcInset_Neg
def from_dict(cls, _dict_tfa, _dict_sub_surfaces): sub_surfaces = [] for sub_surface in _dict_sub_surfaces.values(): new_sub_surface = cls.from_dict( sub_surface, {} ) sub_surfaces.append( new_sub_surface ) new_tfa_obj = cls() new_tfa_obj.id = _dict_tfa.get('id') new_tfa_obj.host_room_name = _dict_tfa.get('host_room_name') new_tfa_obj.params = _dict_tfa.get('params') new_tfa_obj.sub_surfaces = sub_surfaces new_tfa_obj._inset = 0.1 new_tfa_obj._neighbors = None new_tfa_obj._area_gross = _dict_tfa.get('area_gross') new_tfa_obj._depth = _dict_tfa.get('depth', None) srfc_list = _dict_tfa.get('surface_list') if srfc_list: # Remeber, to_face3d returns a LIST of surfaces incase it triangulates # so for now, just getitng the first one in that list to pass along # Someday this'll break everything... lbt_surface = Face3D.from_dict( srfc_list ) rh_surface = from_face3d( lbt_surface ) new_tfa_obj.surface = rh_surface return new_tfa_obj
def getMyCeiling(obj): ceilingFaces = [ srfc for srfc in obj.faces if str(srfc.type) == 'RoofCeiling' ] ceilinggeom = [] for f in ceilingFaces: ceilinggeom.append(fg.from_face3d(f.geometry)) return ceilinggeom
def add_face(face, geo, shades): """Add Face geometry to a geo and shades list.""" geo.append(from_face3d(face.punched_geometry)) for ap in face.apertures: add_aperture(ap, geo, shades) for dr in face.doors: add_door(dr, geo, shades) for shd in face.shades: add_shade(shd, shades)
def rh_surface(self): """Get the LBT Aperture 'Face3d' as a Rhino surface""" if self.aperture: lbt_face3d = self.aperture.geometry rh_surface = from_face3d( lbt_face3d ) return rh_surface else: return None
def inset_LBT_Face3d(_face3d, _inset_dist=0.001): rhino_geom = from_face3d(_face3d) rhino_geom_inset = inset_rhino_surface(rhino_geom, _inset_dist) lbt_face3d = to_face3d(rhino_geom_inset) if lbt_face3d: return lbt_face3d[0] else: return None
def get_footprint(_surfaces): # Finds the 'footprint' of the building for 'Primary Energy Renewable' reference # 1) Re-build the Opaque Surfaces # 2) Join all the surface Breps into a single brep # 3) Find the 'box' for the single joined brep # 4) Find the lowest Z points on the box, offset another 10 units 'down' # 5) Make a new Plane at this new location # 6) Projects the brep edges onto the new Plane # 7) Split a surface using the edges, combine back into a single surface Footprint = namedtuple('Footprint', ['Footprint_surface', 'Footprint_area']) #----- Build brep surfaces = (from_face3d(surface.Srfc) for surface in _surfaces) bldg_mass = ghc.BrepJoin(surfaces).breps bldg_mass = ghc.BoundaryVolume(bldg_mass) if not bldg_mass: return Footprint(None, None) #------- Find Corners, Find 'bottom' (lowest Z) bldg_mass_corners = [v for v in ghc.BoxCorners(bldg_mass)] bldg_mass_corners.sort(reverse=False, key=lambda point3D: point3D.Z) rect_pts = bldg_mass_corners[0:3] #------- Projection Plane projection_plane1 = ghc.Plane3Pt(rect_pts[0], rect_pts[1], rect_pts[2]) projection_plane2 = ghc.Move(projection_plane1, ghc.UnitZ(-10)).geometry matrix = rs.XformPlanarProjection(projection_plane2) #------- Project Edges onto Projection Plane projected_edges = [] for edge in ghc.DeconstructBrep(bldg_mass).edges: projected_edges.append(ghc.Transform(edge, matrix)) #------- Split the projection surface using the curves l1 = ghc.Line(rect_pts[0], rect_pts[1]) l2 = ghc.Line(rect_pts[0], rect_pts[2]) max_length = max(ghc.Length(l1), ghc.Length(l2)) projection_surface = ghc.Polygon(projection_plane2, max_length * 100, 4, 0).polygon projected_surfaces = ghc.SurfaceSplit(projection_surface, projected_edges) #------- Remove the biggest surface from the set(the background srfc) projected_surfaces.sort(key=lambda x: x.GetArea()) projected_surfaces.pop(-1) #------- Join the new srfcs back together into a single one unioned_NURB = ghc.RegionUnion(projected_surfaces) unioned_surface = ghc.BoundarySurfaces(unioned_NURB) return Footprint(unioned_surface, unioned_surface.GetArea())
def set_values_by_hb_room(self, _hb_room): """ Finds the Floor-Type face(s) in a Honeybee Room and gets Params Resets self.floor_area and self.floor_U_value based on the values found in the Honeybee Zone. If more than one Floor face is found, creates a weighted U-Value average of all the faces. Args: self: _hb_room: A Single Honeybee Room object Returns: None """ def is_floor(_face): if str(face.type) != 'Floor': return False if str(face.boundary_condition) != 'Ground' and str( face.boundary_condition) != 'Outdoors': return False return True #----------------------------------------------------------------------- # Get all the data from the HB-Room Floor surfaces floor_areas = [] area_weighted_u_values = [] perim_curve_lengths = [] for face in _hb_room: if not is_floor(face): continue u_floor = face.properties.energy.construction.u_factor floor_areas.append(face.area) area_weighted_u_values.append(u_floor * face.area) face_surface = from_face3d(face.geometry) perim_curve = ghc.JoinCurves( list(face_surface.DuplicateEdgeCurves()), False) perim_curve_lengths.append(ghc.Length(perim_curve)) #----------------------------------------------------------------------- # Set the Floor Element params if floor_areas and area_weighted_u_values: self.floor_area = sum(floor_areas) self.floor_U_value = sum(area_weighted_u_values) / sum(floor_areas) self.perim_len = sum(perim_curve_lengths)
def from_dict(cls, _dict): new_obj = cls() new_obj.quantity = _dict.get('quantity') new_obj._tolerance = _dict.get('_tolerance') new_obj.aperture = Aperture.from_dict( _dict.get('aperture') ) new_obj._shading_factor_winter =_dict.get('_shading_factor_winter') new_obj._shading_factor_summer =_dict.get('_shading_factor_summer') new_obj._glazing_edge_lengths = _dict.get('_glazing_edge_lengths') new_obj.variant_type = _dict.get('variant_type') new_obj.install_depth = _dict.get('install_depth') #---- _edges = _dict.get('_window_edges', {}) _left = _edges.get('Left') _left = LineSegment3D.from_dict( _left ) _right = _edges.get('Right') _right = LineSegment3D.from_dict( _right ) _bottom = _edges.get('Bottom') _bottom = LineSegment3D.from_dict( _bottom ) _top = _edges.get('Top') _top = LineSegment3D.from_dict( _top ) new_obj._window_edges = cls.Output(_left, _right, _bottom, _top) #---- _glazing_surface = _dict.get('_glazing_surface') _glazing_surface = Face3D.from_dict(_glazing_surface) _glazing_surface = from_face3d(_glazing_surface) new_obj._glazing_surface = _glazing_surface new_obj.frame = LBT2PH.windows.PHPP_Frame.from_dict( _dict.get('_frame') ) new_obj.glazing = LBT2PH.windows.PHPP_Glazing.from_dict( _dict.get('_glazing') ) new_obj.installs = LBT2PH.windows.PHPP_Installs.from_dict( _dict.get('_installs') ) new_obj.shading_dimensions = LBT2PH.shading.PHPP_Shading_Dims.from_dict( _dict.get('shading_dimensions') ) return new_obj
LBT2PH.__versions__.set_component_params(ghenv, dev=False) #------------------------------------------------------------------------------- window_surrounds_ = DataTree[Object]() envelope_surfaces_ = [] window_names_ = [] window_surfaces_ = [] envelope_surfaces_punched = [] count = 0 for hb_room in _HB_rooms: for face in hb_room.faces: # ---------------------------------------------------------------------- # Envelope Surfaces for shading #Note, pass along the name so that later, if there is a problem it can be ID'd rh_geom = from_face3d(face.punched_geometry) rh_geom.SetUserString('display_name', face.display_name) envelope_surfaces_punched.append(rh_geom) envelope_surfaces_.append(from_face3d(face.geometry)) # ---------------------------------------------------------------------- # Window Surfaces and reveal geometry if not face.apertures: continue for aperture in face.apertures: name = aperture.display_name try: phpp_window = LBT2PH.windows.PHPP_Window.from_dict( aperture.user_data['phpp'])
def context_shade_geometry(context_shades): """Get Rhino geometry from a list of ContextShades.""" return [from_face3d(fc) for shd_geo in context_shades for fc in shd_geo.geometry]
def getMyFloor(obj): floorFace = [srfc for srfc in obj.faces if str(srfc.type) == 'Floor'] flrgeom = [] for f in floorFace: flrgeom.append(fg.from_face3d(f.geometry)) return flrgeom
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e)) if all_required_inputs(ghenv.Component): # set defaults for any blank inputs if _dist_floor_ is None: _dist_floor_ = 0.8 / conversion_to_meters() # create lists to be filled with content grid = [] points = [] mesh = [] for room in _rooms: # get all of the floor faces of the room as Breps floor_faces = [ from_face3d(face.geometry.flip()) for face in room.faces if isinstance(face.type, Floor) ] if len(floor_faces) != 0: # create the gridded ladybug Mesh3D lb_mesh = to_joined_gridded_mesh3d(floor_faces, _grid_size, _dist_floor_) # remove points outside of the room volume if requested if remove_out_: pattern = [ room.geometry.is_point_inside(pt) for pt in lb_mesh.face_centroids ] lb_mesh, vertex_pattern = lb_mesh.remove_faces(pattern)
def room_2d_geometry(room_2ds): """Get Rhino geometry from a list of Room2Ds.""" return [from_face3d(room.floor_geometry) for room in room_2ds]
def add_aperture(aperture, geo, shades): """Add Aperture geometry to a geo and shades list.""" geo.append(from_face3d(aperture.geometry)) for shd in aperture.shades: add_shade(shd, shades)
def add_door(door, geo, shades): """Add Door geometry to a geo list and shades list.""" geo.append(from_face3d(door.geometry)) for shd in door.shades: add_shade(shd, shades)
def add_shade(shd, shades): """Add Shade geometry to a shades list.""" shades.append(from_face3d(shd.geometry))
try: # import the core ladybug_rhino dependencies from ladybug_rhino.fromgeometry import from_face3d, from_polyface3d from ladybug_rhino.grasshopper import all_required_inputs except ImportError as e: raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e)) if all_required_inputs(ghenv.Component): # lists of rhino geometry to be filled with content geo = [] # loop through all objects and add them for hb_obj in _hb_objs: try: # Face, Shade, Aperture, or Door if isinstance(hb_obj, Face): geo.append(from_face3d(hb_obj.punched_geometry)) else: geo.append(from_face3d(hb_obj.geometry)) except AttributeError: # probably a Room try: geo.append(from_polyface3d(hb_obj.geometry)) except AttributeError: # it's a whole Model for room in hb_obj.rooms: geo.append(from_polyface3d(room.geometry)) for face in hb_obj.orphaned_faces: geo.append(from_face3d(face.punched_geometry)) for ap in hb_obj.orphaned_apertures: geo.append(from_face3d(ap.geometry)) for dr in hb_obj.orphaned_doors: geo.append(from_face3d(dr.geometry)) for shd in hb_obj.orphaned_shades:
raise TypeError('Expected Honeybee Room or Model. Got {}.'.format(type(obj))) for room in rooms: # get all of the floor faces of the room as Breps lb_floors = [face.geometry.flip() for face in room.faces if isinstance(face.type, Floor)] if len(lb_floors) != 0: # create the gridded ladybug Mesh3D if quad_only_: # use Ladybug's built-in meshing methods if x_axis: lb_floors = [Face3D(f.boundary, Plane(f.normal, f[0], x_axis), f.holes) for f in lb_floors] lb_meshes = [geo.mesh_grid(_grid_size, offset=_dist_floor_) for geo in lb_floors] lb_mesh = lb_meshes[0] if len(lb_meshes) == 1 else Mesh3D.join_meshes(lb_meshes) else: # use Rhino's default meshing floor_faces = [from_face3d(face) for face in lb_floors] lb_mesh = to_joined_gridded_mesh3d(floor_faces, _grid_size, _dist_floor_) # remove points outside of the room volume if requested if remove_out_: pattern = [room.geometry.is_point_inside(pt) for pt in lb_mesh.face_centroids] lb_mesh, vertex_pattern = lb_mesh.remove_faces(pattern) # extract positions and directions from the mesh base_points = [from_point3d(pt) for pt in lb_mesh.face_centroids] base_poss = [(pt.x, pt.y, pt.z) for pt in lb_mesh.face_centroids] base_dirs = [(vec.x, vec.y, vec.z) for vec in lb_mesh.face_normals] # create the sensor grid s_grid = SensorGrid.from_position_and_direction(