Navigation

    • Register
    • Login
        No matches found
    • Search
    1. Home
    2. iplai
    iplai

    iplai

    @iplai

    3
    Reputation
    16
    Posts
    4
    Profile views
    0
    Followers
    2
    Following
    Joined Last Online
    Website github.com/iplai/c4djson

    • Profile
    • More
      • Following
      • Followers
      • Topics
      • Posts
      • Best
      • Groups
    iplai Follow

    Best posts made by iplai

    RE: Paste JSON Values on the Node Network?

    @bentraje
    I misunderstood your question in my previous reply.
    This is my trial:

    import c4d
    
    with open(r"Path\to\your\file.json") as f:
        c4d.CopyStringToClipboard(f.read())
        # Paste command in Node Editor
        # Command ID can be got by Script Log
        c4d.CallCommand(465002305)
    

    1.gif

    posted in Cinema 4D SDK •
    RE: C4D Parent constraint python

    @mats

    Maybe you should call the Set Inital State button of the tag and set the local offset vector as the target's negative vector.
    Here's the code:

    import c4d
    
    objList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER | c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    tag = c4d.BaseTag(c4d.Tcaconstraint)
    obj1, obj2 = objList[:2]
    obj1.InsertTag(tag)
    c4d.CallButton(tag, c4d.ID_CA_CONSTRAINT_TAG_SET_INITIAL_STATE) # SET INITIAL STATE
    tag[c4d.ID_CA_CONSTRAINT_TAG_PARENT] = True
    tag[30009, 1000] = obj2[c4d.ID_BASEOBJECT_REL_POSITION] * -1  # Local Offset P
    tag[30001] = obj2  # Target
    c4d.EventAdd()
    
    
    posted in Cinema 4D SDK •
    RE: Complete Replica of a Native Objects UI?

    There is a third-party module to serialize and deserialize the user data of any BaseList2D object in python dict format. Here's an example:

    c4d.ID_USERDATA: {
        (c4d.ID_USERDATA, 1): {
            c4d.DTYPE_: c4d.DTYPE_REAL,
            c4d.DESC_NAME: 'Data',
            c4d.DESC_SHORT_NAME: 'Data',
            c4d.DESC_MIN: 0,
            c4d.DESC_MAX: 1,
            c4d.DESC_STEP: 0.01,
            c4d.DESC_UNIT: c4d.DESC_UNIT_PERCENT,
            c4d.DESC_CUSTOMGUI: c4d.CUSTOMGUI_REAL,
            c4d.DESC_PARENTGROUP: (700, 5, 0),
        },
        (c4d.ID_USERDATA, 2): {
            c4d.DTYPE_: c4d.DTYPE_GROUP,
            c4d.DESC_NAME: 'Group',
            c4d.DESC_SHORT_NAME: 'Group',
            c4d.DESC_ANIMATE: c4d.DESC_ANIMATE_OFF,
            c4d.DESC_COLUMNS: 1,
            c4d.DESC_TITLEBAR: 1,
            c4d.DESC_DEFAULT: 1,
            c4d.DESC_PARENTGROUP: (),
        },
        (c4d.ID_USERDATA, 3): {
            c4d.DTYPE_: c4d.DTYPE_LONG,
            c4d.DESC_NAME: 'Data',
            c4d.DESC_SHORT_NAME: 'Data',
            c4d.DESC_UNIT: c4d.DESC_UNIT_INT,
            c4d.DESC_CUSTOMGUI: c4d.CUSTOMGUI_LONGSLIDER,
            c4d.DESC_MIN: 0,
            c4d.DESC_MAX: 100,
            c4d.DESC_STEP: 1,
            c4d.DESC_PARENTGROUP: ((700, 5, 0), (2, 1, 0)),
        },
    }
    

    Snipaste_2022-12-20_09-45-38.png
    The module is not fully tested, but it's enough for me for my daily scripting work. The processing of parameters is implemented in a way described by @ferdinand . Sort of like the .res file used by plugins developing, the json data defines the details of a parameter. If you feel like it, you can implement it yourself by refering to following functions:
    DumpParams
    DumpParamDetails
    DumpUserDataDetails
    LoadUserData
    ...
    Considering sometimes there's a huge amount of parameters, I spent a lot of time to judge and handle dirty parameters, namely the parameter has been changed, there is still no perfect way. If you don't care whether the parameter is dirty, problem goes easier. Maybe do some filters by restricting DescLevel.creator to a specific value etc.

    posted in Cinema 4D SDK •

    Latest posts made by iplai

    RE: HowTo set keyframes for PosXYZ/RotXYZ/ScaleXYZ with a script

    Hello @vannipo ,
    What you need may not a plugin, scripts is enough. In Command Manager, search your script's name, then assign the shortcut you like. Assign a shortcut key to each of your nine scripts, You can even drag the item out of the list tree view and turn it into a button.
    Snipaste_2023-01-12_06-08-50.png

    posted in Cinema 4D SDK •
    RE: Complete Replica of a Native Objects UI?

    There is a third-party module to serialize and deserialize the user data of any BaseList2D object in python dict format. Here's an example:

    c4d.ID_USERDATA: {
        (c4d.ID_USERDATA, 1): {
            c4d.DTYPE_: c4d.DTYPE_REAL,
            c4d.DESC_NAME: 'Data',
            c4d.DESC_SHORT_NAME: 'Data',
            c4d.DESC_MIN: 0,
            c4d.DESC_MAX: 1,
            c4d.DESC_STEP: 0.01,
            c4d.DESC_UNIT: c4d.DESC_UNIT_PERCENT,
            c4d.DESC_CUSTOMGUI: c4d.CUSTOMGUI_REAL,
            c4d.DESC_PARENTGROUP: (700, 5, 0),
        },
        (c4d.ID_USERDATA, 2): {
            c4d.DTYPE_: c4d.DTYPE_GROUP,
            c4d.DESC_NAME: 'Group',
            c4d.DESC_SHORT_NAME: 'Group',
            c4d.DESC_ANIMATE: c4d.DESC_ANIMATE_OFF,
            c4d.DESC_COLUMNS: 1,
            c4d.DESC_TITLEBAR: 1,
            c4d.DESC_DEFAULT: 1,
            c4d.DESC_PARENTGROUP: (),
        },
        (c4d.ID_USERDATA, 3): {
            c4d.DTYPE_: c4d.DTYPE_LONG,
            c4d.DESC_NAME: 'Data',
            c4d.DESC_SHORT_NAME: 'Data',
            c4d.DESC_UNIT: c4d.DESC_UNIT_INT,
            c4d.DESC_CUSTOMGUI: c4d.CUSTOMGUI_LONGSLIDER,
            c4d.DESC_MIN: 0,
            c4d.DESC_MAX: 100,
            c4d.DESC_STEP: 1,
            c4d.DESC_PARENTGROUP: ((700, 5, 0), (2, 1, 0)),
        },
    }
    

    Snipaste_2022-12-20_09-45-38.png
    The module is not fully tested, but it's enough for me for my daily scripting work. The processing of parameters is implemented in a way described by @ferdinand . Sort of like the .res file used by plugins developing, the json data defines the details of a parameter. If you feel like it, you can implement it yourself by refering to following functions:
    DumpParams
    DumpParamDetails
    DumpUserDataDetails
    LoadUserData
    ...
    Considering sometimes there's a huge amount of parameters, I spent a lot of time to judge and handle dirty parameters, namely the parameter has been changed, there is still no perfect way. If you don't care whether the parameter is dirty, problem goes easier. Maybe do some filters by restricting DescLevel.creator to a specific value etc.

    posted in Cinema 4D SDK •
    RE: Complete Replica of a Native Objects UI?

    Hi, @bentraje
    For each parameter input box, formula expressions are supported in c4d, x : represents the parameter's current value. If you want to change the intensity by 125% than their current value for each light, you can select all of them and simply input x * 1.25 .
    The document for Expanded Formula Entry by Multiple Selections is here:
    Snipaste_2022-12-18_04-33-07.png

    posted in Cinema 4D SDK •
    RE: C4D Parent constraint python

    @ferdinand
    Thanks, you are the best. This is exactly the internal operation I'm finding.

    posted in Cinema 4D SDK •
    RE: C4D Parent constraint python

    @ferdinand
    The Constrain Tag may not only influence position, but also rotation, scale. I think the set inital state button should be called as mentioned in my first reply:

    c4d.CallButton(tag, c4d.ID_CA_CONSTRAINT_TAG_SET_INITIAL_STATE) # SET INITIAL STATE
    
    tag[30009,1000] = -parent.GetRelPos() #?
    tag[30009,1001] = -parent.GetRelScale() #?
    tag[30009,1002] = -parent.GetRelRot() #?
    
    posted in Cinema 4D SDK •
    RE: C4D Parent constraint python

    @ferdinand
    I verified the scene again, the two methods do the same thing indeed. Forgive my mistakes last post.
    The problem is when the parent is not at original position, after apply the script, the offset arises.
    The selection order might also affect the result. I'm trying to figure it out.

    posted in Cinema 4D SDK •
    RE: C4D Parent constraint python

    @ferdinand @Mats
    I compared the two pieces of code and found the key diffence is the lines of creating the Constraint Tag:
    When you using MakeTag, c4d will do some internal operations I guess:

    tag: c4d.BaseTag = child.MakeTag(c4d.Tcaconstraint)
    

    While using BaseTag constructor, then InsertTag, no internal operations are done:

    tag = c4d.BaseTag(c4d.Tcaconstraint)
    child.InsertTag(tag)
    

    In my experience, for the most cases of tags, both of them work properly, apart from the above exception.

    posted in Cinema 4D SDK •
    RE: Mograph Objects Python

    @joel
    What you mentioned now is available in c4d 2023 version.
    Snipaste_2022-11-10_12-04-07.png
    Here is the link: Cinema 4D SDK 2023.1.0 documentation

    posted in Cinema 4D SDK •
    RE: Python Cloner Effectors Keyframe

    @joel
    The simplest way is to drag the parameter to the python console, then you could get desclevel id without dtype and creator. e.g.c4d.DescID(1500).
    1.gif
    If you want to get the DescID programmatically. I wrote a function to list all parameters and detail descriptions of an object. This may help you.

    import c4d
    
    def find_ident(value: int, prefix=""):
        for key, val in c4d.__dict__.items():
            if val == value and key.startswith(prefix):
                return f"c4d.{key}"
    
    def dump_params(obj: c4d.BaseList2D):
        def dump_param_desc(bc):
            for k, v in bc:
                ident = find_ident(k, "DESC_")
                if type(v) == str:
                    v = repr(v)
                if not ident:
                    continue
                if k == c4d.DESC_UNIT:
                    v = find_ident(v, "DESC_")
                if k == c4d.DESC_CUSTOMGUI:
                    v = find_ident(v, "CUSTOMGUI") or v
                if isinstance(v, c4d.Vector) and abs(v.x) > 1e10:
                    v = "Vector"
                print('\t', ident, ":", v)
    
        description = obj.GetDescription(c4d.DESCFLAGS_DESC_0)
        descid: c4d.DescID
        for bc, descid, _ in description:
            name = bc[c4d.DESC_NAME] or bc[c4d.DESC_SHORT_NAME]
            if not name:
                continue
            if descid[descid.GetDepth() - 1].dtype == c4d.DTYPE_GROUP:
                print("---------")
            print(name, descid, ":", repr(obj[descid]))
            dump_param_desc(bc)
            if bc[c4d.DESC_CUSTOMGUI] == c4d.CUSTOMGUI_SUBDESCRIPTION:
                for subvector in [c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z]:
                    subdescid = c4d.DescID(*[descid[i] for i in range(descid.GetDepth())])
                    subdescid.PushId(c4d.DescLevel(subvector))
                    subbc = description.GetParameter(subdescid)
                    name = subbc[c4d.DESC_NAME] or subbc[c4d.DESC_SHORT_NAME]
                    if not name:
                        continue
                    name = name.replace(" . ", ".")
                    print(name, ":", obj[subdescid])
                    dump_param_desc(subbc)
    
    if __name__ == "__main__":
        obj = doc.GetActiveObject()
        dump_params(obj)
    

    Following is the outputs to the end:

    Effectors (2009, 1009290, 1018639) : <c4d.InExcludeData object at 0x00000198DD88E9C0>
    	 c4d.DESC_NAME : 'Effectors'
    	 c4d.DESC_SHORT_NAME : 'Effectors'
    	 c4d.DESC_VERSION : 3
    	 c4d.DESC_ANIMATE : 0
    	 c4d.DESC_CUSTOMGUI : c4d.CUSTOMGUI_INEXCLUDE_LIST
    	 c4d.DESC_ACCEPT : <c4d.BaseContainer object at 0x00000198DD88DE00>
    	 c4d.DESC_IDENT : 'ID_MG_MOTIONGENERATOR_EFFECTORLIST'
    Plain (1500, 19, 1018544) : 0.99
    	 c4d.DESC_NAME : 'Plain'
    	 c4d.DESC_SHORT_NAME : 'Plain'
    	 c4d.DESC_VERSION : 3
    	 c4d.DESC_MIN : -1e+20
    	 c4d.DESC_MAX : 1e+20
    	 c4d.DESC_MINEX : 0
    	 c4d.DESC_MAXEX : 0
    	 c4d.DESC_STEP : 0.01
    	 c4d.DESC_ANIMATE : 1
    	 c4d.DESC_UNIT : c4d.DESC_UNIT_PERCENT
    	 c4d.DESC_CUSTOMGUI : c4d.CUSTOMGUI_REALSLIDER
    	 c4d.DESC_MINSLIDER : 0.0
    	 c4d.DESC_MAXSLIDER : 1.0
    	 c4d.DESC_REMOVEABLE : 0
    Plain.1 (1501, 19, 1018544) : 1.0
    	 c4d.DESC_NAME : 'Plain.1'
    	 c4d.DESC_SHORT_NAME : 'Plain.1'
    	 c4d.DESC_VERSION : 3
    	 c4d.DESC_MIN : -1e+20
    	 c4d.DESC_MAX : 1e+20
    	 c4d.DESC_MINEX : 0
    	 c4d.DESC_MAXEX : 0
    	 c4d.DESC_STEP : 0.01
    	 c4d.DESC_ANIMATE : 1
    	 c4d.DESC_UNIT : c4d.DESC_UNIT_PERCENT
    	 c4d.DESC_CUSTOMGUI : c4d.CUSTOMGUI_REALSLIDER
    	 c4d.DESC_MINSLIDER : 0.0
    	 c4d.DESC_MAXSLIDER : 1.0
    	 c4d.DESC_REMOVEABLE : 0
    

    Then you can get the DescID: c4d.DescID(c4d.DescLevel(1500, 19, 1018544))

    posted in Cinema 4D SDK •
    RE: C4D Parent constraint python

    @mats

    Maybe you should call the Set Inital State button of the tag and set the local offset vector as the target's negative vector.
    Here's the code:

    import c4d
    
    objList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER | c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    tag = c4d.BaseTag(c4d.Tcaconstraint)
    obj1, obj2 = objList[:2]
    obj1.InsertTag(tag)
    c4d.CallButton(tag, c4d.ID_CA_CONSTRAINT_TAG_SET_INITIAL_STATE) # SET INITIAL STATE
    tag[c4d.ID_CA_CONSTRAINT_TAG_PARENT] = True
    tag[30009, 1000] = obj2[c4d.ID_BASEOBJECT_REL_POSITION] * -1  # Local Offset P
    tag[30001] = obj2  # Target
    c4d.EventAdd()
    
    
    posted in Cinema 4D SDK •