I am trying to write a simple move and rotate utility command to speed up some of the tasks we do at work very often.
Here is what I am trying to get it to do.
Step1 - Prompted to select objects, then ask for offset distance.
Step2 - Copy object in -Y direction with a predefined offset distance in between the 2 objects
Step3 - Rotate object from Step 2 Down
Step4 - Copy object from Step3 in +X direction with a predefined offset distance
Step5 - Rotate object from Step4 on Y axis
Step6 - Repeat all over again until out of selected objects
I’ve made 2 functions
1 for moving in either X or Y direction
1 for rotating on either X or Y axis
Both functions and both parts of the function work independently on multiple objects at once.
I cannot figure out how to string along the while loop (or some other loop method for that matter) correctly. So it runs all the functions on one object then moves to the next object.
Attaching some print screens to illustrate the final result
Here is what I got for code…
import rhinoscriptsyntax as rs
__commandname__ = "viMoveAndRotate"
# RunCommand is the called when the user enters the command name in Rhino.
# The command name is defined by the filname minus "_cmd.py"
def RunCommand( is_interactive ):
print "Running", __commandname__
ids = rs.GetObjects(message = "Select objects to move and rotate", group = True, preselect = True)
offsetDistance = rs.GetReal("Offset Distance", 10, 1.0)
if not ids: return
def vi_moveObject(_id, mDir, mDist):
if _id:
bb = rs.BoundingBox(_id)
if mDir == 'X':
sizeX = bb[1].DistanceTo(bb[0])
sizeZ = bb[4].DistanceTo(bb[0])
translateX = ((sizeX/2) + offsetDistance + (sizeZ/2))
trDir = [translateX, 0, 0]
if mDir == 'Y':
sizeY = bb[3].DistanceTo(bb[0])
translateY = -(sizeY + offsetDistance)
trDir = [0, translateY, 0]
rs.CopyObject(_id, trDir)
def vi_rotateObject(_id, rDir):
if _id:
centroid = rs.SurfaceVolumeCentroid(_id)[0] #need a better center finding method
# Rotation on X axis
if rDir == 'Down':
angle = 90
axis = [1,0,0]
# Rotation on Y axis
if rDir == 'Right':
angle = -90
axis = [0,1,0]
rs.RotateObjects(_id, centroid, angle, axis, copy=False) #True is for test only remove later
print 'Selection Length', len(ids)
i = 0
while i < len(ids):
vi_moveObject(ids[i], 'Y', offsetDistance)
vi_rotateObject(ids[i], 'Down')
vi_moveObject(ids[i], 'X', offsetDistance)
vi_rotateObject(ids[i], 'Right')
print i
i+=1
# you can optionally return a value from this function
# to signify command result. Return values that make
# sense are
# 0 == success
# 1 == cancel
# If this function does not return a value, success is assumed
return 0
if __name__ == "__main__":
RunCommand(True)
I am sure it’s evident, but I am super new to python or anything that has to do with classes
I am trying to do my best and use functions instead of writing something sloppy. I am sure what I have is sloppy either way, but from all the reading about def and classes I am just trying to wrap my head around it all.
The goal is to be able to feed 100+ objects at a time…
In advance, thank you for your help!