How to move axis to desired matrix without affecting object in python?
-
Hi, i've been searching for this code everywhere and can't get to it..
I'm importing from Rhino a parametric design worked in Grasshopper as .obj for animation purposes but since imported models doesn't import the axis information i'm trying to doing it by coding with python reaching for exporting a csv file with the plane vector information out of grasshopper and put it into each object in c4d.
I'm stuck in the tedious part of just moving the axis and leave the object intact, apparently in c4d python this doesn't work, first you have to move the entire object with his axis in desired place and then reverse the object points to the initial place. I can move object (axis) with this simple code:
op.SetMg(matrixWanted)
but how can i move the object points backwards to the original place considering that the changed matrix involved not just position but also the rotation.I've tried this great threads:
https://developers.maxon.net/forum/topic/11788/move-object-axis-problem-in-python
https://developers.maxon.net/forum/topic/11705/beginner-how-to-set-axis-to-the-bottom-of-a-cube-by-python
I've tried learning something in the Matrix Fundamentals:
https://developers.maxon.net/docs/py/2023_2/manuals/data_algorithms/classic_api/matrix.html#matrix-fundamental
but everything seams to be explained if you have an HPB rotation instead of xyz vectors.Maybe there's a simpler code for this like freezing the object while moving the axis or something, anyway, does someone have a solution?
Regards!
-
@alfredogzz If an object has axis system A, and you want it to get axis system B, but keep the points, you need to multiply each point with A (getting the point out of the A system into the global system), and then multiply it again with the inverse of B (getting the point from the global system to the B system):
import c4d from c4d import gui def main(): # Assuming: Currently selected object is a point object; # next object is a null defining the target coordinates mat = op.GetMg() targetMat = op.GetNext().GetMg() points = op.GetAllPoints() for i,p in enumerate(points): points[i] = ~targetMat * mat * p op.SetAllPoints(points) op.SetMg(targetMat) op.Message(c4d.MSG_UPDATE) c4d.EventAdd() # Execute main() if __name__=='__main__': main()
Note that the multiplication sequence needs to be read from the right to the left.
Learn more about Python for C4D scripting:
https://www.patreon.com/cairyn -
Hi @alfredogzz,
welcome to the Plugin Cafe forum and the Cinema 4D development community! Please have a look at our Forum Guidelines as we have to ask all users to flag their questions with tags. I have added a Python tag (assuming that is the programming environment you are after) to your posting for you, but you have still to add an OS and Cinema 4D version tag yourself. Please also note that providing full solutions is outside of the scope of support (see Forum Guidelines), so it would be best if you could post whatever code you already have.
About your problem, let's assume you have an object
Obj
which has has the "incorrect"c4d.Matrix
, i.e., transform,M_old
and you want to move that transform to the known transformM_new
. Let's also assume that all our transforms are in global space.What you basically have to do is:
- Compute a difference matrix
M_dif
forM_old
andM_new
. One way to do it, is to multiplyM_new
by the inverse ofM_old
, i.e., "untransform"M_new
by the amount ofM_old
. - Multiply all vertices of
Obj
by the inverse ofM_dif
. - Set the global matrix of
O
toM_new
.
Here are some other postings, topics and examples (the first one contains code for pretty much what you want to do) that might be helpful for you regarding this topic:
"Move" the transform of a point object
Setting coordinates for selected faces (Python - Beginner)
Mirroring with Matching or Different AxesIf you import your geometry from Rhino, you might also have to deal with baked normals, i.e., normal tags. Please take a look at this thread for that scenario.
It also noteworthy that Rhino's coordinate system is right-handed with
Z
being up, while Cinema 4D's system is left-handed withY
being up. Handedness of coordinate systems has been discussed in Mirroring with Matching or Different Axes for example.Cheers,
Ferdinand - Compute a difference matrix