• 0 Votes
    9 Posts
    1k Views
    ferdinandF
    Hello @jenandesign, without any further questions we will consider this topic as solved by Friday, December the 17th. Thank you for your understanding, Ferdinand
  • Changing VideoPost leads to TypeError

    Cinema 4D SDK r25 windows python
    4
    0 Votes
    4 Posts
    463 Views
    ?
    @m_magalhaes Yes, I think the error was because Octane was the result of rdata.GetFirstVideoPost() and those symbols don't exist in it. If I check for the Viewport Renderer, it seems to work fine. Thanks for the reply and symbol tip!
  • How to Rotate an Object

    Cinema 4D SDK r25 s24 r23 python macos windows
    7
    0 Votes
    7 Posts
    2k Views
    ferdinandF
    Hello @WDP, this question would technically also be a new topic, please follow these rules. There is no formal notion of an object axis in the sense of a moveable entity in the API. Objects have their matrices (the global and the local one), which are effectively their own coordinate system opposed to the world coordinate system (or transform or frame when you prefer these terms over coordinate system). So, when you want to reproduce what is possible in the app, and move, rotate, or scale the axes of an object, without moving the geomtery of the object itself, then you will have to transform the vertices of that object. So, when the object has the world offset (0, 0, 0) and you want to move the axes to (100, 0, 0), you must first set the global object matrix to an offset of (100, 0, 0) and then apply the inverse of a transform that translates by (100, 0, 0) to all its vertices. I would recommend reading the matrix manual I did post in my first answer here. This will however only be possible for editable point objects, e.g., a c4d.PolygonObject. You are showing a generator object, i.e., a c4d.BaseObject with some cached geometry in your screenshot. You cannot move the axes for these objects, neither in the SDK nor in the app itself. We had recently this topic which dealt with moving the axes of a polygon object. Cheers, Ferdinand
  • Cutome Render Token do not update Filename each Frame

    Cinema 4D SDK
    11
    1
    0 Votes
    11 Posts
    2k Views
    ferdinandF
    Hello @nason, without any further questions we will consider this topic as solved by Friday, December the 17th. Thank you for your understanding, Ferdinand
  • Override material tag in take

    Cinema 4D SDK r25 c++
    13
    0 Votes
    13 Posts
    2k Views
    ferdinandF
    Hey @krfft, thanks for posting your detailed results. Cheers, Ferdinand
  • GeDialog Button Highlighted By Default

    Cinema 4D SDK r25 python sdk windows
    3
    1
    1 Votes
    3 Posts
    333 Views
    ferdinandF
    Hello @blastframe , we will set this topic to 'Solved' when there are no further questions or replies until Monday, November the 22th. Thank you for your understanding, Ferdinand
  • 0 Votes
    5 Posts
    2k Views
    ferdinandF
    Hello @HolgerBiebrach, we will set this topic to 'Solved' when there are no further questions or replies until Monday, November the 22th. Thank you for your understanding, Ferdinand
  • 0 Votes
    3 Posts
    566 Views
    Y
    Hello @ferdinand , Thank you for your answer! I made a search by the forum but have lost your post above because of I sorted topics only for a C++. My bad) I also read the C++ manual for a DescID and DescLevel and the examples in there. But they are not cover the examples like my above for a [50004,1] - IDs (or maybe I've not found). For a Python version of my plugin I did not have a problem with understanding the access to the parameters at all. But on C++... For example I stuck in my mind with figuring out how does the second DescLevel work. But after your explanation above I understand it. The first level DescLevel in your code locates this sub-container: [image: 1634311057292-%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5_2021-10-15_181737.png] And next with the codeline: const DescLevel secondLevel (0, DTYPE_LONG, 0); we access into the one of this items. So I've changed your your code into: const DescLevel secondLevel (1, DTYPE_LONG, 0); and I got access into the 5004,1 item. Thank you very much!
  • Effector Updates

    Cinema 4D SDK c++ windows r25 sdk
    2
    0 Votes
    2 Posts
    489 Views
    ferdinandF
    Hello @JohnTerenece, thank you for reaching out to us. Unfortunately, our answer is mostly the same as it was for the previous topic on this plugin of yours. You are using the MoData tags in a way not intended by us. It is not supported by our SDK to implement a custom MoGraph generator and you are therefore not intended to populate and manage your own MoData tags. There is nothing preventing you from doing it anyways, this however will then be out of scope of support as declared in our Forum Guidelines under "Scope of Support". We cannot debug your code for you, especially when the employed techniques are a violation of point one listed here. This is also outlined in "Scope of Support". You are also misusing the maxon API. Specifically, the error system, as you cannot just step over all errors which are returned. Which is what you do when you store them in some fields attached to your plugin implementation; never to be used or looked at again. Which can introduce all sorts of problems. The cases I saw do look unlikely to go wrong, but this is still a fundamental misuse of our API. See the end of my posting for details. Finally, about your question. I would look at your CheckDirty(), since this is the likely culprit for your problems. But we cannot debug that for you. When you can show us that something is not being flagged as dirty what was flagged before, we will be glad to provide a context for that. Please also note that example code should be condensed as also outlined in our Forum Guidelines. I understand that this is not the support you did hope for, but these limitations of scope of support must be enforced by us to a certain degree, as it would otherwise become a boundless task. Thank you for your understanding, Ferdinand maxon::Result Example What you do: void EffectorTestClass::CheckDirty(BaseObject *op, BaseDocument *doc) { // ... if (op->GetDown() != nullptr) // This could fail and you just step over it. resultBaseObject = objArray.Append(op->GetDown()); // ... flags = data->GetFlags(doc, object); if ((flags & 1) == 1) { // This could fail and you just step over it. resultBaseObject = objArray.Append(object); } // ... } What you should do: void EffectorTestClass::CheckDirty(BaseObject *op, BaseDocument *doc) { // An error scope handler that brings the classic and maxon API together. iferr_scope_handler { // you could also write to one of the loggers here, e.g. ApplicationOutput("Error in CheckDirty() @", err); return false; } // ... if (op->GetDown() != nullptr) objArray.Append(op->GetDown()) iferr_return; // ... flags = data->GetFlags(doc, object); if ((flags & 1) == 1) { objArray.Append(object) iferr_return; } // ... }
  • How to Access the Values of GeDialog Gadgets

    Cinema 4D SDK s24 r25 python
    2
    0 Votes
    2 Posts
    455 Views
    ferdinandF
    Hello @mocoloco, thank you for reaching out to us. I have forked your question from How to Highlight a Button since it is a new question which does constitute a new topic. I am also currently on vacation which means that you will have to address the rest of the team to get support in a timely fashion (addressing just me and hiding your question in an older topic was probably what got your question being overlooked). About your question(s): You can find out more about dialog resources, i.e., defining a dialog in a file and not programmatically, in Resource Files Manual and Dialog Resource. Both manuals are part of our C++ documentation but do translate quite directly to Python since resource files are mostly a language agnostic topic. It also remains unclear to me if you actually want to define a dialog or a node since *"using .RES" does not distinguish the two. In either case the resource snippet I did post in the other thread could be used as a template for both cases. I am also not quite sure how the second part of your question is meant. You usually do react to dialog input events in GeDialog.Command. In a node you would have to indeed listen in NodeData.Message() as pointed out by yourself. In a dialog the value would be then attached to the dialog and in case of a node to the node. I.e., in the case of the muscle object thingy polling the quicktab gadget could look like this: Message(self, node, mid, mdata): """Polls a quicktab gadget for the hypothetical muscle object case. Args: node (c4d.BaseList2D): The node to which the message has been sent. mid (int): The message id. mdata (any): The message data. In case of description messages usually a `dict` in Python. """ # The conditioning to a specific message/event type is optional, but # should be in your case probably MSG_DESCRIPTION_POSTSETPARAMETER. if mid == c4d.MSG_DESCRIPTION_POSTSETPARAMETER: # Unpack from which element the message has been sent. eid = mdata["descid"][0].id # This has been sent by the quicktab gadget. if eid == c4d.ID_CA_MUSCLE_OBJECT_STATE: # Get the node state of the parameter which has that quicktab GUI # and do different things based on the state. state = node[c4d.ID_CA_MUSCLE_OBJECT_STATE] if state == c4d.ID_CA_MUSCLE_OBJECT_STATE_RELAX: # ... elif state == c4d.ID_CA_MUSCLE_OBJECT_STATE_COMPRESSED: # ... # ... return True For a more precise answer you should post code or a more precise description of what you are trying to do. And you should also address the rest of the team since I am still going to be on vacation for a few days. Cheers, Ferdinand
  • R25 - DrawPoint2D,DrawHandle2D not drawing pixel size anymore

    Moved Bugs r25
    4
    0 Votes
    4 Posts
    1k Views
    ferdinandF
    Hello @WTools3D, without any further questions, we will consider this topic as solved by Tuesday, November the 2nd and flag it accordingly. Thank you for your understanding, Ferdinand
  • Loading Materials from AssetDescriptions into a Scene

    Cinema 4D SDK c++ r25
    3
    0 Votes
    3 Posts
    702 Views
    ferdinandF
    Hello @krfft, here the promised code. It is an extension of the Search Assets example which can be found in the Asset API Handbook. I hope this helps and cheers, Ferdinand The result: [image: 1633088569248-1.gif] The code: static Int32 g_max_materials = 10; /// ------------------------------------------------------------------------------------------------ /// Loads in the first ten material assets into the active document which can be found in the user /// prefs repository. /// /// I did remove most of the comment fluff here, assuming you are already familiar with the rest. /// ------------------------------------------------------------------------------------------------ maxon::Result<void> LoadAssets() { iferr_scope; // Get the active document and do some setup stuff to search for all materials in the user prefs // repository. See FindAssets() example function in the Assets API exmaples for details. BaseDocument* doc = GetActiveDocument(); if (doc == nullptr) return maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "No active document."_s); const maxon::AssetRepositoryRef& repository = maxon::AssetInterface::GetUserPrefsRepository(); const maxon::AssetType assetType = maxon::AssetTypes::File(); const maxon::Id assetFindId = {}; const maxon::Id assetVersion = {}; maxon::BaseArray<maxon::AssetDescription> results; repository.FindAssets( assetType, assetFindId, assetVersion, maxon::ASSET_FIND_MODE::LATEST, results) iferr_return; // Iterate over the results until we have found ten materials. maxon::Int counter = 0; for (maxon::AssetDescription assetDescription : results) { if (counter == g_max_materials) break; maxon::AssetMetaData metadata = assetDescription.GetMetaData(); maxon::Id subTypeId = metadata.Get(maxon::ASSETMETADATA::SubType) iferr_return; // This is a material asset. if (subTypeId == maxon::ASSETMETADATA::SubType_ENUM_Material) { // With a valid url. maxon::Url url = assetDescription.GetUrl() iferr_return; if (url.IsEmpty()) continue; // The url of the asset is in case of material assets a c4d file. So, we merge that asset // document with the active document. ApplicationOutput("@| Type: @, Url: @", counter, subTypeId, url); maxon::String* error = {}; maxon::Bool didMerge = MergeDocument( doc, MaxonConvert(url), SCENEFILTER::MATERIALS, nullptr, error); ApplicationOutput("@: Merged: @, Error: @", counter, didMerge, error); if (didMerge) counter++; } } return maxon::OK; }