• Python Objekte X Y Z

    Moved Cinema 4D SDK python r21 windows macos
    8
    0 Votes
    8 Posts
    1k Views
    W
    Thank you very much!
  • How to get Data unit

    Cinema 4D SDK r21 python
    3
    1
    0 Votes
    3 Posts
    411 Views
    chuanzhenC
    @ferdinand Thanks,great!
  • BaseDraw::DrawTexture alpha issue

    Cinema 4D SDK r20 r21 c++
    5
    1
    0 Votes
    5 Posts
    820 Views
    C4DSC
    @m_magalhaes [image: 1631562541042-gradients.png] Did some more testing, using the original code and the conversion code, with linear workflow on and off. When I look at the original code with linear workflow OFF, this most resembles the gradient from Photoshop. Except for the gap at the top .. obviously. The result from conversion code with linear workflow ON is what I am using now, as this provides the smallest gap. And to my eyes that result looks the most linear.
  • Implementing a watermark on render

    Cinema 4D SDK c++ windows r21
    6
    0 Votes
    6 Posts
    1k Views
    ferdinandF
    Hello @dunhou, Thank you for reaching out to us. Please read our Forum Guidelines regarding the scope of topics, your question does not seem to be a valid follow-up question to me, and therefore should be its own topic. I also struggle to see how this is an API question, as you seem to report an end-user problem which has nothing to do with one of our APIs. Please contact user support via the Support Center for such questions. Cheers, Ferdinand
  • Drag and Drop Gradient Data onto a Gradient

    Cinema 4D SDK c++ r20 r21 r23 s22 s24 sdk
    5
    0 Votes
    5 Posts
    787 Views
    ferdinandF
    Hello @kbar, without any further questions, we will consider this topic as solved by Monday, the 25th and flag it accordingly. Thank you for your understanding, Ferdinand
  • Filename::SetMemoryReadMode Docs don't seem right.

    Moved Bugs c++ r20 r21 r23 s22 s24 sdk
    4
    1
    0 Votes
    4 Posts
    977 Views
    ferdinandF
    Hello @kbar, I should have replied here since there is at least an implied request in your last answer. I have added a task for this in our documentation task pool and added the tracking tag to this topic. Without any further questions or replies, we will consider this thread as solved by Monday the 20th and flag it accordingly. But that does not mean that the topic is forgotten, due to its to fix tag. Thank you for your understanding, Ferdinand
  • Get string value from long cycle.

    Cinema 4D SDK c++ r21
    3
    0 Votes
    3 Posts
    622 Views
    O
    I came up with this solution which is working fine. Thanks for your help. std::string getDropDownName(Description* const description, Int32 group_id, Int32 SelectedItem) { const DescID* singleid = description->GetSingleDescID(); const DescID cid = DescLevel(group_id, DTYPE_LONG, 0); std::string selected_name = ""; if (!singleid || cid.IsPartOf(*singleid, nullptr)) { AutoAlloc<AtomArray> arr; BaseContainer* selectionParameter = description->GetParameterI(DescLevel(group_id, DTYPE_LONG, 0), arr); if (selectionParameter != nullptr) { BaseContainer* items = selectionParameter->GetContainerInstance(DESC_CYCLE); if (items != nullptr) { selected_name = items->GetData(SelectedItem).GetString().GetCStringCopy(); } } } return selected_name; }
  • 0 Votes
    5 Posts
    511 Views
    chuanzhenC
    @m_adam Thanks
  • Target Tag not fixing to target

    Cinema 4D SDK r21 python
    8
    0 Votes
    8 Posts
    2k Views
    A
    Hi @Cairyn, Understood and works like a charm! Many thanks guys
  • SplineCustomGui settings issue

    Cinema 4D SDK r21 python windows
    11
    2
    0 Votes
    11 Posts
    2k Views
    ferdinandF
    You need to call NodeData.InitAttr() in NodeData.Init. E.g.: def Init(self, node): """ """ self.InitAttr(node, float, c4d.PY_TUBEOBJECT_RAD) self.InitAttr(node, float, c4d.PY_TUBEOBJECT_IRADX) node[c4d.PY_TUBEOBJECT_RAD] = 200.0 node[c4d.PY_TUBEOBJECT_IRADX] = 50.0 return True But you should check the allocation problem first, it is the most likely culprit. Se the edit in my last posting. Cheers, Ferdinand
  • DRAGANDDROP_FLAG_FORBID

    Cinema 4D SDK c++ r21
    2
    1
    0 Votes
    2 Posts
    426 Views
    M
    Hi @AiMiDi, MSG_DRAGANDROP will be received when the host receive a drag, I didn't tried but I guess only dialog can react to this message. In you case you will need to set the NBIT NBIT_NO_DD like so op.ChangeNBit(c4d.NBIT_NO_DD, c4d.NBITCONTROL_SET). Cheers, Maxime.
  • ZipFile OpenEncrypted for read not working

    Cinema 4D SDK c++ r21 sdk
    7
    0 Votes
    7 Posts
    1k Views
    ferdinandF
    Hello @kbar, in case you are interested in it for academic purposes or someone else is, here is a full example for how to use some stuff within the maxon::StreamConversions namespace. I included examples for hashing, encrypting, and compressing inputs. The example also reverses the operation for compression and encryption. This might be helpful, because there is a bug in the Stream Conversions Manual AES encryption example code, which cause the code to fail due to not filling up the plain text message to the correct block size. There are also some minor bits and bobs which might not be obvious. I have reached out to the developers about some problems of mine regarding the example code in the docs (which was provided by them, not us) and how Cinema deals with the term block size in the context of AES encryptions. My variant does run and does what I would expect it to do. I will report back here if there are any relevant updates (which I would not anticipate being the case). Cheers, Ferdinand The output: Password: wubba lubba dub-dub, Secret: d7a2f8231c17aabc885683fb4781a648 Content: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd guber, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Encrypted content: {0,0,3,22,120,-38,-43,-110,49,110,3,49,12,4,-65,-78,15,48,-18,15,-23,-35,-27,5,60,-119,56,48,-106,-60,-117,72,30,-32,-33,-121,118,82,36,-123,-35,-91,112,-53,37,119,23,3,-98,117,114,-121,-20,22,29,85,-101,78,-104,56,-88,-77,-97,80,116,24,59,123,-28,-112,106,-18,20,25,27,-72,-119,-49,19,-116,43,-86,80,-57,-48,17,-3,10,-106,-39,-75,-62,-71,-17,105,34,-29,-112,26,-61,17,-114,70,107,-122,-128,-3,59,-128,-47,105,27,4,106,-14,25,-41,52,-32,73,-2,-53,-17,-48,22,-69,7,45,120,115,28,60,21,-84,118,-69,-90,82,-62,110,-5,-114,-113,48,87,-44,-48,31,-53,-69,-50,-124,-55,107,-12,5,-17,89,26,37,123,18,46,100,21,-40,98,-27,-20,60,52,99,8,78,23,-23,-108,-94,-47,40,30,121,108,-114,-13,67,16,-53,19,-19,15,-92,23,36,115,7,-77,77,30,-1,14,-25,-91,62,-24,11,106,-106,31,-35,0,94,-62,-56,-61,-127,58,-108,-54,89,-93,-64,10,-42} Decrypted content: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd guber, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. The code: // Example for a maxon API conformant implementation to encrypt and compress text data. // // This mostly showcases the maxon::StreamConversions namespace which contains operations for // streams of data, not just text. The example showcases the three important functionalities of // compression, encryption and hashing of StreamConversions. // // This will effectively take an input string and compress and then encrypt it, and after that // reverse the operation. I deliberately left out file operations here, to make this a bit more // streamlined. File operations would have to be done with maxon::BaseStreamInterface types (in- // and output streams) within the maxon API. // // As discussed in: // https://developers.maxon.net/forum/topic/13449 #include "c4d.h" #include "c4d_symbols.h" #include "maxon/cryptography.h" #include "maxon/cryptography_hash.h" #include "maxon/datacompression.h" #include "maxon/iostreams.h" #include "maxon/secure_random.h" #include "maxon/streamconversion.h" /// ----------------------------------------------------------------------------------------------- /// Hashes a password into a 32 characters secret. /// /// Could also be done with maxon::GetPasswordHash() and maxon::HashPasswordWithSalt() in a more /// convenient form. /// /// @param[in] password The password to hash. /// @return The hashed password. /// ----------------------------------------------------------------------------------------------- maxon::Result<maxon::String>GetAES128Secret(const maxon::String password) { iferr_scope; // The input password and a temporary hash result as arrays. const maxon::BaseArray<maxon::Char> secret = password.GetCString() iferr_return; maxon::BaseArray<maxon::UChar> hash; // Use the StreamConverions MD5 hash to hash the password into a 32 characters secret. const maxon::StreamConversionRef md5 = maxon::StreamConversions::HashMD5().Create() iferr_return; md5.ConvertAll(secret, hash) iferr_return; // Get the hash as a hex string. const maxon::String result = maxon::GetHashString(hash) iferr_return; return result; } /// ----------------------------------------------------------------------------------------------- /// Compresses and encrypts an input string. /// /// @param[in] content The input text to compress and encrypt. /// @param[in] secret The encryption secret. /// @return The compressed and encrypted content as a char array. /// ----------------------------------------------------------------------------------------------- maxon::Result<maxon::BaseArray<maxon::Char>>GetEncrypted( const maxon::String content,const maxon::String secret) { iferr_scope; // The in- and output as char arrays. maxon::BaseArray<maxon::Char> plaintextContent = content.GetCString() iferr_return; maxon::BaseArray<maxon::Char> encryptedContent; // The compression settings, the compression rate can lie between 0 and 9, where 9 is the // strongest (and slowest) compression. maxon::DataDictionary settings; settings.Set(maxon::STREAMCONVERSION::ZIP::ENCODER::COMPRESSION, maxon::Int(9)) iferr_return; settings.Set(maxon::STREAMCONVERSION::ZIP::ENCODER::WRITESIZE, true) iferr_return; // Build a CryptoKey for an AES encryption. const maxon::Id encoderID = maxon::StreamConversions::AesEncoder.GetId(); const maxon::Int blockSize = 128; const maxon::Int keySize = 128; const maxon::BaseArray<maxon::Char> key = secret.GetCString() iferr_return; const maxon::CryptoKey cryptoKey (encoderID, blockSize, key.GetFirst(), keySize); maxon::DataDictionary cryptoSettings; cryptoSettings.Set(maxon::CryptographyOptions::CRYPTOKEY, cryptoKey) iferr_return; // We can either compress first and then encrypt the data or do it the other way around. I did // choose to compress first, since trying to decompress data first is relatively common attack // pattern. Encrypting first and then compressing might yield more favorable compression rates. // This will be most impactful when the plain text is relatively small, due to us filling // up the plain text message up to the AES encryption block size further down below. So, if the // compressed message happens to be 17 bytes long, the code below will fill it up to 32 bytes. // If we compress after encrypting, we will also compress that "filling up". But since the // maximum overhead due to this is 15 bytes, it can be ignored IMHO. const maxon::StreamConversionRef zipEncoder = maxon::StreamConversions::ZipEncoder().Create(settings) iferr_return; zipEncoder.ConvertAll(plaintextContent, encryptedContent) iferr_return; // Make sure the compressed data is null terminated. We are going to have to fill up this data to // the fixed block size of an AES encryption. And we are going to use this null as a marker when // we later decrypt the data and then have to separate the message from the "fill-up"-content. encryptedContent.Append(0) iferr_return; // Setup an AES encoder. const maxon::StreamConversionRef aesEncoder = maxon::StreamConversions::AesEncoder().Create(cryptoSettings) iferr_return; // Determine if the data does match the fixed block size (128 bits) of an AES encryption. const maxon::Int initialSize = encryptedContent.GetCount(); const maxon::Int aesBlockSize = aesEncoder.GetBlockSize(); const maxon::Int targetSize = (((8 * initialSize) / blockSize) + 1) * aesBlockSize; const maxon::Int diff = targetSize - initialSize; // Fill the difference of the data to the block size stride with random bits/bytes. if (diff > 0) { encryptedContent.Resize(targetSize) iferr_return; maxon::UChar* randomDataStart = (maxon::UChar*)(encryptedContent.GetFirst()) + initialSize; const maxon::Int randomDataSize = diff; const auto randomDataBlock = maxon::ToBlock<maxon::UChar>(randomDataStart, randomDataSize); const maxon::SecureRandomProvider provider = maxon::SecureRandom::GetDefaultProvider(); maxon::SecureRandom::GetRandomNumber(provider, randomDataBlock); } // Check if the encoder does support in place conversions. if (!aesEncoder.SupportInplaceConversion()) return maxon::UnexpectedError(MAXON_SOURCE_LOCATION); // Encrypt the data in place. aesEncoder.ConvertAllInplace(encryptedContent) iferr_return; return encryptedContent; } /// ----------------------------------------------------------------------------------------------- /// Decrypts and decompresses a message that has been encoded with GetEncrypted(). /// /// @param[in] content The input text to decompress and decrypt. /// @param[in] secret The encryption secret. /// @return The decompressed and decrypted content as a string. /// ----------------------------------------------------------------------------------------------- static maxon::Result<maxon::String>GetDecrypted( const maxon::BaseArray<maxon::Char>& encryptedContent, const maxon::String secret) { iferr_scope; // The compression settings, the compression rate can lie between 0 and 9, where 9 is the // strongest (and slowest) compression. maxon::DataDictionary settings; settings.Set(maxon::STREAMCONVERSION::ZIP::ENCODER::COMPRESSION, maxon::Int(9)) iferr_return; settings.Set(maxon::STREAMCONVERSION::ZIP::ENCODER::WRITESIZE, true) iferr_return; // Build a CryptoKey for an AES encryption. const maxon::Id encoderID = maxon::StreamConversions::AesEncoder.GetId(); const maxon::Int blockSize = 128; const maxon::Int keySize = 128; maxon::BaseArray<maxon::Char> key = secret.GetCString() iferr_return; const maxon::CryptoKey cryptoKey(encoderID, blockSize, key.GetFirst(), keySize); // Setup an AES decoder. maxon::DataDictionary cryptoSettings; cryptoSettings.Set(maxon::CryptographyOptions::CRYPTOKEY, cryptoKey) iferr_return; const maxon::StreamConversionRef aesDecoder = maxon::StreamConversions::AesDecoder().Create(cryptoSettings) iferr_return; // Check if decoder supports in place conversions. if (!aesDecoder.SupportInplaceConversion()) return maxon::UnexpectedError(MAXON_SOURCE_LOCATION); // Decrypt the message in place. aesDecoder.ConvertAllInplace(encryptedContent) iferr_return; // Decompress the data up to the null termination within the decrypted message now written into // encryptedContent. maxon::BaseArray<maxon::Char> decompressed; const maxon::StreamConversionRef zipDecoder = maxon::StreamConversions::ZipDecoder().Create(settings) iferr_return; zipDecoder.ConvertAll(encryptedContent, decompressed) iferr_return; return maxon::String (decompressed); } /// ----------------------------------------------------------------------------------------------- /// Runs the example. /// /// @param doc Not needed, requirement of private interface. /// ----------------------------------------------------------------------------------------------- static maxon::Result<void> RunExample(BaseDocument* doc) { iferr_scope; //The password and some mock data to encrypt. const maxon::String password = "wubba lubba dub-dub"_s; const maxon::Char* content = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam " "voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd " "guber, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, " "consetetur elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna " "aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. " "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem " "ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt " "ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo " "duo dolores et ea rebum."; const maxon::String inputContent (content); // Variables for the encrypted & decrypted content and secret. maxon::BaseArray<maxon::Char> encryptedContent; maxon::String decryptedContent, secret; // Hash the password. iferr(secret = GetAES128Secret(password)) ApplicationOutput("Failed to hash password."); // Compress and encrypt the content. iferr (encryptedContent = GetEncrypted(inputContent, secret)) ApplicationOutput("Failed to encrypt data."); // Decrypt and decompress the content. iferr(decryptedContent = GetDecrypted(encryptedContent, secret)) ApplicationOutput("Failed to decrypt data."); ApplicationOutput("Password: @, Secret: @", password, secret); ApplicationOutput("Content: @", inputContent); ApplicationOutput("Encrypted content: @", encryptedContent); ApplicationOutput("Decrypted content: @", decryptedContent); return maxon::OK; }
  • 0 Votes
    5 Posts
    841 Views
    ferdinandF
    Hello @mocoloco, without any further replies or questions, we will consider this thread as solved by Thursday and flag it accordingly. Thank you for your understanding, Ferdinand
  • 0 Votes
    3 Posts
    820 Views
    a_blockA
    Hello Ferdinand, yes, I was talking about the plugin ID argument of GeDialog.Open() and Restore(). Thanks for your explanation. I'm completely fine with your answer, despite some seeming here and there. I do understand the problems a codebase grown over decades can cause for answering such questions definitely. Nevertheless your explanations largely sync with my expectations from quite a few experiments. Regarding the mentioned issue of the other thread, I can acknowledge, the plugin ID parameter did not seem to have influence on the issue in my experiments. This question here was really more targeted the sizing issues I have with requesters of varying content. And your answer provides me with some confidence, I can make use of different plugin IDs (I should probably rather say unique IDs from Plugin Café) even if they are not related to any registered plugins at all. While I had already thought so and did not find any issues with this practice, it's always a bit hard to know for sure from the outside. And there's always this feeling one could be doing something harmful, which will only bite at the worst possible point in future. Thanks for the clarification. Cheers, Andreas
  • How to set the shadow for polygon drawing

    Cinema 4D SDK c++ r21
    3
    1
    0 Votes
    3 Posts
    674 Views
    ferdinandF
    Hello @aimidi, thank you for reaching out to us. Please excuse the delay, but your questions had to be reassigned internally, which is why I only took it on yesterday. The main reason for your problems is the incomplete initialization of Vector Box_vc[4] = {Vector(0)};. Box_vc should be initialized with four vectors as you do declare yourself. This partial initialization causes the shading errors you did experience. Please also note that you did flag your posting as R21, which is out of the support cycle. Below I do provide some example code written for S24. It should work on R21, since there have been no changes to the involved interfaces and methods as far as I am aware of, but I did not try to compile the code for R21. The code is also narrative in nature and lines out a few other problems with the code provided by you. I hope this will be helpful to you. Cheers, Ferdinand The result: [image: example.gif] The code: // Example for some drawing operations via ObjectData::Draw(). // // Draws a white polygon and a red cube in the local coordinate system of the BaseObject. The main // problem of your code was that you did not initialize the color array properly. // // As discussed in: // https://developers.maxon.net/forum/topic/13441 #include "c4d.h" #include "c4d_symbols.h" class Pc13441 : public ObjectData { INSTANCEOF(Pc13441, ObjectData) public: static NodeData* Alloc() { return NewObjClear(Pc13441); } DRAWRESULT Draw(BaseObject* op, DRAWPASS drawpass, BaseDraw* bd, BaseDrawHelp* bh) { if (drawpass == DRAWPASS::OBJECT) { if (op == nullptr || bd == nullptr) { return DRAWRESULT::FAILURE; } // Set the drawing matrix to the global matrix of the object we are drawing for. This is // more intuitive than what you did, because we can now just draw as if the origin of // our object is the origin of the drawing space and also will respect the orientation // of the that object. Or in short: We will draw in the local matrix of op. bd->SetMatrix_Matrix(nullptr, op->GetMg()); // The replacement for the drawing size parameter(s) of your example. Vector poylgonSize = Vector(100); // We are now going to draw a manually shaded polygon. This will ignore shading defined // by the user/scene. The user turning on and off shadows in the viewport or moving // lights will have no impact on this. // Define the vertices of the polygon to draw. Vector vertices[4] = { Vector(+poylgonSize.x, +poylgonSize.y, 0), Vector(-poylgonSize.x, +poylgonSize.y, 0), Vector(-poylgonSize.x, -poylgonSize.y, 0), Vector(+poylgonSize.x, -poylgonSize.y, 0) }; // Define the color for each vertex to draw, Cinema will interpolate between these // colors. Vector colors[4] = { Vector(1), Vector(1), Vector(1), Vector(1) }; // You did not initialize this array properly and also did pass in black as a color. // So, this, // // Vector colors[4] = { Vector(0) }; // // where we only initialize the 0th element, is not equivalent to that: // // Vector colors[4] = { Vector(0), Vector(0), Vector(0), Vector(0) }; // // The first one will give you the weird shading errors you had while the latter will // give you an all black polygon. Black as a color is of course not that useful if we // want to see some shading. // If our polygon is a quad or triangle. bool isQuad = true; // Set the drawing transparency to about 50%. bd->SetTransparency(127); // Draw the polygon. bd->DrawPolygon(vertices, colors, isQuad); // Now we are going to draw a box. // The size of the box. float boxSize = 50; // A transform for the box, we are going to draw it a bit off-center, so that it does // not overlap with the polygon we did draw. Matrix boxTransform = Matrix(); boxTransform.off = Vector(200, 0, 0); // The color for the box, this can only be a solid color. Vector boxColor = Vector(1, 0, 0); // And if we want to draw it as a wire frame. bool isWireFrame = false; // Draw the box. bd->DrawBox(boxTransform, boxSize, boxColor, isWireFrame); // For more complex drawing operations one could use DrawPoly() to draw a single // polygon, while respecting scene shading, or DrawPolygonObject() to draw a BaseObject // that is a PolygonObject. Which will also respect user defined scene shading by // default. I would not recommend constructing such polygon object to draw in Draw() as // this method is rather performance critical. If possible, this should be done // beforehand, i.e., in a cached manner. } return SUPER::Draw(op, drawpass, bd, bh); } };
  • 0 Votes
    16 Posts
    3k Views
    ferdinandF
    Hey Andreas, no need to feel sorry. It is valuable for us to be aware of this, as this could cause more serious problems further down the road, even though it is hard to reproduce for now. We have pushed this off to QA for now, due to them having the required tools (hardware) to assess this more thoroughly. I do not see anything inherently wrong with that. But the only ones who could answer this with complete certainty are the developers who wrote the Cinema 4D core. And until we cannot say with a reasonable degree of certainty that this is a reproduceable bug that we want to address, I will not bother them with this, since there is other "stuff" in front of the queue for them anyway. I have forked your second part of the question, as I would like to keep this thread clean, as I would anticipate that QA will confirm this bug, it then going to the developers, and we will then report back here. Which will get a bit convoluted when there is a second question being discussed here. The topic can be found here. I understand that this is not the most satisfying procedure for you, as it will take a bit of time. The issue of yours must go through our bug tracking system now first, rather than taking the shortcut we sometimes offer here, of us talking with the developers and then creating an issue if we decide to do so. Cheers, Ferdinand
  • Accessing json data from DataDictionary

    Cinema 4D SDK c++ r20 r21 r23 s22 s24
    3
    0 Votes
    3 Posts
    573 Views
    kbarK
    That is what I was looking for. Thanks Manuel!
  • SearchPluginMenuResource has wrong default value

    Cinema 4D SDK r21
    3
    0 Votes
    3 Posts
    465 Views
    M
    Hi @Boony2000 with the latest update of Cinema 4D (R24 SP1), c4d.gui.SearchPluginMenuResource default value was fixed in Python. Cheers, Maxime.
  • 0 Votes
    4 Posts
    696 Views
    ferdinandF
    Hello @Boony2000, without any further questions or postings, we will consider this topic as solved by Wednesday and flag it accordingly. Cheers, Ferdinand
  • How to update the scene in a threaded

    Cinema 4D SDK r21 c++
    4
    0 Votes
    4 Posts
    699 Views
    ferdinandF
    Hello @AiMiDi, it would really help if you could clarify/confirm the context. I am still assuming that you are writing a SceneLoaderData, namely for your MikuMikuDance project. We have an example on GitHub for how to implement an im- and exporter plugin, the STL-example. Invoking the status bar indicators, i.e., StatusSetSpin. StatusSetBar and StatusSetText, for a computational process, e.g., loading a file, are a bit of a special case regarding the UI-restrictions. I always also struggle with them and what is allowed where. In general, you can get away with a bit more with them, as they do not check immediately for being on the main thread and do not refuse execution if they are not. But you can also run into problems with them outside of the main thread. With that being said, our STL example also makes use of StatusSetBar, which sort of indicates that it is safe to use within SceneLoaderData::Load (more on that later). Regarding providing a custom progress dialogs for the import process: Most importers of Cinema do not do that. There are exceptions like the FBX importer which spawns its own dialog to give feedback for the importing process. When you invoke GeIsMainThread() in SceneLoaderData::Load, you will see that you are in almost all cases in the main thread (at least the ones where I did try). But in the end, there is no guarantee that this will always hold true. What I would do is safeguard all GUI operations with GeIsMainThread(), including status-bar operations, i.e., only carry them out when Load is being called from the main thread and otherwise just skip them. Then you can also open as many dialogs as you want from there. Our FBX importer plugin for example instantiates an interface for handling importing FBX within Load. Cascading out from that interfac instantiation, also a ProgressDialog will be being instantiated and opened (there are some types involved in between). But frankly, I would not bother with all that complexity and just use the status bar of the main app, i.e., StatusSetBar. Checking for the main thread seems advisable though. Cheers, Ferdinand