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

    Autokey method

    Scheduled Pinned Locked Moved PYTHON Development
    3 Posts 0 Posters 335 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

      On 04/03/2013 at 06:18, xxxxxxxx wrote:

      I created a method for autokeying object psr changes.
      It seems to work well and behave exactly like in Cinema autokey.

      But maybe some of you much more experienced guys could have a look at the code and tell me if there´s something wrong, missing or could be done in a much better manner.

      It currently works on a single object, I wonder if it would be preferable to call the method within a object list loop or to iterate an object list within the function itself?

          def Autokey(self, obj_list, psr_track, xyz_vector, value, min_value) :  
            self.psr_track = psr_track  
            self.xyz_vector = xyz_vector  
            self.obj_list = obj_list  
            self.value = value  
            self.min_value = min_value  
        
            # Get the psr track type:  
            desc_id = c4d.DescID(c4d.DescLevel(self.psr_track, c4d.DTYPE_VECTOR, 0, ),  
                                 c4d.DescLevel(self.xyz_vector, c4d.DTYPE_REAL, 0))  
            doc = c4d.documents.GetActiveDocument()  
            current_time = doc.GetTime()  
            start_time = doc.GetMinTime()  
            a_track = self.obj_list.FindCTrack(desc_id)  # find the track for selection  
        
            if not a_track:  # no animation yet, sets a key at start time  
                if current_time == start_time:  # if at start time, set no new track/key  
                    return True  
                new_track = c4d.CTrack(self.obj_list, desc_id)  
                a_track = self.obj_list.InsertTrackSorted(new_track)  
                a_track = self.obj_list.FindCTrack(desc_id)  
                a_curve = a_track.GetCurve()  
                keydict = a_curve.AddKey(start_time)  
                key = keydict["key"]  
                key.SetValue(a_curve, self.min_value)  
                a_curve.SetKeyDefault(doc, keydict["nidx"])  
        
            if a_track:  # there is animation  
                a_curve = a_track.GetCurve()  
                keyfind = a_curve.FindKey(current_time)  
        
                if not keyfind:  # if no key is already at current time, set a key  
                    keydict = a_curve.AddKey(current_time)  
                    key = keydict["key"]  
                    key.SetValue(a_curve, self.value)  
                    a_curve.SetKeyDefault(doc, keydict["nidx"])  
                    c4d.EventAdd()  
                    return True  
        
                else:  # if there is a key already, just modify the value  
                    found_key = keyfind["key"]  
                    found_key.SetValue(a_curve, self.value)  
                    c4d.EventAdd()  
                    return True  
            return True
      

      The arguments could be and the method could be called with:

      obj_list = c4d.documents.GetActiveDocument().GetActiveObject()  
      psr_track = c4d.ID_BASEOBJECT_POSITION  
      xyz_vector = c4d.VECTOR_X  
      value = 100 # received form a Number Edit field  
      min_value = 0 # initial value of a Number Edit field  
        
      if c4d.IsCommandChecked(12425) == True: # check for Autokey State  
        Autokey(obj, psr_track, xyz_vector, value, min_value)
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 04/03/2013 at 06:55, xxxxxxxx wrote:

        It depends on what you want the method to do. It'd be a more modular approach letting the function
        work on a single object only, but more generous in most cases to let the function itself do it. However,
        if the algorithm does not include iterating over the other objects, I prefer to not to do it. Keep
        a functions implementation as narrow as possible to its required behavior. Iterating over the other
        objects can still be done outside and if necessary even put into another function.

        -Niklas

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

          On 04/03/2013 at 10:47, xxxxxxxx wrote:

          Thanks Niklas, I´ll keep it single object then.
          For anybody who´s interested, I extended it to get vectors and set keys for all three vector curves, like native autokey does too:

              def Autokey(self, obj, psr_track, value, min_value) :  
                # psr_track can be:  
                # -c4d.ID_BASEOBJECT_POSITION  
                # -c4d.ID_BASEOBJECT_SCALE  
                # -c4d.ID_BASEOBJECT_ROTATION  
                self.psr_track = psr_track  
            
                # single Object input  
                self.obj = obj  
            
                # Values input must be a vector  
                self.value = value  
                self.min_value = min_value  
            
                l_value = [self.value.x, self.value.y, self.value.z]  # vector to x,y,z list for the "for" loop  
                l_min_value = [self.min_value.x, self.min_value.y, self.min_value.z]  # ^  
            
                # Get the psr track type:  
                desc_id_x = c4d.DescID(c4d.DescLevel(self.psr_track, c4d.DTYPE_VECTOR, 0, ),  
                                       c4d.DescLevel(c4d.VECTOR_X, c4d.DTYPE_REAL, 0))  
                desc_id_y = c4d.DescID(c4d.DescLevel(self.psr_track, c4d.DTYPE_VECTOR, 0, ),  
                                       c4d.DescLevel(c4d.VECTOR_Y, c4d.DTYPE_REAL, 0))  
                desc_id_z = c4d.DescID(c4d.DescLevel(self.psr_track, c4d.DTYPE_VECTOR, 0, ),  
                                       c4d.DescLevel(c4d.VECTOR_Z, c4d.DTYPE_REAL, 0))  
            
                l_desc_id = [desc_id_x, desc_id_y, desc_id_z]  # desc_id x,y,z list for the "for" loop  
            
                doc = c4d.documents.GetActiveDocument()  
                current_time = doc.GetTime()  
                start_time = doc.GetMinTime()  
            
                # loop through x-y-z  
                for i in range(0, 3) :  
            
                    a_track = self.obj.FindCTrack(l_desc_id[i])  # find the track for selection  
            
                    if not a_track:  # no animation yet  
                        if current_time == start_time:  # if at doc-start time, set no new track  
                            return True  
                        new_track = c4d.CTrack(self.obj, l_desc_id[i])  
                        a_track = self.obj.InsertTrackSorted(new_track)  
                        a_track = self.obj.FindCTrack(l_desc_id[i])  
                        a_curve = a_track.GetCurve()  
                        keydict = a_curve.AddKey(start_time)  # sets a key at start time  
                        key = keydict["key"]  
                        key.SetValue(a_curve, l_min_value[i])  
                        a_curve.SetKeyDefault(doc, keydict["nidx"])  
            
                    if a_track:  # there is already animation  
                        a_curve = a_track.GetCurve()  
                        keyfind = a_curve.FindKey(current_time)  
            
                        if not keyfind:  # if no key is already at current time, set a key  
                            keydict = a_curve.AddKey(current_time)  
                            key = keydict["key"]  
                            key.SetValue(a_curve, l_value[i])  
                            a_curve.SetKeyDefault(doc, keydict["nidx"])  
            
                        else:  # if there is a key already, just modify the value  
                            found_key = keyfind["key"]  
                            found_key.SetValue(a_curve, l_value[i])  
            
                    c4d.EventAdd()  
            
                return True
          
          1 Reply Last reply Reply Quote 0
          • First post
            Last post