Instancing Objects from one DOC ... [SOLVED]



  • On 10/10/2014 at 11:19, xxxxxxxx wrote:

    Hi All,

    I am new to C4D python, but not python itself. I have a series of road tiles in one C4D document. I want to write a script that constructs a drivable road from the pieces in another document.

    Are there any examples on how to reference an object in one document and make an instance copy in another document?

    Any examples on creating instanced objects would be helpful.

    Thanks.



  • On 10/10/2014 at 16:26, xxxxxxxx wrote:

    Xrefs



  • On 13/10/2014 at 09:40, xxxxxxxx wrote:

    Ah, a one word reply...thanks Shawn.

    This is a python question, however. Does anyone have any working code?



  • On 13/10/2014 at 14:29, xxxxxxxx wrote:

    Let's say that you have a scene called objects.c4d saved on your desktop.
    And you wanted to copy and load a specific object named "Sphere" from it into your current scene.

    This is very basic script with no error checking. That will do that:

    import c4d,os  
    from c4d import documents  
    from c4d.documents import LoadDocument  
    def main() :  
      
      path = c4d.storage.GeGetC4DPath(c4d.C4D_PATH_DESKTOP)  #Find the path to the desktop  
      path = os.path.join(path,'objects.c4d')                #Add the file name to the path variable  
            
      fn = LoadDocument(path, c4d.SCENEFILTER_OBJECTS)  
        
      #Find the specific object in the file  
      obj = fn.SearchObject("Sphere")  
      
      #Make a copy of it in memory  
      clone = obj.GetClone()    
      
      #Add the copy to your current open scene     
      doc.InsertObject(clone,None,None)   
      
      c4d.EventAdd()  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 14/10/2014 at 13:13, xxxxxxxx wrote:

    Thank you Scott, that looks promising.

    Is there a way to scan the already loaded documents collection?

    Something like...

    for doc in all_documents:
        obj = doc.SearchObject("myObj")
        if obj != None:
            # Continue processing.
    

    I see in the API that I can get the first and active document but what about iterating through all the rest?



  • On 14/10/2014 at 14:51, xxxxxxxx wrote:

    The docs are held in a linked list.
    Use GetNext() and the other Baselist2D functions to traverse it.

    Example:

    import c4d  
    from c4d import documents  
    def main() :  
       
      #Start with the first document  
      doc = documents.GetFirstDocument()  
      
      #Then grab the next ones using a loop  
      while doc:  
          print doc.GetDocumentName()  
          #Search for a specific object here  
          doc = doc.GetNext()  
            
      c4d.EventAdd()      
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 15/10/2014 at 08:39, xxxxxxxx wrote:

    Thanks again for the example code. I notice you are using GetNext() which appears to be undocumented. I expected there would be a get next but when I reviewed the C4D API it is not listed at all.
    http://plugincafe.com/python/

    I ran your example code on the default document that appears when you open C4D. I expected to see one document name printed because that is all that is loaded when you open the C4D appliocation. However, your code produced 2 print lines ("Untitled 1"). I was curious to see what GetNext() returns so I printed the contents of the doc variable and sure enough it was None.

    I altered your code so it was more clear that the while should stop when the doc variable is None , but the loop still seems to run twice when it really should only run once on the blank C4D document.

    import c4d
    from c4d import documents
    def main() :
        
        #Start with the first document
        doc = documents.GetFirstDocument()
      
        #Then grab the next ones using a loop
        while doc != None:
            print (doc.GetDocumentName())
            #Search for a specific object here
            doc = doc.GetNext()
            print(doc)
            
        c4d.EventAdd()    
      
    if __name__=='__main__':
        main()
    

    I am just trying to get my head around this seeming flaw in execution. Is there some C4D based rule in python that would cause the loop to execute twice?

    For instance, I run this code in Blender and it and it prints one value. I run this same code in C4D and I get two values printed..?

    def main() :        
        var = 1 
        while var != None:        
            print (var)        
            var = None
            
    if __name__=='__main__':    
        main()
    


  • On 15/10/2014 at 08:57, xxxxxxxx wrote:

    Hello,

    The class BaseDocument is based on GeListNode so you find the documentation for GetNext() there.

    When I run your code it only executes once. Can you explain what result you get and how exacly you run this code?

    Best wishes,
    Sebastian



  • On 15/10/2014 at 09:10, xxxxxxxx wrote:

    I have the expression editor open and I have the console open.
    I pasted the code in to the expression editor and click the Execute button. It says no errors but the console shows double output as mentioned above.

    Using C4D Studio R14.025 Build RC62983



  • On 16/10/2014 at 08:03, xxxxxxxx wrote:

    Hello,

    are you using Python inside a Python Generator object? In this case you don't need the lines:

      
    if __name__=='__main__':      
      main()  
    

    Just write:

      
    def main() :          
      var = 1   
      while var != None:          
          print (var)          
          var = None  
    

    best wishes,
    Sebastian



  • On 16/10/2014 at 11:06, xxxxxxxx wrote:

    Yes I am using the Python Generator, is there another way?

    Thank you, that does only execute one time now. But why does the definition of a function trigger the call? what if I just want to define several functions? Does that mean they will all automatically execute?



  • On 17/10/2014 at 00:11, xxxxxxxx wrote:

    Hello,

    there are many ways to use Python in Cinema 4D.

    • The most simple way to manage simple scripts is to use the Script Manager ("Script"->"Script Manager"). There you can store, edit and execute command scripts.

    • But you can also write plugins with Python. I your case you might want to create a CommandData or ObjectData plugin.

    • You can use Python inside the Python generator but also inside the Python tag.

    • And finally you can use Python in the MoGraph Python effector and a special Xpresso node.

    Inside a Python generator Cinema will search for the "main" function and will execute it. But it seems that any code outside of a function will be executed first. This is why "main" was called two times.

    best wishes,
    Sebastian



  • On 17/10/2014 at 06:26, xxxxxxxx wrote:

    Thanks for the explanation, I think the Script Manager is where I'll start then.


Log in to reply