Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Move object axis problem in python

    Cinema 4D SDK
    python
    3
    9
    2.1k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • gheyretG
      gheyret
      last edited by

      Hi, guys! i'm a new python guy and i want to move my object axis only, like center axis tool .and now i can move the axis on Y axis like this:
      it's work fine
      Work Fine.gif
      but if i rotate the object , it's have a problem(I don't know why i can't upload my next GIF).

      I think this is a matrix problem, but matrix a little bit hard for me ,i have no idea how to fix it.
      Hope you guys can help me.☹

      This is my code:

      import c4d
      
      
      def main():
          obj = doc.GetActiveObject()
          axis_offset = c4d.Vector(0,100,0)
          
          points = obj.GetAllPoints()
          count = obj.GetPointCount()
          obj_pos = obj.GetAbsPos()
          
          doc.AddUndo(c4d.UNDOTYPE_CHANGE,obj)
          for i in xrange(len(points)):
              points[i] = points[i] + (axis_offset*-1)
              obj.SetAllPoints(points)
              obj.SetAbsPos(obj_pos+axis_offset)
              
          obj.Message(c4d.MSG_UPDATE)
          c4d.EventAdd()
          
      if __name__=='__main__':
          main()
      

      www.boghma.com

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi,

        I am a bit confused regarding what your actual question is, since your code does not contain any matrix operations. I assume you want to know how matrix transforms work, so that you can construct one? You can check the ScratchPixel section on matrices, they have a pretty good explanation on how you can define transforms with matrices (if you don't already know what vectors are you should probably read that chapter too, especially regarding the geometric meaning of the cross product). Note that practically every software has a slightly different interpretation of transformation matrices, so read ScratchPixel more as a general guide.

        c4d.utils defines three functions to construct a rotation matrix axis by axis, the example also modifies the offset component of the final rotation matrix so that it also translates points by 100 units along the y axis.

        90_DEGREE = math.pi * .5
        # construct a rotation matrix for each axis.
        mg_x = c4d.utils.MatrixRotX(90_DEGREE)
        mg_y = c4d.utils.MatrixRotY(0)
        mg_z = c4d.utils.MatrixRotZ(-90_DEGREE)
        
        # multiplying matrices will give you a matrix which combines all transformations
        my_final_transform = mg_x * mg_y * mg_z
        # set the offset
        my_final_transform.off = c4d.Vector(0, 100, 0)
        
        # transform a point in global space
        some_point_in_global_space = c4d.Vector(100, 0, 0)
        transformed_point = my_final_transform * some_point_in_global_space 
        

        You can also construct matrices manually if you have one or multiple normals (or vectors if you also want to scale stuff), using the cross product:

        # note that the x and y components are switched, so we rotate by 90 degree on
        # the axis orthogonal to the xy-plane (the z axis).
        x_component = c4d.Vector(0, 1, 0)
        # the y component is not an unit vector so we scale by 2 on that axis
        y_component = c4d.Vector(2, 0, 0)
        # define the z axis manually
        z_component = c4d.Vector(0, 0, 1)
        # or construct it using the x and y component
        z_component = x_component.Cross(y_component).GetNormaliezd()
        # the offset (the translation component) for the matrix
        off_component = c4d.Vector(100, 0, 0)
        # build the matrix
        my_transform = c4d.Matrix(off_component, x_component, y_component, z_component)
        
        #do stuff with it
        transformed = []
        for p in points:
            transformed.append(my_transform * p)
        

        Cheers
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        gheyretG 1 Reply Last reply Reply Quote 0
        • gheyretG
          gheyret @ferdinand
          last edited by

          @zipit
          Thank you very much for your reply. Maybe I did not describe the problem clearly. Actually, the problem I encountered is like this:

          For example : if i use rotate tool rotate my object and click my script.
          1.the axis can move correctly.
          2.but the object moves with it.(this is my problem)

          I don't want my objects to move,and I want my object to stay in place and only move the object axis

          thank you again.
          Cheers
          harry

          www.boghma.com

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by ferdinand

            Hi,

            well then you have to apply the invers of the translation you have applied to your points also to your object. Something like this:

            my_vector = c4d.Vector(0, 100, 0)
            
            for i, p in enumerate(points):
                points[i] = p + my_vector
            
            my_object.SetAllPoints(points)
            my_object.SetRelPos(my_object.GetRelPos() - my_vector)
            

            Cheers
            zipit

            MAXON SDK Specialist
            developers.maxon.net

            gheyretG 1 Reply Last reply Reply Quote 0
            • gheyretG
              gheyret @ferdinand
              last edited by gheyret

              @zipit
              yes it works. but if you object is rotated on X axis 90 degrees, and click the script ,something is wrong...

              www.boghma.com

              ferdinandF 1 Reply Last reply Reply Quote 0
              • ferdinandF
                ferdinand @gheyret
                last edited by ferdinand

                @gheyret said in Move object axis problem in python:

                @zipit
                yes it works. but if you object is rotated on X axis 90 degrees, and click the script ,something is wrong...

                I do not have C4D here, so i cannot run your code, also "something is wrong" is a rather vague description.

                However, if you rotate your object you have to respect the matrix of that object when reapplying the invers of your vector (since you are operating in local coordinates for vertices). See my examples on matrices above. There are methods to get and set global and local matrices of objects in c4d.BaseObject.

                Cheers
                zipit

                MAXON SDK Specialist
                developers.maxon.net

                gheyretG 1 Reply Last reply Reply Quote 0
                • gheyretG
                  gheyret @ferdinand
                  last edited by

                  @zipit
                  Thanks for everything. You're really been a big help for me.
                  It works!!!

                  Cheers
                  Harry

                  www.boghma.com

                  1 Reply Last reply Reply Quote 0
                  • r_giganteR
                    r_gigante
                    last edited by

                    Hi Harry, thanks for reaching out us.

                    With regard to your topic, as suggested by @zipit - thanks a lot dude -, I strongly recommend in having a look at geometry fundamentals as presented in ScratchPixel or in our documentation at Matrix Fundamentals.

                    Taking in consideration the global object orientation in space you could reconsider your code to use the inverse global matrix directly applied to your offset vector.

                        # set the offset vector
                        myOff = c4d.Vector(0,-100,0)
                        
                        # check op is valid and assume it's already a mesh
                        if op is None:
                            return
                        
                        # retrieve object global inverse matrix
                        invOpMg = ~(op.GetMg())   
                        
                        #get the mesh points 
                        points = op.GetAllPoints()
                        
                        # browse over them and add the offset vector left multiplied by the inverse global matrix
                        for i,p in enumerate(points):
                            points[i] = p + invOpMg*myOff
                            
                        # set points and update
                        op.SetAllPoints(points)
                        op.Message(c4d.MSG_UPDATE)
                        c4d.EventAdd()
                    

                    Best, Riccardo

                    gheyretG 1 Reply Last reply Reply Quote 0
                    • gheyretG
                      gheyret @r_gigante
                      last edited by

                      @r_gigante
                      Yes! It's really helpful.🍻

                      www.boghma.com

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post