def f(r, k): """ receives: r = the size of all rectangles ( 50<r ) k = the density of rectangles (2<k) works: draw cube returns: None """ def cube(x, y, z): line1 = rs.AddLine((x, y, z), (x, y + 5, z)) line2 = rs.AddLine((x, y, z), (x + 5, y, z)) surface = rs.ExtrudeCurve(line1, line2) line3 = rs.AddLine((x, y, 0), (x, y, 5)) rs.ExtrudeSurface(surface, line3) for x in rs.frange(0, r, 6): for y in rs.frange(0, r, 6): for z in rs.frange(0, r, 6): if rd.random() * z < k: cube(x, y, z) else: None
def g(): """ receives: theta = degree of line ( 0 < theta < 45 ) num = number of pattern ( 0 < num < 15 ) works: draw wire returns: None """ r = 10 sp = rs.AddSphere((0, 0, 0), r) box = [] for x in rs.frange(-r, r, 0.1): for y in rs.frange(-r, r, 0.1): if r**2 > x**2 + y**2: z = ma.sqrt(abs(r**2 - x**2 - y**2)) box.append((x, y, z)) for y in rs.frange(-r, r, 0.1): if r**2 > x**2 + y**2: z = ma.sqrt(abs(r**2 - x**2 - y**2)) box.append((x, -y, -z)) ll = len(box) rbox = [] for i in range(0, ll): r = rd.random() if r < 0.01: rbox.append(box[i]) box2 = [] box2.append(rd.sample(box, 300)) box3 = [] """ for i in range(0,100): if i == 0: dis=[] dis2=[] for k in range(1,100): x = box2[0][0][0] y = box2[0][0][1] z = box2[0][0][2] xx = box2[0][k][0] yy = box2[0][k][1] zz = box2[0][k][2] d = (x-xx)**2 + (y-yy)*2 + (z-zz)**2 dis.append(d) dis2.append(d) box2.remove(box2[0][0]) dis.sort() n = dis2.index(dis[-1]) k = box2[n] box2.remove(k) """ curve = rs.AddCurve(rbox, 2) rs.AddPipe(curve, 0, 0.05, True)
def komatsu_moyou(): R = 360 r = 10 t1 = 5 t2 = 18 all_points = [] for a in rs.frange(1, r, r / t1): points = [] for b in rs.frange(0, R, R / t2): radius = a theta = b p = polar(a, b) points.append(p) all_points.append(points) print all_points for c in range(0, t1): for d in range(0, t2 + 1): p1 = all_points[c][d] p1p = rs.AddPoint(p1) p2 = all_points[c][d - 1] p2p = rs.AddPoint(p2) # rs.AddLine(p1, p2) p3 = all_points[c - 1][d] p3p = rs.AddPoint(p3) p4 = all_points[c - 1][d - 1] p4p = rs.AddPoint(p4) # rs.AddLine(p3, p2) (x1, y1, z1) = rs.PointCoordinates(p1p) (x2, y2, z2) = rs.PointCoordinates(p2p) (x3, y3, z3) = rs.PointCoordinates(p3p) (x4, y4, z4) = rs.PointCoordinates(p4p) x = (x1 + x2 + x3 + x4) / 4 + rd.random() / 3 y = (y1 + y2 + y3 + y4) / 4 + rd.random() / 3 p = rs.AddPoint(x, y, 0) rs.AddLine(p, p1) rs.AddLine(p, p2) rs.AddLine(p, p3) rs.AddLine(p, p4)
def flange(typeofFlange): #variables points = [] #collection nP = 100 nSin = 10 #conditional assignment if (typeofFlange == "floppy"): t = 3 r = 15 amp = 10 if (typeofFlange == "extrafloppy"): t = 3 r = 30 amp = 20 #iteration to calculate points for i in rs.frange(0, nP, 1): x = r * math.sin(i * 360 / (nP - 1)) y = r * math.cos(i * 360 / (nP - 1)) z = amp * math.sin(i * nSin * 360 / (nP - 1)) #Feature point = rs.AddPoint([x, y, z]) points.append(point)
def flange(typeofFlange): #variables points = [] #collection nP = 100 nSin = 10 #conditional assignment if (typeofFlange == "floppy"): t = 3 r = 15 amp = 10 if (typeofFlange == "extrafloppy"): t = 3 r = 30 amp = 20 #iteration to calculate points for i in rs.frange(0, nP, 1): x = r * math.sin(i*360/(nP-1)) y = r * math.cos(i*360/(nP-1)) z = amp*math.sin(i*nSin*360/(nP-1)) #Feature point = rs.AddPoint([x,y,z]) points.append(point)
def ptsOnSrf (): surfaceId = rs.GetObject("pick surface", 8, True, True) uVal = rs.GetInteger("pick u/row count",4, 1, 20) vVal = rs.GetInteger("pick v/col count",4, 1, 20) uDomain = rs.SurfaceDomain(surfaceId, 0) vDomain = rs.SurfaceDomain(surfaceId, 1) uStep = (uDomain[1] - uDomain[0])/ uVal vStep = (vDomain[1] - vDomain[0])/ vVal count = 0 for i in rs.frange(uDomain[0], uDomain[1], uStep): for j in rs.frange(vDomain[0], vDomain[1], vStep): point = rs.EvaluateSurface(surfaceId, i, j) newPt = rs.AddPoint(point) count += 1 rs.AddText(count,newPt, .25)
def getHOYs(hours, days, months, timeStep, lb_preparation, method = 0): if method == 1: stDay, endDay = days numberOfDaysEachMonth = lb_preparation.numOfDaysEachMonth if timeStep != 1: hours = rs.frange(hours[0], hours[-1] + 1 - 1/timeStep, 1/timeStep) HOYS = [] for monthCount, m in enumerate(months): # just a single day if method == 1 and len(months) == 1 and stDay - endDay == 0: days = [stDay] elif method == 1: #based on analysis period if monthCount == 0: days = range(stDay, numberOfDaysEachMonth[monthCount] + 1) elif monthCount == len(months) - 1: days = range(1, lb_preparation.checkDay(endDay, m) + 1) else: days = range(1, numberOfDaysEachMonth[monthCount] + 1) for d in days: for h in hours: h = lb_preparation.checkHour(float(h)) m = lb_preparation.checkMonth(int(m)) d = lb_preparation.checkDay(int(d), m) HOY = lb_preparation.date2Hour(m, d, h) if HOY not in HOYS: HOYS.append(HOY) return HOYS
def create_cross_sections(self): crvdomain = rs.CurveDomain(self.curve_object) self.cross_sections = [] self.cross_section_planes = [] t_step = (crvdomain[1] - crvdomain[0]) / self.SAMPLES pi_step_size = math.pi / self.SAMPLES pi_step = 0 prev_normal = None prev_perp = None for t in rs.frange(crvdomain[0], crvdomain[1], t_step): crvcurvature = rs.CurveCurvature(self.curve_object, t) crosssectionplane = None if not crvcurvature: crosssectionplane = self.cross_section_plane_no_curvature( t, prev_normal, prev_perp) else: crosssectionplane = self.cross_section_plane_curvature( crvcurvature, prev_normal, prev_perp) if crosssectionplane: prev_perp = crosssectionplane.XAxis prev_normal = crosssectionplane.YAxis pi_scalar = self.create_scalar(pi_step) radii = self.ellipse_radii(pi_scalar) csec = rs.AddEllipse(crosssectionplane, radii[0], radii[1]) self.cross_sections.append(csec) self.cross_section_planes.append(crosssectionplane) pi_step += pi_step_size
def GenerateCrossSection(sectionPoints, radius, rotation, smooth, curve, samples, p, q): points = [] avoidRoundoff = 0.01 for angle in rs.frange(0.0, 360.0+avoidRoundoff, 360.0/sectionPoints): points.append(rs.Polar((0.0, 0.0, 0.0), angle, radius)) rotXform = rs.XformRotation2(rotation, (0, 0, 1), (0, 0, 0)) points = rs.PointArrayTransform(points, rotXform) t = curve.Domain[0] crossSections = [] curveCurvature = curve.CurvatureAt(t) crossSectionPlane = None if not curveCurvature: crvPoint = curve.PointAt(t) crvTangent = curve.TangentAt(t) crvPerp = (0,0,1) crvNormal = Rhino.Geometry.Vector3d.CrossProduct(crvTangent, crvPerp) crossSectionPlane = Rhino.Geometry.Plane(crvPoint, crvPerp, crvNormal) else: crvPoint = curve.PointAt(t) crvTangent = curve.TangentAt(t) crvPerp = curve.CurvatureAt(t) crvPerp.Unitize crvNormal = Rhino.Geometry.Vector3d.CrossProduct(crvTangent, crvPerp) crossSectionPlane = Rhino.Geometry.Plane(crvPoint, crvPerp, crvNormal) if crossSectionPlane: xform = rs.XformChangeBasis(crossSectionPlane, rs.WorldXYPlane()) sectionVerts = rs.PointArrayTransform(points, xform) if (smooth): # Degree 3 curve to smooth it sectionCurve = Rhino.Geometry.Curve.CreateControlPointCurve(sectionVerts, 3) else: # Degree 1 curve (polyline) sectionCurve = Rhino.Geometry.Curve.CreateControlPointCurve(sectionVerts, 1) crossSection = rs.coercecurve(sectionCurve) return crossSection
def manypoints(): pt = [] imax = rs.GetInteger("number of spheres in X-axis", 5, 1, 10) jmax = rs.GetInteger("number of spheres in Y-axis", 5, 1, 10) kmax = rs.GetInteger("number of spheres in Z-axis", 5, 1, 10) for i in rs.frange(0, imax, 1): for j in rs.frange(0, jmax, 1): for k in rs.frange(0, kmax, 1): #set up coordinate arrPointCoord = rs.AddPoint([i, j, k]) pt.append(arrPointCoord) r = 0 + (255 - 0) / (imax) * i g = 255 - (0 + (255 - 0) / (jmax) * j) b = (255 / kmax * k) rs.ObjectColor(pt, [r, g, b])
def create_cross_sections(self): crvdomain = rs.CurveDomain(self.curve_object) self.cross_sections = [] self.cross_section_planes = [] t_step = (crvdomain[1]-crvdomain[0])/self.SAMPLES pi_step_size = math.pi/self.SAMPLES pi_step = 0 prev_normal = None prev_perp = None for t in rs.frange(crvdomain[0], crvdomain[1], t_step): crvcurvature = rs.CurveCurvature(self.curve_object, t) crosssectionplane = None if not crvcurvature: crosssectionplane = self.cross_section_plane_no_curvature(t, prev_normal, prev_perp) else: crosssectionplane = self.cross_section_plane_curvature(crvcurvature, prev_normal, prev_perp) if crosssectionplane: prev_perp = crosssectionplane.XAxis prev_normal = crosssectionplane.YAxis pi_scalar = self.create_scalar(pi_step) radii = self.ellipse_radii(pi_scalar) csec = rs.AddEllipse(crosssectionplane, radii[0], radii[1]) self.cross_sections.append(csec) self.cross_section_planes.append(crosssectionplane) pi_step += pi_step_size
def flatWorm(): curveObject = rs.GetObject("pick a backbone curve", 4, True, False) samples = rs.GetInteger("# of crosssections", 100, 5) bend_radius = rs.GetReal("bend radius", 0.5, 0.001) # r1 perp_radius = rs.GetReal("ribbon plan radius", 2.0, 0.001) #r2 crvDom = rs.CurveDomain(curveObject) # domain != length // why do we use domains? == "The domain is the set of all possible input values to the function that defines the curve or surface." crossSections = [] # empty array to store sections t_step = (crvDom[1] - crvDom[0]) / samples # this is starting to be a pattern! t = crvDom[0] # start pt for loop at the start of the line for t in rs.frange(crvDom[0], crvDom[1], t_step): # loop thru entire domain w/ floats crvCurvature = rs.CurveCurvature(curveObject, t) # evaluate curve with a circle - gives 3d normals & gives radius info crossSecPlane = None if not crvCurvature: crvPoint = rs.EvaluateCurve(curveObject, t) crvTan = rs.CurveTangent(curveObject, t) # get tangent vector crvPerp = (0,0,1) crvNorm = rs.VectorCrossProduct(crvTan, crvPerp)# = product of 2 vectors crossSecPlane = rs.PlaneFromFrame(crvPoint, crvPerp, crvNorm) else: crvPoint = crvCurvature[0] crvTan = crvCurvature[1] crvPerp = rs.VectorUnitize(crvCurvature[4]) crvNorm = rs.VectorCrossProduct(crvTan, crvPerp)# look up crossSecPlane = rs.PlaneFromFrame(crvPoint, crvPerp, crvNorm) if crossSecPlane: csec = rs.AddEllipse(crossSecPlane, bend_radius, perp_radius) # draw ellipse at tan/normal to point along curve with radii crossSections.append(csec) # add ellipses to an array t += t_step # step through domain rs.AddLoftSrf(crossSections) # loft list of curves rs.DeleteObjects(crossSections) # delete original list of curves as cleanup
def drawNurbsCurvePts(self,nums,u): pts = [] for f in rs.frange( self.knots[0],self.knots[-1],(self.knots[-1]-self.knots[0])/float(nums) ): if f<u: pt, _, _ = nurbs.calculateNurbsPoint(f) pts.append(pt) pointAtU, ptsGoo, deBoorlines = nurbs.calculateNurbsPoint(u,1) return pts,pointAtU, ptsGoo, deBoorlines
def ptsOnSrf (): surfaceId = rs.GetObject("pick surface", 8, True, True) uVal = rs.GetInteger("pick u/row count",4, 1, 20) vVal = rs.GetInteger("pick v/col count",4, 1, 20) uDomain = rs.SurfaceDomain(surfaceId, 0) vDomain = rs.SurfaceDomain(surfaceId, 1) uStep = (uDomain[1] - uDomain[0])/ uVal vStep = (vDomain[1] - vDomain[0])/ vVal count = 0 allPts = [] for i in rs.frange(uDomain[0], uDomain[1], uStep): for j in rs.frange(vDomain[0], vDomain[1], vStep): point = rs.EvaluateSurface(surfaceId, i, j) newPt = rs.AddPoint(point) allPts.append(newPt) rs.AddInterpCrvOnSrf(surfaceId, allPts) rs.DeleteObjects(allPts)
def ptsOnSrf(): surfaceId = rs.GetObject("pick surface", 8, True, True) uVal = rs.GetInteger("pick u/row count", 4, 1, 20) vVal = rs.GetInteger("pick v/col count", 4, 1, 20) uDomain = rs.SurfaceDomain(surfaceId, 0) vDomain = rs.SurfaceDomain(surfaceId, 1) uStep = (uDomain[1] - uDomain[0]) / uVal vStep = (vDomain[1] - vDomain[0]) / vVal count = 0 allPts = [] for i in rs.frange(uDomain[0], uDomain[1], uStep): for j in rs.frange(vDomain[0], vDomain[1], vStep): point = rs.EvaluateSurface(surfaceId, i, j) newPt = rs.AddPoint(point) allPts.append(newPt) rs.AddInterpCrvOnSrf(surfaceId, allPts) rs.DeleteObjects(allPts)
def draw_warp(): n = 360 warp = [] for i in rs.frange(0, n, d): point = [] for z in rs.frange(1, 120, 5): si = draw_sikaku(i) do = draw_outline(z) p = rs.CurveSurfaceIntersection(do, si) rs.DeleteObject(si) rs.DeleteObject(do) point.append(p[0][1]) curve_1 = rs.AddCurve(point) curve_2 = rs.CopyObject(curve_1, polar(t, i, 0)) domain = rs.CurveDomain(curve_1) increment = (domain[1] - domain[0]) point_1 = rs.EvaluateCurve(curve_1, domain[0]) point_2 = rs.EvaluateCurve(curve_1, domain[1]) arc_1 = draw_arc(point_1, i, -1) arc_2 = draw_arc(point_2, i, 1) wakame = [curve_1, curve_2, arc_1, arc_2] #konobubunnde_ugokasiteru # rs.RotateObjects(wakame,(0,0,0),90,polar(10,i,0),False) # rs.MoveObjects (wakame, polar(0, i ,0)) # rs.RotateObjects(wakame,(0,0,0),-i,None,False) # rs.MoveObjects (wakame, (i*t/5,10,5)) #konobubunnde_ugokasiteru point_3 = rs.EvaluateCurve(curve_1, increment * 28 / 29) rec_1 = draw_rectangle_2(point_3, 0) point_4 = rs.EvaluateCurve(curve_1, increment * 1 / 14) rec_2 = draw_rectangle_2(point_4, 0) warp.append(curve_1) return warp
def draw_bottom(): points = [] for theta in rs.frange(0, 360, c): R = ran_2 * ma.cos(ma.radians(theta) * ran_1) x = (R + 15) * ma.cos(ma.radians(theta)) y = (R + 18) * ma.sin(ma.radians(theta)) points.append((x, y, 0)) curve = rs.AddCurve(points) return curve
def __generate_form_levels(self, spine_curve): crvdomain = rs.CurveDomain(spine_curve) printedState = "" crosssection_planes = [] crosssection_plane_nums = [] crosssections = [] t_step = (crvdomain[1] - crvdomain[0]) / ( self.object_properties["number_of_lofts"] - 1) t = crvdomain[0] for t in rs.frange(crvdomain[0], crvdomain[1], t_step): if (self.emotion_properties["vertical_AR"][str(int(t + 1))] != None): crvcurvature = rs.CurveCurvature(spine_curve, t) crosssectionplane = None if not crvcurvature: crvPoint = rs.EvaluateCurve(spine_curve, t) crvTangent = rs.CurveTangent(spine_curve, t) crvPerp = (0, 0, 1) crvNormal = rs.VectorCrossProduct(crvTangent, crvPerp) printedState = printedState + str(crvNormal) crosssectionplane = rs.PlaneFromNormal( crvPoint, crvTangent) if (t == 0): crosssectionplane = rs.PlaneFromNormal([0, 0, 0], [0, 0, 1]) else: crvPoint = crvcurvature[0] crvTangent = crvcurvature[1] crvPerp = rs.VectorUnitize(crvcurvature[4]) crvNormal = rs.VectorCrossProduct(crvTangent, crvPerp) printedState = printedState + str(crvNormal) crosssectionplane = rs.PlaneFromNormal( crvPoint, crvTangent, crvNormal) if crosssectionplane: crosssection_planes.append(crosssectionplane) crosssection_plane_nums.append(str(int(t + 1))) if len(crosssection_plane_nums) > 0: last_element = crosssection_plane_nums.pop( len(crosssection_plane_nums) - 1) crosssection_plane_nums.insert(0, last_element) for index in xrange(len(crosssection_plane_nums)): crosssections.append( self.__generate_individual_levels( crosssection_planes[index], crosssection_plane_nums[index])) if not crosssections: return crosssections.append(crosssections.pop(0)) rs.AddLoftSrf(crosssections, closed=False, loft_type=int( round(self.emotion_properties["vertical_wrapping"]))) return crosssection_planes[0]
def getHOYs(hours, days, months, timeStep, lb_preparation, method = 0): if method == 1: stDay, endDay = days numberOfDaysEachMonth = lb_preparation.numOfDaysEachMonth numOfHours = timeStep * len(hours) if timeStep != 1: step = 1/timeStep hours = rs.frange(hours[0], hours[-1] + 1, step) # make sure hours are generated correctly if len(hours) > numOfHours: hours = hours[:numOfHours] elif len(hours) < numOfHours: newHour = hours[-1] + step HOYS = [] for monthCount, m in enumerate(months): # just a single day if method == 1 and len(months) == 1 and stDay - endDay == 0: days = [stDay] # few days in a single month elif method == 1 and len(months) == 1: days = range(stDay, endDay + 1) elif method == 1: #based on analysis period if monthCount == 0: # first month days = range(stDay, numberOfDaysEachMonth[m-1] + 1) elif monthCount == len(months) - 1: # last month days = range(1, lb_preparation.checkDay(endDay, m) + 1) else: #rest of the months days = range(1, numberOfDaysEachMonth[m-1] + 1) for d in days: for h in hours: h = lb_preparation.checkHour(float(h)) m = lb_preparation.checkMonth(int(m)) d = lb_preparation.checkDay(int(d), m) HOY = lb_preparation.date2Hour(m, d, h) if HOY not in HOYS: HOYS.append(HOY) return HOYS
def getValueBasedOnOrientation(valueList): angles = [] if valueList == None or len(valueList) == 0: value = None if len(valueList) == 1: value = valueList[0] elif len(valueList) > 1: initAngles = rs.frange(0, 360, 360/len(valueList)) for an in initAngles: angles.append(an-(360/(2*len(valueList)))) angles.append(360) for angleCount in range(len(angles)-1): if angles[angleCount] <= (getAngle2North(normalVector))%360 <= angles[angleCount +1]: targetValue = valueList[angleCount%len(valueList)] value = targetValue return value
def draw_top_wakka(): top_outline = draw_outline(20) rs.ScaleObject(top_outline, (0, 0, 20), (1.09, 1.09, 1), False) n = 360 top_rectangle = [] for i in rs.frange(0, n, d): si = draw_sikaku(i) p = rs.CurveSurfaceIntersection(top_outline, si) rs.DeleteObject(si) dr = draw_rectangle_1(p[0][1], i) rs.MoveObject(dr, polar(0.1, i, 0)) top_rectangle.append(dr) top_curve = [top_outline, top_rectangle]
def draw_bottom_wakka(): bottom_outline = draw_outline(11) rs.ScaleObject(bottom_outline, (0, 0, 10), (1.06, 1.06, 1), False) n = 360 bottom__rectangle = [] for i in rs.frange(0, n, d): si = draw_sikaku(i) do = draw_outline(11) p = rs.CurveSurfaceIntersection(do, si) rs.DeleteObject(si) rs.DeleteObject(do) dr = draw_rectangle_1(p[0][1], i) rs.MoveObject(dr, polar(0.6, i, 0)) bottom__rectangle.append(dr)
def orientaionStr(divisionAngle, totalAngle): divisionAngle = float(divisionAngle) totalAngle = float(totalAngle) # check the numbers if divisionAngle> totalAngle: print "Division angle cannot be bigger than the total angle!" w = gh.GH_RuntimeMessageLevel.Error ghenv.Component.AddRuntimeMessage(w, "Division angle cannot be bigger than the total angle!") return 0 elif totalAngle%divisionAngle!=0: print "Total angle should be divisible by the division angle!" w = gh.GH_RuntimeMessageLevel.Error ghenv.Component.AddRuntimeMessage(w, "Total angle should be divisible by the division angle!") return 0 else: return [0] + rs.frange(0, totalAngle, divisionAngle)
def points_from_ellipse(self, index): ellipse = self.cross_sections[index] even = index % 2 == 0 ellipse_domain = rs.CurveDomain(ellipse) ellipse_step = (ellipse_domain[1] - ellipse_domain[0])/self.POINTS_ON_CROSS_SECTION points = [] j = 0 for i in rs.frange(ellipse_domain[0], ellipse_domain[1] - ellipse_step, ellipse_step): if even: if j % 2 == 0: points.append(rs.EvaluateCurve(ellipse, i)) else: if (j + 1) % 2 == 0: points.append(rs.EvaluateCurve(ellipse, i)) j += 1 return points
def flatWorm(): curveObject = rs.GetObject("pick a backbone curve", 4, True, False) samples = rs.GetInteger("# of crosssections", 100, 5) bend_radius = rs.GetReal("bend radius", 0.5, 0.001) # r1 perp_radius = rs.GetReal("ribbon plan radius", 2.0, 0.001) #r2 crvDom = rs.CurveDomain( curveObject ) # domain != length // why do we use domains? == "The domain is the set of all possible input values to the function that defines the curve or surface." crossSections = [] # empty array to store sections t_step = (crvDom[1] - crvDom[0]) / samples # this is starting to be a pattern! t = crvDom[0] # start pt for loop at the start of the line for t in rs.frange(crvDom[0], crvDom[1], t_step): # loop thru entire domain w/ floats crvCurvature = rs.CurveCurvature( curveObject, t ) # evaluate curve with a circle - gives 3d normals & gives radius info crossSecPlane = None if not crvCurvature: crvPoint = rs.EvaluateCurve(curveObject, t) crvTan = rs.CurveTangent(curveObject, t) # get tangent vector crvPerp = (0, 0, 1) crvNorm = rs.VectorCrossProduct(crvTan, crvPerp) # = product of 2 vectors crossSecPlane = rs.PlaneFromFrame(crvPoint, crvPerp, crvNorm) else: crvPoint = crvCurvature[0] crvTan = crvCurvature[1] crvPerp = rs.VectorUnitize(crvCurvature[4]) crvNorm = rs.VectorCrossProduct(crvTan, crvPerp) # look up crossSecPlane = rs.PlaneFromFrame(crvPoint, crvPerp, crvNorm) if crossSecPlane: csec = rs.AddEllipse( crossSecPlane, bend_radius, perp_radius ) # draw ellipse at tan/normal to point along curve with radii crossSections.append(csec) # add ellipses to an array t += t_step # step through domain rs.AddLoftSrf(crossSections) # loft list of curves rs.DeleteObjects( crossSections) # delete original list of curves as cleanup
def distortArray(fuseList, rec): bFuse = rs.BoundingBox(fuseList[0]) lenFuse = bFuse[1][0] - bFuse[0][0] bRec = rs.BoundingBox(rec) lenRec = bRec[1][0] - bRec[0][0] xRange = lenRec - lenFuse step = xRange/ (len(fuseList)) distortion = rs.frange(0, xRange, step) for i in range(0, len(fuseList)): x = choice(distortion) distortion.remove(x) xform = [x,0,0] rs.MoveObject(fuseList[i], xform) return fuseList
def TorusKnotVerts(p, q, res, zScale): # Determine if we need to loop less because of non coprime p and q upLimit = 2.0*math.pi P = int(p); Q = int(q) hcf = HighestCommonFactor(P, Q) if (hcf != 1): upLimit /= hcf verts = [] roundTol = 0.01 # Fudge factor to make sure loop closes tStep = math.pi/(res/2.0) for t in rs.frange(0.0, upLimit+roundTol, tStep): r = math.cos(q*t)+2.0 x = r*math.cos(p*t) y = r*math.sin(p*t) z = -math.sin(q*t)*2.0 z *= zScale pt = Rhino.Geometry.Point3d(x, y, z) verts.append(pt) return verts
def points_from_ellipse(self, index): ellipse = self.cross_sections[index] even = index % 2 == 0 ellipse_domain = rs.CurveDomain(ellipse) ellipse_step = (ellipse_domain[1] - ellipse_domain[0]) / self.POINTS_ON_CROSS_SECTION points = [] j = 0 for i in rs.frange(ellipse_domain[0], ellipse_domain[1] - ellipse_step, ellipse_step): if even: if j % 2 == 0: points.append(rs.EvaluateCurve(ellipse, i)) else: if (j + 1) % 2 == 0: points.append(rs.EvaluateCurve(ellipse, i)) j += 1 return points
def __generate_form_levels(self, spine_curve): crvdomain = rs.CurveDomain(spine_curve) printedState = "" crosssection_planes = [] crosssection_plane_nums = [] crosssections = [] t_step = (crvdomain[1] - crvdomain[0]) / (self.object_properties["number_of_lofts"]-1) t = crvdomain[0] for t in rs.frange(crvdomain[0], crvdomain[1], t_step): if(self.emotion_properties["vertical_AR"][str(int(t+1))] != None): crvcurvature = rs.CurveCurvature(spine_curve, t) crosssectionplane = None if not crvcurvature: crvPoint = rs.EvaluateCurve(spine_curve, t) crvTangent = rs.CurveTangent(spine_curve, t) crvPerp = (0,0,1) crvNormal = rs.VectorCrossProduct(crvTangent, crvPerp) printedState = printedState + str(crvNormal) crosssectionplane = rs.PlaneFromNormal(crvPoint, crvTangent) if(t==0): crosssectionplane = rs.PlaneFromNormal([0,0,0], [0,0,1]) else: crvPoint = crvcurvature[0] crvTangent = crvcurvature[1] crvPerp = rs.VectorUnitize(crvcurvature[4]) crvNormal = rs.VectorCrossProduct(crvTangent, crvPerp) printedState = printedState + str(crvNormal) crosssectionplane = rs.PlaneFromNormal(crvPoint, crvTangent, crvNormal) if crosssectionplane: crosssection_planes.append(crosssectionplane) crosssection_plane_nums.append(str(int(t+1))) if len(crosssection_plane_nums) > 0: last_element = crosssection_plane_nums.pop(len(crosssection_plane_nums)-1) crosssection_plane_nums.insert(0, last_element) for index in xrange(len(crosssection_plane_nums)): crosssections.append(self.__generate_individual_levels(crosssection_planes[index], crosssection_plane_nums[index])) if not crosssections: return crosssections.append(crosssections.pop(0)) rs.AddLoftSrf(crosssections,closed=False,loft_type=int(round(self.emotion_properties["vertical_wrapping"]))) return crosssection_planes[0]
def TorusKnotVerts(p, q, res, zScale): # Determine if we need to loop less because of non coprime p and q upLimit = 2.0 * math.pi P = int(p) Q = int(q) hcf = HighestCommonFactor(P, Q) if (hcf != 1): upLimit /= hcf verts = [] roundTol = 0.01 # Fudge factor to make sure loop closes tStep = math.pi / (res / 2.0) for t in rs.frange(0.0, upLimit + roundTol, tStep): r = math.cos(q * t) + 2.0 x = r * math.cos(p * t) y = r * math.sin(p * t) z = -math.sin(q * t) * 2.0 z *= zScale pt = Rhino.Geometry.Point3d(x, y, z) verts.append(pt) return verts
def outline(s): x1= 6*s y1= 0 x2= 3*s y2= 6*s*ma.sqrt(3)/2 xy1 = (x1, y1, 0) xy2 = (x2, y2, 0) line_origin = rs.AddLine(xy1, xy2) o = length_of_outline = 0.1 #0.05<0<0.10 line = rs.ScaleObject(line_origin, (0, 0, 0), (1+o, 1+o, 0), False) for angle in rs.frange(60, 360, 60): rs.RotateObject(line, (0, 0, 0), angle, None, True) all_lines = rs.ObjectsByType(0) rs.ObjectColor(all_lines,colors[0])
def contour(crvOffset): # get geometry surfaceId = rs.GetObject("pick surface to contour", 0, True, True) startPt = rs.GetPoint("base point of contours") endPt = rs.GetPoint("end point of contours") count = 0 reference = [] target = [] # make contours & store in newCrvs newCrvs = rs.AddSrfContourCrvs( surfaceId, (startPt, endPt), crvOffset ) # output is a list of GUIDs. can't access raw points # divide the target surface printBed = rs.GetObject("pick surface for layout", 8, True, True) intCount = len(newCrvs) uDomain = rs.SurfaceDomain(printBed, 0) vDomain = rs.SurfaceDomain(printBed, 1) uStep = (uDomain[1] - uDomain[0]) / intCount for u in rs.frange(uDomain[0], uDomain[1], uStep): layout = rs.SurfaceFrame(printBed, [u, 1]) target1 = layout[0] # set target to point inside of object - note this is a single point target2 = rs.PointAdd(target1, (0, 10, 0)) # this could be more parametric target.extend([target1, target2]) # print target # add text, reference and orient! # for orient, we need a list 3 points to reference and 3 points to target! # maybe reference should be curve origin crvPl[0] and midpoint? or else polyline verticies -- need to convert curve to polyline first? for crv in newCrvs: count += 1 # for label crvPl = rs.CurvePlane(crv) # plane for text rs.AddText(count, crvPl, 0.25) # should you label on the ground? # crvPl = rs.PointAdd(crvPl[0], (0,0,-1)) # if you wanted to offset text ref1 = rs.CurveMidPoint(crv) ref2 = crvPl[0] reference.extend([ref1, ref2])
def GenerateCrossSection(sectionPoints, radius, rotation, smooth, curve, samples, p, q): points = [] avoidRoundoff = 0.01 for angle in rs.frange(0.0, 360.0 + avoidRoundoff, 360.0 / sectionPoints): points.append(rs.Polar((0.0, 0.0, 0.0), angle, radius)) rotXform = rs.XformRotation2(rotation, (0, 0, 1), (0, 0, 0)) points = rs.PointArrayTransform(points, rotXform) t = curve.Domain[0] crossSections = [] curveCurvature = curve.CurvatureAt(t) crossSectionPlane = None if not curveCurvature: crvPoint = curve.PointAt(t) crvTangent = curve.TangentAt(t) crvPerp = (0, 0, 1) crvNormal = Rhino.Geometry.Vector3d.CrossProduct(crvTangent, crvPerp) crossSectionPlane = Rhino.Geometry.Plane(crvPoint, crvPerp, crvNormal) else: crvPoint = curve.PointAt(t) crvTangent = curve.TangentAt(t) crvPerp = curve.CurvatureAt(t) crvPerp.Unitize crvNormal = Rhino.Geometry.Vector3d.CrossProduct(crvTangent, crvPerp) crossSectionPlane = Rhino.Geometry.Plane(crvPoint, crvPerp, crvNormal) if crossSectionPlane: xform = rs.XformChangeBasis(crossSectionPlane, rs.WorldXYPlane()) sectionVerts = rs.PointArrayTransform(points, xform) if (smooth): # Degree 3 curve to smooth it sectionCurve = Rhino.Geometry.Curve.CreateControlPointCurve( sectionVerts, 3) else: # Degree 1 curve (polyline) sectionCurve = Rhino.Geometry.Curve.CreateControlPointCurve( sectionVerts, 1) crossSection = rs.coercecurve(sectionCurve) return crossSection
def contour (crvOffset): # get geometry surfaceId = rs.GetObject("pick surface to contour", 0, True, True) startPt = rs.GetPoint("base point of contours") endPt = rs.GetPoint("end point of contours") count = 0 reference = [] target = [] # make contours & store in newCrvs newCrvs = rs.AddSrfContourCrvs(surfaceId, (startPt, endPt), crvOffset) # output is a list of GUIDs. can't access raw points # divide the target surface printBed = rs.GetObject("pick surface for layout", 8, True, True) intCount = len(newCrvs) uDomain = rs.SurfaceDomain(printBed, 0) vDomain = rs.SurfaceDomain(printBed, 1) uStep = (uDomain[1] - uDomain[0]) / intCount for u in rs.frange(uDomain[0], uDomain[1], uStep): layout = rs.SurfaceFrame(printBed, [u,1]) target1 = layout[0] # set target to point inside of object - note this is a single point target2 = rs.PointAdd(target1,(0,10,0)) # this could be more parametric target.extend([target1, target2]) #print target # add text, reference and orient! # for orient, we need a list 3 points to reference and 3 points to target! # maybe reference should be curve origin crvPl[0] and midpoint? or else polyline verticies -- need to convert curve to polyline first? for crv in newCrvs: count += 1 # for label crvPl = rs.CurvePlane(crv) # plane for text rs.AddText(count, crvPl, 0.25) # should you label on the ground? #crvPl = rs.PointAdd(crvPl[0], (0,0,-1)) # if you wanted to offset text ref1 = rs.CurveMidPoint(crv) ref2 = crvPl[0] reference.extend([ref1, ref2])
#Create alternating sine curves with alternating colors #import both RS and math libraries import rhinoscriptsyntax as rs import math #Boolean switch flip = True #Create two colors, colors are tuples (R, G, B) color01 = (0, 255, 255) color02 = (255, 0, 255) #For loops with frange(start, stop, step) for x in rs.frange(0.0, 10.0, 0.1): #create the list here, we create a new list once we exhaust Y coords. to create individual sets of points in the Y Direction ptsForCurve = [] for y in rs.frange(0.0, 10.0, 0.1): #Z coords based on product of sines z = math.sin(x) * math.sin(y) #store each point as a tuple with X, Y, and Z and append to the point list pt = (x, y, z) ptsForCurve.append(pt) #once we have all the points, create a curve using those points and add it to the Rhino Document curve = rs.AddCurve(ptsForCurve) #Alternating colors using boolean switch if flip: rs.ObjectColor(curve, color01)
import rhinoscriptsyntax as rs import math #Call rs.EnableRedraw(False) for t in rs.frange(-50, 50, 1.25): arrPoint = [t * math.sin(5 * t), t * math.cos(5 * t), t] print(arrPoint) rs.AddPoint(arrPoint) #Call rs.EnableRedraw(True)
def analyzeGlz(glzSrf, distBetween, numOfShds, horOrVertical, lb_visualization, normalVector): # find the bounding box bbox = glzSrf.GetBoundingBox(True) if horOrVertical == None: horOrVertical = True if numOfShds == None and distBetween == None: numOfShds = 1 if numOfShds == 0 or distBetween == 0: sortedPlanes = [] elif horOrVertical == True: # Horizontal #Define a bounding box for use in calculating the number of shades to generate minZPt = bbox.Corner(False, True, True) maxZPt = bbox.Corner(False, True, False) maxZPt = rc.Geometry.Point3d(maxZPt.X, maxZPt.Y, maxZPt.Z - sc.doc.ModelAbsoluteTolerance) centerPt = bbox.Center #glazing hieghts glzHeight = minZPt.DistanceTo(maxZPt) # find number of shadings try: numOfShd = int(numOfShds) except: numOfShd = math.ceil(glzHeight/distBetween) shadingHeight = glzHeight/numOfShd # find shading base planes planeOrigins = [] planes = [] X, Y, z = minZPt.X, minZPt.Y, minZPt.Z try: for Z in rs.frange(minZPt.Z + shadingHeight , maxZPt.Z, shadingHeight): planes.append(rc.Geometry.Plane(rc.Geometry.Point3d(X, Y, Z), rc.Geometry.Vector3d.ZAxis)) except: # single shading planes.append(rc.Geometry.Plane(rc.Geometry.Point3d(maxZPt), rc.Geometry.Vector3d.ZAxis)) # sort the planes sortedPlanes = sorted(planes, key=lambda a: a.Origin.Z) elif horOrVertical == False: # Vertical # Define a vector to be used to generate the planes planeVec = rc.Geometry.Vector3d(normalVector.X, normalVector.Y, 0) planeVec.Rotate(1.570796, rc.Geometry.Vector3d.ZAxis) #Define a bounding box for use in calculating the number of shades to generate minXYPt = bbox.Corner(True, True, True) maxXYPt = bbox.Corner(False, False, True) centerPt = bbox.Center #glazing distance glzHeight = minXYPt.DistanceTo(maxXYPt) # find number of shadings try: numOfShd = int(numOfShds) except: numOfShd = math.ceil(glzHeight/distBetween) shadingHeight = glzHeight/numOfShd - sc.doc.ModelAbsoluteTolerance # find shading base planes planeOrigins = [] planes = [] pointCurve = rc.Geometry.Curve.CreateControlPointCurve([minXYPt, maxXYPt]) divisionParams = pointCurve.DivideByLength(shadingHeight, True) divisionPoints = [] for param in divisionParams: divisionPoints.append(pointCurve.PointAt(param)) planePoints = divisionPoints[1:] try: for point in planePoints: planes.append(rc.Geometry.Plane(point, planeVec)) except: # single shading planes.append(rc.Geometry.Plane(rc.Geometry.Point3d(maxXYPt), planeVec)) # sort the planes try: sortedPlanes = sorted(planes, key=lambda a: a.Origin.X) except: sortedPlanes = sorted(planes, key=lambda a: a.Origin.Y) # return planes return sortedPlanes
def main(HBZones): if not sc.sticky.has_key('honeybee_release'): print "You should first let Honeybee to fly..." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage( w, "You should first Honeybee to fly...") return try: if not sc.sticky['honeybee_release'].isCompatible(ghenv.Component): return -1 except: warning = "You need a newer version of Honeybee to use this compoent." + \ "Use updateHoneybee component to update userObjects.\n" + \ "If you have already updated userObjects drag Honeybee_Honeybee component " + \ "into canvas and try again." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, warning) return hb_hive = sc.sticky["honeybee_Hive"]() # Call Honeybee zones from the lib HBZones = hb_hive.callFromHoneybeeHive(HBZones) # create an empty dictionary # the structure should be as {type : {construction: { orientation : {area of opaque : area , area of glass : area}}} srfData = {} # produce division angles - keep it to 8 directions for now divisionAngles = rs.frange(0 - (360 / 8), 360 - (360 / 8), 360 / 8) # iterate through faces and add them to the dictionary for HBZone in HBZones: for srfCount, HBSrf in enumerate(HBZone.surfaces): # let's add it to the dictionary # I need to know what is the type of the surface (wall, roof, ?) # HBSrf.type will return the type. I'm not sure how much detailed you want the type to be # what is the approach for surfcaes with adjacencies? Here are simple types # srf.type == 0 #wall, # srf.type == 1 #roof, # int(srf.type) == 2 #floor # print "type: ", HBSrf.type srfType = int(HBSrf.type) # I add the key to the dictionary if it is not there yet if not srfData.has_key(srfType): srfData[srfType] = {} # let's find the construction next as your workflow is based on different construction types # you can get it form a Honeybee surface using HBSrf.EPConstruction # print "EP construction: ", HBSrf.EPConstruction constr = HBSrf.EPConstruction if not srfData[srfType].has_key(constr): # create a place holder for this construction and put the initial area as 0 srfData[srfType][constr] = {} # now let's find the direction of the surface # in case of roof or floor orientation doesn't really matter (or does it?) # so I just add it to dictionary and consider orientation as 0 if srfType != 0: direction = 0 else: # otherwise we need to find the direction of the surface # you can use HBSrf.angle2North to get it # print "angle: ", HBSrf.angle2North # check and see where it stands, 0 will be north, 1 is NE, etc. for direction in range(len(divisionAngles) - 1): if divisionAngles[direction] + ( 0.5 * sc.doc.ModelAngleToleranceDegrees ) <= HBSrf.angle2North % 360 <= divisionAngles[ direction + 1] + (0.5 * sc.doc.ModelAngleToleranceDegrees): # here we found the direction break # Now that we know direction let's make an empty dictionary for that if not srfData[srfType][constr].has_key(direction): srfData[srfType][constr][direction] = {} srfData[srfType][constr][direction]["area"] = 0 # in case surface has glazing then create a place holder with # type 5 reperesnts glazing if HBSrf.hasChild: if not srfData.has_key(5): srfData[5] = {} # this is tricky here as I assume that all the glazing in the same wall # has same construction and I pick the first one - we can change this later if needed glzConstr = HBSrf.childSrfs[0].EPConstruction if not srfData[5].has_key(glzConstr): srfData[5][glzConstr] = {} if not srfData[5][glzConstr].has_key(direction): srfData[5][glzConstr][direction] = {} srfData[5][glzConstr][direction]["area"] = 0 # add the area to the current area # Honeybee has methods that return area for opaque and glazed area #print "Opaque area: ", HBSrf.getOpaqueArea() #print "Glazing area: ", HBSrf.getGlazingArea() srfData[srfType][constr][direction]["area"] += HBSrf.getOpaqueArea( ) if HBSrf.hasChild: srfData[5][HBSrf.childSrfs[0].EPConstruction][direction][ "area"] += HBSrf.getGlazingArea() # return surface data return srfData
def main(HBZones): # check for Honeybee if not sc.sticky.has_key('honeybee_release'): print "You should first let Honeybee to fly..." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage( w, "You should first let Honeybee to fly...") return try: if not sc.sticky['honeybee_release'].isCompatible(ghenv.Component): return if sc.sticky['honeybee_release'].isInputMissing(ghenv.Component): return -1 except: warning = "You need a newer version of Honeybee to use this compoent." + \ " Use updateHoneybee component to update userObjects.\n" + \ "If you have already updated userObjects drag Honeybee_Honeybee component " + \ "into canvas and try again." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, warning) return # call the objects from the lib hb_hive = sc.sticky["honeybee_Hive"]() HBObjectsFromHive = hb_hive.callFromHoneybeeHive(HBZones) #Get the types to be made adiabatic. types = [] intTypes = [] if undergroundWalls_: types.append(0.5) if roofs_: types.append(1) if undergroundCeilings_: types.append(1.5) if floors_: types.append(2) if undergroundSlabs_: types.append(2.25) if groundFloors_: types.append(2.5) if exposedFloors_: types.append(2.75) if ceilings_: types.append(3) if airWalls_: types.append(4) if windows_: types.append(5) if interiorWalls_: intTypes.append(0) if interiorWindows_: intTypes.append(5) if floors_: intTypes.append(2) if airWalls_: intTypes.append(4) if ceilings_: intTypes.append(3) #See if the wall properties are being specified based on orientation. angles = [] if len(walls_) == 0: pass elif len(walls_) == 1: if walls_[0] != False: types.append(0) else: types.append(0) initAngles = rs.frange(0, 360, 360 / len(walls_)) for an in initAngles: angles.append(an - (360 / (2 * len(walls_)))) angles.append(360) for HBO in HBObjectsFromHive: for HBS in HBO.surfaces: if HBS.BC.title() != 'Surface': if HBS.type in types: if HBS.type == 0 and len(walls_) > 1: for angleCount in range(len(angles) - 1): if angles[angleCount] + ( 0.5 * sc.doc.ModelAngleToleranceDegrees ) <= HBS.angle2North % 360 <= angles[ angleCount + 1] + (0.5 * sc.doc.ModelAngleToleranceDegrees): targetAdiabatic = walls_[angleCount % len(walls_)] if targetAdiabatic == True: HBS.BC = "Adiabatic" HBS.sunExposure = "NoSun" HBS.windExposure = "NoWind" else: HBS.BC = "Adiabatic" HBS.sunExposure = "NoSun" HBS.windExposure = "NoWind" if HBS.hasChild and 5 in types: for childSrf in HBS.childSrfs: childSrf.BC = "Adiabatic" childSrf.sunExposure = "NoSun" childSrf.windExposure = "NoWind" else: if HBS.type in intTypes: HBS.BC = "Adiabatic" HBS.sunExposure = "NoSun" HBS.windExposure = "NoWind" if HBS.hasChild and 5 in intTypes: for childSrf in HBS.childSrfs: childSrf.BC = "Adiabatic" childSrf.sunExposure = "NoSun" childSrf.windExposure = "NoWind" HBZones = hb_hive.addToHoneybeeHive(HBObjectsFromHive, ghenv.Component) return HBZones
import rhinoscriptsyntax as rs import math #Sub waveGrid rowSpace = 3 colSpace = 3 limit = 20 arrPoints = [limit, limit] #array to hold points pi = math.pi amp = 3 startTheta = 0 freq = 6 rs.EnableRedraw(False) for rows in rs.frange(0,limit,1): for cols in rs.frange(0,limit,1): #equate cols loop to angle slices around a circle ( angles in radians ) #+ starting point on the circle rad = ((cols/limit)*(2*math.pi)) + startTheta x = cols*colSpace y = rows*rowSpace z = (math.sin(rad * freq)*amp) n = rs.AddPoint([x,y,z]) #iterate between rows startTheta = startTheta + ((2*math.pi)*(cols/limit)) rs.EnableRedraw(True)
import math import rhinoscriptsyntax as rs dblA = -8.0 dblB = 8.0 dblStep = 0.25 for x in rs.frange(dblA, dblB, dblStep): y = 2*math.sin(x) rs.AddPoint([x, y, 0]) mpoints = rs.ObjectsByType(1, True) mcurves = rs.AddCurve(mpoints) rs.DeleteObjects(mpoints) rs.CopyObject( mcurves, [0,1,0] )
# Simple count #for i in range(0,50): # print(i) # Count by even numbers #for i in range(0,50,2): # print(i) # Count by odd numbers #for i in range(1,50,2): # print(i) # Using RhinoScript's frange to step with floats #for d in rs.frange(0.0,10.0,0.1): # print(d) #for d in rs.frange(0.0,10.0,0.1): # rs.AddPoint(d,0,0) points = [] for d in rs.frange(0.0, 10.0, 0.1): x = d * math.sin(d) y = d * math.cos(d) z = 0.0 rs.AddPoint(x, y, z) pt = (x, y, z) points.append(pt) curve = rs.AddCurve(points)
def main(HBZones): # check for Honeybee if not sc.sticky.has_key("honeybee_release"): print "You should first let Honeybee to fly..." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, "You should first let Honeybee to fly...") return try: if not sc.sticky["honeybee_release"].isCompatible(ghenv.Component): return if sc.sticky["honeybee_release"].isInputMissing(ghenv.Component): return -1 except: warning = ( "You need a newer version of Honeybee to use this compoent." + " Use updateHoneybee component to update userObjects.\n" + "If you have already updated userObjects drag Honeybee_Honeybee component " + "into canvas and try again." ) w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, warning) return # call the objects from the lib hb_hive = sc.sticky["honeybee_Hive"]() HBObjectsFromHive = hb_hive.callFromHoneybeeHive(HBZones) # Get the types to be made adiabatic. types = [] intTypes = [] if undergroundWalls_: types.append(0.5) if roofs_: types.append(1) if undergroundCeilings_: types.append(1.5) if floors_: types.append(2) if undergroundSlabs_: types.append(2.25) if groundFloors_: types.append(2.5) if exposedFloors_: types.append(2.75) if ceilings_: types.append(3) if airWalls_: types.append(4) if windows_: types.append(5) if interiorWalls_: intTypes.append(0) if interiorWindows_: intTypes.append(5) if floors_: intTypes.append(2) if airWalls_: intTypes.append(4) if ceilings_: intTypes.append(3) # See if the wall properties are being specified based on orientation. angles = [] if len(walls_) == 0: pass elif len(walls_) == 1: if walls_[0] != False: types.append(0) else: types.append(0) initAngles = rs.frange(0, 360, 360 / len(walls_)) for an in initAngles: angles.append(an - (360 / (2 * len(walls_)))) angles.append(360) for HBO in HBObjectsFromHive: for HBS in HBO.surfaces: if HBS.BC.title() != "Surface": if HBS.type in types: if HBS.type == 0 and len(walls_) > 1: for angleCount in range(len(angles) - 1): if ( angles[angleCount] + (0.5 * sc.doc.ModelAngleToleranceDegrees) <= HBS.angle2North % 360 <= angles[angleCount + 1] + (0.5 * sc.doc.ModelAngleToleranceDegrees) ): targetAdiabatic = walls_[angleCount % len(walls_)] if targetAdiabatic == True: HBS.BC = "Adiabatic" HBS.sunExposure = "NoSun" HBS.windExposure = "NoWind" else: HBS.BC = "Adiabatic" HBS.sunExposure = "NoSun" HBS.windExposure = "NoWind" if HBS.hasChild and 5 in types: for childSrf in HBS.childSrfs: childSrf.BC = "Adiabatic" childSrf.sunExposure = "NoSun" childSrf.windExposure = "NoWind" else: if HBS.type in intTypes: HBS.BC = "Adiabatic" HBS.sunExposure = "NoSun" HBS.windExposure = "NoWind" if HBS.hasChild and 5 in intTypes: for childSrf in HBS.childSrfs: childSrf.BC = "Adiabatic" childSrf.sunExposure = "NoSun" childSrf.windExposure = "NoWind" HBZones = hb_hive.addToHoneybeeHive(HBObjectsFromHive, ghenv.Component.InstanceGuid.ToString() + str(uuid.uuid4())) return HBZones
import rhinoscriptsyntax as rs import math import random arrPoints = list() for t in rs.frange(-100,100,2): x0 = t*math.sin(t) y0 = t*math.cos(t) z0 = t arrPoint = [x0, y0, z0] # print(arrPoint) arrPoints.append(arrPoint) print(arrPoints) # rs.AddPoint(arrPoint) #Call rs.EnableRedraw(True) # rs.AddInterpCurve(arrPoints) def limit(n, minn, maxn): if n < minn: return minn elif n > maxn: return maxn else: return n class Mover(object): def __init__(self):
def main(windowHeight, sillHeight, glzRatio, skyLightRatio, breakUpWindow): # check if honeybee is flying # import the classes if sc.sticky.has_key('ladybug_release')and sc.sticky.has_key('honeybee_release'): # don't customize this part hb_EPZone = sc.sticky["honeybee_EPZone"] hb_EPSrf = sc.sticky["honeybee_EPSurface"] hb_EPFenSurface = sc.sticky["honeybee_EPFenSurface"] else: print "You should first let both Ladybug and Honeybee to fly..." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, "You should first let both Ladybug and Honeybee to fly...") return [], [] # call the objects from the lib hb_hive = sc.sticky["honeybee_Hive"]() HBZoneObjects = hb_hive.callFromHoneybeeHive(_HBObjects) joinedSrf = [] zonesWithOpeningsGeometry =[] ModifiedHBZones = [] # find the percentage of glazing for each direction based on the input list angles = [] if len(glzRatio)!=0: for ratio in glzRatio: if ratio > 0.95: giveWarning("Please ensure that your glazing ratio is between 0.0 and 0.95. glazing ratios outside of this are not accepted.") return None, None initAngles = rs.frange(0, 360, 360/len(glzRatio)) else: initAngles = [] if len(glzRatio) > 1: for an in initAngles: angles.append(an-(360/(2*len(glzRatio)))) angles.append(360) else: angles = initAngles #Check if the length of the glzRatio, windowHeight, and sillHeight lists are the same. listLenCheck = True if len(windowHeight) != len(glzRatio) and len(windowHeight) != 1 and len(windowHeight) != 0: print "The number of items in the windowHeight list does not match the number in the glzRatio list. Please ensure that either your lists match, you put in a single windowHeight value for all windows, or you leave the windowHeight blank and accept a default value." listLenCheck = False if len(sillHeight) != len(glzRatio) and len(sillHeight) != 1 and len(sillHeight) != 0: print "The number of items in the sillHeight list does not match the number in the glzRatio list. Please ensure that either your lists match, you put in a single sillHeight value for all windows, or you leave the sillHeight blank and accept a default value." listLenCheck = False if HBZoneObjects and HBZoneObjects[0] != None and listLenCheck == True: # collect the surfaces HBSurfaces = [] for HBObj in HBZoneObjects: if HBObj.objectType == "HBZone": for surface in HBObj.surfaces: HBSurfaces.append(surface) elif HBObj.objectType == "HBSurface": if not hasattr(HBObj, 'type'): # find the type based on HBObj.type = HBObj.getTypeByNormalAngle() if not hasattr(HBObj, 'angle2North'): # find the type based on HBObj.getAngle2North() if not hasattr(HBObj, "BC"): HBObj.BC = 'OUTDOORS' HBSurfaces.append(HBObj) # print zone for surface in HBSurfaces: # print surface if surface.hasChild: surface.removeAllChildSrfs() targetPercentage = 0 winHeight = None sill = None if surface.type == 0: srfType = 0 if len(glzRatio) == 1: targetPercentage = glzRatio[0] if len(windowHeight) == 1: winHeight = windowHeight[0] if len(sillHeight) == 1: sill = sillHeight[0] for angleCount in range(len(angles)-1): if angles[angleCount]+(0.5*sc.doc.ModelAngleToleranceDegrees) <= surface.angle2North%360 <= angles[angleCount +1]+(0.5*sc.doc.ModelAngleToleranceDegrees): #print surface.angle2North%360 targetPercentage = glzRatio[angleCount%len(glzRatio)] if len(windowHeight) == 1: winHeight = windowHeight[0] elif len(windowHeight) == len(glzRatio): winHeight = windowHeight[angleCount%len(windowHeight)] else: winHeight = None if len(sillHeight) == 1: sill = sillHeight[0] elif len(sillHeight) == len(glzRatio): sill = sillHeight[angleCount%len(sillHeight)] else: sill = None break elif surface.type == 1 and skyLightRatio: targetPercentage = skyLightRatio srfType = 1 if targetPercentage!=0 and surface.BC.upper() == 'OUTDOORS': face = surface.geometry # call surface geometry # This part of the code sends the parameters and surfaces to their respective methods of of galzing generation. It is developed by Chris Mackey. lastSuccessfulGlzSrf, lastSuccessfulRestOfSrf = findGlzBasedOnRatio(face, targetPercentage, winHeight, sill, srfType, breakUpWindow) # print lastSuccessfulGlzSrf if lastSuccessfulGlzSrf!= None: if isinstance(lastSuccessfulGlzSrf, list): for glzSrfCount, glzSrf in enumerate(lastSuccessfulGlzSrf): fenSrf = hb_EPFenSurface(glzSrf, surface.num, surface.name + '_glz_' + `glzSrfCount`, surface, 5, lastSuccessfulRestOfSrf) zonesWithOpeningsGeometry.append(glzSrf) surface.addChildSrf(fenSrf) if lastSuccessfulRestOfSrf==[]: surface.calculatePunchedSurface() else: fenSrf = hb_EPFenSurface(lastSuccessfulGlzSrf, surface.num, surface.name + '_glz_0', surface, 5, lastSuccessfulRestOfSrf) zonesWithOpeningsGeometry.append(lastSuccessfulGlzSrf) surface.addChildSrf(fenSrf) if lastSuccessfulRestOfSrf==[]: surface.calculatePunchedSurface() else: surface.hasChild = False #print HBZoneObjects #add zones to dictionary ModifiedHBZones = hb_hive.addToHoneybeeHive(HBZoneObjects, ghenv.Component.InstanceGuid.ToString() + str(uuid.uuid4())) return zonesWithOpeningsGeometry, ModifiedHBZones
def fib(n): #return fibonacci series up to n #return a list containing the fibonacci series up to n result = [] a,b = 0,1 while a<n: result.append(a) a,b = b,a+b return result result.append(n) r = fib(100) #call it z=0 for z in rs.frange(0,5,1): for t in rs.frange(0,360,1): rads = t*pi/2 #defines the rotation angle which is equal to time t multiplied by angular velocity #mathematical description of a 3,8 Torus knot x = (3+ 2*math.cos(rads))*math.cos(t) y = (3+2*math.cos(rads))*math.sin(t) n = rs.AddPoint([x, y, r[z]]) points.append(n) rs.AddInterpCurve(points) #rs.EnableRedraw(True)
#3,8 Torus knot import rhinoscriptsyntax as rs import math points = [] #declares the size of my point array pi = math.pi #rs.EnableRedraw(False) for t in rs.frange(0,360,1): rads = t*pi/2 #defines the rotation angle which is equal to time t multiplied by angular velocity #mathematical description of a 3,8 Torus knot x = (3+ 2*math.cos(rads))*math.cos(t) y = (3+2*math.cos(rads))*math.sin(t) z = 2*math.sin(rads) n = rs.AddPoint([x, y, z]) points.append(n) rs.AddInterpCurve(points) #rs.EnableRedraw(True)
def main(analysisResult, inputMesh, contourType, heightDomain, legendPar, analysisTitle, legendTitle, bakeIt, layerName, lb_preparation, lb_visualization): # Get the Unit System. conversionFac = lb_preparation.checkUnits() # Check the mesh's structure. if inputMesh.Faces.Count == len(analysisResult): meshStruct = 0 elif inputMesh.Vertices.Count == len(analysisResult): meshStruct = 1 else: warning = 'length of the results [=' + str( len(analysisResult )) + '] is not equal to the number of mesh faces [=' + str( inputMesh.Faces.Count) + '] or mesh vertices[=' + str( inputMesh.Vertices.Count) + '].' print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Warning, warning) return -1 singleValMesh = False # Read the legend and generate a list of blank colors. lowB, highB, numSeg, customColors, legendBasePoint, legendScale, legendFont, legendFontSize, legendBold, decimalPlaces, removeLessThan = lb_preparation.readLegendParameters( legendPar, False) blankColors = [] if meshStruct == 0: for count in inputMesh.Faces: blankColors.append(System.Drawing.Color.Gray) elif meshStruct == 1: for count in inputMesh.Vertices: blankColors.append(System.Drawing.Color.Gray) # Generate an underlay mesh to cover our ass when the intersection fails. underlayMesh = None if contourType == 0 or contourType == 1 or contourType == None: colors = lb_visualization.gradientColor(analysisResult, lowB, highB, customColors) underlayMesh = lb_visualization.colorMesh(colors, inputMesh, True, meshStruct) if heightDomain != None: underlayMesh = lb_visualization.create3DColoredMesh( underlayMesh, analysisResult, heightDomain, colors, meshStruct) moveTrans = rc.Geometry.Transform.Translation( 0, 0, -(1 / conversionFac) * .03) underlayMesh.Transform(moveTrans) # Check the mesh's planarity minPt = inputMesh.GetBoundingBox(rc.Geometry.Plane.WorldXY).Min meshIsPlanar, inputMesh, meshPlane, meshNormals = checkMeshPlanarity( inputMesh, minPt) if meshIsPlanar == False: warning = 'The connected inputMesh is not planar and this component only works for planar meshes.' + \ '\n Try breaking up your mesh into planar pieces and feeding them individually into this component.' print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Warning, warning) # Find the min and max of the dataset. sortedData = analysisResult[:] sortedData.sort() dataMin = sortedData[0] dataMax = sortedData[-1] fullRange = dataMax - dataMin if lowB != 'min' and highB != 'max': legendRange = highB - lowB elif lowB != 'min': legendRange = dataMax - lowB elif highB != 'max': legendRange = highB - dataMin else: legendRange = fullRange if fullRange == 0 or fullRange < (legendRange / numSeg): singleValMesh = True fullRange = 1 contIncr = legendRange / numSeg else: contIncr = legendRange / fullRange # Create a mesh with a height domain, which can then be contoured. if heightDomain != None: coloredChart = lb_visualization.create3DColoredMesh( inputMesh, analysisResult, heightDomain, blankColors, meshStruct, meshNormals) contInterval = contIncr * (heightDomain.Max - heightDomain.Min) / (numSeg - 1) else: heightD = rc.Geometry.Interval(0, (numSeg - 1) * (1 / conversionFac)) contInterval = contIncr * (1 / conversionFac) coloredChart = lb_visualization.create3DColoredMesh( inputMesh, analysisResult, heightD, blankColors, meshStruct) # Figure out some basic things about the Legend. lb_visualization.calculateBB([coloredChart], True) if not legendTitle: legendTitle = 'unknown units ' if not analysisTitle: analysisTitle = '\nno title' if legendFont == None: legendFont = 'Verdana' if legendFontSize == None: legendFontSize = legendScale * (lb_visualization.BoundingBoxPar[2] / 20) if contourType == 3: legendSrfs, legendText, legendTextCrv, textPt, textSize = lb_visualization.createLegend( analysisResult, lowB, highB, numSeg, legendTitle, lb_visualization.BoundingBoxPar, legendBasePoint, legendScale, legendFont, legendFontSize, legendBold, decimalPlaces, removeLessThan) elif contourType == 2: legendSrfs, legendText, legendTextCrv, textPt, textSize = lb_visualization.createLegend( analysisResult, lowB, highB, numSeg, legendTitle, lb_visualization.BoundingBoxPar, legendBasePoint, legendScale, legendFont, legendFontSize, legendBold, decimalPlaces, removeLessThan) legendSrfs, legendTextCrv, textPt = [], [], [] else: legendSrfs, legendText, legendTextCrv, textPt, textSize = lb_visualization.createLegend( analysisResult, lowB, highB, numSeg + 1, legendTitle, lb_visualization.BoundingBoxPar, legendBasePoint, legendScale, legendFont, legendFontSize, legendBold, decimalPlaces, removeLessThan, True) # generate legend colors. legendColors = lb_visualization.gradientColor(legendText[:-1], lowB, highB, customColors) # Generate intersection planes. intMeshes = [] if contourType == 0 or contourType == 1 or contourType == None: BB = coloredChart.GetBoundingBox(rc.Geometry.Plane.WorldXY) boundBox = BB.ToBrep() baseSplitPlaneOrigin = boundBox.Faces[4].GetBoundingBox( rc.Geometry.Plane.WorldXY).Min baseSplitPlane = boundBox.Faces[4].ToBrep() intMeshes = [rc.Geometry.Mesh.CreateFromBrep(baseSplitPlane)[0]] lastPt = lb_visualization.BoundingBoxPar[0] if lowB != 'min': if heightDomain != None: startVal = ((lowB - dataMin) / fullRange) * (heightDomain.Max - heightDomain.Min) else: startVal = ((lowB - dataMin) / fullRange) * (numSeg - 1) * (1 / conversionFac) lastPt = rc.Geometry.Point3d(lastPt.X, lastPt.Y, startVal) movedPlane = copy.deepcopy(baseSplitPlane) planeTransf = rc.Geometry.Transform.Translation( 0, 0, lastPt.Z - baseSplitPlaneOrigin.Z) movedPlane.Transform(planeTransf) movedPlaneMesh = rc.Geometry.Mesh.CreateFromBrep(movedPlane)[0] intMeshes = [movedPlaneMesh] intPlanes = [rc.Geometry.Plane(lastPt, rc.Geometry.Vector3d.ZAxis)] for count in range(int(numSeg)): lastPt = rc.Geometry.Point3d(lastPt.X, lastPt.Y, lastPt.Z + contInterval) intPlanes.append(rc.Geometry.Plane(lastPt, rc.Geometry.Vector3d.ZAxis)) if contourType == 0 or contourType == 1 or contourType == None: movedPlane = copy.deepcopy(baseSplitPlane) planeTransf = rc.Geometry.Transform.Translation( 0, 0, lastPt.Z - baseSplitPlaneOrigin.Z) movedPlane.Transform(planeTransf) movedPlaneMesh = rc.Geometry.Mesh.CreateFromBrep(movedPlane)[0] intMeshes.append(movedPlaneMesh) # Contour the mesh. contourMeshArea = rc.Geometry.AreaMassProperties.Compute(inputMesh).Area initMeshArea = contourMeshArea failedIntersects = [] contourMesh = [] contourLines = [] contourLabels = [] contourColors = [] labelText = [] labelTextPts = [] startTrigger = False failIntersecTrigger = False #Generate colored regions. if contourType == 0 or contourType == 1 or contourType == None: if singleValMesh == True: val = analysisResult[0] if lowB == 'min': lowB = val if legendRange == 0: legendRange = 1 colorIndex = int((val - lowB) / legendRange) coloredChart.VertexColors.CreateMonotoneMesh( legendColors[colorIndex]) contourMesh.append(coloredChart) else: try: finalSplitMesh = rc.Geometry.Mesh.Split( coloredChart, intMeshes[0])[-1] finalSplitMesh.VertexColors.CreateMonotoneMesh(legendColors[0]) contourArea = rc.Geometry.AreaMassProperties.Compute( finalSplitMesh).Area if contourArea < contourMeshArea - sc.doc.ModelAbsoluteTolerance and finalSplitMesh.IsValid: contourMesh.append(finalSplitMesh) startTrigger = True except: pass for count in range(len(intMeshes) - 1): try: if startTrigger == False: finalSplitMesh = rc.Geometry.Mesh.Split( coloredChart, intMeshes[count])[-1] finalSplitMesh.VertexColors.CreateMonotoneMesh( legendColors[count]) contourArea = rc.Geometry.AreaMassProperties.Compute( finalSplitMesh).Area if contourArea < contourMeshArea - sc.doc.ModelAbsoluteTolerance and finalSplitMesh.IsValid: contourMesh.append(finalSplitMesh) contourColors.append([legendColors[count]]) startTrigger = True initSplitMesh = rc.Geometry.Mesh.Split( coloredChart, intMeshes[count + 1])[-1] finalSplitMesh = rc.Geometry.Mesh.Split( initSplitMesh, intMeshes[count])[0] elif count == len(intMeshes) - 2: finalSplitMesh = rc.Geometry.Mesh.Split( coloredChart, intMeshes[count])[0] else: initSplitMesh = rc.Geometry.Mesh.Split( coloredChart, intMeshes[count])[-1] initMeshArea = rc.Geometry.AreaMassProperties.Compute( initSplitMesh).Area finalSplitMesh = rc.Geometry.Mesh.Split( initSplitMesh, intMeshes[count + 1])[0] try: lColor = legendColors[count + 1] finalSplitMesh.VertexColors.CreateMonotoneMesh(lColor) except: lColor = legendColors[count + 1] finalSplitMesh.VertexColors.CreateMonotoneMesh(lColor) contourArea = rc.Geometry.AreaMassProperties.Compute( finalSplitMesh).Area if contourArea < contourMeshArea - sc.doc.ModelAbsoluteTolerance and contourArea < initMeshArea - sc.doc.ModelAbsoluteTolerance and finalSplitMesh.IsValid: contourMesh.append(finalSplitMesh) contourColors.append([lColor]) except: try: finalSplitMesh = rc.Geometry.Mesh.Split( coloredChart, intMeshes[count])[0] finalSplitMesh.VertexColors.CreateMonotoneMesh( legendColors[count]) finalSplitMesh.Transform(moveTrans) contourArea = rc.Geometry.AreaMassProperties.Compute( finalSplitMesh).Area if contourArea < contourMeshArea - sc.doc.ModelAbsoluteTolerance: failedIntersects.append(finalSplitMesh) except: pass # Generate Labeled Contours try: if contourType == 0 or contourType == 2 or contourType == None: if lowB != 'min' and highB != 'max': numbers = rs.frange(lowB, highB, round((highB - lowB) / (numSeg - 1), 6)) elif lowB != 'min': numbers = rs.frange(lowB, dataMax, round((dataMax - lowB) / (numSeg - 1), 6)) elif highB != 'max': numbers = rs.frange(dataMin, highB, round((highB - dataMin) / (numSeg - 1), 6)) else: numbers = rs.frange( dataMin, dataMax, round((dataMax - dataMin) / (numSeg - 1), 6)) if decimalPlaces == None: decimalPlaces = 2 formatString = "%." + str(decimalPlaces) + "f" numbersStr = [(formatString % x) for x in numbers] if _labelSize_ == None: labelSize = textSize / 5 else: labelSize = _labelSize_ for count, plane in enumerate(intPlanes): contourLines.append([]) contourLabels.append([]) theLines = rc.Geometry.Mesh.CreateContourCurves( coloredChart, plane) for line in theLines: contourLines[count].append(line) try: pts = line.DivideByLength(labelSize, True) ptIndex = int(len(pts) / 2) ltextPt = line.PointAt(pts[ptIndex]) labelText.append(numbersStr[count]) labelTextPts.append(ltextPt) labelTextMesh = lb_visualization.text2srf( [numbersStr[count]], [ltextPt], legendFont, labelSize, legendBold)[0] contourLabels[count].append(labelTextMesh) except: pass except: legendSrfs = None if contourType == 3: for count, plane in enumerate(intPlanes): try: contourColors.append([legendColors[count]]) except: pass contourLines.append( rc.Geometry.Mesh.CreateContourCurves(coloredChart, plane)) # Project the mesh back to the XYPlane. if heightDomain == None: planeTrans = rc.Geometry.Transform.PlanarProjection( rc.Geometry.Plane.WorldXY) crvMove = rc.Geometry.Transform.Translation( 0, 0, sc.doc.ModelAbsoluteTolerance * 5) for geo in contourMesh: geo.Transform(planeTrans) for geo in failedIntersects: geo.Transform(planeTrans) for geo in intMeshes: geo.Transform(planeTrans) for crvList in contourLines: for geo in crvList: geo.Transform(planeTrans) geo.Transform(crvMove) for crvList in contourLabels: for geoList in crvList: for geo in geoList: geo.Transform(planeTrans) geo.Transform(crvMove) # color legend surfaces if contourType != 2: legendSrfs = lb_visualization.colorMesh(legendColors, legendSrfs) else: legendSrfs = None titlebasePt = lb_visualization.BoundingBoxPar[-2] titleTextCurve = lb_visualization.text2srf(["\n\n" + analysisTitle], [titlebasePt], legendFont, legendFontSize, legendBold) flattenedLegend = lb_preparation.flattenList(legendTextCrv + titleTextCurve) if legendBasePoint == None: legendBasePoint = lb_visualization.BoundingBoxPar[0] # Change the geomtry back to its original plane. transfBack = rc.Geometry.Transform.ChangeBasis(meshPlane, rc.Geometry.Plane.WorldXY) for geo in contourMesh: geo.Transform(transfBack) for geo in failedIntersects: geo.Transform(transfBack) for geo in intMeshes: geo.Transform(transfBack) for crvList in contourLines: for geo in crvList: geo.Transform(transfBack) for crvList in contourLabels: for geoList in crvList: for geo in geoList: geo.Transform(transfBack) for geo in flattenedLegend: geo.Transform(transfBack) legendBasePoint.Transform(transfBack) if legendSrfs != None: try: legendSrfs.Transform(transfBack) except: pass # Move any failed intersections below the main surface. moveTrans = rc.Geometry.Transform.Translation(0, 0, -(1 / conversionFac) * .03) for geo in failedIntersects: geo.Transform(moveTrans) # If the user has requested to bake the geomtry, then bake it. if bakeIt > 0: # Greate a joined mesh. joinedContMesh = rc.Geometry.Mesh() for colMesh in contourMesh: joinedContMesh.Append(colMesh) # Flatten the list of contour curves. flatContourLines = lb_preparation.flattenList(contourLines) # Format the text to be baked as text. formatString = "%." + str(decimalPlaces) + "f" for count, item in enumerate(legendText): try: legendText[count] = formatString % item except: pass if contourType == 2: legendText = [] legendText.append(analysisTitle) textPt.append(titlebasePt) legendText.extend(labelText) textPt.extend(labelTextPts) if heightDomain == None: for geo in textPt: geo.Transform(planeTrans) for geo in textPt: geo.Transform(transfBack) #Set up the study layer studyLayerName = 'CUSTOM_PRESENTATION' if layerName == None: layerName = 'Custom' # check the study type newLayerIndex, l = lb_visualization.setupLayers( 'Modified Version', 'LADYBUG', layerName, studyLayerName) if bakeIt == 1: lb_visualization.bakeObjects(newLayerIndex, joinedContMesh, legendSrfs, legendText, textPt, textSize, legendFont, flatContourLines, decimalPlaces, True) else: lb_visualization.bakeObjects(newLayerIndex, joinedContMesh, legendSrfs, legendText, textPt, textSize, legendFont, flatContourLines, decimalPlaces, False) return contourMesh, [ underlayMesh ] + failedIntersects, contourLines, contourColors, contourLabels, [ legendSrfs, flattenedLegend ], legendBasePoint, legendColors, intMeshes
def main(north, hourlyWindDirection, hourlyWindSpeed, annualHourlyData, analysisPeriod, conditionalStatement, numOfDirections, centerPoint, scale, legendPar, bakeIt, maxFrequency): # import the classes if sc.sticky.has_key('ladybug_release'): try: if not sc.sticky['ladybug_release'].isCompatible(ghenv.Component): return -1 if sc.sticky['ladybug_release'].isInputMissing(ghenv.Component): return -1 except: warning = "You need a newer version of Ladybug to use this compoent." + \ "Use updateLadybug component to update userObjects.\n" + \ "If you have already updated userObjects drag Ladybug_Ladybug component " + \ "into canvas and try again." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, warning) return -1 lb_preparation = sc.sticky["ladybug_Preparation"]() lb_runStudy_GH = sc.sticky["ladybug_RunAnalysis"]() lb_visualization = sc.sticky["ladybug_ResultVisualization"]() conversionFac = lb_preparation.checkUnits() def movePointList(textPt, movingVector): for ptCount, pt in enumerate(textPt): ptLocation = rc.Geometry.Point(pt) ptLocation.Translate(movingVector) # move it to the right place textPt[ptCount] = rc.Geometry.Point3d(ptLocation.Location) return textPt # copy the custom code here # check the input data try: if hourlyWindDirection[2] == 'Wind Direction' and hourlyWindSpeed[2] == 'Wind Speed': checkData = True indexList, listInfo = lb_preparation.separateList(hourlyWindDirection + hourlyWindSpeed, lb_preparation.strToBeFound) # check that both data are horly and for same time range if listInfo[0][4] != 'Hourly' or listInfo[1][4] != 'Hourly': checkData = False warning = "At list one of the input lists for windSpeed or windDirection is not hourly." print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Error, warning) return -1 elif listInfo[1][5]!=(1,1,1) or listInfo[1][6]!=(12,31,24): checkData = False warning = "hourlyWindSpeed data should be annual. Find annual wind data as an output of importEPW component." print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Error, warning) return -1 # wind direction data windDir = hourlyWindDirection[7:] windSpeed = hourlyWindSpeed[7:] else: checkData = False warning = "Please provide valid lists of hourly wind direction and hourly wind speed!" print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Warning, warning) return -1 except Exception,e: checkData = False warning = "Please provide valid lists of hourly wind direction and hourly wind speed!" # print `e` print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Warning, warning) return -1 if checkData: titleStatement = -1 annualHourlyData = hourlyWindSpeed + annualHourlyData if conditionalStatement and len(annualHourlyData)!=0 and annualHourlyData[0]!=None: print 'Checking conditional statements...' # send all data and statement to a function and return back # True, False Pattern and condition statement titleStatement, patternList = checkConditionalStatement(annualHourlyData, conditionalStatement) if titleStatement != -1 and True not in patternList: warning = 'No hour meets the conditional statement.' print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Warning, warning) return -1 if titleStatement == -1: patternList = [[True]] * 8760 titleStatement = False # check the scale try: if float(scale)!=0: try:scale = 10*float(scale)/conversionFac except: scale = 10/conversionFac else: scale = 10/conversionFac except: scale = 10/conversionFac cenPt = lb_preparation.getCenPt(centerPoint) if not numOfDirections or int(numOfDirections) < 4: numOfDirections = 16 elif int(numOfDirections)> 360: numOfDirections = 360 else: try: numOfDirections = int(numOfDirections) except: numOfDirections = 16 # define angles segAngle = 360/numOfDirections roseAngles = rs.frange(0,360,segAngle); if round(roseAngles[-1]) == 360: roseAngles.remove(roseAngles[-1]) movingVectors = []; sideVectors = [] northAngle, northVector = lb_preparation.angle2north(north) for i, angle in enumerate(roseAngles): northVector1 = rc.Geometry.Vector3d(northVector) northVector2 = rc.Geometry.Vector3d(northVector) northVector1.Rotate(-float(math.radians(angle)), rc.Geometry.Vector3d.ZAxis) movingVectors.append(northVector1) northVector2.Rotate(-float(math.radians(angle + (segAngle/2))), rc.Geometry.Vector3d.ZAxis) sideVectors.append(northVector2) HOYS, months, days = lb_preparation.getHOYsBasedOnPeriod(analysisPeriod, 1) selectedWindDir = [] for count in HOYS: selectedWindDir.append(windDir[count-1]) #selectedWindDir = lb_preparation.selectHourlyData(windDir, analysisPeriod)[7:] # read analysis period stMonth, stDay, stHour, endMonth, endDay, endHour = lb_preparation.readRunPeriod(analysisPeriod, False) # find the study hours based on wind direction data startHour = lb_preparation.date2Hour(stMonth, stDay, stHour) endingHour = lb_preparation.date2Hour(endMonth, endDay, endHour) if startHour <= endingHour: studyHours = range(startHour-1, endingHour) else: studyHours = range(startHour - 1, 8760) + range(0, endingHour) calmHour = [] # count hours with no wind separatedBasedOnAngle = [] [separatedBasedOnAngle.append([]) for i in range(len(roseAngles))] #print len(studyHours) #print len(selectedWindDir) for hour, windDirection in enumerate(selectedWindDir): h = studyHours[hour] if patternList[h]: # if the hour pass the conditional statement # check if windSpeed is 0 so collect it in center if windSpeed[h] == 0: calmHour.append(h) else: for angleCount in range(len(roseAngles)-1): # print roseAngles[angleCount], roseAngles[angleCount + 1] #print windDirection if windDirection == 360.0: windDirection = 0 if roseAngles[angleCount]-(segAngle/2)<= windDirection < roseAngles[angleCount + 1]-(segAngle/2): separatedBasedOnAngle[angleCount].append(h) break elif roseAngles[-1]<= windDirection: separatedBasedOnAngle[-1].append(h) break # calculate the frequency calmFreq = (100*len(calmHour)/len(studyHours)) comment1 = 'Calm for ' + '%.2f'%calmFreq + '% of the time = ' + `len(calmHour)` + ' hours.' print comment1 windFreq = [] for angle in separatedBasedOnAngle: windFreq.append(100*len(angle)/len(studyHours)) calmFreq = (100*len(calmHour)/len(studyHours))/numOfDirections # draw the basic geometry for windRose ## draw the first polygon for calm period of the year def freqPolyline(cenPt, freq, vectorList, scale, onlyPts = False): pts = [] for vector in vectorList: newPt = rc.Geometry.Point3d.Add(cenPt, freq * scale * vector) pts.append(newPt) pts.append(pts[0]) # close the polyline if onlyPts: return pts return rc.Geometry.Polyline(pts).ToNurbsCurve() freqCrvs = [] minFreq = calmFreq try: maxFreq = float(maxFrequency)%100 if maxFreq ==0: maxFreq == 100 # overwrite minimum so all the graphs will have similar curves # regardless of calm hours minFreq = 0 except: maxFreq = max(windFreq) + calmFreq step = (maxFreq-minFreq)/10 comment2 = 'Each closed polyline shows frequency of ' + "%.1f"%step + '%. = ' + `int(step * len(studyHours)/100)` + ' hours.' print comment2 for freq in rs.frange(minFreq, maxFreq + step, step): freqCrvs.append(freqPolyline(cenPt, freq, sideVectors, scale)) # initial compass for BB textSize = 10 compassCrvs, compassTextPts, compassText = lb_visualization. compassCircle(cenPt, northVector, 1.11 *(maxFreq) * scale, roseAngles, 1.5*textSize) # initiate legend parameters overwriteScale = False if legendPar == []: overwriteScale = True elif legendPar[-1] == None: overwriteScale = True lowB, highB, numSeg, customColors, legendBasePoint, legendScale, legendFont, legendFontSize, legendBold, decimalPlaces, removeLessThan = lb_preparation.readLegendParameters(legendPar, False) numberCrvs = lb_visualization.text2srf(compassText, compassTextPts, 'Times New Romans', textSize/1.5, legendBold) compassCrvs = compassCrvs + lb_preparation.flattenList(numberCrvs) lb_visualization.calculateBB(compassCrvs, True) if overwriteScale: legendScale = 0.9 legend = []; legendText = []; textPt = []; legendSrfs = None allWindRoseMesh = []; allWindCenMesh = []; cenPts = [] legendBasePoints = []; allWindRoseCrvs = []; allLegend = [] titleTextCurveFinal = [] # for each of the information in hourly data if len(annualHourlyData)!=0 and annualHourlyData[0]!=None: try: movingDist = 1.8 * lb_visualization.BoundingBoxPar[1] # moving distance for sky domes except: movingDist = 0 #separate data indexList, listInfo = lb_preparation.separateList(annualHourlyData, lb_preparation.strToBeFound) for i in range(len(listInfo)): customHeading = 'Wind-Rose\n' movingVector = rc.Geometry.Vector3d(i * movingDist, 0, 0) selList = []; modifiedsunPosInfo = [] [selList.append(float(x)) for x in annualHourlyData[indexList[i]+7:indexList[i+1]]] if listInfo[i][4]!='Hourly' or listInfo[i][5]!=(1,1,1) or listInfo[i][6]!=(12,31,24) or len(selList)!=8760: warning = 'At least one of the input data lists is not a valis ladybug hourly data! Please fix this issue and try again!\n List number = '+ `i+1` print warning ghenv.Component.AddRuntimeMessage(gh.GH_RuntimeMessageLevel.Warning, warning) return -1 else: values= []; allValues = [] [values.append([]) for v in range(len(separatedBasedOnAngle))] #find the values based on the hours separated before for segNum, eachSegment in enumerate(separatedBasedOnAngle): for h in eachSegment: values[segNum].append(selList[h]) allValues.append(selList[h]) calmValues = [] for h in calmHour: calmValues.append(selList[h]) allValues.append(selList[h]) # get the legend done legendSrfs, legendText, legendTextCrv, textPt, textSize = lb_visualization.createLegend(allValues , lowB, highB, numSeg, listInfo[i][3], lb_visualization.BoundingBoxPar, legendBasePoint, legendScale, legendFont, legendFontSize, legendBold, decimalPlaces, removeLessThan) # generate legend colors legendColors = lb_visualization.gradientColor(legendText[:-1], lowB, highB, customColors) # color legend surfaces legendSrfs = lb_visualization.colorMesh(legendColors, legendSrfs) customHeading = customHeading + listInfo[i][1] + \ '\n'+lb_preparation.hour2Date(lb_preparation.date2Hour(stMonth, stDay, stHour)) + ' - ' + \ lb_preparation.hour2Date(lb_preparation.date2Hour(endMonth, endDay, endHour)) + \ '\nHourly Data: ' + listInfo[i][2] + ' (' + listInfo[i][3] + ')\n' customHeading = customHeading + comment1 + '\n' + comment2 + '\n' if titleStatement: resultStr = "%.1f" % (len(allValues)) + ' hours of total ' + ("%.1f" % len(windDir)) + ' hours' + \ ' (' + ("%.2f" % (len(allValues)/len(windDir) * 100)) + '%).' if analysisPeriod != [(1, 1, 1), (12, 31, 24)] and analysisPeriod != []: additStr = "%.1f" % (len(allValues)) + ' hours of analysis period ' + ("%.1f" % len(HOYS)) + ' hours' + \ ' (' + ("%.2f" % (len(allValues)/len(HOYS) * 100)) + '%).' customHeading = customHeading + '\n' + titleStatement + '\n' + resultStr + '\n' + additStr else: customHeading = customHeading + '\n' + titleStatement + '\n' + resultStr titleTextCurve, titleStr, titlebasePt = lb_visualization.createTitle([listInfo[i]], lb_visualization.BoundingBoxPar, legendScale, customHeading, True, legendFont, legendFontSize, legendBold) # find the freq of the numbers in each segment numRanges = legendText[:-1] if len(numRanges) == 1: numRanges.insert(0, 0.0) # do it for the calm period # calculate the frequency for calm freqInCenter = [] [freqInCenter.append([]) for v in range(len(numRanges))] for v in calmValues: for rangeCount in range(len(numRanges)): if numRanges[rangeCount]<= v <= numRanges[rangeCount + 1]: freqInCenter[rangeCount].append(v) break elif numRanges[-1]<= v: freqInCenter[-1].append(v) break centerFrqPts = [] cumFreq = 0 freqList = [] avrValues = [] for freq in freqInCenter: if len(freq)!=0: freqList.append(len(freq)/len(calmValues)) avrValues.append(sum(freq)/len(freq)) cumFreq = cumFreq + ((len(freq)/len(calmValues)) * calmFreq) centerFrqPts.append(freqPolyline(cenPt, cumFreq , sideVectors, scale, True)) centerMesh = rc.Geometry.Mesh() cenMeshColors = [] for crvNum in range(len(centerFrqPts)): avr = avrValues[crvNum] color = lb_visualization.gradientColor([avr], numRanges[0], numRanges[-1], customColors) if crvNum==0: for ptCount in range(len(centerFrqPts[crvNum])-1): try: singleMesh = rc.Geometry.Mesh() pt1 = cenPt pt2 = centerFrqPts[crvNum][ptCount] pt3 = centerFrqPts[crvNum][ptCount + 1] singleMesh.Vertices.Add(pt1) singleMesh.Vertices.Add(pt2) singleMesh.Vertices.Add(pt3) singleMesh.Faces.AddFace(0, 1, 2) cenMeshColors.append(color[0]) centerMesh.Append(singleMesh) except Exception, e: print `e` else: for ptCount in range(len(centerFrqPts[crvNum])-1): try: singleMesh = rc.Geometry.Mesh() pt1 = centerFrqPts[crvNum-1][ptCount] pt2 = centerFrqPts[crvNum][ptCount] pt3 = centerFrqPts[crvNum-1][ptCount + 1] pt4 = centerFrqPts[crvNum][ptCount + 1] singleMesh.Vertices.Add(pt1) singleMesh.Vertices.Add(pt2) singleMesh.Vertices.Add(pt3) singleMesh.Vertices.Add(pt4) singleMesh.Faces.AddFace(0, 1, 3, 2) cenMeshColors.append(color[0]) centerMesh.Append(singleMesh) except Exception, e: print `e` centerMesh.Flip(True, True, True) segments = rc.Geometry.Mesh() segmentsColors = [] for direction, segmentValues in enumerate(values): freqInEachSeg = [] [freqInEachSeg.append([]) for v in range(len(numRanges))] for v in segmentValues: for rangeCount in range(len(numRanges)-1): if numRanges[rangeCount]<= v <= numRanges[rangeCount + 1]: freqInEachSeg[rangeCount].append(v) break elif numRanges[-1]<= v: freqInEachSeg[-1].append(v) break totalFr = 0 for rangeCount in range(len(numRanges)): if len(segmentValues)!=0: fr = (len(freqInEachSeg[rangeCount])/len(segmentValues)) if fr!=0: avr = [sum(freqInEachSeg[rangeCount])/len(freqInEachSeg[rangeCount])] color = lb_visualization.gradientColor(avr, numRanges[0], numRanges[-1], customColors) pt1 = rc.Geometry.Point3d.Add(cenPt, (calmFreq + (windFreq[direction] * totalFr)) * scale * sideVectors[direction-1]) pt2 = rc.Geometry.Point3d.Add(cenPt, (calmFreq + (windFreq[direction] * (totalFr + fr)))* scale * sideVectors[direction-1]) pt3 = rc.Geometry.Point3d.Add(cenPt, (calmFreq + (windFreq[direction] * totalFr)) * scale * sideVectors[direction]) pt4 = rc.Geometry.Point3d.Add(cenPt, (calmFreq + (windFreq[direction] * (totalFr + fr)))* scale * sideVectors[direction]) segment = rc.Geometry.Mesh() segment.Vertices.Add(pt1) segment.Vertices.Add(pt2) segment.Vertices.Add(pt3) segment.Vertices.Add(pt4) segment.Faces.AddFace(0, 1, 3, 2) segmentsColors.append(color[0]) segments.Append(segment) totalFr = totalFr + fr segments.Flip(True, True, True) segments = lb_visualization.colorMesh(segmentsColors, segments) centerMesh = lb_visualization.colorMesh(cenMeshColors, centerMesh) legendText.append(titleStr) textPt.append(titlebasePt) compassCrvs, compassTextPts, compassText = lb_visualization. compassCircle(cenPt, northVector, 1.11 *maxFreq * scale, roseAngles, 1.5*textSize) numberCrvs = lb_visualization.text2srf(compassText, compassTextPts, 'Times New Romans', textSize/1.5, legendBold) compassCrvs = compassCrvs + lb_preparation.flattenList(numberCrvs) # let's move it move it move it! if legendScale > 1: movingVector = legendScale * movingVector crvsTemp = [] try: moveTransform = rc.Geometry.Transform.Translation(movingVector) for pt in compassTextPts: pt.Transform(moveTransform) segments.Translate(movingVector); allWindRoseMesh.append(segments) if centerMesh!=-1: centerMesh.Translate(movingVector); allWindCenMesh.append(centerMesh) textPt = movePointList(textPt, movingVector) newCenPt = movePointList([cenPt], movingVector)[0]; cenPts.append(newCenPt) if legendBasePoint == None: nlegendBasePoint = lb_visualization.BoundingBoxPar[0] movedLegendBasePoint = movePointList([nlegendBasePoint], movingVector)[0]; else: movedLegendBasePoint = movePointList([legendBasePoint], movingVector)[0]; legendBasePoints.append(movedLegendBasePoint) for crv in legendTextCrv: for c in crv: c.Translate(movingVector) for crv in titleTextCurve: for c in crv: c.Translate(movingVector) for c in freqCrvs + compassCrvs: cDuplicate = c.Duplicate() cDuplicate.Translate(movingVector) crvsTemp.append(cDuplicate) allWindRoseCrvs.append(crvsTemp) legendSrfs.Translate(movingVector) allLegend.append(lb_visualization.openLegend([legendSrfs, [lb_preparation.flattenList(legendTextCrv)]])) titleTextCurveFinal.append(titleTextCurve[0]) except Exception, e: print `e` if bakeIt > 0: #Join everything into one mesh. finalJoinedMesh = rc.Geometry.Mesh() try: finalJoinedMesh.Append(segments) except: pass try: finalJoinedMesh.Append(centerMesh) except: pass #Put all of the curves into one list. finalCrvs = [] for crv in crvsTemp: try: testPt = crv.PointAtEnd finalCrvs.append(crv) except: pass #Put all of the text together. legendText.extend(compassText) textPt.extend(compassTextPts) #Make labels for the layer. studyLayerName = 'WINDROSE' try: layerName = listInfo[i][1] dataType = 'Hourly Data:' + listInfo[i][2] except: layerName = 'Latitude=' +`latitude` dataType = 'No Hourly Data' # check the study type newLayerIndex, l = lb_visualization.setupLayers(dataType, 'LADYBUG', layerName, studyLayerName) if bakeIt == 1: lb_visualization.bakeObjects(newLayerIndex, finalJoinedMesh, legendSrfs, legendText, textPt, textSize, legendFont, finalCrvs, decimalPlaces, True) else: lb_visualization.bakeObjects(newLayerIndex, finalJoinedMesh, legendSrfs, legendText, textPt, textSize, legendFont, finalCrvs, decimalPlaces, False)
def analyzeGlz(glzSrf, distBetween, numOfShds, horOrVertical, lb_visualization, normalVector): # find the bounding box bbox = glzSrf.GetBoundingBox(True) if horOrVertical == None: horOrVertical = True if numOfShds == None and distBetween == None: numOfShds = 1 if numOfShds == 0 or distBetween == 0: sortedPlanes = [] elif horOrVertical == True: # Horizontal #Define a bounding box for use in calculating the number of shades to generate minZPt = bbox.Corner(False, True, True) minZPt = rc.Geometry.Point3d(minZPt.X, minZPt.Y, minZPt.Z) maxZPt = bbox.Corner(False, True, False) maxZPt = rc.Geometry.Point3d(maxZPt.X, maxZPt.Y, maxZPt.Z - sc.doc.ModelAbsoluteTolerance) centerPt = bbox.Center #glazing hieghts glzHeight = minZPt.DistanceTo(maxZPt) # find number of shadings try: numOfShd = int(numOfShds) shadingHeight = glzHeight / numOfShd shadingRemainder = shadingHeight except: shadingHeight = distBetween shadingRemainder = (((glzHeight / distBetween) - math.floor(glzHeight / distBetween)) * distBetween) if shadingRemainder == 0: shadingRemainder = shadingHeight # find shading base planes planeOrigins = [] planes = [] X, Y, z = minZPt.X, minZPt.Y, minZPt.Z zHeights = rs.frange(minZPt.Z + shadingRemainder, maxZPt.Z + 0.5 * sc.doc.ModelAbsoluteTolerance, shadingHeight) try: for Z in zHeights: planes.append( rc.Geometry.Plane(rc.Geometry.Point3d(X, Y, Z), rc.Geometry.Vector3d.ZAxis)) except: # single shading planes.append( rc.Geometry.Plane(rc.Geometry.Point3d(maxZPt), rc.Geometry.Vector3d.ZAxis)) # sort the planes sortedPlanes = sorted(planes, key=lambda a: a.Origin.Z) elif horOrVertical == False: # Vertical # Define a vector to be used to generate the planes planeVec = rc.Geometry.Vector3d(normalVector.X, normalVector.Y, 0) planeVec.Rotate(1.570796, rc.Geometry.Vector3d.ZAxis) #Define a bounding box for use in calculating the number of shades to generate minXYPt = bbox.Corner(True, True, True) minXYPt = rc.Geometry.Point3d(minXYPt.X, minXYPt.Y, minXYPt.Z) maxXYPt = bbox.Corner(False, False, True) maxXYPt = rc.Geometry.Point3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z) centerPt = bbox.Center #Test to be sure that the values are parallel to the correct vector. testVec = rc.Geometry.Vector3d.Subtract( rc.Geometry.Vector3d(minXYPt.X, minXYPt.Y, minXYPt.Z), rc.Geometry.Vector3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z)) if testVec.IsParallelTo(planeVec) == 0: minXYPt = bbox.Corner(False, True, True) minXYPt = rc.Geometry.Point3d(minXYPt.X, minXYPt.Y, minXYPt.Z) maxXYPt = bbox.Corner(True, False, True) maxXYPt = rc.Geometry.Point3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z) #Adjust the points to ensure the creation of the correct number of shades starting from the northernmost side of the window. tolVec = rc.Geometry.Vector3d.Subtract( rc.Geometry.Vector3d(minXYPt.X, minXYPt.Y, minXYPt.Z), rc.Geometry.Vector3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z)) tolVec.Unitize() tolVec = rc.Geometry.Vector3d.Multiply( sc.doc.ModelAbsoluteTolerance * 2, tolVec) if tolVec.X > 0 and tolVec.Y > 0: tolVec = rc.Geometry.Vector3d.Multiply(1, tolVec) norOrient = False if tolVec.X < 0 and tolVec.Y > 0: tolVec = rc.Geometry.Vector3d.Multiply(1, tolVec) norOrient = False if tolVec.X < 0 and tolVec.Y < 0: tolVec = rc.Geometry.Vector3d.Multiply(-1, tolVec) norOrient = True else: tolVec = rc.Geometry.Vector3d.Multiply(-1, tolVec) norOrient = True maxXYPt = rc.Geometry.Point3d.Subtract(maxXYPt, tolVec) minXYPt = rc.Geometry.Point3d.Subtract(minXYPt, tolVec) #glazing distance glzHeight = minXYPt.DistanceTo(maxXYPt) # find number of shadings try: numOfShd = int(numOfShds) shadingHeight = glzHeight / numOfShd shadingRemainder = shadingHeight except: shadingHeight = distBetween shadingRemainder = (((glzHeight / distBetween) - math.floor(glzHeight / distBetween)) * distBetween) if shadingRemainder == 0: shadingRemainder = shadingHeight # find shading base planes planeOrigins = [] planes = [] pointCurve = rc.Geometry.Curve.CreateControlPointCurve( [maxXYPt, minXYPt]) divisionParams = pointCurve.DivideByLength(shadingHeight, True) divisionPoints = [] for param in divisionParams: divisionPoints.append(pointCurve.PointAt(param)) planePoints = divisionPoints try: for point in planePoints: planes.append(rc.Geometry.Plane(point, planeVec)) except: # single shading planes.append( rc.Geometry.Plane(rc.Geometry.Point3d(minXYPt), planeVec)) sortedPlanes = planes return sortedPlanes
def main(HBZones): if not sc.sticky.has_key('honeybee_release'): print "You should first let Honeybee to fly..." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, "You should first Honeybee to fly...") return try: if not sc.sticky['honeybee_release'].isCompatible(ghenv.Component): return -1 except: warning = "You need a newer version of Honeybee to use this compoent." + \ "Use updateHoneybee component to update userObjects.\n" + \ "If you have already updated userObjects drag Honeybee_Honeybee component " + \ "into canvas and try again." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, warning) return hb_hive = sc.sticky["honeybee_Hive"]() # Call Honeybee zones from the lib HBZones = hb_hive.callFromHoneybeeHive(HBZones) # create an empty dictionary # the structure should be as {type : {construction: { orientation : {area of opaque : area , area of glass : area}}} srfData = {} # produce division angles - keep it to 8 directions for now divisionAngles = rs.frange(0- (360/8), 360 -(360/8), 360/8) # iterate through faces and add them to the dictionary for HBZone in HBZones: for srfCount, HBSrf in enumerate(HBZone.surfaces): # let's add it to the dictionary # I need to know what is the type of the surface (wall, roof, ?) # HBSrf.type will return the type. I'm not sure how much detailed you want the type to be # what is the approach for surfcaes with adjacencies? Here are simple types # srf.type == 0 #wall, # srf.type == 1 #roof, # int(srf.type) == 2 #floor # print "type: ", HBSrf.type srfType = int(HBSrf.type) # I add the key to the dictionary if it is not there yet if not srfData.has_key(srfType): srfData[srfType] = {} # let's find the construction next as your workflow is based on different construction types # you can get it form a Honeybee surface using HBSrf.EPConstruction # print "EP construction: ", HBSrf.EPConstruction constr = HBSrf.EPConstruction if not srfData[srfType].has_key(constr): # create a place holder for this construction and put the initial area as 0 srfData[srfType][constr] = {} # now let's find the direction of the surface # in case of roof or floor orientation doesn't really matter (or does it?) # so I just add it to dictionary and consider orientation as 0 if srfType!=0: direction = 0 else: # otherwise we need to find the direction of the surface # you can use HBSrf.angle2North to get it # print "angle: ", HBSrf.angle2North # check and see where it stands, 0 will be north, 1 is NE, etc. for direction in range(len(divisionAngles)-1): if divisionAngles[direction]+(0.5*sc.doc.ModelAngleToleranceDegrees) <= HBSrf.angle2North%360 <= divisionAngles[direction +1]+(0.5*sc.doc.ModelAngleToleranceDegrees): # here we found the direction break # Now that we know direction let's make an empty dictionary for that if not srfData[srfType][constr].has_key(direction): srfData[srfType][constr][direction] = {} srfData[srfType][constr][direction]["area"] = 0 # in case surface has glazing then create a place holder with # type 5 reperesnts glazing if HBSrf.hasChild: if not srfData.has_key(5): srfData[5] = {} # this is tricky here as I assume that all the glazing in the same wall # has same construction and I pick the first one - we can change this later if needed glzConstr = HBSrf.childSrfs[0].EPConstruction if not srfData[5].has_key(glzConstr): srfData[5][glzConstr] = {} if not srfData[5][glzConstr].has_key(direction): srfData[5][glzConstr][direction] = {} srfData[5][glzConstr][direction]["area"] = 0 # add the area to the current area # Honeybee has methods that return area for opaque and glazed area #print "Opaque area: ", HBSrf.getOpaqueArea() #print "Glazing area: ", HBSrf.getGlazingArea() srfData[srfType][constr][direction]["area"] += HBSrf.getOpaqueArea() if HBSrf.hasChild: srfData[5][HBSrf.childSrfs[0].EPConstruction][direction]["area"] += HBSrf.getGlazingArea() # return surface data return srfData
def main(genCumSkyResult, context, numOfArrows, surfaceTiltAngle, centerPoint, scale, arrowHeadScale, legendPar, showTotalOnly, bakeIt): # import the classes if sc.sticky.has_key('ladybug_release'): lb_preparation = sc.sticky["ladybug_Preparation"]() lb_mesh = sc.sticky["ladybug_Mesh"]() lb_runStudy_GH = sc.sticky["ladybug_RunAnalysis"]() lb_visualization = sc.sticky["ladybug_ResultVisualization"]() conversionFac = lb_preparation.checkUnits() # copy the custom code here # check the input data try: if genCumSkyResult[2][:11] == 'Sky Patches': checkData = True else: checkData = False except: checkData = False if checkData: # separate the data indexList, listInfo = lb_preparation.separateList(genCumSkyResult, lb_preparation.strToBeFound) if indexList[-1] == 456: patchesNormalVectors = lb_preparation.TregenzaPatchesNormalVectors elif indexList[-1] == 1752: patchesNormalVectors = lb_preparation.getReinhartPatchesNormalVectors() # check num of arrows if not numOfArrows or int(numOfArrows) < 4: numOfArrows = 36 else: try: numOfArrows = int(numOfArrows) except: numOfArrows = 36 # define angles northVector = (0,1,0) roseAngles = rs.frange(0,360,(360/numOfArrows)); if round(roseAngles[-1]) == 360: roseAngles.remove(roseAngles[-1]) # check the scale try: if float(scale)!=0: try:scale = 0.5 * float(scale)/conversionFac except: scale = 0.5/conversionFac else: scale = 0.5/conversionFac except: scale = 0.5/conversionFac # check vertical surface angle if surfaceTiltAngle == None: surfaceTiltAngle = 90 else: try: surfaceTiltAngle = float(surfaceTiltAngle) except: surfaceTiltAngle = 90 #separate total, diffuse and direct radiations separatedLists = [] for i in range(len(indexList)-1): selList = [] [selList.append(float(x)) for x in genCumSkyResult[indexList[i] + 7:indexList[i+1]]] separatedLists.append(selList) ###################### # start visualization# ###################### # generate the legend legendTitles = [listInfo[0][3], listInfo[1][3], listInfo[2][3]] customHeading = ['Total Radiation('+ listInfo[0][3]+')', 'Diffuse Radiation(' + listInfo[1][3] + ')', 'Direct Radiation(' + listInfo[2][3] + ')'] def visualizeData(i, results, arrows, legendTitle, legendPar, bakeIt, cenPt): movingVector = rc.Geometry.Vector3d(i * movingDist, 0, 0) overwriteScale = False if legendPar == []: overwriteScale = True elif legendPar[-1] == None: overwriteScale = True lowB, highB, numSeg, customColors, legendBasePoint, legendScale = lb_preparation.readLegendParameters(legendPar, False) if overwriteScale: legendScale = 0.9 legendSrfs, legendText, legendTextCrv, textPt, textSize = lb_visualization.createLegend(results , lowB, highB, numSeg, legendTitle, lb_visualization.BoundingBoxPar, legendBasePoint, legendScale) titleTextCurve, titleStr, titlebasePt = lb_visualization.createTitle([listInfo[i]], lb_visualization.BoundingBoxPar, legendScale, customHeading[i]) northVector = rc.Geometry.Vector3d.YAxis # print legendMax[i] compassCrvs, compassTextPts, compassText = lb_visualization. compassCircle(cenPt, northVector, 0.3 * scale * legendMax[i], roseAngles, 1.2*textSize, True) numberCrvs = lb_visualization.text2crv(compassText, compassTextPts, 'Times New Romans', textSize/1.7) compassCrvs = compassCrvs + lb_preparation.flattenList(numberCrvs) for crv in legendTextCrv + [compassCrvs]: for c in crv: c.Translate(movingVector) # move it to the right place for crv in titleTextCurve: for c in crv: c.Translate(movingVector) # move it to the right place textPt.append(titlebasePt) ptCount = 0 for pt in textPt: ptLocation = rc.Geometry.Point(pt) ptLocation.Translate(movingVector) # move it to the right place textPt[ptCount] = rc.Geometry.Point3d(ptLocation.Location) ptCount += 1 # generate legend colors legendColors = lb_visualization.gradientColor(legendText[:-1], lowB, highB, customColors) # color legend surfaces legendSrfs = lb_visualization.colorMesh(legendColors, legendSrfs) legendSrfs.Translate(movingVector) # move it to the right place # generate dome patches colors totalRadiationColors = lb_visualization.gradientColor(results, lowB, highB, customColors) arrowsJoined = rc.Geometry.Mesh(); # mesh the patches meshParam = rc.Geometry.MeshingParameters.Smooth cenPtMoved = rc.Geometry.Point3d.Add(cenPt, movingVector) colForMesh = []; arrowsEndPts = [] for arrow in arrows: newMesh = arrow.DuplicateMesh() if newMesh: newMesh.Translate(movingVector) # move it to the right place arrowsJoined.Append(newMesh) # append to the main mesh endPt = newMesh.Vertices[2] # if endPt.X < cenPtMoved.X: endPt = rc.Geometry.Point3d.Add(endPt, -1.1*textSize* rc.Geometry.Vector3d.XAxis) arrowsEndPts.append(endPt) newMesh.Dispose() # delete the polysurface # color the meshed patches domeMeshed = lb_visualization.colorMesh(totalRadiationColors, arrowsJoined, False) placeName = listInfo[i][1] skyTypes = ['Total_Radiation' + placeName[:3], 'Diffuse_Radiation' + placeName[:3], 'Direct_Radiation' + placeName[:3]] if legendBasePoint == None: nlegendBasePoint = lb_visualization.BoundingBoxPar[0] movedLegendBasePoint = rc.Geometry.Point3d.Add(nlegendBasePoint, movingVector); else: movedLegendBasePoint = rc.Geometry.Point3d.Add(legendBasePoint, movingVector); if bakeIt: legendText.append(titleStr) studyLayerName = 'RadiationRose' # check the study type newLayerIndex, l = lb_visualization.setupLayers(skyTypes[i], 'LADYBUG', placeName, studyLayerName, False, False, 0, 0) lb_visualization.bakeObjects(newLayerIndex, domeMeshed, legendSrfs, legendText, textPt, textSize, 'Verdana', compassCrvs) return domeMeshed, [legendSrfs, lb_preparation.flattenList(legendTextCrv + titleTextCurve)], compassCrvs, arrowsEndPts, movedLegendBasePoint if not showTotalOnly: skyTypes = 3 else: skyTypes = 1 zVector = (0,0,1) # calculate the vectors # this is a copy-paste from the old version NVecTilted = rs.VectorRotate(zVector, -float(surfaceTiltAngle), (1,0,0)) movingVectors = []; tiltedRoseVectors = [] for angle in roseAngles: movingVectors.append(rs.VectorRotate(northVector, float(angle), (0,0,1))) tiltedRoseVectors.append(rs.VectorRotate(NVecTilted, float(angle), (0,0,1))) ## mesh the context geometires if len(context)!=0: ## clean the geometry and bring them to rhinoCommon separated as mesh and Brep contextMesh, contextBrep = lb_preparation.cleanAndCoerceList(context) ## mesh Brep contextMeshedBrep = lb_mesh.parallel_makeContextMesh(contextBrep) ## Flatten the list of surfaces contextMeshedBrep = lb_preparation.flattenList(contextMeshedBrep) contextSrfs = contextMesh + contextMeshedBrep # join the mesh if contextSrfs: contextSrfs = lb_mesh.joinMesh(contextSrfs) else: contextSrfs = [] radResult = [] for i in range(skyTypes): if centerPoint == None: cenPt = rc.Geometry.Point3d.Origin else: cenPt = centerPoint radResult.append(lb_runStudy_GH.calRadRoseRes(tiltedRoseVectors, patchesNormalVectors, separatedLists[i], cenPt, contextSrfs)) normLegend = False; res = [[], [], [], [], [], []]; if not showTotalOnly: legendMax = [max(radResult[0]), max(radResult[1] + radResult[2]), max(radResult[1] + radResult[2])] legendMin = [0,0,0] else: legendMax = [max(radResult[0])] legendMin = [0] for i in range(skyTypes): # fix the bake try: if legendPar[1] is None or normLegend: legendPar[1] = legendMax[i] legendPar[0] = legendMin[i] normLegend = True except: # make an initial legend parameter to replace the max legendPar = [None,None,None,[],None, None] legendPar[1] = legendMax[i] legendPar[0] = legendMin[i] normLegend = True internalScale = 0.3 # generate arrows cenPt = lb_preparation.getCenPt(centerPoint) arrows = lb_preparation.genRadRoseArrows(movingVectors, radResult[i], cenPt, float(scale), internalScale, arrowHeadScale) tempCircle = rc.Geometry.Circle(cenPt, 1.2 * internalScale * float(scale)*max(radResult[i])).ToNurbsCurve() # calculate the bounding box for the skyDome if i == 0: try: lb_visualization.calculateBB([tempCircle]) #arrows) movingDist = 1.5 * lb_visualization.BoundingBoxPar[1] # moving distance for radiation rose except: print "Input Radiation values are all 0" w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, "Input Radiation values are all 0") return -1 arrowsColored, leg, compassCrvs, arrowsEndPts, legendBsePt= visualizeData(i, radResult[i], arrows, legendTitles[i], legendPar, bakeIt, cenPt) res[0].append(arrowsColored) res[1].append(leg) res[2].append(compassCrvs) res[3].append(legendBsePt) res[4].append(arrowsEndPts) strResult = [] [strResult.append("%.2f"%num) for num in radResult[i]] res[5].append(strResult) # remove the sky polysurfaces for arrow in arrows: arrow.Dispose() return res else: print "Please provide valid selctedSkyMtx!" w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, "Please provide valid selctedSkyMtx!") return -1 else: print "You should first let the Ladybug fly..." w = gh.GH_RuntimeMessageLevel.Warning ghenv.Component.AddRuntimeMessage(w, "You should first let the Ladybug fly...") return -1
def analyzeGlz(glzSrf, distBetween, numOfShds, horOrVertical, lb_visualization, normalVector): # find the bounding box bbox = glzSrf.GetBoundingBox(True) if horOrVertical == None: horOrVertical = True if numOfShds == None and distBetween == None: numOfShds = 1 if numOfShds == 0 or distBetween == 0: sortedPlanes = [] elif horOrVertical == True: # Horizontal #Define a bounding box for use in calculating the number of shades to generate minZPt = bbox.Corner(False, True, True) minZPt = rc.Geometry.Point3d(minZPt.X, minZPt.Y, minZPt.Z) maxZPt = bbox.Corner(False, True, False) maxZPt = rc.Geometry.Point3d(maxZPt.X, maxZPt.Y, maxZPt.Z - sc.doc.ModelAbsoluteTolerance) centerPt = bbox.Center #glazing hieghts glzHeight = minZPt.DistanceTo(maxZPt) # find number of shadings try: numOfShd = int(numOfShds) shadingHeight = glzHeight/numOfShd shadingRemainder = shadingHeight except: shadingHeight = distBetween shadingRemainder = (((glzHeight/distBetween) - math.floor(glzHeight/distBetween))*distBetween) if shadingRemainder == 0: shadingRemainder = shadingHeight # find shading base planes planeOrigins = [] planes = [] X, Y, z = minZPt.X, minZPt.Y, minZPt.Z zHeights = rs.frange(minZPt.Z + shadingRemainder, maxZPt.Z + 0.5*sc.doc.ModelAbsoluteTolerance, shadingHeight) try: for Z in zHeights: planes.append(rc.Geometry.Plane(rc.Geometry.Point3d(X, Y, Z), rc.Geometry.Vector3d.ZAxis)) except: # single shading planes.append(rc.Geometry.Plane(rc.Geometry.Point3d(maxZPt), rc.Geometry.Vector3d.ZAxis)) # sort the planes sortedPlanes = sorted(planes, key=lambda a: a.Origin.Z) elif horOrVertical == False: # Vertical # Define a vector to be used to generate the planes planeVec = rc.Geometry.Vector3d(normalVector.X, normalVector.Y, 0) planeVec.Rotate(1.570796, rc.Geometry.Vector3d.ZAxis) #Define a bounding box for use in calculating the number of shades to generate minXYPt = bbox.Corner(True, True, True) minXYPt = rc.Geometry.Point3d(minXYPt.X, minXYPt.Y, minXYPt.Z) maxXYPt = bbox.Corner(False, False, True) maxXYPt = rc.Geometry.Point3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z) centerPt = bbox.Center #Test to be sure that the values are parallel to the correct vector. testVec = rc.Geometry.Vector3d.Subtract(rc.Geometry.Vector3d(minXYPt.X, minXYPt.Y, minXYPt.Z), rc.Geometry.Vector3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z)) if testVec.IsParallelTo(planeVec) == 0: minXYPt = bbox.Corner(False, True, True) minXYPt = rc.Geometry.Point3d(minXYPt.X, minXYPt.Y, minXYPt.Z) maxXYPt = bbox.Corner(True, False, True) maxXYPt = rc.Geometry.Point3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z) #Adjust the points to ensure the creation of the correct number of shades starting from the northernmost side of the window. tolVec = rc.Geometry.Vector3d.Subtract(rc.Geometry.Vector3d(minXYPt.X, minXYPt.Y, minXYPt.Z), rc.Geometry.Vector3d(maxXYPt.X, maxXYPt.Y, maxXYPt.Z)) tolVec.Unitize() tolVec = rc.Geometry.Vector3d.Multiply(sc.doc.ModelAbsoluteTolerance*2, tolVec) if tolVec.X > 0 and tolVec.Y > 0: tolVec = rc.Geometry.Vector3d.Multiply(1, tolVec) norOrient = False if tolVec.X < 0 and tolVec.Y > 0: tolVec = rc.Geometry.Vector3d.Multiply(1, tolVec) norOrient = False if tolVec.X < 0 and tolVec.Y < 0: tolVec = rc.Geometry.Vector3d.Multiply(-1, tolVec) norOrient = True else: tolVec = rc.Geometry.Vector3d.Multiply(-1, tolVec) norOrient = True maxXYPt = rc.Geometry.Point3d.Subtract(maxXYPt, tolVec) minXYPt = rc.Geometry.Point3d.Subtract(minXYPt, tolVec) #glazing distance glzHeight = minXYPt.DistanceTo(maxXYPt) # find number of shadings try: numOfShd = int(numOfShds) shadingHeight = glzHeight/numOfShd shadingRemainder = shadingHeight except: shadingHeight = distBetween shadingRemainder = (((glzHeight/distBetween) - math.floor(glzHeight/distBetween))*distBetween) if shadingRemainder == 0: shadingRemainder = shadingHeight # find shading base planes planeOrigins = [] planes = [] pointCurve = rc.Geometry.Curve.CreateControlPointCurve([maxXYPt, minXYPt]) divisionParams = pointCurve.DivideByLength(shadingHeight, True) divisionPoints = [] for param in divisionParams: divisionPoints.append(pointCurve.PointAt(param)) planePoints = divisionPoints try: for point in planePoints: planes.append(rc.Geometry.Plane(point, planeVec)) except: # single shading planes.append(rc.Geometry.Plane(rc.Geometry.Point3d(minXYPt), planeVec)) sortedPlanes = planes return sortedPlanes
import rhinoscriptsyntax as rs import math rs.EnableRedraw(False) #Sin curve numPoints = 30 freq = 6 scale = 4 pi = math.pi radius = 5 points = [] for i in rs.frange(0,numPoints,.2): rads = (i/numPoints)*((2*pi)*freq) x = i*scale y = radius*math.sin(rads) z = 0 n = rs.AddPoint([x,y,z]) points.append(n) rs.AddInterpCurve(points) rs.EnableRedraw(True)
#Python Workshop Lesson:08 #http://www.designalyze.com/int2pythonscripting08_controlflow02 #If Else with Math #If Else with Boolean Flag import rhinoscriptsyntax as rs import math rs.EnableRedraw(False) #boolean flag flip = True color01 = [255,0,255] color02 = [0,255, 255] for i in rs.frange(0.0, 10.0, 0.1): ptsForCurve = [] for j in rs.frange(0.0, 10.0, 0.1): x = j y = i z = math.sin(i)*math.sin(j) pt = [x,y,z] ptsForCurve.append(pt) curve = rs.AddCurve(ptsForCurve) if flip == True: rs.ObjectColor(curve, color01) flip = False else: rs.ObjectColor(curve, color02) flip = True
idSurface = rs.GetObject("srf to frame? ", 8, True, True) intCount = rs.GetReal("# of itera. per direction") #domains are rough dims of the surface - can check via _what uDomain = rs.SurfaceDomain(idSurface, 0) vDomain = rs.SurfaceDomain(idSurface, 1) # get size int from domain & / by intended count = increment between surfaces uStep = (uDomain[1] - uDomain[0]) / intCount vStep = (vDomain[1] - vDomain[0]) / intCount #print uStep #print vStep rs.EnableRedraw(False) # loop through size of surface by step increment in both u & v directions for u in rs.frange(uDomain[0], uDomain[1], uStep): for v in rs.frange(vDomain[0], vDomain[1], vStep): pt = rs.EvaluateSurface(idSurface, u, v) # get points at each domain step if rs.Distance(pt, rs.BrepClosestPoint(idSurface, pt)[0]) < 0.1: srfFrame = rs.SurfaceFrame(idSurface, [u, v]) # create ref plane at each division point newPlane = rs.AddPlaneSurface(srfFrame, 1.0, 1.0) # create surface at each ref plane # add height guideline from plane's origin to "ceiling" centerPt = rs.SurfaceAreaCentroid(newPlane) # locate center of each new plane limit = 10 # set "ceiling" endPt = limit - centerPt[0][2] # access z coordinate with the tuple rs.AddLine(centerPt[0], rs.PointAdd(centerPt[0], (0,0,endPt)) ) rs.EnableRedraw(True) # refresh viewport at one time only