Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    Rotate axis?

    Scheduled Pinned Locked Moved PYTHON Development
    10 Posts 0 Posters 2.0k Views
    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.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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/888507

              Disclaimer:
              I'm just learning all of this myself, so my code may not be the most elegant or efficient solution yet 🙂

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  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

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    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

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      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....

                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        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

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