Navigation

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

    ThomasB

    @ThomasB

    0
    Reputation
    27
    Posts
    13
    Profile views
    0
    Followers
    1
    Following
    Joined Last Online
    Website 3deoskill.com

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

    Best posts made by ThomasB

    This user hasn't posted anything yet.

    Latest posts made by ThomasB

    RE: Object Plugin self.OptimizeCache(False) . How to refresh internal calculations

    @ferdinand

    Thanks Ferdinand,

    • I additionally implemented such a blink paramater the user can animate Led's on and off

    • the internal structure of the led construction:

    MyPluginNode
        Container(Null-Object)
            Dummies(Null-Object) (invisible in Editor and Render View)
                LED-Object(e.g. disc) with luminous-Material (Material was created and is live)
                LED-Object(e.g. disc) with non-luminous-Material and empty texture tag
            Block-Container(Multi-Instance-Object Referenz: Dummies)
                Block_1 (Null-Object)
                    Led_1 (Render-Instance-Object / Reference: eg. LED-Object with luminous-Material
                    Led_2 (Render-Instance-Object) / Reference: eg. LED-Object with luminous-Material
                    Led_3 (Render-Instance-Object) etc.
                    ...
                    Led_35 (Render-Instance-Object)
                Block_2 (Null-Object)
                    Led_1 (Render-Instance-Object)
                    Led_2 (Render-Instance-Object)
                    Led_3 (Render-Instance-Object)
                    ...
                    Led_35 (Render-Instance-Object)
                    
                .....
                Block_12
                    .....
    

    The Container(Null-Object) is returned
    I created so to say my own Cloner with Multiinstances

    The blink algorithm just exchanges the Reference in the LED instance object in the Blocks.
    The plugin has two Baselist Links for a luminous and non luminous material and if you insert some, one Dummies Object gets the luminous the other one the non-luminous Material
    You write the Text you want in a text-field and an internal led-font-dictionary with the indexes decides which of the 35 led's per block and letter are getting the luminous dummy or the non luminous dummy.
    If the user doesn't insert a luminous material , the led's just show the returned geometry because the reference material link in the texture tag of the luminous dummy object is empty.

    Yes maybe I remove the blink algorithm and let the user just animate the blink manually.
    Or I try this Tag thing, can I use a python tag?
    I do not know yet how to create such a tag-plugin with code together with my Object-Plugin (blame) and also I do not know how to write a shader 😞 . Not yet

    Best Regards

    posted in Cinema 4D SDK •
    RE: Object Plugin self.OptimizeCache(False) . How to refresh internal calculations

    Sorry Ferdinand for the bad explanation.

    The plugin creates Led blocks with 35 Led's each block. And every Led is an c4d.OInstance Object. Depending what LED is on it gets either a dummy object with the luminous material or one with a non luminous material.
    Internally I have written specific algorithms to let the Led's blink in different variations.
    However, this replacement of these dummy objects in the c4d.Oinstance objects is not displayed if optimize cache is True, because nothing will be changed in the plugin's UI.
    So either I set OptimizeCache to False, but then the performance and frame rate drops rapidly.
    The user can also turn led's off manually and set Keyframes for this......
    But to ensure good framerate and performance the user should also have the opportunity to turn the optmizie cache to True....like it is in the PythonGenerator....

    But I looked for a way which gives me better performance as I get with SetOptimizeCache(False)

    I already tried the method

    dirty: bool = op.CheckCache(hierarchyhelp) or op.IsDirty(c4d.DIRTYFLAGS_DATA)
    if not dirty:
        return op.GetCache(hierarchyhelp)
    

    but this doesn´t work because cinema4d doesn't recognize this blinking and exchange in the c4d.Oinstance objects.
    so that is the reason why I set optmizeCache to False when the user activates the blinking function, as you can do in the python generator

    Best Regards

    posted in Cinema 4D SDK •
    Object Plugin self.OptimizeCache(False) . How to refresh internal calculations

    Hi,
    in my Object Plugin I have set the Cache to False in my __init__method

    self.OptimizeCache(False)
    

    The problem I have now is. In my code there is a blink function which does some calculation when a specific parameter in the Plugin UI is checked.
    Internally it exchanges the reference object in the instances which were returned. And so calculates a looping blink behavior depending on the frame in the timeline.
    Since nothing is changing in the UI of the Plugin the blink thing doesn't work if OptimizeCache = True

    Is there any possibility to refresh the state of the returned object in another way ...I am not yet so familiar with the message system.
    EventAdd() doesn't work.

    My current workflow is:
    I set OptimizeCache to False if the parameter is checked otherwise it is True.

    Best Regards
    Tom

    posted in Cinema 4D SDK •
    RE: Make Description Parameter Uneditable

    @ferdinand
    As always thank you very much Ferdinand, it works as expected

    posted in Cinema 4D SDK •
    Make Description Parameter Uneditable

    Hi folks,

    I am to stupid for this I guess 🙂

    I created an Object Plugin and so the res, header and str files.
    The plugin works fine so far. But now I want to make some parameters uneditable, when the user switches a LONG with some Quicktabradio buttons, because some parameters have no impact when a specific mode is entered.

    I was able to hide the parameters successfully in my nodedata.GedDescription(self, node, id......) function
    with setBool...
    But when the plugin is getting started for the first time, it looks odd when some parameters suddenly appear once the user clicked some buttons. It is confusing.

    But as I have read in the forum it doesn´t work with the c4d.DESC_EDITABLE Description.

    So do I have to use the NodeData.GetDEnabling Method?

    so do I have to overload this function in my class with and what do I have to write in this class:

    def GetDEnabling(self, node, id, t_data, flags, itemdesc):
            pass
    
    
    • Where do I have to call this function? In my GetDDescription Method?

    .
    so for clarifying??
    node = op
    id = c4d.PY_LED_ANIMATION_DISTANCE
    t_data = c4d.DESC_EDITABLE

    • what is itemdesc????**

    • the itemdesc argument do I get the container with **```

    decription.GetParameterI(c4d.PY_LED_ANIMATION_DISTANCE, ar=None)
    

    I do not really understand some things here.

    ===============================================

    ok in the following figure you can see the entry

      1. Modus id = c4d.PY_LED_MODE with Quicktabradio int 0=dynamisch, 1=fest, 2=Buchstaben Ticker
      1. Animationdistanz id = c4d.PY_LED_ANIMATION_DISTANCE
      1. Vertikale Animationsdistanz id = c4d.LED_VERT_ANIMATION_DISTANCE

    once the user checks Modus/dynamisch the parameter 2. and 3. should turn to Not-Editable.
    If he checks Modus/fest and Modus/Buchstaben Ticker it should be editable

    Screenshot 2023-01-12 224420.png

    Best Regards
    Tom

    posted in Cinema 4D SDK •
    RE: Question: Takesystem...changing texture for each take

    First thank you Ferdinand,
    as always, you put so much effort in your answers, this is so great..
    Related to my code, yes there are of course weird things going on sometimes :-), I am not professional and the API is sometimes
    like a jungle and so Python, so I am messing up a few things...This process is called "learning" 🙂

    But anyways thank you for your detailed and quick answer....

    Sincerely Thomas

    posted in Cinema 4D SDK •
    Question: Takesystem...changing texture for each take

    Hi fellows,
    another stupid question from me

    Job:

    • We have a scene with a lot of different objects and a lot of takes.

    • Every take has a specific naming convention: 6 digits number - R number
      e.g. 123456 - R 1234567...

    • the client wants that the first 6 digits of the take is the filename of a picture.

    • The pictures are in a folder and already have that number as filename

    • Then he wants that every take changes the texture accordingly to it's name in a Main-Material
      Because there are so many takes , he wishes for an automated process with a script for instance

    My solution:

    • Get the path to the texture folder
    • Get the Main-Material
    • Create a Bitmap-Shader
    • Go step by step through the takes and grab the name
    • join path and name to get the file-name
    • simultanously changing the textures in the material
    • and adding them to the take-system by overriding each node

    Problem:

    • I get all the names, takes succesfully and so the filenames
    • The material is not updating and so the nodes in the takesystem.
    • The material does not recognize the texture-paths at all.
    • So I am using absolute paths because I do not know where he has installed the textures.
    • So there is no updating c4d.BITMAPSHADER_FILENAME and so the takes.

    Here is the code: ( a bit messy because I tried a few things, the code can definitely be shortened..But script works...

    import c4d
    from c4d import gui
    from c4d.modules.takesystem import TakeData
    import os
    
    
    
    def main():
    
    #check if auto take and override is checked
        if doc.GetTakeData().GetOverrideEnabling()== 4095 and doc.GetTakeData().GetTakeMode()== c4d.TAKE_MODE_AUTO:  
    
    #Get texture folder path
            dir_path = c4d.storage.LoadDialog(type=c4d.FILESELECTTYPE_ANYTHING,
                            title="Choose Folder for textures",
                            flags=c4d.FILESELECT_DIRECTORY)   
    
    #define material and shader
            mat=doc.SearchMaterial("Main-Material")
            shader=c4d.BaseList2D(c4d.Xbitmap)
            mat[c4d.MATERIAL_COLOR_SHADER]=shader
    
    #define take data and main take
            take_data = doc.GetTakeData()
            main_take = take_data.GetMainTake()
    
            take_data.SetCurrentTake(main_take)
    
    
    #check if main take has a child then continue the script
            if main_take.GetDown()!= None:
    
    #Go to the child of main take
                take_data.SetCurrentTake(main_take.GetDown())
                current=take_data.GetCurrentTake()
    
     #give the material the shader with the filename
    
                shader[c4d.BITMAPSHADER_FILENAME]=os.path.join(dir_path,current[c4d.ID_BASELIST_NAME].split(" -")[0]+".png")
     
    
                mat[c4d.MATERIAL_COLOR_SHADER]=shader
                mat.Update(True, True)
    
                try:
                    mat.InsertShader(shader)
                except:
                    pass
    
               #try to add the node to the take and override if existing (bad code :cry: )
                overrider=current.OverrideNode(take_data,mat,True)
                desc=overrider.GetAllOverrideDescID()
    
                for i in desc:
                    overrider.UpdateSceneNode(take_data,i)
                del desc
    
    
            #===Just to get the rest count of takes===================
                counter=0
                while take_data.GetCurrentTake().GetNext() != None:
                    take_data.SetCurrentTake(take_data.GetCurrentTake().GetNext())
                    counter+=1
    
    #aktivate the first child go down each take and change texture and add to take
                take_data.SetCurrentTake(main_take.GetDown())
    
                for i in range(counter):
    
                    take_data.SetCurrentTake(take_data.GetCurrentTake().GetNext())
                    current=take_data.GetCurrentTake()
    
    
                    shader[c4d.BITMAPSHADER_FILENAME]=os.path.join(dir_path,current[c4d.ID_BASELIST_NAME].split(" -")[0]+".png")
                    mat[c4d.MATERIAL_COLOR_SHADER]=shader
    
    #I do not know if I have to insert shader again, basically not , so I just tried
                    try:
                        mat.InsertShader(shader)
                    except:
                        pass
                    mat.Update( True, True)
    
    # I do not know if this is correct so I just overrided all
                    overrider=current.OverrideNode(take_data,mat,True)
                    desc=overrider.GetAllOverrideDescID()
    
                    for i in desc:
                        overrider.UpdateSceneNode(take_data,i)
    
    
                    c4d.EventAdd()
    
    
        else:
            c4d.gui.MessageDialog("Please Turn on Auto Take and Lock Overrides Mode")
    
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    I added the four pics with the correct filename and the c4d file. Simply save all in a folder and
    put the script into the script folder if you want, to test it out..

    Thank you very much

    Takesystem.c4d 34348.png 23456.png 23455.png 12344.png

    Take-tests.py

    posted in Cinema 4D SDK •
    RE: Help needed * .res files, dialogs etc...Plugin beginner

    So I figured it out....

    • first in the .res file the first group was named wrong, this is the group which directly comes after the basic and coords tab.....It has to be named ID_OBJECTPROPERTIES
      It costed me 2 hours to figure out, that I also have forgotten the "P" in OBJECT(P)ROPERTIES 🤢

    this f....... res , header and str. files concept ....I hate it....
    also you have to initialize the parameter in the plugin , too.....
    double work......

    so now it works

    res file:

    CONTAINER OCUBO
    {
        NAME Cube;
        INCLUDE Obase;
        //INCLUDE Mpreview;
    
    
    	GROUP ID_OBJECTPROPERTIES
    	{
    
    
            REAL SIDE{ UNIT METER; MIN 0.0;}
    
    
    
    	}
    
    	GROUP IHATEIT
    	{
    
    	    REAL LENGTH{ UNIT METER;}
    
    	}
    
    }
    

    .h-file

    #ifndef _OCUBO_H_
    #define _OCUBO_H_
    
    enum
    {
    
        //Ocubo  =  1000001,
    
    	SIDE      = 1001, // link [just for compatibilty <V9.200]
    	IHATEIT=1003,
    	LENGTH    = 1002,
    
    
    
    }
    
    #endif
    

    .str file

    STRINGTABLE  Ocubo
    {
        Cube "Settings";
    
    	SIDE "Side-Length";
    	LENGTH "Length";
    	IHATEIT "Hate this";
    
    
    
    }
    
    
    posted in Cinema 4D SDK •
    RE: How to move multiple objects axis to origin?

    Yes simply use a direction vector to move the points back

    Here is a script where the Z-Axis of all selected obects is set to Zero:

    import c4d
    
    
    # Main function
    def main():
        doc.StartUndo
        objs=doc.GetActiveObjects(0)
        points_list=[]
        pos_list=[]
    
        #==Append Position of every selected Object into a list ============
        for a in objs:
            pos_list.append(a.GetAbsPos())
    
        counter=0
        #===move every Object in Z to Zero and a inner for-Loop to move every point of the object back with a direction vector
    
        for i in objs:
    
            i.SetAbsPos(c4d.Vector(i.GetAbsPos().x,i.GetAbsPos().y,0))
            doc.AddUndo(c4d.UNDOTYPE_CHANGE, i)
            richtung=i.GetAbsPos()-pos_list[counter]
            single_points=[]
    
            for p in i.GetAllPoints():
                single_points.append(p-richtung)
    
            i.SetAllPoints(single_points)
    
    
            counter+=1
    
        doc.EndUndo()
        c4d.EventAdd()
    
    
    
    # Execute main()
    if __name__=='__main__':
        main()
    

    luckily it worked for me 🙂

    posted in Cinema 4D SDK •
    RE: Help needed * .res files, dialogs etc...Plugin beginner

    @m_magalhaes

    OK thank you, yes I already tried that with the GetVirtualObject.....but can I do my own init function? anyways....

    I changed the description now to my res filename....but he shows me now an error in line 9 in resfile, after calling the "plugin" in Cinema.

    In the meanwhile I just changed the filename and the names etc.

    CONTAINER CUBE_SETTINGS
    {
        NAME cube_object;
        INCLUDE Obase;
        INCLUDE Mpreview;
    
    	GROUP ID_CUBE_PROPERTIES
    	{
            GROUP
            {
    
                    REAL SIDE{ UNIT METER; MIN 0.0; }
            }
    
    
    	}
    }
    

    b52bae2f-44bb-4e94-a657-10af342f32b7-image.png
    Sincerely
    Thomas

    posted in Cinema 4D SDK •