Rotate axis?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 01/04/2011 at 10:12, xxxxxxxx wrote:
Hi,
I'm trying to convert my Coffee code that rotates the axis of an object to Python. But my Coffee example uses two functions called GetMulM() & GetMulP(). Which aren't in the Python SDK.
import c4d from c4d import gui def main() : newMatrix = c4d.Matrix(c4d.Vector(45), c4d.Vector(0), c4d.Vector(0), c4d.Vector(0)) obj = doc.GetActiveObject() points = obj.GetAllPoints(); count = obj.GetPointCount(); mLocal = obj.GetMl() # the local matrix mGlobal = mLocal.GetMulM(newMatrix) # <------How to do this with python? obj.SetMl(mGlobal) invertedMatrix = newMatrix.GetClone() invertedMatrix.Invert() for i in range(len(points)) : points[i] = invertedMatrix.GetMulP(points[i]) # <------How to do this with python? # Write the points back to the object. obj.SetPoints(points) obj.Message(MSG_UPDATE) c4d.EventAdd() if __name__=='__main__': main()
Does anyone know how to convert this to Python?
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 01/04/2011 at 18:24, xxxxxxxx wrote:
Hi Scott,
You can multiply a matrix using the '*' operator. You can invert a matrix using the '~' operator before the matrix.
The following pieces are what you're missing:
#mGlobal = mLocal.GetMulM(newMatrix) # <------How to do this with python? mGlobal = mLocal * newMatrix
invertedMatrix = copy.copy(newMatrix) invertedMatrix = ~invertedMatrix #The '~' operator inverts a matrix
#points[i] = invertedMatrix.GetMulP(points[i]) # <------How to do this with python? points[i] = invertedMatrix * points[i]
Note: I'm not great with matrix math, so someone please correct me if I'm wrong here. My above answer was generated by poking around in the COFFEE & Python SDKs and online docs.
Cheers,Donovan
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 02/04/2011 at 08:52, xxxxxxxx wrote:
Thanks Donovan,
That gets me a little bit closer. But using straight multiplication on the points crushes them all down to the same vector(0,0,0) position.
The two Coffee functions I used must have something inside of them that does more than multiplication.Here's my code:
import c4d from c4d import gui def main() : newMatrix = c4d.Matrix(c4d.Vector(45), c4d.Vector(0), c4d.Vector(0), c4d.Vector(0)) obj = doc.GetActiveObject() points = obj.GetAllPoints(); count = obj.GetPointCount(); mLocal = obj.GetMl() # the local matrix mGlobal = mLocal * newMatrix obj.SetMl(mGlobal) invertedMatrix = ~newMatrix #The '~' operator inverts a matrix for i in range(len(points)) : points[i] = invertedMatrix * points[i] # Write the points back to the object. obj.SetAllPoints(points) obj.Message(c4d.MSG_UPDATE) c4d.EventAdd() if __name__=='__main__': main()
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 02/04/2011 at 10:50, xxxxxxxx wrote:
Got it!
Since python does things a little differently. I dumped my Coffee code and started from scratch.Thinking about how global point positions are calculated by multiplying their local positions by the object's matrix.
I finally came up with the code to rotate the axis, and then move the points back to their previous global positions.import c4d from c4d import * def main() : RotAmount = c4d.Vector(0,.4,0) op.SetRelRot(RotAmount) matrix = op.GetMg() inverted = ~matrix points = op.GetAllPoints() for i in range(len(points)) : points[i] = points[i]* inverted op.SetAllPoints(points) op.Message(c4d.MSG_UPDATE) c4d.EventAdd() if __name__=='__main__': main()
-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/04/2011 at 14:07, xxxxxxxx wrote:
I asked the exact same questions (equivalent of GetMulP and Rotate axis) a few days ago.
For completeness here's the links to the posts:https://developers.maxon.net/forum/topic/5610/5639_how-to-rotate-just-the-axis
https://developers.maxon.net/forum/topic/5618/5648_equivalent-of-getmulp-But I think your solution is far better since you avoid MatrixToHPB(HPBToMatrix()) roundtrips. Gotta try this right away.
Also, over at CGTalk I have a post going in the script resources thread where I post all my Python Helper functions as I come across them.
It's a bit of the same spirit as the COFFEE bible just without nice wordings and context
I'll post it as gist, since it's better to read...
https://gist.github.com/888507Disclaimer:
I'm just learning all of this myself, so my code may not be the most elegant or efficient solution yet -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/04/2011 at 20:01, xxxxxxxx wrote:
And I think now I know why my rotate axis solution isn't working as great as yours.... GetRelRot returns verbatim what the coordinate manager shows for rotation of an object, whereas MatrixToHPB returning Euler angles, often times has more than one "solution" that it can return, namely the angle as recorded in the coordinate manager or 360 degrees - the angle as recorded in the coordinate manager.
Now using GetRelRot, I should be able to get rid of the recursion in my function. It was always striking me as odd that I needed this.
Code smelled funny as they say.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/04/2011 at 20:38, xxxxxxxx wrote:
Scott, can I add your function to my Helpers class?
With credits, of course.Oh and btw, I would add a check at the beginning of the function if the current rotation is already the desired new axis rotation, because if you execute the function twice on an object with the same desired rotation, the second time the axis wont move but the points will.
def SetAxisRotation(op, rot, local=False) : """ Set the rotation of the object axis (i.e. keeping points in place). obj object rot vector Courtesy of Scott Ayers, source: https://developers.maxon.net/forum/topic/5632/5663_rotate-axis&PID;=23480#23480 """ if op is None: return False if not isinstance(rot, c4d.Vector) : raise TypeError("expected c4d.Vector, got %s" % type(rot)) currot = op.GetRelRot() if VectorEqual(currot, rot) : return op.SetRelRot(rot) if local is True: mat = op.GetMl() else: mat = op.GetMg() inv = ~mat points = op.GetAllPoints() for i in range(len(points)) : points[i] = points[i] * inv op.SetAllPoints(points) op.Message(c4d.MSG_UPDATE) c4d.EventAdd()
VectorEqual needs
from c4d.utils import *
Andre
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/04/2011 at 21:02, xxxxxxxx wrote:
Sure Andre.
That's fine with me.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 03/04/2011 at 21:34, xxxxxxxx wrote:
Does it work reliably for you if the object is already rotated?
My function will do it, but it needs like 10 recursions or more to get there... hm....
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 04/04/2011 at 08:09, xxxxxxxx wrote:
It works fine the first time for me.
But....
I just noticed that this is a one shot deal.
It works the first time. But if you try to run the script again with a different vector value. The points will also rotate with the matrix for some strange reason!?
It's as if the script skips over the whole get-move point routine for some reason.I guess it still needs more work.
-ScottA