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 join_touching_tfa_groups(_tfa_surface_groups, _ghenv=None): tfa_srfcs_joined = [] for group in _tfa_surface_groups.values(): # if there is only a single element in the group, add it to the list # otherwise, try and join together the elements in the group if len(group) == 1: tfa_srfcs_joined.append(group[0]) else: ventFlowRates_Sup = [] ventFlowRates_Eta = [] ventFlowRates_Tran = [] areas_tfa = [] areas_gross = [] srfc_exterior_perimeters = [] sub_surfaces = [] usage = [] lighting = [] motion = [] for tfa_srfc in group: # Get the ventilation flow rates ventFlowRates_Sup.append( tfa_srfc.get_vent_flow_rate('V_sup') ) ventFlowRates_Eta.append( tfa_srfc.get_vent_flow_rate('V_eta') ) ventFlowRates_Tran.append( tfa_srfc.get_vent_flow_rate('V_trans') ) # Get the geometric information areas_tfa.append(tfa_srfc.area_tfa) areas_gross.append(tfa_srfc.area_gross) srfc_exterior_perimeters.append(tfa_srfc.surface_perimeter) sub_surfaces.append(tfa_srfc) # Get the Non-Res params usage.append(tfa_srfc.non_res_usage) lighting.append(tfa_srfc.non_res_lighting) motion.append(tfa_srfc.non_res_motion) # Build the new TFA surface perim_curve = ghc.RegionUnion(srfc_exterior_perimeters) unioned_surface = Rhino.Geometry.Brep.CreatePlanarBreps(perim_curve, 0.01) if len(unioned_surface) != 0: unioned_surface = unioned_surface[0] else: break host_room_name = group[0].host_room_name params = group[0].params unionedTFAObj = TFA_Surface(unioned_surface, host_room_name, params, sub_surfaces) # Set the new TFA Surface's param properties unionedTFAObj.area_gross = sum(areas_gross) unionedTFAObj.tfa_factor = sum(areas_tfa) / sum(areas_gross) unionedTFAObj.space_number = group[0].space_number unionedTFAObj.space_name = group[0].space_name unionedTFAObj.set_surface_param('V_sup', max(ventFlowRates_Sup) ) unionedTFAObj.set_surface_param('V_eta', max(ventFlowRates_Eta) ) unionedTFAObj.set_surface_param('V_trans', max(ventFlowRates_Tran) ) # Set the new TFA Surface's Non-Res params usage = sorted(list(set(filter(None, usage)))) lighting = sorted(list(set(filter(None, lighting)))) motion = sorted(list(set(filter(None, motion)))) unionedTFAObj.non_res_usage = usage[0] unionedTFAObj.non_res_lighting = lighting[0] unionedTFAObj.non_res_motion = motion[0] # Give Warnings if needed if len(usage) > 1: msg = 'Warning: Found more than one Non-Res. "Usage" type on room "{}"?'.format( unionedTFAObj.space_name ) _ghenv.Component.AddRuntimeMessage( ghK.GH_RuntimeMessageLevel.Warning, msg ) if len(lighting) > 1: msg = 'Warning: Found more than one Non-Res. "Lighting" type on room "{}"?'.format( unionedTFAObj.space_name ) _ghenv.Component.AddRuntimeMessage( ghK.GH_RuntimeMessageLevel.Warning, msg ) if len(motion) > 1: msg = 'Warning: Found more than one Non-Res. "Motion Detector" type on room "{}"?'.format( unionedTFAObj.space_name ) _ghenv.Component.AddRuntimeMessage( ghK.GH_RuntimeMessageLevel.Warning, msg ) # Pass back the new Joined TFA surface tfa_srfcs_joined.append(unionedTFAObj) return tfa_srfcs_joined
def getIDFWindowObjects(_IDF_Objs, _windowConstructionsSimple, _windowMaterialsSimple): # Finds all the widnow surfaces and builds window objects windowSurfaces = [] windowObjs_raw = [] windowObjs_filtered = [] windowObjs_triangulated = {} for eachIDFobj in _IDF_Objs: try: idfObjName = getattr(eachIDFobj, 'objName') except: idfObjName = '' # If its an EP Window Object if 'FenestrationSurface:Detailed' in idfObjName: windowObjs_raw.append(eachIDFobj) ################################################## # Fix for window triangulation for windowObj in windowObjs_raw: # Honeybee adds the code '..._glzP_0, ..._glzP_1, etc..' suffix to the name for its triangulated windows if '_glzP_' in windowObj.Name: # See if it has only 3 vertices as well just to double check numOfVerts = 0 for key in windowObj.__dict__.keys(): if 'XYZ Vertex' in key: numOfVerts += 1 if numOfVerts == 3: # Ok, so its a triangulated window. # File the triangulated window in the dictionary using its name as key tempWindowName = windowObj.Name.split('_glzP_')[0] if tempWindowName not in windowObjs_triangulated.keys(): windowObjs_triangulated[tempWindowName] = [windowObj] else: windowObjs_triangulated[tempWindowName].append(windowObj) else: windowObjs_filtered.append(windowObj) else: windowObjs_filtered.append(windowObj) # Unite the triangulated objects for key in windowObjs_triangulated.keys(): perims = [] for windowObj in windowObjs_triangulated[key]: triangleVerts = [] # Get the verts for key in windowObj.__dict__.keys(): if 'XYZ Vertex' in key: verts = getattr(windowObj, key).split(' ') verts = [float(x) for x in verts] point = ghc.ConstructPoint(verts[0], verts[1], verts[2]) triangleVerts.append(point) # Union the Segments, find the outside perimeter perim = ghc.PolyLine(triangleVerts, closed=True) perims.append(perim) unionedPerim = ghc.RegionUnion(perims) # Build a new Window Obj using this now unioned geometry newVertPoints = ghc.ControlPoints( unionedPerim).points #windowObj.__dict__ newWindowObj = copy.deepcopy(windowObj) for i in range(len(newVertPoints)): setattr(newWindowObj, 'XYZ Vertex {} {}'.format(i + 1, '{m}'), str(newVertPoints[i]).replace(',', ' ')) setattr(newWindowObj, 'Name', windowObj.Name[:-7]) windowObjs_filtered.append(newWindowObj) ################################################## # Build the Window Objects for eachWindowObj in windowObjs_filtered: # Find the windows's CONSTRUCTION and MATERIAL information in the IDF thisWindowEP_CONST_Name = getattr( eachWindowObj, 'Construction Name') # Get the name of the Windows' Construction thisWindowEP_MAT_Name = _windowConstructionsSimple[ thisWindowEP_CONST_Name].Layers[0][ 1] # Find the Material name of 'Layer 1' in the Window's Construction thisWindowEP_WinSimp_Obj = _windowMaterialsSimple[ thisWindowEP_MAT_Name] # Find the 'WindowMaterial:SimpleGlazingSystem' Object with the same name as 'Layer 1' winterShadingFactor = 0.75 summerShadingFactor = 0.75 # Create the new IDF_Obj_surfaceWindow Object windowSurfaces.append( IDF_Obj_surfaceWindow(eachWindowObj, thisWindowEP_WinSimp_Obj, winterShadingFactor, summerShadingFactor)) return windowSurfaces
def joinTouchingTFAsurfaces(_tfaSrfcObjs, _HBzoneObjs): # Takes in a set of TFA Surface Objects that are touching # Returns a new single TFA Surface Obj with averaged / joined values srfcExtPerims = [] AreaGross = [] TFAs = [] # Figure out the new joined room's Ventilation Flow Rates ventFlowRates_Sup = [] ventFlowRates_Eta = [] ventFlowRates_Tran = [] # Get all the already input flow rates for the TFA Surfaces (if any) for srfcObj in _tfaSrfcObjs: ventFlowRates_Sup.append(srfcObj.V_sup) ventFlowRates_Eta.append(srfcObj.V_eta) ventFlowRates_Tran.append(srfcObj.V_trans) # Use the max values from the input set as the new Unioned objs' vent flow rates unionedSrfcVentRates = [ max(ventFlowRates_Sup), max(ventFlowRates_Eta), max(ventFlowRates_Tran) ] for srfcObj in _tfaSrfcObjs: TFAs.append(srfcObj.getArea_TFA()) AreaGross.append(srfcObj.Area_Gross) srfcExtEdges = ghc.BrepEdges(rs.coercebrep(srfcObj.Surface))[0] srfcExtPerims.append(ghc.JoinCurves(srfcExtEdges, preserve=False)) unionedSrfc = ghc.RegionUnion(srfcExtPerims) unionedTFAObj = PHPP_TFA_Surface(unionedSrfc, _HBzoneObjs, unionedSrfcVentRates, _inset=0, _offsetZ=0) # Set the TFA Surface Attributes unionedTFAObj.Area_Gross = sum(AreaGross) unionedTFAObj.TFAfactor = sum(TFAs) / sum(AreaGross) unionedTFAObj.RoomNumber = _tfaSrfcObjs[0].RoomNumber unionedTFAObj.RoomName = _tfaSrfcObjs[0].RoomName return unionedTFAObj