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://plugincafe.maxon.net/topic/11788/move-object-axis-problem-in-python
    https://plugincafe.maxon.net/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/Cinema4DPythonSDK/html/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!
    Captura de Pantalla 2021-01-26 a la(s) 17.46.27.png
    Captura de Pantalla 2021-01-26 a la(s) 17.46.05.png



  • @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 transform M_new. Let's also assume that all our transforms are in global space.

    What you basically have to do is:

    1. Compute a difference matrix M_dif for M_old and M_new. One way to do it, is to multiply M_new by the inverse of M_old, i.e., "untransform" M_new by the amount of M_old.
    2. Multiply all vertices of Obj by the inverse of M_dif.
    3. Set the global matrix of O to M_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 Axes

    If 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 with Y being up. Handedness of coordinate systems has been discussed in Mirroring with Matching or Different Axes for example.

    Cheers,
    Ferdinand


Log in to reply