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
    • Recent
    • Tags
    • Users
    • Login

    Detecting Parameters & Connecting XPresso Ports

    Scheduled Pinned Locked Moved PYTHON Development
    3 Posts 0 Posters 368 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 03/12/2015 at 18:33, xxxxxxxx wrote:

      Hi,

      I'm trying to write a script that duplicates an object and connects all animatable parameters of the new object, with the corresponding parameters of the source object via Xpresso. So far, I've been able to achieve the basics (clone object, create XPresso tag & nodes, link parameters) :

      However, I'm still struggling with the following issues/questions:

      1. How do I get Cinema 4D to show that a parameter has been linked as an input/output via XPresso? Something like this:

      2. How do I determine if a parameter in an object's description is animatable? For example: "Size.x" can be keyed but "Size" cannot be.

      Here is my current code, I'd be very interested in any suggestions you may have:

        
      """Name-US: CV-Make Replicant   
      Description-US: Duplicates the selected object and links all parameters via Xpresso.   
        
      USAGE INSTRUCTIONS   
      ------------------   
        
      1. Select an object.   
      2. Run "Scripts > CV-Make Replicant"   
        
      LICENSE   
      -------   
        
      Copyright (C) 2015 Maxon Computer, Inc.   
      Programming: Donovan Keith <[email protected]>   
        
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE   
      WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR   
      COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR   
      OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.   
      """   
        
      #====== IMPORTS ======#   
        
      import c4d   
        
      #====== GLOBALS ======#   
        
      PLUGIN_ID = None   
      PLUGIN_VERSION = "0.01"   
        
      #====== UTILS ======#   
        
      def AddObjectNode(node_master, obj, x=0) :   
          """Adds and returns an object node into Xpresso graph's node_master"""   
             
          obj_node = node_master.CreateNode(parent=node_master.GetRoot(), id=c4d.ID_OPERATOR_OBJECT, x=x, y=50)   
          obj_node[c4d.GV_OBJECT_OBJECT_ID] = obj   
          return obj_node   
        
      #====== MAIN ======#   
        
      def main() :   
          doc.StartUndo()   
             
          #Get the active objects   
          active_objects = doc.GetActiveObjects(flags=c4d.GETACTIVEOBJECTFLAGS_CHILDREN)   
             
          for source in active_objects:   
              #Make and insert a copy of the selected object   
              destination = source.GetClone()   
              destination.SetName(source.GetName() + " Replicant")   
              doc.InsertObject(destination, pred=source)   
              doc.AddUndo(c4d.UNDOTYPE_NEW, destination)   
             
              #Create XPresso Tag   
              xpresso_tag = c4d.modules.graphview.XPressoTag()   
              node_master = xpresso_tag.GetNodeMaster()   
        
              #Add the Tag to the destination object   
              destination.InsertTag(xpresso_tag)   
        
              #Add a Node for the source object   
              source_node = AddObjectNode(node_master, source, x=50)   
              dest_node = AddObjectNode(node_master, destination, x=300)   
        
        
              #Add and link ports for all parameters, except:   
              banned_ids = [   
                  c4d.ID_BASELIST_NAME,   
                  c4d.ID_LAYER_LINK,   
                  c4d.ID_BASEOBJECT_VISIBILITY_EDITOR,   
                  c4d.ID_BASEOBJECT_VISIBILITY_RENDER,   
                  c4d.ID_BASEOBJECT_USECOLOR,   
                  c4d.ID_BASEOBJECT_COLOR,   
                  c4d.ID_BASEOBJECT_GENERATOR_FLAG,   
                  c4d.ID_BASEOBJECT_XRAY   
              ]   
        
              banned_types = [   
                  c4d.CUSTOMGUI_BUTTON,   
                  c4d.CUSTOMGUI_STATICTEXT,   
                  c4d.CUSTOMGUI_SEPARATOR,   
                  c4d.CUSTOMGUI_PROGRESSBAR   
              ]   
        
        
              #Loop through all parameters of the active   
              source_obj_description = source.GetDescription(flags=c4d.DESCFLAGS_DESC_0)   
              for bc, descid, groupid in source_obj_description:   
                  id = descid[0].id   
                  if id in banned_ids:   
                     continue   
        
                  data_type = bc[c4d.DESC_CUSTOMGUI]   
                  if (data_type is not None) and (data_type not in banned_types) :   
                     #Add a output port   
                     output_port = source_node.AddPort(c4d.GV_PORT_OUTPUT, descid)   
        
                     #Tell C4D that it should display the Output port???   
                     bc[c4d.DESC_OUTPORT] = True   
        
                     #Add an input port   
                     input_port = dest_node.AddPort(c4d.GV_PORT_INPUT, descid, flag=c4d.GV_PORT_FLAG_IS_VISIBLE)   
        
                     #Link the two   
                     output_port.Connect(input_port)   
        
              source.Message(c4d.MSG_CHANGE)   
              destination.Message(c4d.MSG_CHANGE)   
              doc.AddUndo(c4d.UNDOTYPE_NEW, xpresso_tag)   
             
          c4d.EventAdd()   
          doc.EndUndo()   
        
      if __name__=='__main__':   
          main()   
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 04/12/2015 at 03:38, xxxxxxxx wrote:

        Hello,

        if you want to find out if a parameter is animateable you can check the DESC_ANIMATE parameter of the description. But you are asking if a parameter has a subdescription. Since the Description is very limited in Python I guess the best solution is to check if the parameter is question is a vector or color and to handle the subparameters manually.

        The BaseContainer returned by GetDescription() is a copy so changing this BaseContainer won't do anything.

        The Xpresso usage of a parameter is only displayed in the Attribute Manager if the connection between the Object Operator and the referenced object is created properly. To do this one would have to use OperatorSetData() which is only available in C++.

        The Object Operator is able to fix this connection. This is done for example when the document is merged with another document. So a "hack" would be to send the MSG_DOCUMENTINFO_TYPE_LOAD message. Something like this:

          
        doc.SendInfo(c4d.MSG_DOCUMENTINFO_TYPE_LOAD, c4d.FORMAT_C4DIMPORT, "", None, False)  
        

        best wishes,
        Sebastian

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

          On 04/12/2015 at 11:41, xxxxxxxx wrote:

          Hi Sebastian,

          That hack does the trick! I never would have found that. Thank you. I assume this will be pretty slow on large scenes as it will force a full reload?
          Thanks!

          Donovan

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