• Project Tool Stops At Non-Existent Path

    Cinema 4D SDK project tool sdk
    4
    1
    0 Votes
    4 Posts
    954 Views
    M
    Hi @Yakuza just in case you do have space in your Cinema 4D space, so the projectool don't understand clearly your input so you need to escape it by adding "" so something like: kernel_app_64bit.exe g_updateproject="D:\MAXON_CODE\Maxon Cinema 4D 2023_CODE\sdk" Cheers, Maxime.
  • DragDrop Model from UserArea into Viewport or Object Manager

    Moved Bugs c++ r20 s26 sdk
    2
    0 Votes
    2 Posts
    970 Views
    M
    Hi Kent, so far for the moment the viewport drop operation are more related to scene management rather than scene creation. By that I means except for an asset being loaded which create new elements (scene, object, material, etc...) other drag command are just here to act on the active object. So regarding drag operation for file, only DRAGTYPE_FILENAME_IMAGE is allowed and an object should be selected, then a texture tag will be applied to this object and a new material with the texture will be automatically assigned. DRAGTYPE_FILENAME_SCENE is not supported. For DRAGTYPE_ATOMARRAY it is only allowed for some particular categories, like layers to be applied on the active object or even materials for the same condition, so in any case the layer/material should already be part of the scene. So for the moment the only workaround would be to create your own temporary asset and pass this asset to be inserted into the document. For more information about the asset API I let you read Asset API - Handbook but this is S26.0+ only. Cheers, Maxime.
  • Cinema 4D 2023 None bug

    Cinema 4D SDK sdk python windows
    3
    2
    0 Votes
    3 Posts
    598 Views
    DunhouD
    @ferdinand I Check with my home PC in R 2023, It works fine , And for some reason , It report a none last time I am pretty sure I have not insert a layer field in fieldlist ( I just miniest the scene for test code ) , But when I resart C4D today this none warning just gone Maybe It is just a oolong events I make some thing I don't know . Sorry for that . And Thanks for the TIPS , next post I will take a more spesific report cheers~
  • 0 Votes
    7 Posts
    1k Views
    DunhouD
    @ferdinand Thnaks for your help, I think it is enough for this specific toppic . It work as espected
  • some problem with CUSTOMGUI_BITMAPBUTTON

    Cinema 4D SDK s26 python sdk
    3
    2
    0 Votes
    3 Posts
    565 Views
    M
    thank you very much! It's help me a lot! sorry about the multiple topics, I'll take them apart next time
  • Remove Shortcut failed

    Cinema 4D SDK
    3
    1
    0 Votes
    3 Posts
    437 Views
    DunhouD
    @ferdinand Thank you for detailed explain . It's great to add a shortcut container document update and small examples , actually , more examples on sdk or Github is really helpful. After reading I try to re-write it and add some functions like add shortcut or check plugin's shortcut list, It's all worked as expected . Shortcut BaseContainer explain is that great to move on . By the way , from those examples , I learned and try to keep code style as easy to read and repair like yours at the same time . So much appreciated.
  • GeDialog Failing To Open

    Cinema 4D SDK c++ s26 sdk
    6
    0 Votes
    6 Posts
    1k Views
    J
    Thanks for the response. This seems to have solved the problem. John Terenece
  • InExcludeData modifying in the ParalelFor?

    Cinema 4D SDK c++ s26 sdk
    7
    0 Votes
    7 Posts
    1k Views
    ferdinandF
    Hello @yaya And actually as I understand it is pretty logical. I have 2 InExData parameters in my plugin. So when I copying 3000 items into 2 InExData`s, plus adding 3000 objects into the scene, then the number of operations increases up to 9 000. It depends a bit on what you consider an 'operation' in this context, but I would say your calculation is at least misleading. Due to the copying nature of IncludeExcludeData::InsertObject, inserting objects is not a constant cost operation (other than your example implies). It scales linearly with the number of items already in the list (in practice probably even a little bit worse, because the copying itself calls a function which is non-constant). So, when you have a list with 5 items and add one, it is 5 + 1 = 6 - you must copy over the five old items and then add the new one - operations. And adding 5 items in total to an empty list would be 1 + 2 + 3 + 4 + 5 = 15 operations. The term operations is a bit fuzzy here, and there is a lot of room for interpretation, but what I want to make clear is that adding an item to an InExcludeData is not a constant operation. So, adding 3000 items to an InExcludeData does not result in 9000 operations, but 4498500. From this also follows, that it is computationally advantageous to store items in a larger number of lists, e.g., adding to two InExcludeData 1500 items each, costs 1124250 operations per batch, i.e., 'only' 2248500 operations for all 3000 items. Splitting up the data is IMHO your best route of optimization. InExcludeData is also simply not intended for such a large number of objects being stored in them. And as stressed before: I would really test first if InExcludeData is indeed the culprit. ::InsertObject has been designed in a way which does not mesh that well with what you want to do. But I do not really see it eating up 10 seconds, even for 3000 objects. I personally would expect the other calls in your loop to take up more time. But that is very hard to guesstimate from afar, and I might be wrong. Cheers, Ferdinand
  • embed interface

    Cinema 4D SDK python sdk
    6
    4
    0 Votes
    6 Posts
    853 Views
    M
    @ferdinand thanks a lot, best wishes!
  • something problem with using TreeViewCustomGui

    Cinema 4D SDK python sdk
    3
    2
    0 Votes
    3 Posts
    457 Views
    M
    @ferdinand thank you very much,it had been solved According to your method,have a good day!
  • Getting keyboard commands in GeDialog()

    Cinema 4D SDK c++ sdk
    7
    1 Votes
    7 Posts
    1k Views
    ferdinandF
    Hello @c4ds, thank you for reaching out to us. GetInputState() Just as a FYI, while you not might remember me, I was actually already around on the old forum So, I had a look again, looking at our: Codebase: Nothing is using BFM_INPUT_CHANNEL in this manner, not even really, really, really old code. Plugin Café History: Yes, there are some mentions of GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, but these come exclusively from users who a. Have problems with retreiveing the pressed key b. Not use the method to retreive any speciifc key and are only intersted in modifiers or other data provided in the response container. I did not find any code examples posted by Maxon using this form. I do not want to be rude here, but what you are doing is not correct and likely never was. This code floated around on Plugin Café and apparently people were copying each other but the code is at least now simply wrong (when one is interested in polling specific keys). Yes, you can use GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, bc) and this will not crash or any thing, but it is also meaningless. You could also call GetInputState(BFM_INPUT_KEYBOARD, 123456789, bc) and it would be as meaningful. If you are not interested in a specfic key being pressed, than this will also 'work' for you as the askchannel argument is then irrelevant. But we should really stop indicating that this is the right way to go, because that is where all the confusion comes from. Find a Python script at the end of the posting which in detail demonstrates this. Please stop indicating that this is a valid approach, as people will read this and then the cycle starts over again. Input Events Page for the C++ Documentation Thank you for making me aware of this. The target of these links, page_input_events has long been removed. I still have access to that archived page, and while the page was not too useful, I can only speculate why it has been done in this form. I will fix this this in an upcoming release. In the meantime, you should look at: the BFM Symbol Group: This however does not contain only input event symbols, but all GUI related event symbols. Input event related symbols folllow the form BFM_INPUT_... plus things like the KEY symbols or the Input Events page of the Python docs which is much better. Something like this unfournetely never existed in C++ the old C++ page was entierly different. Maybee it got removed in order to make room for something similar to the Python page, and then things were somehow not carried out? Long story short, I will provide a meaningful input events page for C++ in the upcoming release. In the meantime I would recommend the Python page. Cheers, Ferdinand The code for GetInputState(BFM_INPUT_KEYBOARD, BFM_INPUT_CHANNEL, bc) being not a meaningful thing: """Demonstrates that #BFM_INPUT_CHANNEL does not carry any meaning as the argument #askchannel for GetInputState. """ import c4d def main() -> None: """ """ bc: c4d.BaseContainer = c4d.BaseContainer() if not (c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, c4d.BFM_INPUT_CHANNEL, bc)): raise RuntimeError("Could not poll input event.") # Iterate over the container, there is nothing meaningful in there when you want to query a # specific key. print ("\nThe result container:") for key, value in bc: print (f"key: {key}, value: {value}") # And here some selected values to be a bit more verbose. print ("\nSelected values:") print (f"{bc[c4d.BFM_INPUT_CHANNEL] = }") # Will return 1768973153, i.e., itself. print (f"{bc[c4d.BFM_INPUT_VALUE] = }") # Will return False. print (f"{bc[c4d.BFM_INPUT_ASC] = }") # Will return the empty string. # We can of course still use the result container to poll for things that are also evaluated as # for example modifier keys (or the mouse position in case of the mouse device). print ("\nThe container is still valid for other stuff, but BFM_INPUT_CHANNEL is" + "meaningless in that context:") print (f"BFM_INPUT_CHANNEL: {bc[c4d.BFM_INPUT_MODIFIERS] = }") # But we would not have to use BFM_INPUT_CHANNEL for that, we also just could do this here: bc: c4d.BaseContainer = c4d.BaseContainer() if not (c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, 123456789, bc)): raise RuntimeError("Could not poll input event.") print (f"123456789: {bc[c4d.BFM_INPUT_MODIFIERS] = }") # And just for completeness, in case someone is just reading this snippet, here is how you # should use these functions: print ("\nHow it should be done:") bc: c4d.BaseContainer = c4d.BaseContainer() # Querying for a specific key with GetInputState. print ("\nQuerying a specific input state:") # Note that you must poll for upper case characters, e.g., X instead of x. if not c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, ord ("X"), bc): raise RuntimeError("Failed to query input events.") # Test if the queried key is indeed being pressed. print (f"{bc[c4d.BFM_INPUT_VALUE] == 1 = }") # Test if this did co-occur with a CTRL button press. print (f"{bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = }") # Querying for the general state with key with GetInputEvent, i.e., capturing all inputs and # not only a specific one. print ("\nQuerying the current input state:") bc: c4d.BaseContainer = c4d.BaseContainer() if not c4d.gui.GetInputEvent(c4d.BFM_INPUT_KEYBOARD, bc): raise RuntimeError("Failed to query input events.") # Get the key which is currently be pressed as an ASCII value. print (f"{bc[c4d.BFM_INPUT_CHANNEL] = } ({chr (bc[c4d.BFM_INPUT_CHANNEL])})") # We can still read all the other things which are written into an input event container, as # for example a modifier key state. print (f"{bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = }") if __name__ == '__main__': main() An example output for pressing CTRL + X while running the script: The result container: key: 1768973430, value: 1801812322 key: 1768973153, value: 1768973153 key: 1768976737, value: 2 key: 1768975727, value: 258 key: 1768978017, value: 0 key: 1768977985, value: 0.0 key: 1801548643, value: Selected values: bc[c4d.BFM_INPUT_CHANNEL] = 1768973153 bc[c4d.BFM_INPUT_VALUE] = 0 bc[c4d.BFM_INPUT_ASC] = '' The container is still valid for other stuff, but BFM_INPUT_CHANNEL ismeaningless in that context: BFM_INPUT_CHANNEL: bc[c4d.BFM_INPUT_MODIFIERS] = 258 123456789: bc[c4d.BFM_INPUT_MODIFIERS] = 258 How it should be done: Querying a specific input state: bc[c4d.BFM_INPUT_VALUE] == 1 = True bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = True Querying the current input state: bc[c4d.BFM_INPUT_CHANNEL] = 88 (X) bc[c4d.BFM_INPUT_QUALIFIER] == c4d.QUALIFIER_CTRL = True >>>
  • How to detect a new light and pram change?

    Cinema 4D SDK s26 sdk python windows
    6
    0 Votes
    6 Posts
    2k Views
    DunhouD
    @bentraje Thanks a lot ! I always want to spend some thing to do this , but unfortunately I am struggling to work with rendering . If I have some time hopes I can change this a bit more
  • 0 Votes
    6 Posts
    1k Views
    ferdinandF
    Hey @everyone, Yes, the Script Log can be quite handy, especially in cases like these where no symbols do exist. But one should also keep in mind that integer identifiers can sometimes change, and we do not publish such information then. It is therefore best to use the symbols when they exist, as doing so will avoid that problem. Cheers, Ferdinand
  • SaveWorldPreferences() in Python

    Cinema 4D SDK
    5
    0 Votes
    5 Posts
    882 Views
    a_blockA
    Hi Ferdinand, thanks a lot! No ETA needed, I'm grateful it will be added eventually. Cheers, Andreas
  • 0 Votes
    5 Posts
    978 Views
    ManuelM
    Hi, We do not provide "on demande" script. We are here to share the knowledge and help you to find the information you need, but you must learn how to code and learn how some principales works. I provided you a thread where Ferdinand is explaining how it works to move an object to another position. We have a new example in our github repository that will help you to understand how it is done. In your case, there is no function that is doing that. You must move the object's axis at the position (0, 0, 0) and move the points at the place they were. It is a two steps operation. Cheers, Manuel
  • 0 Votes
    1 Posts
    373 Views
    No one has replied
  • Programmatically create a palette?

    Cinema 4D SDK c++ sdk
    4
    0 Votes
    4 Posts
    1k Views
    ferdinandF
    Hello @ECHekman, It is very unlikely that this will ever change unless we do a fundamental rewrite of our UI core (which itself is not that unlikely but there are no current concrete plans or an ETA, Cinema 4D could keep using its current UI core for another decade). What Redshift, or more concretely things like the foreground object, are doing, is not loading or modifying palettes. They are modifying the state of the command via CMD_HIDDEN. For things where you usually do not have control over the command implementation, you can register a CommandGetStateDelegate for a specific command ID. This delegate will be called whenever the state of the command is queried, and you can then modify the state as you see fit. Cheers, Ferdinand Code // Demonstrates how to register a CommandGetStateDelegate for a specific command ID, allowing us to // override the CommandData::GetState behavior of the command, i.e., how its enabled/checked/ // hidden (and more) behavior is. // // Doing this is usually only necessary if the command implementation is not under our control, as // for example, for scene elements (NodeData, ObjectData, etc.) where we usually do not implement the // command ourselves but let Cinema 4D handle it. // // NEVER IMPLEMENT ANY STATE DELEGATES FOR COMMANDS THAT YOU DO NOT OWN. // This is the state handler for the foreground object command. It will hide the command if the active // renderer is Redshift. namespace maxon { MAXON_DECLARATION_REGISTER(CommandGetStateDelegates, NumToString<Oforeground>::value) { CommandGetStateDelegate delegate = [](cinema::BaseDocument* doc) -> Int32 { Int32 state = cinema::CMD_ENABLED; if (doc) { cinema::RenderData* rd = doc->GetActiveRenderData(); if (rd) { const Bool isRedshiftActiveRenderer = rd->GetDataInstance()->GetInt32(RDATA_RENDERENGINE) == VPrsrenderer; if (isRedshiftActiveRenderer) state |= cinema::CMD_HIDDEN; } } return state; }; return delegate; } } // namespace maxon
  • Retrieving camera view volume

    Cinema 4D SDK sdk c++ maxon api
    3
    1
    0 Votes
    3 Posts
    618 Views
    U
    @cairyn Thank you!
  • Add Database to the Asset Browser

    Cinema 4D SDK c++ r25 s26 sdk
    2
    0 Votes
    2 Posts
    457 Views
    ferdinandF
    Hey @kbar, thank you for reaching out to us. How to add asset databases and others things are all explained in the Asset API Handbook. Your specific case is dealt with in the example Add User Databases. You can technically also take a route via the Asset Browser preferences in the Cinema 4D Preferences dialog and the GUI gadget showing these database entries, completely ignoring the Asset API, but I would not recommend doing this. Cheers, Ferdinand
  • How to use GeUserArea.DrawCustomButton()

    Cinema 4D SDK python sdk s26
    5
    1
    0 Votes
    5 Posts
    730 Views
    K
    Hi @m_adam , It is unfortunate because I thought it would be useful if it were available, but I understand. Thank you for your prompt response!