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

    Setting Constraint Target

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 612 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 16/10/2015 at 05:07, xxxxxxxx wrote:

      Hello!
      I'm trying to write my first experimental lines of Python code in C4D.

      Allow me to first explain what I'm after:
      Unfortunately, C4D has no "working pivot" yet, like XSI or 3ds Max.
      For those unfamiliar - it allows for simple and non-destructive repositioning of any object selection, without changing any axes.
      In C4D's component mode, the Axis pretty much already works like this.
      Yet, in object mode, when the selection contains not only editable meshes but also parametric objects like primitives, nulls or generators, moving the Axis in Axis mode can lead to undesirable offsets of those parametric objects.
      Also, there seems to be no decent way to utilize snapping as needed.

      A workaround could be to temporarily group the objects, and moving the parent null, but that could rip objects out of their hierarchy.

      So, here's the script idea:
      - Create a null, call it "TempAxis", create a second null as it's child.
      - Create a Parent Constraint on each selected object, Link the target to the child null.
      - Select the TempAxis, enter Axis mode - script ends here.
      Now the user can now snap the TempAxis null to a first position, leave Axis mode, move to the second postion, and the selected objects follow. Voilá, a working pivot - theoretically.
      (To avoid cluttering the scene with lots of Parent Constraint Tags, some cleaning up  would be done beforehand in the script.)

      Here's the problem:
      I figured how to create the Parent Constraint Tag...

      #oSel = some object
      oTag = oSel.MakeTag(1019364)
      oTag[c4d.ID_BASELIST_NAME]='_TEMP_'
      oTag[c4d.ID_CA_CONSTRAINT_TAG_PARENT] = True

      ... how do I link the target to an object (the child null)?

      Many thanks!!
      Eugen

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

        On 16/10/2015 at 12:05, xxxxxxxx wrote:

        Hi,

        the easiest way to find out about IDs is to simply drag a parameter into the command field at the bottom of the console window.
        As the Constraint tag can have an arbitrary number of different constraints, the IDs are dynamic.
        The first Parent constraint for example has 30001 (use above drag method to find out more).

        Here's some code to get you started:

        import c4d
        from c4d import gui
          
        def main() :
          listSel = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
          if len(listSel) == 0:
            return
          
          oTempAxis = c4d.BaseObject(c4d.Onull)
          if oTempAxis is None:
            return
          oTempAxis.SetName("TempAxis")
          oChild = c4d.BaseObject(c4d.Onull)
          if oChild is None:
            return
          oChild.SetName("Child")
          oChild.InsertUnder(oTempAxis)
          doc.InsertObject(oTempAxis)
          
          for obj in listSel:
            oTag = obj.MakeTag(1019364) # Constraint tag
            if oTag is None:
              break
            oTag.SetName('_TEMP_')
            oTag[c4d.ID_CA_CONSTRAINT_TAG_PARENT] = True
            oTag[30001] = oChild # NOTE: These IDs are dynamic IDs, depending on number and type of constraint
          
          doc.SetActiveObject(oTempAxis, c4d.SELECTION_NEW)
          doc[c4d.DOCUMENT_AXIS] = True # Enable Axis mode
          c4d.EventAdd()
          
        if __name__=='__main__':
          main()
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 17/10/2015 at 01:23, xxxxxxxx wrote:

          Thanks a lot, Andreas!!

          That's the trick:
          oTag[30001] = oChild
          Interesting are the ways of C4D...

          Here's my go at it: (how do I get this dashed code frame?)

          #Temporary Axis import c4d from c4d import gui from c4d.modules import snap def main() : oDoc = c4d.documents.GetActiveDocument() if oDoc.IsEditMode() : # No Temp Axis is needed in Component mode. # We simply assume that the user wants to turn on Axis Mode. oDoc[c4d.DOCUMENT_AXIS] = True # Axis mode return else: # Object mode lSel = oDoc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0) # Get selection without children. if len(lSel) == 0: return # Clean up previous Temp Axis and Constraint Tags. oAxis = oDoc.SearchObject('_TEMP_AXIS_') if oAxis: oAxis.Remove() for oSel in lSel: lTags = oSel.GetTags() for oTag in lTags: if oTag.GetName() == '_TEMP_AXIS_': oTag.Remove() # Create "Temp Axis" Null oTempAxis = c4d.BaseObject(c4d.Onull) if oTempAxis is None: return oTempAxis.SetName('_TEMP_AXIS_') oTempAxis[c4d.NULLOBJECT_DISPLAY] = 1 # Display as a point, not dot. oTempAxis[c4d.NULLOBJECT_ORIENTATION] = 1 # XY # We want the Temp Axis to be moved in Axis mode with "child compensation". # For that, we need a child null. oNull = c4d.BaseObject(c4d.Onull) oNull.SetName('_TEMP_AXIS_NULL_') oNull[c4d.NULLOBJECT_DISPLAY] = 1 oNull[c4d.NULLOBJECT_ORIENTATION] = 1 oNull[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 1 oNull.InsertUnder(oTempAxis) oDoc.InsertObject(oTempAxis) # The selected objects are moved via Constraint Tag. for oSel in lSel: oTag = oSel.MakeTag(1019364) oTag[c4d.ID_BASELIST_NAME] = '_TEMP_AXIS_' oTag[c4d.ID_CA_CONSTRAINT_TAG_PARENT] = True # Parent constraint oTag[30001] = oNull doc.SetActiveObject(oTempAxis, c4d.SELECTION_NEW) oDoc[c4d.DOCUMENT_AXIS] = True # Enable Axis mode c4d.CallCommand(c4d.ID_MODELING_MOVE) # Enable Move Tool snap.EnableSnap(True, oDoc)# Enable Snapping c4d.EventAdd() def Group(lObj) : oNull = c4d.BaseObject(c4d.Onull) for oObj in lObj: oObj.InsertUnder(oNull) return oNull if __name__=='__main__': main()

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

            On 17/10/2015 at 01:27, xxxxxxxx wrote:

            Usage:
            Put the script under some shortcut (mine's 'T'), and Axis mode under another (mine's 'D').

            Select some objects, press T, move/snap to the source location, press D, move to the target location.

            Works allright for now, although there are special cases to take care of, like editable meshes in component mode are selected, but also parametric objects.

            Best regards
            Eugen

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

              On 20/10/2015 at 07:24, xxxxxxxx wrote:

              Hello Andreas!
              Could you please also show me the script line how to change the Constraint's "Priority" parameter to something else? (I need "Initial")

              Thanks a lot!
              Best
              Eugen

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

                On 21/10/2015 at 12:58, xxxxxxxx wrote:

                Never mind, I figured:
                http://www.cineversity.com/wiki/Python%3A_Setting_Priorities/

                Sorry for the noise!
                Best regards
                Eugen

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