• 0 Votes
    8 Posts
    1k Views
    M
    Correct, thanks for poitning it I will add a task to improve documentation of Custom GUI
  • 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; }
  • How to check if the object/document in on Render Queue

    Cinema 4D SDK sdk c++
    3
    0 Votes
    3 Posts
    577 Views
    ferdinandF
    Hello @victor, 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
  • Sampling an Effector

    Cinema 4D SDK r20 c++ sdk
    5
    0 Votes
    5 Posts
    858 Views
    ferdinandF
    Hello @d_schmidt, without further questions or replies, we will consider this topic as solved by Monday, the 30th and flag it accordingly. Thank you for your understanding, Ferdinand
  • Demo code for c4d.GeGetLanguage in Documentation

    Moved Bugs s24 sdk
    3
    0 Votes
    3 Posts
    789 Views
    ferdinandF
    Hello @blastframe, thank you again for reporting this But can we close this or are there any remaining issues? The thread has been added to the fixed issues pool, see tag in the first posting. This is how we track documenation and API updates that are the result of a forum thread. When this issue has been fixed, we will post here and remove the tag. So, closing this thread does not mean that we will ignore the issue. Cheers, Ferdinand
  • 0 Votes
    5 Posts
    936 Views
    ManuelM
    Hi, you can create those preset with a commandData sure. When you add the graph to your node material it will call the function you defined in maxon::nodes::NODESPACE::CREATEMATERIALGRAPHFUNC See Proving Default Graph Setup for more information. So be sure to remove the nodes added by this function if they are not needed. You must create a NodeMaterial, insert it in the document, add the graph for the right nodespace and retrieve the graph itself (by first retrieving the nimbusref). We got an example on this page: Reading and Modifying Node This page also contains an introduction to Transaction. maxon::GraphModelInterface::BeginTransaction must be used if you want to modify the graph. You can than Commit your changes, which will ensure the graph is in a correct state. You can have a look a nodespace_impl.cpp, you will find the function CreateMaterialGraphDefaultSetup. remarque: this function doesn't need transactions to modify the graph. In this handbook, we are using transaction to modify some port's value inside a graph. With both examples, you will understand how to add nodes, connect them, and sets values. Cheers, Manuel.
  • FieldLayer GetDirty

    Cinema 4D SDK c++ r20 sdk
    10
    0 Votes
    10 Posts
    1k Views
    J
    Thanks for the response, that seems to have solved the issue. John Terenece
  • FieldList Modifiers

    Cinema 4D SDK r20 sdk c++
    6
    0 Votes
    6 Posts
    1k Views
    ManuelM
    hi, Would be nice to share the solution. Cheers, Manuel
  • CCurve.GetTangents() broken

    Moved Bugs sdk
    2
    1 Votes
    2 Posts
    900 Views
    M
    Hi with the latest update of Cinema 4D (R24 SP1), CCurve.GetTangents is now fixed. Cheers, Maxime.
  • EDITTEXT symbols missing

    Cinema 4D SDK s24 sdk python
    3
    0 Votes
    3 Posts
    490 Views
    a_blockA
    Oh, my bad then. Will update immediately, which I should have probably done before posting to the public forum. I'd say, if you can, please remove this thread, so nobody gets confused. And don't worry about InitValues(). Cheers
  • EnchanceMenu Questions

    Cinema 4D SDK c++ sdk
    15
    0 Votes
    15 Posts
    2k Views
    D
    Hi! Sorry about not replying and closing the topic. This has been solved. Thank you for all the help!
  • 0 Votes
    3 Posts
    661 Views
    M
    Aha I see, this makes sense for the NormalTag data. And yeah of course cross product is what I need... Regarding the primitives not turning into polygon object, I thought that was happening with a cube, but now after testing it again it definitely is. So I must have been mistaken before. Thanks for the help, going to mark this as solved.
  • 0 Votes
    7 Posts
    1k Views
    M
    Hey guys, thanks for the explanations. My only concern is that I can't really do anything besides closing Cinema4D to cancel the operation. Just for reference my plugin is a fluid volume that needs to be visualized in the viewport. This is not an expected workload, stumbled on it by chance, but so can one of the users. Anyway we can close this thread if it's not a bug. Regards, Georgi.
  • 0 Votes
    3 Posts
    498 Views
    orestiskonO
    Thanks Manuel, yes that's how I ended up doing it in the end. I thought it would've been simpler to extract a variable from the main function, since it had already calculated. All I would need is to save the variable somewhere where the button function can read it, so this is where I tried the global variables but it didn't work.
  • Fields and Adding an Effector

    Cinema 4D SDK c++ python r20 sdk
    3
    0 Votes
    3 Posts
    750 Views
    D
    @m_magalhaes Thank you! Works perfectly. Dan
  • Building R23 SDK with Visual Studio 16.9

    News & Information news sdk
    1
    2 Votes
    1 Posts
    1k Views
    No one has replied
  • Build fails with R23 SDK

    Cinema 4D SDK r23 sdk
    3
    0 Votes
    3 Posts
    644 Views
    K
    Thank you for your advice. The build was successful !!
  • Gradient GRADINTPROPERTY_NOBIASPOSITION not working

    Cinema 4D SDK c++ sdk
    7
    0 Votes
    7 Posts
    1k Views
    D
    Hi @ferdinand, Thanks for looking into this. It is not so crucial to hide the handles - I will try the custom GUI approach as you suggest.
  • 0 Votes
    18 Posts
    2k Views
    ManuelM
    Hi, Sorry about not having time to investigate the gradient part of your question. I was waiting for feedback about the color presets. With the new asset browser out there's no point into investigate this question furthermore. Cheers, Manuel