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
    • Unread
    • Recent
    • Tags
    • Users
    • Login
    1. Maxon Developers Forum
    2. Peek
    P
    • Profile
    • Following 0
    • Followers 0
    • Topics 5
    • Posts 21
    • Best 1
    • Controversial 0
    • Groups 0

    Peek

    @Peek

    1
    Reputation
    8
    Profile views
    21
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Peek Unfollow Follow

    Best posts made by Peek

    • RE: Traversing a layer shader with python

      @ferdinand : The GetAllAssetsNew is a far more elegant solution for the problem I am trying to solve and I've rewritten the code so that it works now. We use Corona render and Redshift so it's a bonus that this works with pretty much all materials.

      Thank you very much for the help, I will put your information about the layer shader in my database for future reference as I'm sure it will become helpful in another project!

      Kind regards,
      Joep

      posted in Cinema 4D SDK
      P
      Peek

    Latest posts made by Peek

    • RE: Running commanline application with Python

      @ferdinand : Yeah I will because that is definitely not what I'm seeing 🙂

      Manually login in in both commandline/c4dpy works. As that is what we are doing now on all render nodes when the licenses vanish yet again.

      Thanks!

      posted in General Talk
      P
      Peek
    • RE: Running commanline application with Python

      @ferdinand When I was talking about Commandline I mean the actual Cinema4D app/.exe, not the terminal/powershell.

      I will give the command a go Today and see how it goes. Thanks for the help regardless that it was outside of scope 🙂

      Well, with your command on MacOS I basically get a wall of text but it does finish. However when I then manually run the C4D commandline again I get the standard "Enter the license method:" window

      When I run it in c4dpy it ends on "Welcome to the world of C4D and python (....)" and >>>.

      Cheers,

      posted in General Talk
      P
      Peek
    • RE: Running commanline application with Python

      @ferdinand

      Thanks for adding the SDK info and also thanks for the hints, I will investigate further. We normally log in to Maxon accounts via the commandline or via the login window in Cinema, so it should work I imagine.

      posted in General Talk
      P
      Peek
    • RE: Running commanline application with Python

      @ferdinand Due to the busy schedule at work I've only now gotten around to getting to implement this and I'm a bit stuck.

      • When I run both the commandline and c4dpy the terminal goes into some kind of endless loop on one of the MacOS rendernodes, it just keeps going endlessly with the same wall of text.
      • When I run just the commandline part it ends, but the license info doesn't seem to be inputted. As when I then manually run the commandline afterwards it asks for license info again.
      • When I run just the c4dpy part it also goes into an endless loop spouting the same wall of text over and over again.

      You mentioned in your reply "and we will also expose it in the technical and user documentation (in fact a few things should be updated there)." but I can't find anything in the SDK documentation about "g_license", just one quick mention in c4dpy about passing username and password as arguments.

      posted in General Talk
      P
      Peek
    • RE: Running commanline application with Python

      Hi @ferdinand : Thanks a ton for helping out even though technically this kind of support is outside the scope.

      I will read up on the material you provided and implement the code example into our own code.

      As always you've been very helpful 🙂

      Cheers,

      Joep

      posted in General Talk
      P
      Peek
    • RE: Running commanline application with Python

      @ferdinand : I will, thanks again for investigating 🙂

      Cheers,
      Joep

      posted in General Talk
      P
      Peek
    • RE: Running commanline application with Python

      @ferdinand : Hi Ferdinand, thanks for getting back to me on this.

      As for the legal aspects (the following is my personal opinion), what do you mean exactly?
      We pay for licenses and we don't want the inconvenience of having to manually go through all render clients when the licensing system fails us yet again.
      These actions (inputting license information on all commandline clients in our farm) cost man hours which can be more effectively spent working for clients rather than working around a needlessly cumbersome system.
      There is no effective difference between me manually inputting the information on a client and doing it in an automated fashion with a piece of code.

      That being said, if I'm missing something else here please feel free to correct my thinking.

      Cheers,
      Joep

      posted in General Talk
      P
      Peek
    • Running commanline application with Python

      Hi guys,

      Running into a bit of an issue with the commandline application on Windows/MacOS when running and "driving" it via Python (standalone, outside Cinema4D).

      We're writing an application that automatically handles the license logins on the machines in our renderfarms. Every time there is a minor update to Cinema or the Maxon App, all our machines seem to lose their license which is a lot of manual labor to get working again.

      We have the following code:

      import subprocess
      import os
      from os.path import expanduser
      import time
      
      # Petermine the platform (Windows or MacOS)
      is_windows = os.name == 'nt'
      
      # Path to your C4D executable
      if is_windows:
          try:
              c4d_executable = r'C:\Program Files\Maxon Cinema 4D 2023\Commandline.exe'
          except:
              print("Commandline executablecould not be found!")
              subprocess.wait(5)
      else:
          try:
              c4d_executable = '/Applications/Maxon Cinema 4D 2023/Commandline.app/Contents/MacOS/Commandline'
          except:
              print("Commandline executablecould not be found!")
              subprocess.wait(5)
      
      
      # Define the license information to provide
      license_method = "2"
      license_username = "XXXXXXXX"
      license_password = "XXXXXXXX"
      license_floating_commandline = '1'
      
      # Define license files
      
      
      # Get user home directory
      home = expanduser("~")
      print(home)
      
      
      # Create a subprocess to run C4D
      c4d_process = subprocess.Popen(
          [c4d_executable],
          stdin=subprocess.PIPE,
          stdout=subprocess.PIPE,
          stderr=subprocess.PIPE,
          shell=True,
          text=True
      )
      
      # Use a loop to read and print the output in real-time
      def capture_and_print_output(process):
          while True:
              output_line = process.stdout.readline()
              if not output_line:
                  break  # No more output, exit the loop
              print(output_line, end='')  # Print the line without adding extra newline
      
              # Check for error messages in the output
              if "Error:" in output_line:
                  print("Error message detected:", output_line)
      
          while True:
              error_line = process.stderr.readline()
              if not error_line:
                  break  # No more error output, exit the loop
              print("Error:", error_line, end='')
      
      # Capture and print outputs before providing license information
      capture_and_print_output(c4d_process)  # Output before license input
      
      # Wait for Commandline to prompt for input
      output, _ = c4d_process.communicate(timeout=10)
      
      print("Output:", output)
      
      if "Please select:" in output:
          print("Inside the license method loop")
          # Provide the license information
          time.sleep(5)
          c4d_process.stdin.write(license_method + '\n')
          c4d_process.stdin.flush()
      
          print("sleeping")
          time.sleep(2)
      
          # Capture and print outputs after providing license method
          capture_and_print_output(c4d_process)
      
          # Send the Enter key
          c4d_process.stdin.write('\n')
          c4d_process.stdin.flush()
      
          print("sleeping after Enter")
          time.sleep(2)
      
          # Capture and print outputs after providing license method
          capture_and_print_output(c4d_process)
          
          time.sleep(2)
          
      
          # Capture and print outputs after providing license method
          capture_and_print_output(c4d_process)
      
      if "Account email address []: " in output:
          print("Inside the email address loop")
          # Provide the license information
          c4d_process.stdin.write(license_username)
          c4d_process.stdin.flush()
      
          # Send the Enter key
          c4d_process.stdin.write('\n')
          c4d_process.stdin.flush()
      
          # Capture and print outputs after providing email address
          capture_and_print_output(c4d_process)
      
      if "Password: " in output:
          print("Inside the password loop")
          # Provide the license information
          c4d_process.stdin.write(license_password)
          c4d_process.stdin.flush()
      
          # Send the Enter key
          c4d_process.stdin.write('\n')
          c4d_process.stdin.flush()
      
          # Capture and print outputs after providing password
          capture_and_print_output(c4d_process)
      
      if "Please choose one of the following options: " in output:
          print("Inside the license type loop")
          # Provide type of license
          c4d_process.stdin.write(license_floating_commandline)
          c4d_process.stdin.flush()
      
          # Send the Enter key
          c4d_process.stdin.write('\n')
          c4d_process.stdin.flush()
      
          # Capture and print outputs after providing license type
          capture_and_print_output(c4d_process)
      
      else:
          print("No input detected!")
          c4d_process.wait(5)
          c4d_process.stdin.close()
          c4d_process.stdout.close()
          c4d_process.stderr.close()
          c4d_process.terminate()
      
      # You can now continue working with the C4D process or wait for it to finish
      print("Licensing process ran succesfully")
      c4d_process.wait(5)
      
      # Close the subprocess and clean up
      c4d_process.stdin.close()
      c4d_process.stdout.close()
      c4d_process.stderr.close()
      c4d_process.terminate()
      

      Basically what happens is that the commandline application doesn't seem to register the "replies" that Python gives it when it asks for specific license information inputs. I've tried a ton of different ways to go about it but none seem to work.
      Tried with sleep, without sleep, "Please select: ", "Please select:", "Enter the license method:", "Enter the license method: ", with \n, without \n etc.

      Is there some specific timing I need to adhere to or something else behind the scenes that I'm not aware of?

      Kind regards

      posted in General Talk 2023 python macos windows
      P
      Peek
    • RE: Problems with Reused Asset Resources in MGS_GETALLASSETS

      Hi @ferdinand , thanks a ton for the very extensive reply. I do understand where you are coming from decision/code wise and that it might indeed be intended behavior, but I also appreciate you flagging this behavior to be looked at!

      I will look into the code you provided and see what I can make of it to work for our specific case. As with all the examples i receive on here it is also about learning itself, to become better.
      I already found out that I can run my piece of code 2 times to catch the first set of instances, perhaps it is also possible to run that on a loop until the len() doesn't increase anymore 🙂 It's a hack-job but it might be a good last resort.

      To address the first comment about the post itself, my reasoning was that since it was about GetAllAssetsNew which we talked about last, I added it to my post to keep it all together.
      But I can see how it deviated too much from the original question that started the topic, my apologies.

      Cheers,

      posted in Bugs
      P
      Peek
    • Problems with Reused Asset Resources in MGS_GETALLASSETS

      @ferdinand : I've been working for a while with the solution of GetAllAssetsNew now but Today I noticed an issue:
      When a texture is used in multiple shaders, in the "Project Asset Inspector" it has a "+" before "Asset". However when I pull that texture with GetAllAssetsNew it seems that is only displaying 1 "owner" shader, even though in reality it's multiple.

      When I then loop over all texture assets to convert the paths from local to global, the extra owners keep their local paths and it's only changed for one of the owner shaders.

      In my example I have 4 images assinged to 5 shaders. When I pull a len() on the list of assets I get 4. Then when I convert the paths to global, one of the shaders get's left behind and in the Project Asset Inspector the "+" vanishes and I now see 5 textures instead of 4. Same goes if I then pull a len() on the list again, it now says 5.

      How can I make sure that it makes paths global on all owners of the texture?

      Cheers,
      Joep

      Code:

      def globalizeTextures():
          doc = c4d.documents.GetActiveDocument()
          textures = []
          c4d.documents.GetAllAssetsNew(doc, 0, "", flags=c4d.ASSETDATA_FLAG_TEXTURESONLY, 
                                        assetList=textures)
      
          print("The numder of textures is: ", len(textures))
          print("Textures are: ", textures)
      
          # Extract filename from all textures and put that name into the owner (shader) using the bitmap
          for texture in textures:
              print(texture)
              filePath = texture
              file = os.path.split(filePath["filename"])
      
              workPath = doc.GetDocumentPath()
              globalPath = str(os.path.join(workPath, "tex"))
      
               # Check whether the texture file is in the texture (sub)folder(s)
              for texture in os.walk(globalPath):
                  i = 0             
                  for filename in texture[2]:                
                      # print("Texture in tex folder is: ", filename)
                      # Check if the filenames match between the file in the shader and the file on the 
                      # network
                      if (file[1] == filename):
                          globalPath = str(os.path.join(str(globalPath),str(filename)))
                          owner = filePath["owner"]
                          print("Owner is: ",filePath["owner"])
                          returnShader(owner, globalPath)  
                      else:
                          i += 1
                      
                      if (i == len(texture[2])):
                          if not filePath["exists"]:
                              print("This file ", file[1], " does not exist!")
                          else:
                              print("File ", file[1], " not found in the tex folder of the project, use "
                                    "'Localize texture paths' first to copy the file to the tex folder "
                                    "of the project")
              updateScene()
          return True
      

      edit: forked form https://developers.maxon.net/forum/topic/14732/ by Ferdinand.

      To have your code not "messed up", you should markdown formating.

      ```
      def foo: return 3.14
      ```

      which would render as

      def foo: return 3.14
      
      posted in Bugs python
      P
      Peek