• Compiling my plugin on R23

    6
    1
    0 Votes
    6 Posts
    1k Views
    P
    Ok, success. Copying the plugin folder from pc to mac was the issue!
  • Polygonize() and scene camera

    Moved c++ sdk
    4
    0 Votes
    4 Posts
    547 Views
    ManuelM
    hi, i don't think there's a particular reason for not keeping the camera but the function description is : Returns a copy of the document in which all objects are converted to polygon objects. As a camera doesn't generate polygon, it just doesn't follow. I'm expecting the same for light, atmosphere, background, floor etc. Cheers, Manuel
  • r23 console

    python
    9
    0 Votes
    9 Posts
    2k Views
    oli_dO
    I confirm that with versionn 10.15.6 it works. Once again thank you very much Maxime for your availability and quick answers! Best regards
  • Invoke Dialog from Python Tag

    6
    0 Votes
    6 Posts
    1k Views
    indexofrefractionI
    Hi Manuel, I just thought it must be possible to Message something to a CommandData plugin, too. The idea behind the CommandData was to combine some other functionality, but I guess i just get a new plugin ID and go the MessageData way... best, Index hm, somehow I cant find how to tag this as solved
  • Copy All Parameters of One Object to Another in Real Time?

    r21 python
    4
    0 Votes
    4 Posts
    528 Views
    B
    Thanks for the response @m_magalhaes Oh thanks. It now works on native c4d emitter but not in xparticles emitter. No worries, the solution by @zipit works @zipit Thanks. It works as expected. Here's the code I used added in a python tag orig = doc.SearchObject("original") dup = doc.SearchObject("duplicate") orig_container = orig.GetDataInstance() orig_container.CopyTo(dup.GetDataInstance(), flags= c4d.COPYFLAGS_PRIVATE_CONTAINER_COPY_IDENTICAL, trans=None) c4d.EventAdd()
  • Overlaying icons (like Alembic)

    r20 r21 s22 c++ classic api
    9
    1
    0 Votes
    9 Posts
    1k Views
    fwilleke80F
    OK, I got it. Once it's all figured out, the solution seems laughably simple. In case anybody else needs to maintain R20 compatibility and wants to use custom icon overlays, here's a solution: In MyObject class declaration: (R20 code) class MyObject : public ObjectData { INSTANCEOF(MyObject, ObjectData); // ... private: #if API_VERSION < 21000 BaseBitmap *_customIcon; ///< Used to store a node's custom icon in R20 #endif }; public: #if API_VERSION < 21000 MyObject() : _customIcon(nullptr) { } ~ MyObject() { if (_customIcon) BaseBitmap::Free(_customIcon); } #endif In MyObject::Message(): (R20 code) const BaseContainer &dataRef = op->GetDataInstanceRef(); // // 1. Copy default icon into customIcon // // Load default icon IconData defaultIconData; if (!GetIcon(node->GetType(), &defaultIconData)) return false; // Free _customIcon if it has been allocated before, because // it will now receive the pointer to a newly allocated BaseBitmap. if (_customIcon) BaseBitmap::Free(_customIcon); // Get the actual bitmap that is our icon _customIcon = defaultIconData.GetClonePart(); if (!_customIcon) return false; // // 2. Blit overlay into customIcon // // Load overlay icon IconData overlayIcon; const Int32 overlayIconId = MyFunctionToGetTheIconId(); if (overlayIconId == NOTOK) return false; const Bool overlayIconloaded = GetIcon(overlayIconId, &overlayIcon); if (overlayIconloaded) { BlitOverlayBitmap(overlayIcon.bmp, _customIcon, overlayIcon.x, overlayIcon.y, overlayIcon.w, overlayIcon.h, 32, 32); // // 3. Set cid->dat to use customIcon // cid->dat->bmp = _customIcon; cid->dat->x = 0; cid->dat->y = 0; cid->dat->w = _customIcon->GetBw(); cid->dat->h = _customIcon->GetBh(); cid->filled = true; } And BlitOverlayBitmap(), a variation of your BlitOverlayIcon(): void BlitOverlayBitmap(BaseBitmap *overlay, BaseBitmap *dest, Int32 x, Int32 y, Int32 bw, Int32 bh, Int32 xOffset, Int32 yOffset) { if (!overlay || !dest) return; BaseBitmap *overlayAlpha = overlay->GetInternalChannel(); BaseBitmap *destAlpha = dest->GetInternalChannel(); const Int32 destW = dest->GetBw(); const Int32 destH = dest->GetBh(); if (bw > destW) bw = destW; if (bh + yOffset > destH) bh = destH - yOffset; if (bw + xOffset > destW) bw = destW - xOffset; UInt16 aa, a, rr, r, gg, g, bb, b; aa = a = rr = r = gg = g = bb = b = 0xff; for (Int32 py = 0; py < bh; py++) { for (Int32 px = 0; px < bw; px++) { // get color and alpha from overlay icon overlay->GetPixel(x + px, y + py, &r, &g, &b); overlay->GetAlphaPixel(overlayAlpha, x + px, y + py, &a); // get color and alpha from background icon if available dest->GetPixel(px + xOffset, py + yOffset, &rr, &gg, &bb); if (destAlpha) { dest->GetAlphaPixel(destAlpha, px + xOffset, py + yOffset, &aa); } // blend overlay color against existing icon background color Float blend = a / 255.0; dest->SetPixel(px + xOffset, py + yOffset, (Int32)Blend(rr, r, blend), (Int32)Blend(gg, g, blend), (Int32)Blend(bb, b, blend)); // use only the overlay alpha if the opacity is higher to keep the original icon complete // and only in case the background has an alpha at all if (destAlpha && aa < a) { dest->SetAlphaPixel(destAlpha, px + xOffset, py + yOffset, a); } } } } Thanks for patience & support! Cheers, Frank
  • Blip before Correctly Updating

    c++ r20 sdk
    16
    0 Votes
    16 Posts
    2k Views
    D
    @m_magalhaes Sorry about the late reply again! I went to build some simplified code to post and I might have figured it out in the process. It seems that if I correctly mark the children with AddDependence then GetCache returns the cache I expect. Having the object lower in the object manager than mine causes it to lag behind slightly, but that seems consistent with other Cinema objects. Dan
  • Broken Links in Documentation

    python sdk
    6
    0 Votes
    6 Posts
    655 Views
    r_giganteR
    Hi guys, we've should have fixed the caching issue in the documentation and we kindly ask, before emptying the cache, to see if the issue persists on your side. In case you still experience the issue, please follow-up with a new post in this thread. Thanks for your help! R
  • Debug Python related CRASH

    10
    0 Votes
    10 Posts
    2k Views
    indexofrefractionI
    @zipit just FYI, the CacheInterface immediately crashes R20 but works on R21 @m_adam Ok, thanks! I was doing this in every Python Tag and I have 100-200 of those in the File. I don't really need to do this, it was just a "beauty" thing... that did end up ugly
  • Get the Next Object of doc.SearchObject() Method?

    r21 python
    3
    0 Votes
    3 Posts
    652 Views
    B
    @m_adam Ah gotcha. Thanks for the confirmation and the sample code.
  • Crash in ChannelShader plugin

    s22 c++ macos
    9
    1
    0 Votes
    9 Posts
    812 Views
    fwilleke80F
    I’m confident they will find out Thanks for everything!
  • C4D R21.207 Console don't do anything

    r21 python
    10
    1
    0 Votes
    10 Posts
    2k Views
    C
    Finally fix it! I reinstalled c4d and everything goes well! Thank you for all you helps!
  • Copy Pixels from Active BaseDraw?

    python
    5
    0 Votes
    5 Posts
    590 Views
    ?
    Hi, Thank you @m_adam and @zipit . I am specifically interested in copying the Viewport pixels for speed. Thank you both for your help.
  • Shader that gets data from an object: Refresh

    r20 r21 s22 maxon api c++
    6
    0 Votes
    6 Posts
    1k Views
    fwilleke80F
    It works like a charm! Thank you again! I was surprised at how little code was required. Sharing is caring. In case anyone needs it, here's the code: #include "ge_prepass.h" #include "c4d_general.h" #include "c4d_baselinkarray.h" #include "c4d_basedocument.h" /// /// \brief Registers observers and sends messages to them. /// class Observable { public: /// /// \brief Subscribes a new observer. /// /// \param[in] observer Pointer to an AtomGoal /// \param[in] doc The document that owns the AtomGoal /// /// \return A maxon error object if anything went wrong, otherwise maxon::OK /// maxon::Result<void> Subscribe(C4DAtomGoal *observer, BaseDocument *doc); /// /// \brief Unsubscribes an observer /// /// \param[in] observer Pointer to an AtomGoal that has previously been subscribed /// \param[in] doc The document that owns the AtomGoal /// void Unsubscribe(C4DAtomGoal *observer, BaseDocument *doc); /// /// \brief Sends a messages to all subscribed observers /// /// \param[in] type Message type /// \param[in] doc The document that owns the subscribed observers /// \param[in] data Optional message data /// void Message(Int32 type, BaseDocument *doc, void *data = nullptr) const; private: BaseLinkArray _observers; }; maxon::Result<void> Observable::Subscribe(C4DAtomGoal *observer, BaseDocument *doc) { if (!observer) return maxon::NullptrError(MAXON_SOURCE_LOCATION, "Observer must not be nullptr!"_s); // Check if this observer is already registered const Int32 observerIndex = _observers.Find(observer, doc); if (observerIndex != NOTOK) return maxon::OK; // Register new observer if (!_observers.Append(observer)) { return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "Failed to add observer to the list!"_s); } return maxon::OK; } void Observable::Unsubscribe(C4DAtomGoal *observer, BaseDocument *doc) { if (observer && doc) { const Int32 observerIndex = _observers.Find(observer, doc); if (observerIndex != NOTOK) { _observers.Remove(observerIndex); } } } void Observable::Message(Int32 type, BaseDocument *doc, void *data) const { for (Int32 i = 0; i < _observers.GetCount(); ++i) { C4DAtomGoal *atom = _observers.GetIndex(i, doc); if (atom) { atom->Message(type, data); } } }
  • Getting a GadgetID during BFM_INTERACTSTART

    python
    6
    0 Votes
    6 Posts
    681 Views
    ?
    Thank you both! @zipit & @m_magalhaes
  • This topic is deleted!

    1
    0 Votes
    1 Posts
    9 Views
    No one has replied
  • Hide description element using MessageData::CoreMessage() function

    r21
    5
    0 Votes
    5 Posts
    960 Views
    ManuelM
    hi, I'm a bit surprised that your render can be triggered from a NodeData (but why not) But i don't understand why you can't use GetDDescription to update your node. That's what i did (in a probably too naive way) but you got the idea. I just got a boolean display_aboard on my ObjectData and i switch it as i needed. If i presse the button, i switch and i set dirty my node, if i receive the message that the render is finished (or stopped) i set my bool to false and i SetDirty my node. static const Int32 g_pc12584ButtonID = 1000; class pc12584_object : public ObjectData { INSTANCEOF(pc12584_object, ObjectData); public: static NodeData* Alloc() { return NewObjClear(pc12584_object); }; Bool Init(GeListNode* node) override { display_aboard = false; return true; } BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh) override { BaseObject* null = BaseObject::Alloc(Onull); return null; } Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags) override { if (!description->LoadDescription(Obase)) return false; const DescID* singleid = description->GetSingleDescID(); const Int32 ID = g_pc12584ButtonID; const DescID cid = DescLevel(ID, DTYPE_BUTTON, 0); if (!singleid || cid.IsPartOf(*singleid, nullptr)) { BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BUTTON); bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_BUTTON); if (display_aboard) bc.SetString(DESC_NAME, "Aboard Render"_s); else bc.SetString(DESC_NAME, "Render"_s); bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_OFF); bc.SetInt32(DESC_SCALEH, 1); description->SetParameter(cid, bc, DescLevel(ID_OBJECTPROPERTIES)); } flags |= DESCFLAGS_DESC::LOADED; return SUPER::GetDDescription(node, description, flags); } Bool Message(GeListNode* node, Int32 type, void* data) override { switch (type) { case MSG_DESCRIPTION_COMMAND: { DescriptionCommand* dc = (DescriptionCommand*)data; const Int32 id = dc->_descId[0].id; if (id == g_pc12584ButtonID) { display_aboard = !display_aboard; node->SetDirty(DIRTYFLAGS::DESCRIPTION); } break; } case g_pc12584Message: { display_aboard = false; node->SetDirty(DIRTYFLAGS::DESCRIPTION); break; } } return SUPER::Message(node, type, data); }; private: Bool display_aboard = false; }; // function to send a message to the ObjectData. static maxon::Result<void> PC12854_Message(BaseDocument* doc) { iferr_scope; // update the first object BaseObject* op = doc->GetFirstObject(); if (op == nullptr) return maxon::NullptrError(MAXON_SOURCE_LOCATION); op->Message(g_pc12584Message); return maxon::OK; } Cheers, Manuel
  • Adding Keyboard Message: KEY_ENTER & KEY_TAB

    4
    0 Votes
    4 Posts
    584 Views
    ManuelM
    hi, @indexofrefraction, as @blastframe said, let's keep that thread clean and ask your question in another thread, this is working on my system. @blastframe , we will take into consideration your request. Cheers, Manuel
  • Store generator's property

    python
    4
    0 Votes
    4 Posts
    613 Views
    ManuelM
    hi can we considered this thread as resolved ? Cheers, Manuel
  • 0 Votes
    11 Posts
    1k Views
    ManuelM
    hi can we considered this thread as solved ? (even if there's no real right answer) Cheers, Manuel