@Gijs wrote:
I picked up this script that I once made in rhino script and enhanced it with new options and dynamic preview.
I think the usage is quite self explanatory.There are a few more things I want to implement as you can see in the comments, but I'm also open for others' suggestions.
""" This script allows you draw make patterns from multiple curves at once. It assumes all curves are more or less the same size, and have a reasonable width and height to begin with. It will then randomly use the curves to make a pattern. The pattern is then applied to a boundary curve that must be closed. It uses getpoint in order to enable dynamic redraw when changing the pattern settings. *********************************** * script written by Gijs de Zwart * * www.studiogijs.nl * * April, 2016 * *********************************** implemented: * user selects 1 or more curves to use as pattern * user selects boundary to fill (closed curve) * boundary gets filled with a preview of the endresult * curves outside the boundary are removed * curves that intersect with the boundary are removed * pattern looks at the size of the curve(s) (boundingbox) to get correct spacing * possibility to enter a margin from the border of the boundary * possibility to give curve(s) a random scale/ rotation * possibility to offset each row to do: possibility to scale the curve(s) that are used in the boundary possibility to flip curve(s) error checking """ import rhinoscriptsyntax as rs import Rhino.Geometry.Curve as Curve import random as rand import Rhino import System.Drawing.Color as Color import scriptcontext as sc def RunCommand(): class fillcrv(): def __init__(self,crv): bbox=crv.GetBoundingBox(True) self.crv=crv self.width=bbox.Max.X-bbox.Min.X self.height=bbox.Max.Y-bbox.Min.Y self.h_space=self.width self.v_space=self.height self.lower=bbox.Min def getSpace(offset, space): #returns horizontal and vertical space and row offset (skew) h_space=0 v_space=0 for crv in curves: if h_space<crv.h_space: h_space=crv.h_space if v_space<crv.v_space: v_space=crv.v_space h_space+= h_space*space/100 v_space+= v_space*space/100 h_skew=h_space*offset/100 return [h_space,v_space,h_skew] def CalcStartCondition(boundary): #returns width, height and startpoint transformation #and changes boundary to offset margin if requested bbox=boundary.GetBoundingBox(True) cen_boundary=bbox.Center plane=Rhino.Geometry.Plane.WorldXY plane.Origin = bbox.Min b_width=bbox.Max.X-bbox.Min.X b_height=bbox.Max.Y-bbox.Min.Y #calculate translation vector from curve to boundary start=bbox.Min-curves[0].lower return [b_width, b_height, start, boundary] def CreatePatternCurves(v_amount, h_amount, v_space, h_space, h_skew, start, boundary): #creates patterned curves in rectangular grid trans=start reset=start[0] odd=0 i=0 patterncurves=[] for y in range(0,v_amount): #reset transformation in x-direction trans[0]=reset if odd%2==1: trans[0]+=h_skew odd+=1 for x in range(0,h_amount): i=rand.randint(0,len(curves)-1) copy=curves[i].crv.Duplicate() copy.Translate(trans) cen=copy.GetBoundingBox(True).Center random = optRandom.CurrentValue if random and copy!=None: rnd=rand.randint(90,110)/100 rot_rnd=rand.uniform(-.1,.1) scale=Rhino.Geometry.Transform.Scale(cen,rnd) rotation=Rhino.Geometry.Transform.Rotation(rot_rnd, cen) copy.Transform(scale) copy.Transform(rotation) #check if point to copy is inside boundary and margin margin=optMargin.CurrentValue if boundary.Contains(cen) == Rhino.Geometry.PointContainment.Inside: #check if it intersects with the boundarycurve: #uses intersection tolerance to leave a margin intersection_tolerance = margin+0.01 overlap_tolerance = 0.0 intersections = Rhino.Geometry.Intersect.Intersection.CurveCurve( boundary, copy, intersection_tolerance, overlap_tolerance ) if not intersections: patterncurves.append(copy) #increment horizontal transform trans[0]+=h_space #increment vertical transform trans[1]+=v_space return patterncurves def fillBoundary(crv,boundary, offset, space, random): #returns pattern curves within boundary b_width, b_height, start, boundary = CalcStartCondition(boundary) #determine horizontal and vertical spacing and skew h_space,v_space,h_skew = getSpace(offset, space) # calculate amount of curves needed h_amount=int(b_width/h_space)+1 v_amount=int(b_height/v_space)+1 #create the pattern patterncurves=CreatePatternCurves(v_amount, h_amount, v_space, h_space, h_skew, start, boundary) return patterncurves def OnDynamicDraw(sender, e): #try: random=optRandom.CurrentValue offset=optOffset.CurrentValue space=optSpace.CurrentValue h_space,v_space,h_skew = getSpace(offset, space) patterncurves = fillBoundary(curves, boundary, offset, space, random) for curve in patterncurves: e.Display.DrawCurve(curve, Color.LightCyan, 1) """ except Exception as ex: template = "An exception of type {0} occured. Arguments:\n{1!r}" message = template.format(type(ex).__name__, ex.args) print message return """ def addPatternToRhino(): if boolCanOffset==False: print "couldn't offset curve, used boundary instead" patterncurves = fillBoundary(curves, boundary, offset, space, random) for i in range(0, len(patterncurves)): sc.doc.Objects.AddCurve(patterncurves[i]) sc.doc.Views.Redraw() boundary = rs.GetObject("select boundarycurve to fill", rs.filter.curve) if not boundary: return boundary = rs.coercecurve(boundary) crvs=rs.GetObjects("select curves to use as pattern", rs.filter.curve) if not crvs: return if not boundary.IsClosed: return curves=[] for crv in crvs: crv=rs.coercecurve(crv) crv=fillcrv(crv) curves.append(crv) gp=Rhino.Input.Custom.GetPoint() gp.SetCommandPrompt("pattern properties") optMargin=Rhino.Input.Custom.OptionDouble(0,0,100) gp.AddOptionDouble("margin",optMargin) optRandom = Rhino.Input.Custom.OptionToggle(True, "Off", "On") gp.AddOptionToggle("add_randomness", optRandom) optOffset = Rhino.Input.Custom.OptionInteger(50,0,100) gp.AddOptionInteger("offset_percentage",optOffset) optSpace = Rhino.Input.Custom.OptionInteger(50,0,500) gp.AddOptionInteger("space_percentage",optSpace) gp.DynamicDraw+=OnDynamicDraw #start collecting user options while True: gp.Get() if gp.Result()==Rhino.Input.GetResult.Option: continue break random=optRandom.CurrentValue offset=optOffset.CurrentValue margin=optMargin.CurrentValue space=optSpace.CurrentValue boolCanOffset=True addPatternToRhino() if( __name__ == "__main__" ): RunCommand()
Posts: 3
Participants: 2