Пример #1
0
    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
Пример #2
0
def buildZoneBrep(_zoneObjs, _opaqueSurfaces):

    # Takes in the IDF Surfaces and builds Zone Breps from them

    # Sets the ZoneObj as an attr using the new Brep

    zoneBreps = []

    for zone in _zoneObjs:

        zoneSurfaces = []

        for srfc in _opaqueSurfaces:

            if srfc.HostZoneName == zone.ZoneName:

                zoneSurfaces.append(ghc.BoundarySurfaces(srfc.Boundary))

        zoneBrep = ghc.BrepJoin(zoneSurfaces).breps

        zoneBreps.append(zoneBrep)

        setattr(zone, 'ZoneBrep', zoneBrep)

    return zoneBreps
Пример #3
0
def getWindowBasics(_in):
    with idf2ph_rhDoc():
        # Get the Window Geometry
        geom = rs.coercegeometry(_in)
        windowSurface = ghc.BoundarySurfaces(geom)

        # Inset the window just slightly. If any windows touch one another or the zone edges
        # will failt to create a proper closed Brep. So shink them ever so slightly. Hopefully
        # not enough to affect the results.
        windowPerim = ghc.JoinCurves(ghc.DeconstructBrep(windowSurface).edges,
                                     preserve=False)
        try:
            windowPerim = ghc.OffsetonSrf(
                windowPerim, 0.004,
                windowSurface)  # 0.4mm so hopefully rounds down
        except:
            windowPerim = ghc.OffsetonSrf(windowPerim, -0.004, windowSurface)
        windowSurface = ghc.BoundarySurfaces(windowPerim)

        # Pull in the Object Name from Rhino Scene
        windowName = None
        try:
            windowName = rs.ObjectName(_in)
        except:
            warning = "Can't get the Window name from Rhino for some reason?\n"\
            "If you are passing in Rhino Geometry, double check you have named all the surfaces?\n"\
            "If you are passing in Grasshopper geometry though, ignore this message."
            ghenv.Component.AddRuntimeMessage(
                ghK.GH_RuntimeMessageLevel.Remark, warning)

        windowName = windowName if windowName != None else 'Unnamed_Window'
        windowName = cleanUpName(windowName)

        # Double check that the surface Normal didn't get flipped
        c1 = ghc.Area(geom).centroid
        n1 = rs.SurfaceNormal(geom, c1)

        c2 = ghc.Area(windowSurface).centroid
        n2 = rs.SurfaceNormal(windowSurface, c2)

        normAngleDifference = ghc.Degrees(ghc.Angle(n1, n2).angle)
        if round(normAngleDifference, 0) != 0:
            # Flip the surface if it doesn't match the source
            windowSurface = ghc.Flip(windowSurface).surface

        return windowName, windowSurface
Пример #4
0
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())
Пример #5
0
def calcFootprint(_zoneObjs, _opaqueSurfaces):
    # Finds the 'footprint' of the building for 'Primary Energy Renewable' reference
    # 1) Re-build the zone Breps
    # 2) Join all the zone 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 onto the new Plane

    #-----
    zoneBreps = []
    for zone in _zoneObjs:
        zoneSurfaces = []
        for srfc in _opaqueSurfaces:
            if srfc.HostZoneName == zone.ZoneName:
                zoneSurfaces.append(ghc.BoundarySurfaces(srfc.Boundary))
        zoneBrep = ghc.BrepJoin(zoneSurfaces).breps
        zoneBreps.append(zoneBrep)

    bldg_mass = ghc.SolidUnion(zoneBreps)

    if bldg_mass == None:
        return 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]

    #------- Project Brep to Footprint
    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)
    footprint_srfc = rs.TransformObjects(bldg_mass, matrix, copy=True)
    footprint_area = rs.Area(footprint_srfc)

    #------- Output
    Footprint = namedtuple('Footprint',
                           ['Footprint_surface', 'Footprint_area'])
    fp = Footprint(footprint_srfc, footprint_area)

    return fp
Пример #6
0
def inset_rhino_surface(_srfc, _inset_dist=0.001, _srfc_name=""):
    """ Insets/shrinks a Rhino Brep some dimension 
    Arg:
        _srfc: A Rhino Brep
        _inset_dist: float: Default=0.001m
        _srfc_name: str: The name of the surface, used for error messages
    Returns:
        new_srfc: A new Rhino surface, shrunk/inset by the specified amount
    """

    #-----------------------------------------------------------------------
    # Get all the surface params needed
    srfc_Center = ghc.Area(_srfc).centroid
    srfc_normal_vector = brep_avg_surface_normal(_srfc)
    srfc_edges = ghc.DeconstructBrep(_srfc).edges
    srfc_perimeter = ghc.JoinCurves(srfc_edges, False)

    #-----------------------------------------------------------------------
    # Try to inset the perimeter Curve
    inset_curve = rs.OffsetCurve(srfc_perimeter, srfc_Center, _inset_dist, srfc_normal_vector, 0)

    #-----------------------------------------------------------------------
    # In case the new curve goes 'out' and the offset fails
    # Or is too small and results in multiple offset Curves
    if len(inset_curve)>1:
        warning = 'Error. The surface: "{}" is too small. The offset of {} m"\
            "can not be done. Check the offset size?'.format(_srfc_name, _inset_dist)
        print(warning)
        
        inset_curve = rs.OffsetCurve(srfc_perimeter, srfc_Center, 0.001, srfc_normal_vector, 0)
        inset_curve = rs.coercecurve( inset_curve[0] )
    else:
        inset_curve = rs.coercecurve( inset_curve[0] )

    new_srfc = ghc.BoundarySurfaces(inset_curve)

    return new_srfc
        for xx in range(1, int(nsquaresA) + 2):
            noise = perlin_noise([(xx / (speed / (2 * octave))),
                                  (yy / (speed / (2 * octave)))])
            indx = int(((yy - 1) * (nsquaresA + 1)) + xx - 1)
            zvals[indx] += noise * (amplitude / (2 * octave))

pointsMoved = [
    rg.Point3d(pnt.X, pnt.Y, pnt.Z + noise)
    for pnt, noise in zip(pointGrid, zvals)
]

bottom = rg.PolylineCurve(
    rg.Point3d(
        outline.Point(indx).X,
        outline.Point(indx).Y, crvMinHeight - minThickness - abs(min(zvals)))
    for indx in range(0, outline.PointCount))

bottomSurface = ghc.BoundarySurfaces(bottom)
bottomExtruded = ghc.Extrude(
    bottomSurface,
    rg.Vector3d(0, 0, minThickness +
                (abs(max(zvals)) + abs(min(zvals))) * 2))  #*2 just to be safe

top = ghc.SurfaceFromPoints(pointsMoved, nsquaresA + 1, True)

_terrain = ghc.SolidIntersection(top, bottomExtruded)
terrain = ghc.Mirror(_terrain,
                     rg.Plane.WorldYZ)[0]  #to mimic AC and RVT orientation
topography = rg.Brep.CreateContourCurves(
    terrain, rg.Point3d(0, 0, crvMinHeight - abs(min(zvals))),
    rg.Point3d(0, 0, crvMinHeight + abs(max(zvals))), topographyInterval)
    for pt in crvPts:
        x = ghc.RemapNumbers(pt.X, domainX, domain)[0]
        y = ghc.RemapNumbers(pt.Y, domainY, domain)[0]
        surfPts.Add(Surface.PointAt(x, y), path)

# 4) Creating the panels
surcCrvs = DataTree[rg.Curve]()
survPanels = DataTree[rg.Brep]()
for i in range(surfPts.BranchCount):
    path = GH_Path(i)
    branch = surfPts.Branch(i)
    flatCrv = []
    if branch.Count > 3:
        # let the GH do the work for us
        plane = ghc.PlaneFit(branch)[0]
        for i in range(0, branch.Count):
            pt = plane.ClosestPoint(branch[i])
            flatCrv.append(pt)
    else:
        flatCrv = branch
    closedCrv = ghc.PolyLine(flatCrv, True)
    surcCrvs.Add(closedCrv, path)
    Panel = ghc.BoundarySurfaces(closedCrv)
    survPanels.Add(Panel, path)

# -----------------------------------------------------------
# Output
_ptsOnSrf = surfPts
_polyCrv = surcCrvs
_panels = survPanels
Пример #9
0
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation,
            aran, lran, anglerech, angleh, branches, verticality, gchance,
            depthstart, radtolen, radchng, mngon, polygon, branch_cluster):

    #test if depth>0
    if depth:

        #defining random angle variation and length variation
        arn = random.uniform(-angle / 100 * aran, angle / 100 * aran)
        lrn = random.uniform(-length / 100 * lran, length / 100 * lran)

        if hrandom == True:
            #defining horizontal rotation angles
            ahor = random.sample(range(0, 360), branches)
            #removing numbers within tolerance
            ahr = rs.CullDuplicateNumbers(ahor, angleh)
            #in a 360 fashion
            if ahr[0] + 360 - angleh < ahr[-1]:
                del ahr[0]
        else:
            #generating evenly distributed angles
            ahr = range(0, 360 + 1, 360 // branches)[:-1]

        #previous branch vector
        vecst = rg.Point3d(x1, y1, z1)
        vecend = rg.Point3d(x2, y2, z2)
        movevec = ghc.Vector2Pt(vecst, vecend,
                                True)[0]  #returns vector and it's length

        #perpendicular vector
        rotplane3 = ghc.PlaneNormal(
            vecend, movevec)  #creates plane perpendicular to vector
        plns = ghc.DeconstructPlane(rotplane3)  #origin, x, y, z
        rotplane = ghc.ConstructPlane(
            plns[2], plns[1], plns[3]
        )  #constructing new plane switching x and y planes to make perpendicular

        #generating perpendicular vector
        vecperp = ghc.Rotate(movevec, radians(90), rotplane)[0]

        #generating vector amplitudes
        leny = (length + lrn) * sin(
            radians((anglerec + arn) * (1 - (verticality**depth))))
        lenz = (length + lrn) * cos(radians(anglerec + arn))
        ampy = ghc.Amplitude(vecperp, leny)
        ampz = ghc.Amplitude(movevec, lenz)

        #changing branch length dependant on branch depth
        length = length * lvariation

        #building points
        endpoint1 = ghc.Move(
            vecend, ampz)[0]  #returns moved object and transformation data
        endpoint = ghc.Move(
            endpoint1, ampy)[0]  #returns moved object and transformation data

        #rotating point in a cone fashion
        rotpoint = ghc.Rotate3D(
            endpoint, radians(anglerech), vecend,
            movevec)[0]  #returns rotated geometry and transformation data

        #building line between points
        linegeo = rg.Line(vecend, rotpoint)

        #defining recursion depth
        key = depthstart + 1 - depth

        #building geometry
        pln = ghc.PlaneNormal(rotpoint,
                              linegeo)  #returns a plane perp to a vector
        radius = length * (radchng**(key)) / radtolen

        #reduce details with each branch, but not less than 3
        splits = 3 if mngon - key + 1 <= 3 else mngon - key + 1

        polygonend = ghc.Polygon(pln, radius, splits,
                                 0)[0]  #returns a polygon and its perimeter

        #aligning curves for loft creation
        crvst = ghc.EndPoints(polygon)[0]
        pntcld = ghc.Discontinuity(polygonend,
                                   1)  #returns points and point parameters

        #finind seam point
        closest_point = ghc.ClosestPoint(
            crvst, pntcld[0]
        )  #returns closest point, closest point index, distance between closest points
        seampnt = pntcld[1][closest_point[1]]
        polygonend = ghc.Seam(polygonend, seampnt)

        lcurves = [polygon, polygonend]

        #building geometry
        geo = ghc.ExtrudePoint(
            polygon, rotpoint
        ) if depth == 1 and splits == 3 else rg.Brep.CreateFromLoft(
            lcurves, rg.Point3d.Unset, rg.Point3d.Unset, rg.LoftType.Normal,
            False)[0]  #if last branch than make a pyramid
        #make solid
        geocapped = ghc.CapHoles(geo)

        #building a dict of geo with depth as key, and geo as values
        pgons.update(
            {branch_cluster: [geocapped]}) if branch_cluster not in pgons.keys(
            ) else pgons[branch_cluster].append(geocapped)
        branchesout.append(geocapped)

        #setting coords for next branch
        x1 = x2
        y1 = y2
        z1 = z2

        #getting xyz from rotated point
        x2 = rg.Point3d(rotpoint)[0]
        y2 = rg.Point3d(rotpoint)[1]
        z2 = rg.Point3d(rotpoint)[2]

        #setting base polygon for next branch
        polygon = polygonend

        #filling dict with branch clusters
        cluster.append(cluster[-1] + 1)
        branch_cluster = cluster[-1]

        #calling function with different angle parameter for branch splitting, calling as many branches as spread within tolerance
        if depth != 1:
            for aa in ahr:
                if (
                    (random.randint(40, 99) / 100)**depth
                ) < gchance or depth == depthstart + 1:  #or added to prevent blank trees
                    fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle,
                            angle, lvariation, aran, lran, aa, angleh,
                            branches, verticality, gchance, depthstart,
                            radtolen, radchng, mngon, polygon, branch_cluster)
        #leaf logic
        if depth <= leavesdepth and leavesperbranch > 0 and maxleaves > 0:

            #vector for leaf growth spread
            leafpntvec = ghc.Vector2Pt(vecend, rotpoint, True)[0]

            #setting leaf growth position on last barnch, leafpnt list
            lastbranchlength = ghc.Length(linegeo)
            leaves_list = [lastbranchlength]
            [
                leaves_list.append(lengthparam)
                for lengthparam in random.sample(
                    range(0, int(lastbranchlength)), leavesperbranch - 1)
            ] if leavesperbranch > 1 else None

            for leafpnt in leaves_list:
                leafamp = ghc.Amplitude(leafpntvec, leafpnt)
                leafpoint = ghc.Move(vecend, leafamp)[0]

                #plane for leaf generation
                linetocenter = ghc.Line(stpntbase, leafpoint)
                planetocenter = ghc.PlaneNormal(leafpoint, linetocenter)

                #create an imaginary circle with leaflen radius and populate it with points for random leaf generation
                leafgenerationcircle = ghc.CircleCNR(leafpoint, linetocenter,
                                                     leaflen)
                circlesurf = ghc.BoundarySurfaces(leafgenerationcircle)
                leafcnt = random.randint(0, maxleaves)
                if leafcnt > 0:
                    leafendpnts = ghc.PopulateGeometry(circlesurf, leafcnt,
                                                       random.randint(1, 500))

                    def leafgenerator(point):
                        #random z move
                        zmove = rg.Vector3d(0, 0, 1)
                        moveamp = random.uniform(-leaflen / 3, leaflen / 5)
                        ampzmove = ghc.Amplitude(zmove, moveamp)
                        llendpnt = ghc.Move(point, ampzmove)[0]

                        #setting a leaf centerline vector
                        leafvector = ghc.Vector2Pt(leafpoint, llendpnt,
                                                   True)[0]
                        #defining leaf center point as avarage of st and end pnts
                        midpnt = ghc.Average([leafpoint, llendpnt])

                        #generating perpendicular vector
                        vecperpleaf = ghc.Rotate(leafvector, radians(90),
                                                 planetocenter)[0]
                        leafperpamp = ghc.Amplitude(
                            vecperpleaf,
                            random.uniform((leafwidth / 2) / 5 * 4,
                                           (leafwidth / 2) / 5 * 6))

                        #moving mid point to both sides
                        midpnt1 = ghc.Move(midpnt, leafperpamp)[0]
                        midpnt2 = ghc.Move(midpnt, -leafperpamp)[0]

                        #leaf geo
                        leafgeo = rg.NurbsSurface.CreateFromCorners(
                            leafpoint, midpnt1, llendpnt, midpnt2)
                        leaves.append(leafgeo)

                    #iterate over random number of generated points if list, else generate for one point
                    [leafgenerator(pp) for pp in leafendpnts] if isinstance(
                        leafendpnts, list) else leafgenerator(leafendpnts)