def depth(self): '''Used for non-res lighting evaluation. The room depth(m) from the main window wall ''' if self._depth: return self._depth worldXplane = ghc.XYPlane( Rhino.Geometry.Point3d(0,0,0) ) # Find the 'short' edge and the 'long' egde of the srfc geometry srfcEdges = ghc.DeconstructBrep(self.surface).edges segLengths = ghc.SegmentLengths(srfcEdges).longest_length srfcEdges_sorted = ghc.SortList(segLengths, srfcEdges).values_a endPoints = ghc.EndPoints(srfcEdges_sorted[-1]) longEdgeVector = ghc.Vector2Pt(endPoints.start, endPoints.end, False).vector shortEdgeVector = ghc.Rotate(longEdgeVector, ghc.Radians(90), worldXplane).geometry # Use the edges to find the orientation and dimensions of the room srfcAligedPlane = ghc.ConstructPlane(ghc.Area(self.surface).centroid, longEdgeVector, shortEdgeVector) srfcAlignedWorld = ghc.Orient(self.surface, srfcAligedPlane, worldXplane).geometry dims = ghc.BoxProperties( srfcAlignedWorld ).diagonal dims = [dims.X, dims.Y] width = min(dims) depth = max(dims) return depth
def ngons(args): nn, length, lvariation, kk, radtolen, mngon, depth, radchng = args stpnt = ghc.EndPoints(nn)[0] #returns list of two points, start and end endpnt = ghc.EndPoints(nn)[1] vect = ghc.Vector2Pt(stpnt, endpnt, False)[0] #returns list with vector and vector length pln = ghc.PlaneNormal(stpnt, vect) #returns a plane perp to a vector radius = length * (radchng**kk) / radtolen #reduce details with each branch, but not less than 3 if mngon - kk + 1 <= 3: splits = 3 else: splits = mngon - kk + 1 pgn = ghc.Polygon(pln, radius, splits, 0)[0] #returns a polygon and its perimeter if kk == depth and splits == 3: geo = ghc.ExtrudePoint(pgn, endpnt) #if last branch than make a pyramid else: geo = ghc.Extrude(pgn, vect) #extrudes the polygon along vector return ghc.CapHoles(geo) #caps ends on the extruded brep
def CalcRevealDims(_phpp_window_obj, RevealShaderObjs_input, SideIntersectionSurface, Side_OriginPt, Side_Direction): #Test shading objects for their edge points Side_IntersectionCurve = [] Side_IntersectionPoints = [] for i in range(len(RevealShaderObjs_input)): #This is the list of shading objects to filter if ghc.BrepXBrep(RevealShaderObjs_input[i], SideIntersectionSurface).curves != None: Side_IntersectionCurve.append(ghc.BrepXBrep(RevealShaderObjs_input[i], SideIntersectionSurface).curves) for i in range(len(Side_IntersectionCurve)): for k in range(len(ghc.ControlPoints(Side_IntersectionCurve[i]).points)): Side_IntersectionPoints.append(ghc.ControlPoints(Side_IntersectionCurve[i]).points[k]) #Find the top/closets point for each of the objects that could possibly shade Side_KeyPoints = [] Side_Rays = [] Side_Angles = [] for i in range(len(Side_IntersectionPoints)): if Side_OriginPt != Side_IntersectionPoints[i]: Ray = ghc.Vector2Pt(Side_OriginPt, Side_IntersectionPoints[i], False).vector Angle = math.degrees(ghc.Angle(_phpp_window_obj.surface_normal, Ray).angle) if Angle < 89.9: Side_Rays.append(Ray) Side_Angles.append(float(Angle)) Side_KeyPoints.append(Side_IntersectionPoints[i]) Side_KeyPoint = Side_KeyPoints[Side_Angles.index(min(Side_Angles))] Side_KeyRay = Side_Rays[Side_Angles.index(min(Side_Angles))] #use the Key point found to calculte the Distances for the PHPP Shading Calculator Side_Hypot = ghc.Length(ghc.Line(Side_OriginPt, Side_KeyPoint)) Deg = (ghc.Angle(Side_Direction, Side_KeyRay).angle) #note this is in Radians Side_o_reveal = math.sin(Deg) * Side_Hypot Side_d_reveal = math.sqrt(Side_Hypot**2 - Side_o_reveal**2) Side_CheckLine = ghc.Line(Side_OriginPt, Side_KeyPoint) return [Side_o_reveal, Side_d_reveal, Side_CheckLine]
def RunScript(self, AS, CL): # Initialize outputs S = [] TS = CL W = [] CS = [] # Set defaults if no values are provided D = 1000 # Iterate over each test segment for seg in CL: # Extend line to threshold width midpt, TT, t = ghc.EvaluateLength(seg, 0.5, True) SS, E = ghc.EndPoints(seg) V, L = ghc.Vector2Pt(midpt, SS, False) vect = ghc.Amplitude(V, D/2) G1, X = ghc.Move(midpt, vect) G2, X = ghc.Move(midpt, -vect) test_line = ghc.Line(G1, G2) # Rotate test line 90 degrees test_line, X = ghc.Rotate(test_line, math.pi/2, midpt) # Check for intersection srf_intersection = checkIntersection(test_line, AS, midpt, D) # Store results CS.append(srf_intersection) W.append(ghc.Length(srf_intersection)) # Return outputs return TS, W, CS
def leafgenerator(point): #random z move zmove = rg.Vector3d(0, 0, 1) moveamp = random.uniform(-leaflen / 3, leaflen / 5) ampzmove = ghc.Amplitude(zmove, moveamp) llendpnt = ghc.Move(point, ampzmove)[0] #setting a leaf centerline vector leafvector = ghc.Vector2Pt(leafpoint, llendpnt, True)[0] #defining leaf center point as avarage of st and end pnts midpnt = ghc.Average([leafpoint, llendpnt]) #generating perpendicular vector vecperpleaf = ghc.Rotate(leafvector, radians(90), planetocenter)[0] leafperpamp = ghc.Amplitude( vecperpleaf, random.uniform((leafwidth / 2) / 5 * 4, (leafwidth / 2) / 5 * 6)) #moving mid point to both sides midpnt1 = ghc.Move(midpnt, leafperpamp)[0] midpnt2 = ghc.Move(midpnt, -leafperpamp)[0] #leaf geo leafgeo = rg.NurbsSurface.CreateFromCorners( leafpoint, midpnt1, llendpnt, midpnt2) leaves.append(leafgeo)
def copy_modules(): global meshes_a, meshes_b, meshes_c # Copying Modules meshes_a = [] meshes_b = [] meshes_c = [] totals = [0, 0, 0] for i, p in enumerate(points_input): d = voxel_data[i] if d == 0: continue cart = loc_to_cart(i) mesh_id = mesh_strategy_neighbors(cart) translation = gh.Vector2Pt(world_xy, p, False)[0] add = clamp( int((gh.Deconstruct(p)[2] / 4000 * 4) + (perlin_values[i] - 0.5)), 0, 3) if mesh_id == 0: meshes_a.append(gh.Move(mesh_input[16 + add], translation)[0]) elif mesh_id == 1: meshes_a.append(gh.Move(mesh_input[12 + add], translation)[0]) meshes_b.append(gh.Move(mesh_input[8 + add], translation)[0]) elif mesh_id == 2: meshes_b.append(gh.Move(mesh_input[4 + add], translation)[0]) meshes_c.append(gh.Move(mesh_input[0 + add], translation)[0]) totals[mesh_id] += 1 #new_plane = gh.PlaneOrigin(random.choose print totals
def _get_vector_from_center_to_edge(_surface, _surface_plane): """ Find a Vector from center of surface to mid-point on each edge. Arguments: _surface: The Rhino surface to analyze. _surface_plane: A Plane aligned to the surface. Returns: edgeVectors: (List) Vector3D for mid-point on each edge """ worldOrigin = Rhino.Geometry.Point3d(0,0,0) worldXYPlane = ghc.XYPlane(worldOrigin) geomAtWorldZero = ghc.Orient(_surface, _surface_plane, worldXYPlane).geometry edges = ghc.DeconstructBrep(geomAtWorldZero).edges # Find the mid-point for each edge and create a vector to that midpoint crvMidPoints = [ ghc.CurveMiddle(edge) for edge in edges ] edgeVectors = [ ghc.Vector2Pt(midPt, worldOrigin, False).vector for midPt in crvMidPoints ] return edgeVectors
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, verticality, gchance): #test if depth>0 if depth: #defining random angle variation and length variation arn = random.uniform(-angle / 100 * aran, angle / 100 * aran) lrn = random.uniform(-length / 100 * lran, length / 100 * lran) if hrandom == True: #defining horizontal rotation angles ahor = random.sample(range(0, 360), branches) #removing numbers within tolerance ahr = rs.CullDuplicateNumbers(ahor, angleh) #in a 360 fashion if ahr[0] + 360 - angleh < ahr[-1]: del ahr[0] else: #generating evenly distributed angles ahr = range(0, 360 + 1, 360 // branches)[:-1] #previous branch vector vecst = rg.Point3d(x1, y1, z1) vecend = rg.Point3d(x2, y2, z2) movevec = ghc.Vector2Pt(vecst, vecend, True)[0] #returns vector and it's length #perpendicular vector rotplane3 = ghc.PlaneNormal( vecend, movevec) #creates plane perpendicular to vector plns = ghc.DeconstructPlane(rotplane3) #origin, x, y, z rotplane = ghc.ConstructPlane( plns[2], plns[1], plns[3] ) #constructing new plane switching x and y planes to make perpendicular #generating perpendicular vector vecperp = ghc.Rotate(movevec, radians(90), rotplane)[0] #generating vector amplitudes leny = (length + lrn) * sin( radians((anglerec + arn) * (1 - (verticality**depth)))) lenz = (length + lrn) * cos(radians(anglerec + arn)) ampy = ghc.Amplitude(vecperp, leny) ampz = ghc.Amplitude(movevec, lenz) #changing branch length dependant on branch depth length = length * lvariation #building points endpoint1 = ghc.Move( vecend, ampz)[0] #returns moved object and transformation data endpoint = ghc.Move( endpoint1, ampy)[0] #returns moved object and transformation data #rotating point in a cone fashion rotpoint = ghc.Rotate3D( endpoint, radians(anglerech), vecend, movevec)[0] #returns rotated geometry and transformation data #building line between points linegeo = rg.Line(vecend, rotpoint) #setting coords for next branch x1 = x2 y1 = y2 z1 = z2 #getting xyz from rotated point x2 = rg.Point3d(rotpoint)[0] y2 = rg.Point3d(rotpoint)[1] z2 = rg.Point3d(rotpoint)[2] #building a dict of lines with depth as key, and corresponding lines as values if depth not in treelin.keys(): treelin[depth] = [linegeo] else: treelin[depth].append(linegeo) #calling function with different angle parameter for branch splitting #calling as many branches as spread within tolerance for aa in ahr: if ( (random.randint(40, 99) / 100)**depth ) < gchance or depth == depthstart + 1: #or added to prevent blank trees fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle, angle, lvariation, aran, lran, aa, angleh, branches, verticality, gchance)
def find_reveal_shading(_phpp_window_obj, _shadingGeom, _extents=99): WinCenter = ghc.Area(_phpp_window_obj.glazing_surface).centroid edges = _phpp_window_obj._get_edges_in_order( _phpp_window_obj.glazing_surface ) surface_normal = _phpp_window_obj.surface_normal #Create the Intersection Surface for each side Side1_OriginPt = ghc.CurveMiddle( from_linesegment3d(edges.Left) ) Side1_NormalLine = ghc.LineSDL(Side1_OriginPt, surface_normal, _extents) Side1_Direction = ghc.Vector2Pt(WinCenter, Side1_OriginPt, False).vector Side1_HorizLine = ghc.LineSDL(Side1_OriginPt, Side1_Direction, _extents) Side1_IntersectionSurface = ghc.SumSurface(Side1_NormalLine, Side1_HorizLine) #Side2_OriginPt = SideMidPoints[1] #ghc.CurveMiddle(self.Edge_Left) Side2_OriginPt = ghc.CurveMiddle( from_linesegment3d(edges.Right) ) Side2_NormalLine = ghc.LineSDL(Side2_OriginPt, surface_normal, _extents) Side2_Direction = ghc.Vector2Pt(WinCenter, Side2_OriginPt, False).vector Side2_HorizLine = ghc.LineSDL(Side2_OriginPt, Side2_Direction, _extents) Side2_IntersectionSurface = ghc.SumSurface(Side2_NormalLine, Side2_HorizLine) #Find any Shader Objects and put them all into a list Side1_RevealShaderObjs = [] testStartPt = ghc.Move(WinCenter, ghc.Amplitude(surface_normal, 0.1)).geometry #Offsets the test line just a bit Side1_TesterLine = ghc.LineSDL(testStartPt, Side1_Direction, _extents) #extend a line off to side 1 for i in range(len(_shadingGeom)): if ghc.BrepXCurve(_shadingGeom[i],Side1_TesterLine).points != None: Side1_RevealShaderObjs.append(_shadingGeom[i]) Side2_RevealShaderObjs = [] Side2_TesterLine = ghc.LineSDL(testStartPt, Side2_Direction, _extents) #extend a line off to side 2 for i in range(len(_shadingGeom)): if ghc.BrepXCurve(_shadingGeom[i],Side2_TesterLine).points != None: Side2_RevealShaderObjs.append(_shadingGeom[i]) #--------------------------------------------------------------------------- # Calc Shading reveal dims NumShadedSides = 0 if len(Side1_RevealShaderObjs) != 0: Side1_o_reveal = CalcRevealDims(_phpp_window_obj, Side1_RevealShaderObjs, Side1_IntersectionSurface, Side1_OriginPt, Side1_Direction)[0] Side1_d_reveal = CalcRevealDims(_phpp_window_obj, Side1_RevealShaderObjs, Side1_IntersectionSurface, Side1_OriginPt, Side1_Direction)[1] Side1_CheckLine = CalcRevealDims(_phpp_window_obj, Side1_RevealShaderObjs, Side1_IntersectionSurface, Side1_OriginPt, Side1_Direction)[2] NumShadedSides = NumShadedSides + 1 else: Side1_o_reveal = None Side1_d_reveal = None Side1_CheckLine = Side1_HorizLine if len(Side2_RevealShaderObjs) != 0: Side2_o_reveal = CalcRevealDims(_phpp_window_obj, Side2_RevealShaderObjs, Side2_IntersectionSurface, Side2_OriginPt, Side2_Direction)[0] Side2_d_reveal = CalcRevealDims(_phpp_window_obj, Side2_RevealShaderObjs, Side2_IntersectionSurface, Side2_OriginPt, Side2_Direction)[1] Side2_CheckLine = CalcRevealDims(_phpp_window_obj, Side2_RevealShaderObjs, Side2_IntersectionSurface, Side2_OriginPt, Side2_Direction)[2] NumShadedSides = NumShadedSides + 1 else: Side2_o_reveal = None Side2_d_reveal = None Side2_CheckLine = Side2_HorizLine # # # # TODO: how to handel asymetrical reveals???? o_reveal = Side1_o_reveal#(Side1_o_reveal + Side2_o_reveal )/ max(1,NumShadedSides) d_reveal = Side1_d_reveal#(Side1_d_reveal + Side2_d_reveal )/ max(1,NumShadedSides) # # # # # return o_reveal, d_reveal, Side1_CheckLine, Side2_CheckLine
def find_overhang_shading(_phpp_window_obj, _shadingGeom, _extents=99): # Figure out the glass surface (inset a bit) and then # find the origin point for all the subsequent shading calcs (top, middle) glzgCenter = ghc.Area(_phpp_window_obj.glazing_surface).centroid glazingEdges = _phpp_window_obj._get_edges_in_order( _phpp_window_obj.glazing_surface ) glazingTopEdge = from_linesegment3d(glazingEdges.Top) ShadingOrigin = ghc.CurveMiddle(glazingTopEdge) # In order to also work for windows which are not vertical, find the # 'direction' from the glazing origin and the top/middle ege point UpVector = ghc.Vector2Pt(glzgCenter, ShadingOrigin, True).vector #----------------------------------------------------------------------- # First, need to filter the scene to find the objects that are 'above' # the window. Create a 'test plane' that is _extents (99m) tall and 0.5m past the wall surface, test if # any objects intersect that plane. If so, add them to the set of things # test in the next step depth = float(_phpp_window_obj.install_depth) + 0.5 edge1 = ghc.LineSDL(ShadingOrigin, UpVector, _extents) edge2 = ghc.LineSDL(ShadingOrigin, _phpp_window_obj.surface_normal, depth) intersectionTestPlane = ghc.SumSurface(edge1, edge2) OverhangShadingObjs = (x for x in _shadingGeom if ghc.BrepXBrep(intersectionTestPlane, x).curves != None) #----------------------------------------------------------------------- # Using the filtered set of shading objects, find the 'edges' of shading # geom and then decide where the maximums shading point is # Create a new 'test' plane coming off the origin (99m in both directions this time). # Test to find any intersection shading objs and all their crvs/points with this plane HorizontalLine = ghc.LineSDL(ShadingOrigin, _phpp_window_obj.surface_normal, _extents) VerticalLine = ghc.LineSDL(ShadingOrigin, UpVector, _extents) IntersectionSurface = ghc.SumSurface(HorizontalLine, VerticalLine) IntersectionCurves = (ghc.BrepXBrep(obj, IntersectionSurface).curves for obj in OverhangShadingObjs if ghc.BrepXBrep(obj, IntersectionSurface).curves != None) IntersectionPointsList = (ghc.ControlPoints(crv).points for crv in IntersectionCurves) IntersectionPoints = (pt for list_of_pts in IntersectionPointsList for pt in list_of_pts) #----------------------------------------------------------------------- # If there are any intersection Points found, choose the right one to use to calc shading.... # Find the top/closets point for each of the objects that could possibly shade smallest_angle_found = 2 * math.pi key_point = None for pt in IntersectionPoints: if pt == None: continue # Protect against Zero-Length error ray = ghc.Vector2Pt(ShadingOrigin, pt, False).vector if ray.Length < 0.001: continue this_ray_angle = ghc.Angle(_phpp_window_obj.surface_normal , ray).angle if this_ray_angle < 0.001: continue if this_ray_angle <= smallest_angle_found: smallest_angle_found = this_ray_angle key_point = pt #----------------------------------------------------------------------- # Use the 'key point' found to deliver the Height and Distance for the PHPP Shading Calculator if not key_point: d_over = None o_over = None CheckLine = VerticalLine else: d_over = key_point.Z - ShadingOrigin.Z # Vertical distance Hypot = ghc.Length(ghc.Line(ShadingOrigin, key_point)) # Hypot o_over = math.sqrt(Hypot**2 - d_over**2) # Horizontal distance CheckLine = ghc.Line(ShadingOrigin, key_point) return d_over, o_over, CheckLine
def find_horizon_shading(_phpp_window_obj, _shadingGeom, _extents=99): """ Arguments: _phpp_winddow_obj: The PHPP_Window object to calcualte the values for _shadingGeom: (list) A list of possible shading objects to test against _extents: (float) A number (m) to limit the shading search to. Default = 99m Returns: h_hori: Distance (m) out from the glazing surface of any horizontal shading objects found d_hori: Distance (m) up from the base of the window to the top of any horizontal shading objects found """ surface_normal = _phpp_window_obj.surface_normal #----------------------------------------------------------------------- # Find Starting Point glazingEdges = _phpp_window_obj._get_edges_in_order( _phpp_window_obj.glazing_surface ) glazingBottomEdge = glazingEdges.Bottom ShadingOrigin = ghc.CurveMiddle( from_linesegment3d(glazingBottomEdge) ) UpVector = ghc.VectorXYZ(0,0,1).vector #----------------------------------------------------------------------- # Find if there are any shading objects and if so put them in a list HorizonShading = [] HorizontalLine = ghc.LineSDL(ShadingOrigin, surface_normal, _extents) VerticalLine = ghc.LineSDL(ShadingOrigin, UpVector, _extents) for shadingObj in _shadingGeom: if ghc.BrepXCurve(shadingObj, HorizontalLine).points != None: HorizonShading.append( shadingObj ) #----------------------------------------------------------------------- # Find any intersection Curves with the shading objects IntersectionSurface = ghc.SumSurface(HorizontalLine, VerticalLine) IntersectionCurve = [] IntersectionPoints = [] for shadingObj in HorizonShading: if ghc.BrepXBrep(shadingObj, IntersectionSurface).curves != None: IntersectionCurve.append(ghc.BrepXBrep(shadingObj, IntersectionSurface)) for pnt in IntersectionCurve: IntersectionPoints.append(ghc.ControlPoints(pnt).points) #----------------------------------------------------------------------- # Run the "Top-Corner-Finder" if there are any intersecting objects... if len(IntersectionPoints) != 0: # Find the top/closets point for each of the objects that could possibly shade KeyPoints = [] for pnt in IntersectionPoints: Rays = [] Angles = [] if pnt: for k in range(len(pnt)): Rays.append(ghc.Vector2Pt(ShadingOrigin,pnt[k], False).vector) Angles.append(ghc.Angle(surface_normal , Rays[k]).angle) KeyPoints.append(pnt[Angles.index(max(Angles))]) # Find the relevant highest / closest point Rays = [] Angles = [] for i in range(len(KeyPoints)): Rays.append(ghc.Vector2Pt(surface_normal, KeyPoints[i], False).vector) Angles.append(ghc.Angle(surface_normal, Rays[i]).angle) KeyPoint = KeyPoints[Angles.index(max(Angles))] # Use the point it finds to deliver the Height and Distance for the PHPP Shading Calculator h_hori = KeyPoint.Z - ShadingOrigin.Z #Vertical distance Hypot = ghc.Length(ghc.Line(ShadingOrigin, KeyPoint)) d_hori = math.sqrt(Hypot**2 - h_hori**2) CheckLine = ghc.Line(ShadingOrigin, KeyPoint) else: h_hori = None d_hori = None CheckLine = HorizontalLine return h_hori, d_hori, CheckLine
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, verticality, gchance, depthstart, radtolen, radchng, mngon, polygon, branch_cluster): #test if depth>0 if depth: #defining random angle variation and length variation arn = random.uniform(-angle / 100 * aran, angle / 100 * aran) lrn = random.uniform(-length / 100 * lran, length / 100 * lran) if hrandom == True: #defining horizontal rotation angles ahor = random.sample(range(0, 360), branches) #removing numbers within tolerance ahr = rs.CullDuplicateNumbers(ahor, angleh) #in a 360 fashion if ahr[0] + 360 - angleh < ahr[-1]: del ahr[0] else: #generating evenly distributed angles ahr = range(0, 360 + 1, 360 // branches)[:-1] #previous branch vector vecst = rg.Point3d(x1, y1, z1) vecend = rg.Point3d(x2, y2, z2) movevec = ghc.Vector2Pt(vecst, vecend, True)[0] #returns vector and it's length #perpendicular vector rotplane3 = ghc.PlaneNormal( vecend, movevec) #creates plane perpendicular to vector plns = ghc.DeconstructPlane(rotplane3) #origin, x, y, z rotplane = ghc.ConstructPlane( plns[2], plns[1], plns[3] ) #constructing new plane switching x and y planes to make perpendicular #generating perpendicular vector vecperp = ghc.Rotate(movevec, radians(90), rotplane)[0] #generating vector amplitudes leny = (length + lrn) * sin( radians((anglerec + arn) * (1 - (verticality**depth)))) lenz = (length + lrn) * cos(radians(anglerec + arn)) ampy = ghc.Amplitude(vecperp, leny) ampz = ghc.Amplitude(movevec, lenz) #changing branch length dependant on branch depth length = length * lvariation #building points endpoint1 = ghc.Move( vecend, ampz)[0] #returns moved object and transformation data endpoint = ghc.Move( endpoint1, ampy)[0] #returns moved object and transformation data #rotating point in a cone fashion rotpoint = ghc.Rotate3D( endpoint, radians(anglerech), vecend, movevec)[0] #returns rotated geometry and transformation data #building line between points linegeo = rg.Line(vecend, rotpoint) #defining recursion depth key = depthstart + 1 - depth #building geometry pln = ghc.PlaneNormal(rotpoint, linegeo) #returns a plane perp to a vector radius = length * (radchng**(key)) / radtolen #reduce details with each branch, but not less than 3 splits = 3 if mngon - key + 1 <= 3 else mngon - key + 1 polygonend = ghc.Polygon(pln, radius, splits, 0)[0] #returns a polygon and its perimeter #aligning curves for loft creation crvst = ghc.EndPoints(polygon)[0] pntcld = ghc.Discontinuity(polygonend, 1) #returns points and point parameters #finind seam point closest_point = ghc.ClosestPoint( crvst, pntcld[0] ) #returns closest point, closest point index, distance between closest points seampnt = pntcld[1][closest_point[1]] polygonend = ghc.Seam(polygonend, seampnt) lcurves = [polygon, polygonend] #building geometry geo = ghc.ExtrudePoint( polygon, rotpoint ) if depth == 1 and splits == 3 else rg.Brep.CreateFromLoft( lcurves, rg.Point3d.Unset, rg.Point3d.Unset, rg.LoftType.Normal, False)[0] #if last branch than make a pyramid #make solid geocapped = ghc.CapHoles(geo) #building a dict of geo with depth as key, and geo as values pgons.update( {branch_cluster: [geocapped]}) if branch_cluster not in pgons.keys( ) else pgons[branch_cluster].append(geocapped) branchesout.append(geocapped) #setting coords for next branch x1 = x2 y1 = y2 z1 = z2 #getting xyz from rotated point x2 = rg.Point3d(rotpoint)[0] y2 = rg.Point3d(rotpoint)[1] z2 = rg.Point3d(rotpoint)[2] #setting base polygon for next branch polygon = polygonend #filling dict with branch clusters cluster.append(cluster[-1] + 1) branch_cluster = cluster[-1] #calling function with different angle parameter for branch splitting, calling as many branches as spread within tolerance if depth != 1: for aa in ahr: if ( (random.randint(40, 99) / 100)**depth ) < gchance or depth == depthstart + 1: #or added to prevent blank trees fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle, angle, lvariation, aran, lran, aa, angleh, branches, verticality, gchance, depthstart, radtolen, radchng, mngon, polygon, branch_cluster) #leaf logic if depth <= leavesdepth and leavesperbranch > 0 and maxleaves > 0: #vector for leaf growth spread leafpntvec = ghc.Vector2Pt(vecend, rotpoint, True)[0] #setting leaf growth position on last barnch, leafpnt list lastbranchlength = ghc.Length(linegeo) leaves_list = [lastbranchlength] [ leaves_list.append(lengthparam) for lengthparam in random.sample( range(0, int(lastbranchlength)), leavesperbranch - 1) ] if leavesperbranch > 1 else None for leafpnt in leaves_list: leafamp = ghc.Amplitude(leafpntvec, leafpnt) leafpoint = ghc.Move(vecend, leafamp)[0] #plane for leaf generation linetocenter = ghc.Line(stpntbase, leafpoint) planetocenter = ghc.PlaneNormal(leafpoint, linetocenter) #create an imaginary circle with leaflen radius and populate it with points for random leaf generation leafgenerationcircle = ghc.CircleCNR(leafpoint, linetocenter, leaflen) circlesurf = ghc.BoundarySurfaces(leafgenerationcircle) leafcnt = random.randint(0, maxleaves) if leafcnt > 0: leafendpnts = ghc.PopulateGeometry(circlesurf, leafcnt, random.randint(1, 500)) def leafgenerator(point): #random z move zmove = rg.Vector3d(0, 0, 1) moveamp = random.uniform(-leaflen / 3, leaflen / 5) ampzmove = ghc.Amplitude(zmove, moveamp) llendpnt = ghc.Move(point, ampzmove)[0] #setting a leaf centerline vector leafvector = ghc.Vector2Pt(leafpoint, llendpnt, True)[0] #defining leaf center point as avarage of st and end pnts midpnt = ghc.Average([leafpoint, llendpnt]) #generating perpendicular vector vecperpleaf = ghc.Rotate(leafvector, radians(90), planetocenter)[0] leafperpamp = ghc.Amplitude( vecperpleaf, random.uniform((leafwidth / 2) / 5 * 4, (leafwidth / 2) / 5 * 6)) #moving mid point to both sides midpnt1 = ghc.Move(midpnt, leafperpamp)[0] midpnt2 = ghc.Move(midpnt, -leafperpamp)[0] #leaf geo leafgeo = rg.NurbsSurface.CreateFromCorners( leafpoint, midpnt1, llendpnt, midpnt2) leaves.append(leafgeo) #iterate over random number of generated points if list, else generate for one point [leafgenerator(pp) for pp in leafendpnts] if isinstance( leafendpnts, list) else leafgenerator(leafendpnts)
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, verticality, gchance, depthstart, radtolen, radchng, mngon, polygon): #test if depth>0 if depth: #defining random angle variation and length variation arn = random.uniform(-angle / 100 * aran, angle / 100 * aran) lrn = random.uniform(-length / 100 * lran, length / 100 * lran) if hrandom == True: #defining horizontal rotation angles ahor = random.sample(range(0, 360), branches) #removing numbers within tolerance ahr = rs.CullDuplicateNumbers(ahor, angleh) #in a 360 fashion if ahr[0] + 360 - angleh < ahr[-1]: del ahr[0] else: #generating evenly distributed angles ahr = range(0, 360 + 1, 360 // branches)[:-1] #previous branch vector vecst = rg.Point3d(x1, y1, z1) vecend = rg.Point3d(x2, y2, z2) movevec = ghc.Vector2Pt(vecst, vecend, True)[0] #returns vector and it's length #perpendicular vector rotplane3 = ghc.PlaneNormal( vecend, movevec) #creates plane perpendicular to vector plns = ghc.DeconstructPlane(rotplane3) #origin, x, y, z rotplane = ghc.ConstructPlane( plns[2], plns[1], plns[3] ) #constructing new plane switching x and y planes to make perpendicular #generating perpendicular vector vecperp = ghc.Rotate(movevec, radians(90), rotplane)[0] #generating vector amplitudes leny = (length + lrn) * sin( radians((anglerec + arn) * (1 - (verticality**depth)))) lenz = (length + lrn) * cos(radians(anglerec + arn)) ampy = ghc.Amplitude(vecperp, leny) ampz = ghc.Amplitude(movevec, lenz) #changing branch length dependant on branch depth length = length * lvariation #building points endpoint1 = ghc.Move( vecend, ampz)[0] #returns moved object and transformation data endpoint = ghc.Move( endpoint1, ampy)[0] #returns moved object and transformation data #rotating point in a cone fashion rotpoint = ghc.Rotate3D( endpoint, radians(anglerech), vecend, movevec)[0] #returns rotated geometry and transformation data #building line between points linegeo = rg.Line(vecend, rotpoint) #defining recursion depth key = depthstart + 1 - depth #building geometry #stpnt = VECEND ghc.EndPoints(nn)[0] #returns list of two points, start and end #endpnt = ROTPOINT ghc.EndPoints(nn)[1] pln = ghc.PlaneNormal(rotpoint, linegeo) #returns a plane perp to a vector radius = length * (radchng**(key)) / radtolen #polygon = polygonbase #reduce details with each branch, but not less than 3 if mngon - key + 1 <= 3: splits = 3 else: splits = mngon - key + 1 polygonend = ghc.Polygon(pln, radius, splits, 0)[0] #returns a polygon and its perimeter #creating loft between polygons #Normal = rg.LoftType.Normal #loptions = ghc.LoftOptions(False, True, 0, 0, rg.LoftType.Normal) #loft option lcurves = [polygon, polygonend] #loftedgeo = ghc.Loft(lcurves, loptions) if depth == 1 and splits == 3: geo = ghc.ExtrudePoint( polygon, rotpoint) #if last branch than make a pyramid else: geo = ghc.RuledSurface(polygon, polygonend) #setting coords for next branch x1 = x2 y1 = y2 z1 = z2 #getting xyz from rotated point x2 = rg.Point3d(rotpoint)[0] y2 = rg.Point3d(rotpoint)[1] z2 = rg.Point3d(rotpoint)[2] #setting base polygon for next branch polygon = polygonend #pgons.append(polygon) #pgons.append(linegeo) pgons.append(geo) #calling function with different angle parameter for branch splitting #calling as many branches as spread within tolerance for aa in ahr: if ( (random.randint(40, 99) / 100)**depth ) < gchance or depth == depthstart + 1: #or added to prevent blank trees fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle, angle, lvariation, aran, lran, aa, angleh, branches, verticality, gchance, depthstart, radtolen, radchng, mngon, polygon)
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, gravity): #test if depth>0 if depth: #defining random angle variation and length variation arn = random.uniform(-angle / 100 * aran, angle / 100 * aran) lrn = random.uniform(-length / 100 * lran, length / 100 * lran) #defining horizontal rotation angles ahor = random.sample(range(0, 360), branches) """ #removing numbers within tolerance ahr = rs.CullDuplicateNumbers(ahor, angleh) #in a 360 fashion if ahr[0]+360-angleh<ahr[-1]: del ahr[0] random.shuffle(ahr) """ ahr = [0, 90, 270, 180] #previous branch vector vecst = rg.Point3d(x1, y1, z1) vecend = rg.Point3d(x2, y2, z2) movevec = ghc.Vector2Pt(vecst, vecend, True)[0] #returns vector and it's length #perpendicular vector rotation plane rotplane3 = ghc.PlaneNormal( vecend, movevec) #creates plane perpendicular to vector plns = ghc.DeconstructPlane(rotplane3) #origin, x, y, z rotplane = ghc.ConstructPlane( plns[0], plns[3], plns[2] ) #constructing new plane switching x and y planes to make perpendicular #generating perpendicular vector vecperp = ghc.Rotate(movevec, radians(90), rotplane)[0] #generating vector amplitudes leny = (length + lrn) * sin(radians(anglerec + arn)) lenz = (length + lrn) * cos(radians(anglerec + arn)) ampy = ghc.Amplitude(vecperp, leny) ampz = ghc.Amplitude(movevec, lenz) #changing branch length dependant on branch depth length = length * lvariation #building points endpoint1 = ghc.Move( vecend, ampz)[0] #returns moved object and transformation data endpoint = ghc.Move( endpoint1, ampy)[0] #returns moved object and transformation data #rotating point in a cone fashion rotpoint = ghc.Rotate3D( endpoint, anglerech, vecend, movevec)[0] #returns rotated geometry and transformation data #vertical branch angle angl1 = ghc.Angle(rg.Line(vecend, rotpoint), horizont, verticalpln)[0] #outputs angle and reflex angl = ghc.Degrees(angl1) anglls.append(angl) #rotate depending on how horizontal branch is if angl > 0 and angl < 180: if angl < 89: grrot = ((30 / 100) * (100 - (angl * 0.9)) / 100) * gravity elif angl > 91: grrot = ((30 / 100) * (100 - ((180 - angl) * 0.9)) / 100) * gravity try: grrot == 0 rotpoint = ghc.Rotate3D(rotpoint, grrot, vecend, verticalpln)[0] except: pass #building line between points linegeo = rg.Line(vecend, rotpoint) #setting coords for next branch x1 = x2 y1 = y2 z1 = z2 #getting xyz from rotated point x2 = rg.Point3d(rotpoint)[0] y2 = rg.Point3d(rotpoint)[1] z2 = rg.Point3d(rotpoint)[2] #building a dict of lines with depth as key, and corresponding lines as values if depth not in treelin.keys(): treelin[depth] = [linegeo] else: treelin[depth].append(linegeo) #calling function with different angle parameter for branch splitting #calling as many branches as spread within tolerance for aa in ahr: fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle, angle, lvariation, aran, lran, aa, angleh, branches, gravity)
#base angle anglerec = 0 anglerech = 0 #list of lines that form the tree, this is the output variable treelin = {} anglest = [] anglls = [] grav = [] #define xy vecotr for gravity reference refp1 = rg.Point3d(0, 0, 0) refp2 = rg.Point3d(0, 1, 0) refp3 = rg.Point3d(0, 0, 1) horizont = ghc.Vector2Pt(refp1, refp2, True)[0] #vertical plane verticalpln = ghc.Plane3Pt(refp1, refp3, refp2) #recursive function def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, gravity): #test if depth>0 if depth: #defining random angle variation and length variation arn = random.uniform(-angle / 100 * aran, angle / 100 * aran) lrn = random.uniform(-length / 100 * lran, length / 100 * lran)
def fractal(depth, x1, y1, z1, x2, y2, z2, length, anglerec, angle, lvariation, aran, lran, anglerech, angleh, branches, verticality, gchance, depthstart, radtolen, radchng, mngon, polygon, branch_cluster): #test if depth>0 if depth: #defining random angle variation and length variation arn = random.uniform(-angle / 100 * aran, angle / 100 * aran) lrn = random.uniform(-length / 100 * lran, length / 100 * lran) if hrandom == True: #defining horizontal rotation angles ahor = random.sample(range(0, 360), branches) #removing numbers within tolerance ahr = rs.CullDuplicateNumbers(ahor, angleh) #in a 360 fashion if ahr[0] + 360 - angleh < ahr[-1]: del ahr[0] else: #generating evenly distributed angles ahr = range(0, 360 + 1, 360 // branches)[:-1] #previous branch vector vecst = rg.Point3d(x1, y1, z1) vecend = rg.Point3d(x2, y2, z2) movevec = ghc.Vector2Pt(vecst, vecend, True)[0] #returns vector and it's length #perpendicular vector rotplane3 = ghc.PlaneNormal( vecend, movevec) #creates plane perpendicular to vector plns = ghc.DeconstructPlane(rotplane3) #origin, x, y, z rotplane = ghc.ConstructPlane( plns[2], plns[1], plns[3] ) #constructing new plane switching x and y planes to make perpendicular #generating perpendicular vector vecperp = ghc.Rotate(movevec, radians(90), rotplane)[0] #generating vector amplitudes leny = (length + lrn) * sin( radians((anglerec + arn) * (1 - (verticality**depth)))) lenz = (length + lrn) * cos(radians(anglerec + arn)) ampy = ghc.Amplitude(vecperp, leny) ampz = ghc.Amplitude(movevec, lenz) #changing branch length dependant on branch depth length = length * lvariation #building points endpoint1 = ghc.Move( vecend, ampz)[0] #returns moved object and transformation data endpoint = ghc.Move( endpoint1, ampy)[0] #returns moved object and transformation data #rotating point in a cone fashion rotpoint = ghc.Rotate3D( endpoint, radians(anglerech), vecend, movevec)[0] #returns rotated geometry and transformation data #building line between points linegeo = rg.Line(vecend, rotpoint) #defining recursion depth key = depthstart + 1 - depth #building geometry pln = ghc.PlaneNormal(rotpoint, linegeo) #returns a plane perp to a vector radius = length * (radchng**(key)) / radtolen #reduce details with each branch, but not less than 3 if mngon - key + 1 <= 3: splits = 3 else: splits = mngon - key + 1 polygonend = ghc.Polygon(pln, radius, splits, 0)[0] #returns a polygon and its perimeter #aligning curves for loft creation crvst = ghc.EndPoints(polygon)[0] pntcld = ghc.Discontinuity(polygonend, 1) #returns points and point parameters #finind seam point closest_point = ghc.ClosestPoint( crvst, pntcld[0] ) #returns closest point, closest point index, distance between closest points seampnt = pntcld[1][closest_point[1]] polygonend = ghc.Seam(polygonend, seampnt) lcurves = [polygon, polygonend] #building geometry if depth == 1 and splits == 3: geo = ghc.ExtrudePoint( polygon, rotpoint) #if last branch than make a pyramid else: geo = rg.Brep.CreateFromLoft(lcurves, rg.Point3d.Unset, rg.Point3d.Unset, rg.LoftType.Normal, False)[0] #make solid geocapped = ghc.CapHoles(geo) #building a dict of geo with depth as key, and geo as values, for more efficient joins if branch_cluster not in pgons.keys(): pgons[branch_cluster] = [geocapped] else: pgons[branch_cluster].append(geocapped) #setting coords for next branch x1 = x2 y1 = y2 z1 = z2 #getting xyz from rotated point x2 = rg.Point3d(rotpoint)[0] y2 = rg.Point3d(rotpoint)[1] z2 = rg.Point3d(rotpoint)[2] #setting base polygon for next branch polygon = polygonend #calling function with different angle parameter for branch splitting #calling as many branches as spread within tolerance #filling dict with branch clusters cluster.append(cluster[-1] + 1) branch_cluster = cluster[-1] for aa in ahr: if ( (random.randint(40, 99) / 100)**depth ) < gchance or depth == depthstart + 1: #or added to prevent blank trees fractal(depth - 1, x1, y1, z1, x2, y2, z2, length, angle, angle, lvariation, aran, lran, aa, angleh, branches, verticality, gchance, depthstart, radtolen, radchng, mngon, polygon, branch_cluster)