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
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login
    1. Maxon Developers Forum
    2. davidtorno
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 7
    • Best 2
    • Controversial 0
    • Groups 0

    David Torno

    @davidtorno

    VFX veteran since 2000, currently focused on 3D particle fx, volumetric fx, creating educational tutorial content, utility automation scripts, and artwork for sale.

    2
    Reputation
    16
    Profile views
    7
    Posts
    0
    Followers
    0
    Following
    Joined Last Online
    Website fendrafx.com Location Los Angeles

    davidtorno Unfollow Follow

    Best posts made by davidtorno

    • RE: Parameter Description Access not working as expected

      @zipit said in [python] Parameter Description Access not working as expected:

      Your code is almost there, but you probably misconstrued c4d.DESC_DEFAULT as a boolean indicating a changed value, but it is actually the actual default value.

      Correct, I understood it as indicating a changed value. Good to know. These are the nuances I am still adjusting to with C4D python. Thanks for the answer and explanation. I will give this a go tomorrow when I’m back on my machine. I appreciate your help.

      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • RE: Parameter Description Access not working as expected

      @zipit So I have tried implementing your check for DESC_DEFAULT and I am still not getting values for default.

      #.....Snippet from my script, full code at bottom of post.
              #Process tag parameters
              desc = o.GetDescription(c4d.DESCFLAGS_DESC_0)
              for bc, paramid, groupid in desc:
                  
                  #Check if current value matches default value
                  is_default = bc[c4d.DESC_DEFAULT] == o[paramid]
                  
                  #print both values for visual comparison
                  print "DEBUG:: " + str(bc[c4d.DESC_DEFAULT]) + " == " + str(o[paramid]) + " --> " + str(is_default)
                  
                  if is_default is not True:
      #.....
      

      As an example I am currently using a simple Null object for testing the default functionality. Changing only the Object > Display parameter to see if my code catches if it is set to default or not. The print output is like this so far. For simplicity I've only posted the Object Properties results.

      Object Properties
      DEBUG:: None == 0 --> False
      	Display	0
      DEBUG:: None == 10.0 --> False
      	Radius	10.0
      DEBUG:: None == 10.0 --> False
      	Aspect Ratio	10.0
      DEBUG:: None == 0 --> False
      	Orientation	0
      

      I would expect this debug result to read as this since all parameters are at their defaults.

      Object Properties
      DEBUG:: 0 == 0 --> True
      DEBUG:: 10.0 == 10.0 --> True
      DEBUG:: 10.0 == 10.0 --> True
      DEBUG:: 0 == 0 --> True
      #...
      

      ...but bc[c4d.DESC_DEFAULT] is continuously returning None for some reason. What am I missing here? Thanks again for any assistance on this.

      Here is my full script code currently. I cleaned up a lot from previous build as it was getting very messy. The param name/value retrieval is now it's own function (def):

      import c4d
      from c4d import gui
      
      # Main function
      def main():
          o = op
          if o is not None:
              recurse(o)
      
      def getParamData(o):
          try:
              #misc var
              grpName = ""
              
              #Process tag parameters
              desc = o.GetDescription(c4d.DESCFLAGS_DESC_0)
              for bc, paramid, groupid in desc:
                  
                  #Check if current value matches default value
                  is_default = bc[c4d.DESC_DEFAULT] == o[paramid]
                  
                  #print both values for visual comparison
                  print "DEBUG:: " + str(bc[c4d.DESC_DEFAULT]) + " == " + str(o[paramid]) + " --> " + str(is_default)
                  
                  if is_default is not True:
                      isgroup = paramid[0].dtype==c4d.DTYPE_GROUP
                      if isgroup:
                          #handle blank names
                          if bc[c4d.DESC_NAME] is not "":
                              grpName = bc[c4d.DESC_NAME]
                              print grpName
              
                      #check for param name and ident
                      if bc[c4d.DESC_NAME] and bc[c4d.DESC_IDENT]:
                          try:
                              #Adjust color float to 255 range
                              vec = o[paramid]
                              if "Color" in bc[c4d.DESC_NAME] and "Vector" in str(vec):
                                  vec = o[paramid]
                                  val = "Vector(" + str(vec[0]*255) + ", " + str(vec[1]*255) + ", " + str(vec[2]*255) + ")"
                              else:
                                  #Strip None values out
                                  blank = o[paramid]
                                  if blank == None:
                                      val = ""
                                  else:
                                      val = str(o[paramid])
                              
                              #handle group name duplicates in results
                              if bc[c4d.DESC_NAME] == grpName:
                                  pass
                              else:
                                  print "\t" + bc[c4d.DESC_NAME] + "\t" + val
                          except:
                              print "\t" + bc[c4d.DESC_NAME] + ": PARAMETER REQUIRES MANUAL EXTRACTION"
          
          except:
              print "--UNKNOWN PARAMETER--"
      
      
      def recurse(o):
          obj = o
          if obj is not None:
              #Misc variables
              tab = "\t"
      
              #Header
              print "Name\tParameter\tValue\tParam ID"
      
              #Print object name
              on = obj.GetName()
              print on
      
              #Get object data
              #data = obj.GetData()
      
              #Get param name and value
              getParamData(obj)
      
              #Get object tags
              tags = obj.GetTags()
              
              #Loop tags
              for t in tags:
                  tn = t.GetTypeName()
                  if tn is not "" or None:
                      #Add spacer in output
                      print ""
      
                      #Get tag name
                      print t.GetTypeName()
                      
                      #Get param name and value
                      getParamData(t)
      
      
              #Check for child object
              d = obj.GetDown()
              if d is not None:
                  recurse(d)
      
              #Get next object
              n = obj.GetNext()
              if n is not None:
                  recurse(n)
          else:
              print "Error: Select one starting object first."
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D SDK
      davidtornoD
      davidtorno

    Latest posts made by davidtorno

    • RE: Parameter Description Access not working as expected

      @m_adam Wow, thanks Maxime for the explanation and code. I was not expecting that amount of effort.

      I ran the code and encountered two errors so far. I believe one may be App version related possibly, and the other I am unsure.

      So first the section in your GetChangedParameter function

       # List of excluded parameter because they are always different
      unwantedIds = [c4d.ID_BASELIST_ICON_COLOR,
                               c4d.ID_MG_MOTIONGENERATOR_EFFECTORLIST]
      

      I get this attribute error

      AttributeError: 'module' object has no attribute 'ID_BASELIST_ICON_COLOR'
      

      I am assuming this may be an ID added after R20. I am still using R20 for context. Once I remove it from the list the rest of the code will execute.

      The second error I get is when encountering any polygon object. For example you can throw down any primitive shape and make it editable to test this.

      When a polygon object is encounter this type error is thrown:

      TypeError: Required argument 'vcnt' (pos 2) not found
      

      My guess is that since it's a polygon object (which could be a native primitive made editable or a custom geometry imported by user) C4D has no direct reference to recreate the object in a default state?

      So far those are the only two issues I have come across.

      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • RE: Parameter Description Access not working as expected

      @zipit Thanks! All great points. I was trying to check for instance of object initially, but was failing to find the correct syntax in this case. I got impatient and started hacking together solutions that still function even if not optimized/ideal.

      I am so use to Adobe ExtendScript which is JavaScript based and Houdini VEX which is more python/JavaScript like, and their hscript which is Python based. So C4D python syntax can be just close enough to drive me nuts when I don’t find the correct answer. I’ve struggled with C4D python for a long time too. The docs really get confusing fast (for me at least)

      One thing that helped me with Adobe ExtendScript is the object model graph they have in the docs. It showed the object flow hierarchy and each class name. So it was super easy to find every method and attribute associated with each. Almost linear in nature. I think also what help most was the object naming though, it matched more with the front end naming, so it was easy to connect the dots. That’s mostly where I struggle in the C4D docs, and confusion sets in fast for me. Like BaseContainer, Atom, Description, etc... I see the App > Object Panel > Object > Parameter > Value (as a very basic example)

      Granted I never took a traditional route for learning coding, and am self taught. 🙂

      Thanks again for the tips you keep mentioning. I really appreciate it.

      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • RE: Parameter Description Access not working as expected

      Still far from being fully fleshed out, but could prove helpful to others in some form possibly. It's totally specific to my needs so I make no claims of it's longevity, stability, or usability for anyone else's needs. 🙂

      The script prints to the console a tab delimited list of all project objects beginning with a selected object. It then loops downwards through all objects, object parameters, tags, and tag parameters gathering names & values. Choose top most object in your project to get all items in your project.

      Here's the code I'm settling on for the moment. I did a few common parameter conversions from numerical value to it's string value seen in the UI.

      Example 1: Toggle switches return "Unchecked" / "Checked" instead or 0 / 1
      Example 2: Visible in Editor / Renderer return "On" / "Off" / "Default" instead of 0 / 1 / 2

      Source code:

      #--------------------------------------------------------
      #    [IN DEVELOPEMENT AND NOT COMPLETED YET]
      #    Project parameter names and values list script
      #    9/2020 David Torno
      #--------------------------------------------------------
      
      import c4d
      from c4d import gui
      
      # Main function
      def main():
          o = op
          if o is not None:
              recurse(o)
      
      def getParamData(o):
          try:
              #--------------------------------------------------------
              #    PARAMETER DATATYPE NUMBERS R20 (Likely to change with C4D versions)
              #    1 = Group
              #    8 = Button
              #    12 = String
              #    15 = Dropdown
              #    133 = Object Link
              #    1000481 = Color Gradient
              #    1009290 = InExclude List
              #    400006001 = Toggle
              #--------------------------------------------------------
              
              #misc var
              grpName = ""
              #Rotation Order conversion
              rotOrder = ["XYZ", "XZY", "YXZ", "YZX", "ZXY", "ZYX", "HPB"]
              #Vis in editor/renderer conversion
              visEditRender = ["On", "Off", "Default"]
              #Toggle conversion
              tog = ["Unchecked", "Checked"]
              
              #Process tag parameters
              desc = o.GetDescription(c4d.DESCFLAGS_DESC_0)
              for bc, paramid, groupid in desc:
                  #print str(paramid[0].id), str(paramid[0].dtype), str(paramid[0].creator)
                  
                  #-------------------------------------------------------
                  #Currently checking for default parameter value does not work
                  #-------------------------------------------------------
                  #Check if current value matches default value
                  #is_default = bc[c4d.DESC_DEFAULT] == o[paramid]
                  #print both values for visual comparison
                  #print "DEBUG:: " + str(bc[c4d.DESC_DEFAULT]) + " == " + str(o[paramid]) + " --> " + str(is_default)
                  #if is_default is not True:
                  #-------------------------------------------------------
                  
                  isgroup = paramid[0].dtype==c4d.DTYPE_GROUP
                  if isgroup:
                      #handle blank names
                      if bc[c4d.DESC_NAME] is not "":
                          grpName = bc[c4d.DESC_NAME]
                          print "\t" + grpName
          
                  #check for param name and ident
                  if bc[c4d.DESC_NAME] and bc[c4d.DESC_IDENT]:
                      try:
                          #Adjust color float to 255 range
                          vec = o[paramid]
                          if "Color" in bc[c4d.DESC_NAME] and "Vector" in str(vec):
                              vec = o[paramid]
                              val = "Vector(" + str(vec[0]*255) + ", " + str(vec[1]*255) + ", " + str(vec[2]*255) + ")"
                          else:
                              blank = o[paramid]
                              if blank == None:
                                  val = ""
                              else:
                                  val = str(o[paramid])
                                  
                          #Convert toggle value to name str
                          if str(paramid[0].dtype) == "400006001":
                              val = tog[o[paramid]]
                          
                          #Convert dropdown value to name str
                          if str(paramid[0].dtype) == "15":
                              if "Visible in " in bc[c4d.DESC_NAME]:
                                  val = visEditRender[o[paramid]]
                              elif "Rotation Order" == bc[c4d.DESC_NAME]:
                                  val = rotOrder[o[paramid]]
      
                          
                          #handle group name duplicates in results
                          if bc[c4d.DESC_NAME] == grpName or paramid[0].dtype == 8:
                              pass
                          else:
                              print "\t\t" + bc[c4d.DESC_NAME] + "\t" + val
                              
                              #--------------------------------------------------------------------
                              #DEBUG print reveals parameter data type enumeration
                              #--------------------------------------------------------------------
                              #print "DTYPE:" + str(paramid[0].dtype) + "\t\t" + bc[c4d.DESC_NAME] + "\t" + val
                      except:
                          print "\t\t" + bc[c4d.DESC_NAME] + ": PARAMETER REQUIRES MANUAL EXTRACTION"
                          
                          #--------------------------------------------------------------------
                          #DEBUG print reveals parameter data type enumeration
                          #--------------------------------------------------------------------
                          #print "DTYPE:" + str(paramid[0].dtype) + "\t\t" + bc[c4d.DESC_NAME] + ": PARAMETER REQUIRES MANUAL EXTRACTION"
          except:
              print "--UNKNOWN PARAMETER--"
      
      
      def recurse(o):
          obj = o
          if obj is not None:
              #Misc variables
              tab = "\t"
      
              #Header
              #print "Name\tParameter\tValue\tParam ID"
      
              #Print object name
              on = obj.GetName()
              print on
      
              #Get param name and value
              getParamData(obj)
      
              #Get object tags
              tags = obj.GetTags()
              
              #Loop tags
              for t in tags:
                  tn = t.GetTypeName()
                  if tn is not "" or None:
                      #Add spacer in output
                      print ""
      
                      #Get tag name
                      print t.GetTypeName()
                      
                      #Get param name and value
                      getParamData(t)
      
      
              #Check for child object
              d = obj.GetDown()
              if d is not None:
                  recurse(d)
      
              #Get next object
              n = obj.GetNext()
              if n is not None:
                  recurse(n)
          else:
              print "Error: Select one starting object first."
      
      # Execute main()
      if __name__=='__main__':
          main()
      

      Example output:

      Right fill light
      	Basic Properties
      		Name	Right fill light
      		Layer
      		Visible in Editor	Off
      		Visible in Renderer	Default
      		Use Color	0
      		Display Color	Vector(255.0, 255.0, 255.0)
      		Enabled	Checked
      		X-Ray	Unchecked
      		Icon Color	Unchecked
      	Coordinates
      		Position	Vector(337.76, 0, -211.712)
      		Scale	Vector(1, 1, 1)
      		Rotation	Vector(1.326, 0, -1.571)
      		Rotation Order	HPB
      	Quaternion
      		Quaternion Rotation	Unchecked
      	Freeze Transformation
      		Frozen Position	Vector(0, 0, 0)
      		Frozen Scale	Vector(1, 1, 1)
      		Frozen Rotation	Vector(0, 0, 0)
      		Global Position	Vector(337.76, 0, -211.712)
      		Global Rotation	Vector(1.326, 0, -1.571)
      		Transformed Position	Vector(337.76, 0, -211.712)
      		Transformed Scale	Vector(1, 1, 1)
      		Transformed Rotation	Vector(1.326, 0, -1.571)
      	Object Properties
      	General
      		Color	Vector(153.765, 216.8775, 229.5)
      		Use Temperature	Unchecked
      		Color Temperature	6500.0
      		Intensity	0.65
      		Type	8
      		Shadow	2
      		Visible Light	0
      		No Illumination	Unchecked
      		Show Illumination	Checked
      		Ambient Illumination	Unchecked
      		Show Visible Light	Checked
      		Diffuse	Checked
      		Show Clipping	Checked
      		Specular	Checked
      		Separate Pass	Unchecked
      		GI Illumination	Checked
      		Export to Compositing	Checked
      	Details
      		Use Inner Value	Checked
      		Inner Angle	0.0
      		Inner Radius	0.0
      		Outer Angle	0.523598775598
      		Outer Radius	600.0
      		Aspect Ratio	1.0
      		Contrast	0.0
      		Shadow Caster	Unchecked
      		Area Shape	1
      		Object
      		Size X	1200.0
      		Size Y	1200.0
      		Size Z	200.0
      		Falloff Angle	3.14159265359
      		Infinite Angle	0.00872664625997
      		Samples	40
      		Add Grain (Slow)	Unchecked
      		Show in Render	Unchecked
      		Show as Solid in Viewport	Unchecked
      		Show in Specular	Checked
      		Show in Reflection	Unchecked
      		Visibility Multiplier	1.0
      		Falloff	0
      		Falloff Inner Radius	0.0
      		Falloff Radius / Decay	500.0
      		Colored Edge Falloff	Unchecked
      		Z Direction Only	Unchecked
      		Use Gradient	Unchecked
      		Color	<c4d.Gradient object at 0x000000D7967B9570>
      		Use Near Clipping	Unchecked
      		Near Clipping from	0.0
      		Near Clipping to	10.0
      		Use Far Clipping	Unchecked
      		Far Clipping from	90.0
      		Far Clipping to	100.0
      
      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • RE: Parameter Description Access not working as expected

      @zipit said in Parameter Description Access not working as expected:

      You would have to either handle that case manually or use the dirty checksums that I did mention. The problem there is that you can test the data container of a node for being dirty, i.e. its parameters, and by that detect if a parameter has been modified, but not exactly which one of the parameters has been modified.

      Hmmm, bummer. Ya the whole goal was to only return parameters not at default value. I've made similar scripts for Houdini, and After Effects. Cinema4D was my last holdout. 🙂

      I'll take a look at the dirty checksums. If I can at least tell if something was changed, it's better than nothing I guess.

      Thanks again for the help.

      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • RE: Parameter Description Access not working as expected

      @zipit So I have tried implementing your check for DESC_DEFAULT and I am still not getting values for default.

      #.....Snippet from my script, full code at bottom of post.
              #Process tag parameters
              desc = o.GetDescription(c4d.DESCFLAGS_DESC_0)
              for bc, paramid, groupid in desc:
                  
                  #Check if current value matches default value
                  is_default = bc[c4d.DESC_DEFAULT] == o[paramid]
                  
                  #print both values for visual comparison
                  print "DEBUG:: " + str(bc[c4d.DESC_DEFAULT]) + " == " + str(o[paramid]) + " --> " + str(is_default)
                  
                  if is_default is not True:
      #.....
      

      As an example I am currently using a simple Null object for testing the default functionality. Changing only the Object > Display parameter to see if my code catches if it is set to default or not. The print output is like this so far. For simplicity I've only posted the Object Properties results.

      Object Properties
      DEBUG:: None == 0 --> False
      	Display	0
      DEBUG:: None == 10.0 --> False
      	Radius	10.0
      DEBUG:: None == 10.0 --> False
      	Aspect Ratio	10.0
      DEBUG:: None == 0 --> False
      	Orientation	0
      

      I would expect this debug result to read as this since all parameters are at their defaults.

      Object Properties
      DEBUG:: 0 == 0 --> True
      DEBUG:: 10.0 == 10.0 --> True
      DEBUG:: 10.0 == 10.0 --> True
      DEBUG:: 0 == 0 --> True
      #...
      

      ...but bc[c4d.DESC_DEFAULT] is continuously returning None for some reason. What am I missing here? Thanks again for any assistance on this.

      Here is my full script code currently. I cleaned up a lot from previous build as it was getting very messy. The param name/value retrieval is now it's own function (def):

      import c4d
      from c4d import gui
      
      # Main function
      def main():
          o = op
          if o is not None:
              recurse(o)
      
      def getParamData(o):
          try:
              #misc var
              grpName = ""
              
              #Process tag parameters
              desc = o.GetDescription(c4d.DESCFLAGS_DESC_0)
              for bc, paramid, groupid in desc:
                  
                  #Check if current value matches default value
                  is_default = bc[c4d.DESC_DEFAULT] == o[paramid]
                  
                  #print both values for visual comparison
                  print "DEBUG:: " + str(bc[c4d.DESC_DEFAULT]) + " == " + str(o[paramid]) + " --> " + str(is_default)
                  
                  if is_default is not True:
                      isgroup = paramid[0].dtype==c4d.DTYPE_GROUP
                      if isgroup:
                          #handle blank names
                          if bc[c4d.DESC_NAME] is not "":
                              grpName = bc[c4d.DESC_NAME]
                              print grpName
              
                      #check for param name and ident
                      if bc[c4d.DESC_NAME] and bc[c4d.DESC_IDENT]:
                          try:
                              #Adjust color float to 255 range
                              vec = o[paramid]
                              if "Color" in bc[c4d.DESC_NAME] and "Vector" in str(vec):
                                  vec = o[paramid]
                                  val = "Vector(" + str(vec[0]*255) + ", " + str(vec[1]*255) + ", " + str(vec[2]*255) + ")"
                              else:
                                  #Strip None values out
                                  blank = o[paramid]
                                  if blank == None:
                                      val = ""
                                  else:
                                      val = str(o[paramid])
                              
                              #handle group name duplicates in results
                              if bc[c4d.DESC_NAME] == grpName:
                                  pass
                              else:
                                  print "\t" + bc[c4d.DESC_NAME] + "\t" + val
                          except:
                              print "\t" + bc[c4d.DESC_NAME] + ": PARAMETER REQUIRES MANUAL EXTRACTION"
          
          except:
              print "--UNKNOWN PARAMETER--"
      
      
      def recurse(o):
          obj = o
          if obj is not None:
              #Misc variables
              tab = "\t"
      
              #Header
              print "Name\tParameter\tValue\tParam ID"
      
              #Print object name
              on = obj.GetName()
              print on
      
              #Get object data
              #data = obj.GetData()
      
              #Get param name and value
              getParamData(obj)
      
              #Get object tags
              tags = obj.GetTags()
              
              #Loop tags
              for t in tags:
                  tn = t.GetTypeName()
                  if tn is not "" or None:
                      #Add spacer in output
                      print ""
      
                      #Get tag name
                      print t.GetTypeName()
                      
                      #Get param name and value
                      getParamData(t)
      
      
              #Check for child object
              d = obj.GetDown()
              if d is not None:
                  recurse(d)
      
              #Get next object
              n = obj.GetNext()
              if n is not None:
                  recurse(n)
          else:
              print "Error: Select one starting object first."
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • RE: Parameter Description Access not working as expected

      @zipit said in [python] Parameter Description Access not working as expected:

      Your code is almost there, but you probably misconstrued c4d.DESC_DEFAULT as a boolean indicating a changed value, but it is actually the actual default value.

      Correct, I understood it as indicating a changed value. Good to know. These are the nuances I am still adjusting to with C4D python. Thanks for the answer and explanation. I will give this a go tomorrow when I’m back on my machine. I appreciate your help.

      posted in Cinema 4D SDK
      davidtornoD
      davidtorno
    • Parameter Description Access not working as expected

      I am working on limited C4D python api understanding, so forgive what may be an noob question.

      I am building a specialized script for my personal workflow to extract parameter data from a project build. The goal being that it loops through all the scene objects, tags, and parameters, then checks if parameter is not default (or has been changed), then returns a tab delimited string consisting of Object name / Parameter name / Parameter Value

      The resulting list I like to use as a notes reference for when I make my video tutorials. It helps me remember what I changed to achieve final result. So only the changed parameters are required.

      Currently I have the Object/parameter loop, name & value retrieval functioning by cobbling together some snippets I've found online, and from my own knowledge. Some checks and adjustments made to results along the way as well. What I am having issues with are the parameter description name attributes located in this list: https://developers.maxon.net/docs/py/2023_2/modules/c4d/Description/index.html#c4d.Description

      So far I have tried using changed and default to check parameter, but both fail and return None instead of True/False I assume I am using them improperly or there may be a limitation to how I want to use them. As I read in the help docs (url above), changed returns bool if entry is changed, and default returns the parameter default value. Changed would be an easier use, but if I have to do a...

      default != "value"
      

      ...kind of check, that's ok too.

      c4d.DESC_CHANGED
      c4d.DESC_DEFAULT
      

      Any insight as to how I can check for a parameter that in not default or has changed would be appreciated.

      This is the code I have so far, and I am aware that some parameters that are Gradients, Time, Custom, etc.. are not handled with this code currently. Next hurdle to cross when I get to that though.

      import c4d
      from c4d import gui
      
      # Main function
      def main():
          o = op
          if o is not None:
              recurse(o)
      
      
      def recurse(o):
          obj = o
          if obj is not None:
              #Misc variables
              tab = "\t"
              
              #Header
              print "Name\tParameter\tValue\tParam ID"
      
              #Print object name
              on = obj.GetName()
              print on
      
              #Print object PSR
              print on + "\t" + "Position\t" + str(obj[c4d.ID_BASEOBJECT_REL_POSITION])
              print on + "\t" + "Scale\t" + str(obj[c4d.ID_BASEOBJECT_REL_SCALE])
              print on + "\t" + "Rotation\t" + str(obj[c4d.ID_BASEOBJECT_REL_ROTATION])
              print on + "\t" + "Vis Editor\t" + str(obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR])
              print on + "\t" + "Vis Renderer\t" + str(obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER])
              
              #Display color check/conversion and print
              uc = obj[c4d.ID_BASEOBJECT_USECOLOR]
              if uc == 2:
                  dc = obj[c4d.ID_BASEOBJECT_COLOR]
                  print on + "\t" + "Display Color\tVector(" + str(dc[0]*255) + ", " + str(dc[1]*255) + ", " + str(dc[2]*255) + ")"
              
              #Get object data
              data = obj.GetData()
      
              #Get object description
              description = obj.GetDescription(c4d.DESCFLAGS_DESC_0)
              for bc, paramid, groupid in description:
                  #Process object parameters
                  isgroup = paramid[0].dtype==c4d.DTYPE_GROUP
                  if isgroup:
                      continue
      
                  group = groupid[0].id
                  filtergroup = group!=c4d.Tbaselist2d and group!=c4d.FALLOFF_GROUPFALLOFF
                  idname = bc[c4d.DESC_IDENT]
      
                  if idname:
                      filtergroup = filtergroup and not idname.startswith("ID_BASEOBJECT")
      
                  if filtergroup:
                      if bc[c4d.DESC_NAME] and bc[c4d.DESC_IDENT]:
                          #-------------------------------------------
                          #ATTEMPTS TO CHECK FOR PARAMETER CHANGED OR DEFAULT
                          #-------------------------------------------
                          #Fails to return changed correctly
                          #if bc[c4d.DESC_CHANGED] == 1:
                          #Fails to return default correctly
                          #if bc[c4d.DESC_DEFAULT] == 1:
                          #-------------------------------------------
                          try:
                              #Adjust color float to 255 range
                              vec = obj[paramid]
                              if "Color" in bc[c4d.DESC_NAME] and "Vector" in str(vec):
                                  vec = obj[paramid]
                                  val = "Vector(" + str(vec[0]*255) + ", " + str(vec[1]*255) + ", " + str(vec[2]*255) + ")"
                              else:
                                  val = str(obj[paramid])
                              print on + "\t" + bc[c4d.DESC_NAME] + "\t" + val
                          except:
                              print on + "\t" + bc[c4d.DESC_NAME] + ": PARAMETER REQUIRES MANUAL EXTRACTION"
      
              #Get object tags
              tags = obj.GetTags()
              for t in tags:
                  tn = t.GetTypeName()
                  if tn is not "" or None:
                      #Add spacer in output
                      print ""
                      
                      #Get tag name
                      print t.GetTypeName()
                      try:
                          #Process tag parameters
                          tdesc = t.GetDescription(c4d.DESCFLAGS_DESC_0)
                          for bc, paramid, groupid in tdesc:
                              #-------------------------------------------
                              #ATTEMPTS TO CHECK FOR PARAMETER CHANGED OR DEFAULT
                              #-------------------------------------------
                              #Fails to return changed correctly
                              #if tn[c4d.DESC_CHANGED] == 1:
                              #Fails to return default correctly
                              #if tn[c4d.DESC_DEFAULT] == 1:
                              #-------------------------------------------
                              isgroup = paramid[0].dtype==c4d.DTYPE_GROUP
                              if isgroup:
                                  continue
          
                              group = groupid[0].id
                              filtergroup = group!=c4d.Tbaselist2d and group!=c4d.FALLOFF_GROUPFALLOFF
                              idname = bc[c4d.DESC_IDENT]
          
                              if idname:
                                  filtergroup = filtergroup and not idname.startswith("ID_BASEOBJECT")
          
                              if filtergroup:
                                  if bc[c4d.DESC_NAME] and bc[c4d.DESC_IDENT]:
                                      try:
                                          #val = tn+"[c4d."+str(idname)+"]"
                                          print tn + "\t" + bc[c4d.DESC_NAME] + "\t" + str(t[paramid])
                                      except:
                                          print tn + "\t" + bc[c4d.DESC_NAME] + ": PARAMETER REQUIRES MANUAL EXTRACTION"
      
                      except:
                          print "--UNKNOWN PARAMETER--"
      
      
              #Check for child object
              d = obj.GetDown()
              if d is not None:
                  recurse(d)
      
              #Get next object
              n = obj.GetNext()
              if n is not None:
                  recurse(n)
          else:
              print "Error: Select one starting object first."
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      posted in Cinema 4D SDK python r20
      davidtornoD
      davidtorno