Hi everybody,
I’d like to make a script that dispatch selected objects along a grid.
I used to do this with grasshopper by evaluating a source plane on each object, then orient them along a grid of target planes.
But now, I’d be interrested in adapting the workflow to the Rhino UI and give access to that command to other users without going through Grasshopper.
As a start, I was thinking of imitating the ArrayLinear command to define the target planes. After selecting every object to move, the user would then define the direction and the interval of the dispatch. Then, each object would move to its new place with the same properties, name and GUID.
Do you know how I can start a script which would replicate that linear matrix command using python script?
Thanks for your help.
The Array command doesn’t do what you want? Or have I misunderstood the need? --Mitch
Hi Mitch,
The array command copies one single object along a set of points. My aim is to move multiple different object to as many positions aligned and dispatched like the Array command or ArrayLinear command would do.
No, you can Array as many objects as you want in one shot… --Mitch
Yes you’re right. What I meant is that with Array command, the set of source objects will be copy toward each target point. Whereas, i’d like to consider every object of the source object list and dispatch them along a grid, one object to one location.
See the picture in my previous post : I have 5 objects on my source list (on the left) and I get 5 objects as a result (on the right), wheras Array command would have created 25 objects.
OK, understood. How do you know what object goes to what grid point?
It concerns another part of the program, where I’ll have to sort my source list. But it doesn’t really matter because if I move objects, instead of copying them, they’ll keep there own properties so they’ll have same IDs. I may insert lots of other things in the process, such as text annotations which could reflect the object’s name for example. The final is to help for the drawing layout process.
All of this still need to be figured out, the most complex part for me is to reproduce the user interaction (with ghost shapes) of the Array command. I could probably do it with a more basic process but I was wondering how it works and if it’s possible to access to that command code. Maybe somebody has already done something like this ?
Here is what I get for the moment :
import rhinoscriptsyntax as rs
#Select object to dispatch
objectList = rs.GetObjects("Select object to dispatch", rs.filter.polysurface, preselect = True)
#Count object list
objectListCount = len(objectList)
logText = "Selected Objects: {0}".format(objectListCount)
print logText
#Set the dispath pattern
line = rs.GetLine()
intervalVec = rs.VectorCreate(line[1], line[0])
#Move each object to its new destination
index = 0
for object in objectList:
startPoint = rs.BoundingBox(object)[0]
endPoint = line[0] + index*intervalVec
translation = rs.VectorCreate(endPoint, startPoint)
rs.MoveObject(object, translation)
index += 1
I have something like this, using bounding box bottom center to align objects, many other possibilities :
import rhinoscriptsyntax as rs
def TestArrayObjsAlongVector():
objs=rs.GetObjects("Select objects to array",preselect=True)
if not objs: return
m1="Pick start point for array"
m2="Pick point along array direction"
pts=rs.GetPoints(True,message1=m1,message2=m2,max_points=2)
if not pts or len(pts)!=2: return
space=rs.GetReal("Spacing between object centers?")
if space is None: return
move_vec=pts[1]-pts[0]
move_vec.Unitize()
next_start_pt=pts[0]
for obj in objs:
rs.AddPoint(next_start_pt)
bb=rs.BoundingBox(obj)
bot_ctr_pt=(bb[0]+bb[2])/2
rs.MoveObject(obj,next_start_pt-bot_ctr_pt)
next_start_pt=next_start_pt+(space*move_vec)
TestArrayObjsAlongVector()
–Mitch
Thank you, we both write something similar.
Let me know if you have an example with the dynamic shaded shape.