def CalcRevealDims(_phpp_window_obj, RevealShaderObjs_input, SideIntersectionSurface, Side_OriginPt, Side_Direction): #Test shading objects for their edge points Side_IntersectionCurve = [] Side_IntersectionPoints = [] for i in range(len(RevealShaderObjs_input)): #This is the list of shading objects to filter if ghc.BrepXBrep(RevealShaderObjs_input[i], SideIntersectionSurface).curves != None: Side_IntersectionCurve.append(ghc.BrepXBrep(RevealShaderObjs_input[i], SideIntersectionSurface).curves) for i in range(len(Side_IntersectionCurve)): for k in range(len(ghc.ControlPoints(Side_IntersectionCurve[i]).points)): Side_IntersectionPoints.append(ghc.ControlPoints(Side_IntersectionCurve[i]).points[k]) #Find the top/closets point for each of the objects that could possibly shade Side_KeyPoints = [] Side_Rays = [] Side_Angles = [] for i in range(len(Side_IntersectionPoints)): if Side_OriginPt != Side_IntersectionPoints[i]: Ray = ghc.Vector2Pt(Side_OriginPt, Side_IntersectionPoints[i], False).vector Angle = math.degrees(ghc.Angle(_phpp_window_obj.surface_normal, Ray).angle) if Angle < 89.9: Side_Rays.append(Ray) Side_Angles.append(float(Angle)) Side_KeyPoints.append(Side_IntersectionPoints[i]) Side_KeyPoint = Side_KeyPoints[Side_Angles.index(min(Side_Angles))] Side_KeyRay = Side_Rays[Side_Angles.index(min(Side_Angles))] #use the Key point found to calculte the Distances for the PHPP Shading Calculator Side_Hypot = ghc.Length(ghc.Line(Side_OriginPt, Side_KeyPoint)) Deg = (ghc.Angle(Side_Direction, Side_KeyRay).angle) #note this is in Radians Side_o_reveal = math.sin(Deg) * Side_Hypot Side_d_reveal = math.sqrt(Side_Hypot**2 - Side_o_reveal**2) Side_CheckLine = ghc.Line(Side_OriginPt, Side_KeyPoint) return [Side_o_reveal, Side_d_reveal, Side_CheckLine]
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
def find_overhang_shading(_phpp_window_obj, _shadingGeom, _extents=99): # Figure out the glass surface (inset a bit) and then # find the origin point for all the subsequent shading calcs (top, middle) glzgCenter = ghc.Area(_phpp_window_obj.glazing_surface).centroid glazingEdges = _phpp_window_obj._get_edges_in_order( _phpp_window_obj.glazing_surface ) glazingTopEdge = from_linesegment3d(glazingEdges.Top) ShadingOrigin = ghc.CurveMiddle(glazingTopEdge) # In order to also work for windows which are not vertical, find the # 'direction' from the glazing origin and the top/middle ege point UpVector = ghc.Vector2Pt(glzgCenter, ShadingOrigin, True).vector #----------------------------------------------------------------------- # First, need to filter the scene to find the objects that are 'above' # the window. Create a 'test plane' that is _extents (99m) tall and 0.5m past the wall surface, test if # any objects intersect that plane. If so, add them to the set of things # test in the next step depth = float(_phpp_window_obj.install_depth) + 0.5 edge1 = ghc.LineSDL(ShadingOrigin, UpVector, _extents) edge2 = ghc.LineSDL(ShadingOrigin, _phpp_window_obj.surface_normal, depth) intersectionTestPlane = ghc.SumSurface(edge1, edge2) OverhangShadingObjs = (x for x in _shadingGeom if ghc.BrepXBrep(intersectionTestPlane, x).curves != None) #----------------------------------------------------------------------- # Using the filtered set of shading objects, find the 'edges' of shading # geom and then decide where the maximums shading point is # Create a new 'test' plane coming off the origin (99m in both directions this time). # Test to find any intersection shading objs and all their crvs/points with this plane HorizontalLine = ghc.LineSDL(ShadingOrigin, _phpp_window_obj.surface_normal, _extents) VerticalLine = ghc.LineSDL(ShadingOrigin, UpVector, _extents) IntersectionSurface = ghc.SumSurface(HorizontalLine, VerticalLine) IntersectionCurves = (ghc.BrepXBrep(obj, IntersectionSurface).curves for obj in OverhangShadingObjs if ghc.BrepXBrep(obj, IntersectionSurface).curves != None) IntersectionPointsList = (ghc.ControlPoints(crv).points for crv in IntersectionCurves) IntersectionPoints = (pt for list_of_pts in IntersectionPointsList for pt in list_of_pts) #----------------------------------------------------------------------- # If there are any intersection Points found, choose the right one to use to calc shading.... # Find the top/closets point for each of the objects that could possibly shade smallest_angle_found = 2 * math.pi key_point = None for pt in IntersectionPoints: if pt == None: continue # Protect against Zero-Length error ray = ghc.Vector2Pt(ShadingOrigin, pt, False).vector if ray.Length < 0.001: continue this_ray_angle = ghc.Angle(_phpp_window_obj.surface_normal , ray).angle if this_ray_angle < 0.001: continue if this_ray_angle <= smallest_angle_found: smallest_angle_found = this_ray_angle key_point = pt #----------------------------------------------------------------------- # Use the 'key point' found to deliver the Height and Distance for the PHPP Shading Calculator if not key_point: d_over = None o_over = None CheckLine = VerticalLine else: d_over = key_point.Z - ShadingOrigin.Z # Vertical distance Hypot = ghc.Length(ghc.Line(ShadingOrigin, key_point)) # Hypot o_over = math.sqrt(Hypot**2 - d_over**2) # Horizontal distance CheckLine = ghc.Line(ShadingOrigin, key_point) return d_over, o_over, CheckLine
def find_horizon_shading(_phpp_window_obj, _shadingGeom, _extents=99): """ Arguments: _phpp_winddow_obj: The PHPP_Window object to calcualte the values for _shadingGeom: (list) A list of possible shading objects to test against _extents: (float) A number (m) to limit the shading search to. Default = 99m Returns: h_hori: Distance (m) out from the glazing surface of any horizontal shading objects found d_hori: Distance (m) up from the base of the window to the top of any horizontal shading objects found """ surface_normal = _phpp_window_obj.surface_normal #----------------------------------------------------------------------- # Find Starting Point glazingEdges = _phpp_window_obj._get_edges_in_order( _phpp_window_obj.glazing_surface ) glazingBottomEdge = glazingEdges.Bottom ShadingOrigin = ghc.CurveMiddle( from_linesegment3d(glazingBottomEdge) ) UpVector = ghc.VectorXYZ(0,0,1).vector #----------------------------------------------------------------------- # Find if there are any shading objects and if so put them in a list HorizonShading = [] HorizontalLine = ghc.LineSDL(ShadingOrigin, surface_normal, _extents) VerticalLine = ghc.LineSDL(ShadingOrigin, UpVector, _extents) for shadingObj in _shadingGeom: if ghc.BrepXCurve(shadingObj, HorizontalLine).points != None: HorizonShading.append( shadingObj ) #----------------------------------------------------------------------- # Find any intersection Curves with the shading objects IntersectionSurface = ghc.SumSurface(HorizontalLine, VerticalLine) IntersectionCurve = [] IntersectionPoints = [] for shadingObj in HorizonShading: if ghc.BrepXBrep(shadingObj, IntersectionSurface).curves != None: IntersectionCurve.append(ghc.BrepXBrep(shadingObj, IntersectionSurface)) for pnt in IntersectionCurve: IntersectionPoints.append(ghc.ControlPoints(pnt).points) #----------------------------------------------------------------------- # Run the "Top-Corner-Finder" if there are any intersecting objects... if len(IntersectionPoints) != 0: # Find the top/closets point for each of the objects that could possibly shade KeyPoints = [] for pnt in IntersectionPoints: Rays = [] Angles = [] if pnt: for k in range(len(pnt)): Rays.append(ghc.Vector2Pt(ShadingOrigin,pnt[k], False).vector) Angles.append(ghc.Angle(surface_normal , Rays[k]).angle) KeyPoints.append(pnt[Angles.index(max(Angles))]) # Find the relevant highest / closest point Rays = [] Angles = [] for i in range(len(KeyPoints)): Rays.append(ghc.Vector2Pt(surface_normal, KeyPoints[i], False).vector) Angles.append(ghc.Angle(surface_normal, Rays[i]).angle) KeyPoint = KeyPoints[Angles.index(max(Angles))] # Use the point it finds to deliver the Height and Distance for the PHPP Shading Calculator h_hori = KeyPoint.Z - ShadingOrigin.Z #Vertical distance Hypot = ghc.Length(ghc.Line(ShadingOrigin, KeyPoint)) d_hori = math.sqrt(Hypot**2 - h_hori**2) CheckLine = ghc.Line(ShadingOrigin, KeyPoint) else: h_hori = None d_hori = None CheckLine = HorizontalLine return h_hori, d_hori, CheckLine
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, gravity): #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) #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] random.shuffle(ahr) """ ahr = [0, 90, 270, 180] #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 rotation plane rotplane3 = ghc.PlaneNormal( vecend, movevec) #creates plane perpendicular to vector plns = ghc.DeconstructPlane(rotplane3) #origin, x, y, z rotplane = ghc.ConstructPlane( plns[0], plns[3], plns[2] ) #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)) 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, anglerech, vecend, movevec)[0] #returns rotated geometry and transformation data #vertical branch angle angl1 = ghc.Angle(rg.Line(vecend, rotpoint), horizont, verticalpln)[0] #outputs angle and reflex angl = ghc.Degrees(angl1) anglls.append(angl) #rotate depending on how horizontal branch is if angl > 0 and angl < 180: if angl < 89: grrot = ((30 / 100) * (100 - (angl * 0.9)) / 100) * gravity elif angl > 91: grrot = ((30 / 100) * (100 - ((180 - angl) * 0.9)) / 100) * gravity try: grrot == 0 rotpoint = ghc.Rotate3D(rotpoint, grrot, vecend, verticalpln)[0] except: pass #building line between points linegeo = rg.Line(vecend, rotpoint) #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] #building a dict of lines with depth as key, and corresponding lines as values if depth not in treelin.keys(): treelin[depth] = [linegeo] else: treelin[depth].append(linegeo) #calling function with different angle parameter for branch splitting #calling as many branches as spread within tolerance for aa in ahr: fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle, angle, lvariation, aran, lran, aa, angleh, branches, gravity)