[Closed] How to rotate subobjects using script ?
How do you rotate a face or an edge by script?
I did a lot of search on this but only found the questions unanswered.
Moving is simple as there is a move function, and it shows in listner whenever you move a face etc, but nothing for rotate and scale.
Thanks in advance.
Technically speaking, there is no such thing as rotating or scaling vertices, they are just being cunningly moved to simulate scale and rotation. There are, however, rotate and scale functions that work in pretty much the same way as move, you could try that.
I have asked this too. I believe this involves using a matrix. The only example I have seen is in CSPolytools’ “Vert Rotate”, but I am not entirely clear how it works. Would be nice to have a better example for the more mathematically challenged among us.
Somebody asked on the Max Support Forum how to rotate a polygon at 45 degrees about its normal. (This involves rotating all its vertices around a vector)
Here is the simple example from that thread:
(
angle = 45 --the angle to rotate at
selected_faces = (polyOp.getFaceSelection $) as array --the selected polygons
center_face = polyOp.getFaceCenter $ selected_faces[1] --the center of the first polygon
transform_mat = matrixFromNormal (polyOp.getFaceNormal $ selected_faces[1]) --create a matrix using the normal
transform_mat.row4 = center_face --move matrix to center of polygon
face_vertices = (polyOp.getVertsUsingFace $ selected_faces[1]) as array --get the verts of polygon 1
for v in face_vertices do --for every vertex in the first polygon,
(
in coordsys transform_mat vertex_position = (polyOp.getVert $ v) --get vertex in the matix coordinates
RotateZ = (rotateZMatrix angle) * transform_mat -- create a Rotation matrix, transform in the space of the Normal's matrix
polyOp.setVert $ v (vertex_position * RotateZ) --transform the vertex using the new matrix
)
)
Thanks a lot Bobo, it works.
Looks kinda convoluted, but if I pack it in a function which takes the face-seclection and angle as arg, it should do the job neatly.
Ok. So if I wanted to rotate a vertex selection 45 degrees I could do this:
(
selCenter = [0,0,0]
angle = 45
local vertsToMove = #()
-- get selected verts in array
for i = 1 to $.selectedVerts.count do
(
append VertsToMove $.selectedVerts[i].index
)
--find vertex selection center and create matrix about it
for i = 1 to $.selectedverts.count do
(
selCenter += (polyop.getvert $ $.selectedverts[i].index)
)
selCenter /= $.selectedverts.count
transform_mat = transMatrix selCenter
-- rotate matrix and verts with it
for v =1 to $.selectedverts.count do --for every vertex in the selection
(
in coordsys transform_mat vertex_position = (polyop.getVert $ VertsToMove[v]) --get vertex in the matix coordinates
RotateZ = (rotateZMatrix angle) * transform_mat -- create a Rotation matrix, transform in the space of vertex selection center matrix
polyop.setVert $ VertsToMove[v] (vertex_position * RotateZ) --transform the vertex using the new matrix
)
update $
)
This Would be in world coordinates, But we want local object coordinates?
For elements, perhaps we could convert the selection to verts, rotate like this then,
convert it back.
Maybe there is a simpler way then I have here…
Here is a shorter version:
(
angle = 45
vertsToMove = $.selectedVerts
selCenter = [0,0,0]
for v in vertsToMove do selCenter += polyop.getvert $ v.index
selCenter /= vertsToMove.count
transform_mat = transMatrix selCenter
rot_mat = (rotateZMatrix angle) * transform_mat
for v in vertsToMove do
(
in coordsys transform_mat vertex_position = (polyop.getVert $ v.index)
polyop.setVert $ v.index (vertex_position * rot_mat )
)
)
No, this is not necessarily in World coordinates. The reason it IS right now is because the transMatrix is aligned to the world coordinate system and only row4 is translated to the position of the vertex center.
Here is the same in object’s local coordinates:
(
angle = 45
vertsToMove = $.selectedVerts
selCenter = [0,0,0]
for v in vertsToMove do selCenter += polyop.getvert $ v.index
selCenter /= vertsToMove.count
transform_mat = $.transform --get the node's TM
transform_mat.row4 = selCenter --move the TM to the sel.center. Orientation of local Z remains the same!
rot_mat = (rotateZMatrix angle) * transform_mat --rotation matrix is now in local coords!
for v in vertsToMove do
(
in coordsys transform_mat vertex_position = (polyop.getVert $ v.index)
polyop.setVert $ v.index (vertex_position * rot_mat )
)
)
OK heres a modification…
The rotateface function rotates the selcted faces about their respective centers through all x y z axes.
[Btw: I wanted to add an option to rotate about the selection center, but dont know how]
fn rotateface rx ry rz selected_faces =
(
for f=1 to selected_faces.count do --for every face
(
center_face = polyOp.getFaceCenter $ selected_faces[f] --the center of the first polygon
transform_mat = matrixFromNormal (polyOp.getFaceNormal $ selected_faces[f]) --create a matrix using the normal
transform_mat.row4 = center_face --move matrix to center of polygon
face_vertices = (polyOp.getVertsUsingFace $ selected_faces[f]) as array --get the verts of polygon 1
for v in face_vertices do --for every vertex in the first polygon,
(
in coordsys transform_mat vertex_position = (polyOp.getVert $ v) --get vertex in the matix coordinates
RotateXYZ = (rotateYPRMatrix rx ry rz) * transform_mat -- create a Rotation matrix, transform in the space of the Normal's matrix
polyOp.setVert $ v (vertex_position * RotateXYZ) --transform the vertex using the new matrix
)--for v
)--for f
)--fn rotateface
--main body
(
selfaces = (polyOp.getFaceSelection $) as array --the selected polygons
rotateface 20 60 30 selfaces
)