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())
Exemple #2
0
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
Exemple #3
0
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