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

    Rotating Spline Points

    Cinema 4D SDK
    s22 python sdk
    3
    8
    1.6k
    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.
    • ?
      A Former User
      last edited by A Former User

      Hello!

      Does anyone know how to rotate all of the points of a spline in Python?

      1 Reply Last reply Reply Quote 0
      • CairynC
        Cairyn
        last edited by

        There is a long chapter on matrix operations in the docs:
        https://developers.maxon.net/docs/py/2023_2/manuals/data_algorithms/classic_api/matrix.html?highlight=rotation
        Build a matrix (for the correct reference system, center, and rotation axis) and multiply it with the points in question.

        Note: If you are using Bezier splines, there are tangents. These also need to be transformed, but keep in mind that tangents are vectors starting at the point, not at the object center.

        1 Reply Last reply Reply Quote 0
        • CairynC
          Cairyn
          last edited by

          Note that c4d.utils contains the most matrix building functions:
          c4d.utils.MatrixRotX(w)
          c4d.utils.MatrixRotY(w)
          c4d.utils.MatrixRotZ(w)
          c4d.utils.MatrixToRotAxis(m)
          c4d.utils.RotAxisToMatrix(v, w)

          etc.

          https://developers.maxon.net/docs/py/2023_2/modules/c4d.utils/index.html

          1 Reply Last reply Reply Quote 0
          • ?
            A Former User
            last edited by A Former User

            Hi @Cairyn,
            Thank you very much for the reply and for pointing me to the utils. I am familiar with the Matrix documentation, however, I'm not sure how to multiply the points & tangents of my Spline by the target Matrix and apply the result. I know how to get the vectors of the Point, Left Tangent, & Right Tangent, but what comes next?

                    pointCount = obj.GetPointCount()
                    interpolation = obj.GetInterpolationType()
            
                    if interpolation == c4d.SPLINETYPE_BEZIER:
                        for i in range(0,pointCount):
                            point = obj.GetPoint(i) #Point Vector
                            tangent = obj.GetTangent(i)
                            vl = tangent['vl'] #Left Tangent Vector
                            vr = tangent['vr'] #Right Tangent Vector
            

            Thank you.

            1 Reply Last reply Reply Quote 0
            • CairynC
              Cairyn
              last edited by

              You multiply all the points with the desired transformation matrix.
              For the tangents, you need to bring them into the transformation center before multiplying, and afterwards you bring them back to the point (note: the new position of the point).

              In short:

              import c4d
              from c4d import gui
              
              def main():
                  pointCount = op.GetPointCount()
                  mat = c4d.utils.MatrixRotX(c4d.utils.DegToRad(45.0))
                  for i in range(0,pointCount):
                      point = op.GetPoint(i) #Point Vector
                      tangent = op.GetTangent(i)
                      vl = tangent['vl'] #Left Tangent Vector
                      vr = tangent['vr'] #Right Tangent Vector
                      print point
                      
                      vl = (vl - point) * mat
                      vr = (vr - point) * mat
                      point = point * mat
                      vl = vl + point
                      vr = vr + point
                      op.SetTangent(i, vl, vr)
                      op.SetPoint(i,point)
                  op.Message (c4d.MSG_UPDATE)
                  c4d.EventAdd()
              
              if __name__=='__main__':
                  main()
              

              (I removed all tests for object type etc so call this only on a proper bezier curve!)

              Here, I define the transformation matrix as rotation around X by 45 degrees.
              Then I go through the points (your code) and do the transformation for the point and its tangents as mentioned.

              The challenge may be to assemble the transformation matrix if you want a different rotation axis than X, Y, or Z... but you didn't mention what axis, so I stay with X 😊


              Learn more about Python on C4D:
              https://www.patreon.com/cairyn
              (Matrix transformations haven't been handled yet but will follow soon...)

              1 Reply Last reply Reply Quote 0
              • ?
                A Former User
                last edited by A Former User

                @Cairyn
                It works! πŸ˜„ This was VERY helpful, thank you!!!

                1 Reply Last reply Reply Quote 0
                • N
                  nophoto
                  last edited by nophoto

                  You don't have to compensate the position of the tangent, if you use

                  c4d.Matrix.MulV(self, v)
                  

                  to transform the direction vector.

                  import c4d
                  from c4d import gui
                  
                  def main():
                      pointCount = op.GetPointCount()
                      mat = c4d.utils.MatrixRotX(c4d.utils.DegToRad(45.0))
                      for i in range(0,pointCount):
                          
                          point = op.GetPoint(i) #Point Vector
                          point = point * mat
                                 
                          tangent = op.GetTangent(i)
                          vl = tangent['vl'] #Left Tangent Vector
                          vr = tangent['vr'] #Right Tangent Vector
                          
                          vl = mat.MulV(vl)
                          vr = mat.MulV(vr)
                       
                          op.SetPoint(i,point)
                          op.SetTangent(i, vl, vr)        
                          
                      op.Message (c4d.MSG_UPDATE)
                      c4d.EventAdd()
                  
                  if __name__=='__main__':
                      main()
                  
                  ? 1 Reply Last reply Reply Quote 0
                  • ?
                    A Former User @nophoto
                    last edited by

                    @nophoto Very nice! Thank you πŸ†

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