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

    Noob question - referencing object

    Scheduled Pinned Locked Moved PYTHON Development
    11 Posts 0 Posters 1.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 03/12/2012 at 12:41, xxxxxxxx wrote:

      Hi, I'm experienced with programming but am green with Python and C4d SDK, so pardon my rudimentary question.
      But, what property do I use to maintain reference to an object even if its name is changed? I've been looking at .GetID(), but I don't think that's what I'm looking for, no?

      Thanks,
      Jim W.

      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/12/2012 at 07:26, xxxxxxxx wrote:

        From where do you want to reference the object? You can usually just store the object reference somewhere (global scope, instance attribute, dictionary, list, whatever)

        -Nik

        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/12/2012 at 07:45, xxxxxxxx wrote:

          Thanks Niklas, but storing the reference is not my challenge. I just don't know where to find the unique identifier, assuming I have several of the same object type. I could put it in the global scope though once I get it.

          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/12/2012 at 08:17, xxxxxxxx wrote:

            There is no identifier for objects in C4D that always stays attached to the object.
            Maxon wants us to keep track of objects by searching for them periodically as needed.
            I think the reasoning for this is because objects often get destroyed and rebuilt using a copy of itself. Thus destroying any hard coded ID# it might have had.

            However...I do have my own little trick(hack) that I've used to give an object a hard coded ID#:

                #This will assign an ID# to your object  
              #To avoid clashing with the ID#'s in C4D...I use negative numbers for this  
              obj = doc.SearchObject("Cube")  
              obj.SetUniqueIP(-55)  
              
              
              #Now that the object has an ID# I can use it as a condition to grab that object  
              first = doc.GetFirstObject()  
              GetIp = first.GetUniqueIP()  
              if GetIp == -55: first.SetBit(c4d.BIT_ACTIVE)  #Only selects the first object if it has IP# -55  
              c4d.EventAdd()
            

            I suppose you could do the same thing with a BaseContainer too.

            It's not something I would use very often. Since the ID will break when the objects changes in certain cases.
            But if you have an object that doesn't change. And you just want a way to reference it. This might be an option.

            -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 04/12/2012 at 08:36, xxxxxxxx wrote:

              Thanks Scott.
              Yes, I've been searching for the objects in the same way. But not assigning the IP like you had. I was looking at that property, but wasn't sure why I would ever need it 🙂
              Guess I'll take a harder look at that one. Thanks again.

              Jim

              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/12/2012 at 09:30, xxxxxxxx wrote:

                I'm not sure why you should not be able to store the reference but need to search for it via it's IP?

                -Nik

                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/12/2012 at 11:55, xxxxxxxx wrote:

                  My concern is that if the end user decides to change the object name I wouldn't want things to break. If I could listen to whether the name is changed, I could reset the reference based on the SearchObject('foo'), but I don't know how to check for any name change. Still learning the SDK.

                  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/12/2012 at 12:21, xxxxxxxx wrote:

                    ids or naming conventions for object identfication can be used for testing purposes at best. use

                    the pointer approach on objects c4d offers. the GUI front-ends for this would be the LinkBox gui
                    and the InExcludeData gui, which both take BaseList2D as inputs.
                    this will allow you to perform any modification on the objects, including their names, without losing 
                    the access to these objects.

                    that little id trick scott showed you there shouldn't be treated as exemplary (no offense). also the
                    BaseDocument.SearchObject()method isn't meant to be used on a large scale. on a script/ non gui 
                    basis you  either loop through all objects and check their attributes/type for identification or you 
                    simply use c4ds selections (c4d.document.BaseDocument).

                    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/12/2012 at 13:52, xxxxxxxx wrote:

                      Ferdinand,
                      The LinkBox, yes, I understand - thank you.

                      For the looping through all objects, would I check for the name attribute if I'm making a replicator that has an incremental naming system? Or is there another attribute that I would check in order to perform operations on each item individually?

                      As I have it, I am replicating a null with nested objects. Each new object is named with an incremental number suffix (_0 to _n). I can also remove some or add more. I am also performing both identical and unique operations on each replicant as well. Therefore I have been looping and using the .SearchObject method.

                      Again, I am just learning the C4d SDK.

                      I welcome your thoughts and opinions, as I work through this.

                      I appreciate it.
                      Thank you,

                      Jim

                      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/12/2012 at 15:31, xxxxxxxx wrote:

                        Originally posted by xxxxxxxx

                        For the looping through all objects, would I check for the name attribute if I'm making a replicator that has an incremental naming system?

                        i meant more a property / type driven selection. the most basic element of all c4d objects, 
                        the c4d.Atom, provides a GetType() / CheckType() method with which you could make some 
                        basic decisons. Is a material, is it a shader, is polygon object or is a MoGraph Shader Effector ?

                        if (myObject.GetType() == c4d.Onull) :
                        	doSomething()
                        

                        on the other hand there are the properties of the object (the settings shown in the attribute 
                        manager) which you access with the bracket syntax. this goes down to the the c4d.BaseContainer 
                        and c4d.DescID system.

                        while (myObject[myBooleanProperty]) :
                        

                        On your specific task - it is quite difficult to understand what you want to achieve (at least for me),
                        it sounds a bit like some rigging stuff. however, using object names as object identificator is really 
                        unsafe and should be avoided at all cost. for massive object references use InExcludeData which is
                        named a bit misleading, because it is just a list of object (GeListNode) links.

                        if this all doesn't help, please tell us more precisely what you want to do and where the objects 
                        are coming from. when you import some super massive rig from somewhere the user will have to
                        do some mapping (LinkBox) or you will have to rely un propper naming. when you create the
                        objects yourself just use some form reference as nikklas wrote.

                        last but not least some very basic but commented example:

                        import c4d
                          
                        def main() : 
                            # a list to store our objects   
                            myObjectList = []
                            
                            # create some objeccts
                            for n in range(10) :
                                # a parametric cube
                                myCube = c4d.BaseObject(c4d.Ocube)
                                # a display tag
                                myTag = c4d.BaseTag(c4d.Tdisplay)
                                # attach the tag to the cube
                                myCube.InsertTag(myTag)
                                
                                # add both to a local list
                                myObjectList.append(myCube)
                                myObjectList.append(myTag)
                                
                                # insert cube with the tag into the document
                                doc.InsertObject(myCube)
                                
                            # update the gui, the objects are now in the document  
                            c4d.EventAdd()
                            
                            # from somewehre else we want to access our objects and we have 
                            # this list, but we do not know that it contains cube and display tags in a
                            # alternating order, we only know it is a list of c4d.Atoms ,which might also
                            # contain other stuff. so we loop through it and check every object.
                            
                            # some initial vector for the cube size
                            size = c4d.Vector (25,25,25)
                            
                            # loop through the data
                            for n in myObjectList:
                                # if it is a cube set its size and increment the size by factor 1.1
                                if (n.GetType() == c4d.Ocube) :
                                    n[c4d.PRIM_CUBE_LEN] = size
                                    size *= 1.1
                                # if it is a display tag activate the force shading mode and set it to lines
                                if (n.GetType() == c4d.Tdisplay) :
                                    n[c4d.DISPLAYTAG_AFFECT_DISPLAYMODE] = True
                                    n[c4d.DISPLAYTAG_SDISPLAYMODE] = 6
                                    
                        if __name__=='__main__':
                            main()
                        

                        ps : just to be clear, this is a working script example .

                        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 05/12/2012 at 09:21, xxxxxxxx wrote:

                          Ferdinand,
                          I see your method and I understand.
                          Thank you for taking the time to explain so clearly.

                          Yes, I have seen this approach before, and I think that it's not specific enough for my needs, as I will have multiple deformers that I'll be adjusting dynamically – say a couple arrays of bend deformers that will bend from a low value to a high value based on some condition.

                          Perhaps once I develop my code to a further point, I will share and hope for feedback on how to improve it, yes? That would be great and helpful.

                          Thanks again for the time and effort to help me learn.

                          Jim

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