• 0 Votes
    5 Posts
    691 Views
    fwilleke80F
    Thanks for confirming! The strange thing is that I can reproduce this even in R20. Seems, not many people use this function to open URLs. I'll mark this as solved then, as my solution presented in this thread works flawlessly on all R2x releases. Cheers, Frank
  • 1 Votes
    4 Posts
    469 Views
    ferdinandF
    Hi, I did not really expect an answer, I just did put it up to make you guys aware. Regarding your reply, I agree with most of it and am aware that there a some hurdles to overcome in mapping C++ interfaces to Python, i.e. that you do run into problems in general when you want to express overloaded methods in Python. But as @mp5gosu pointed out, my major point was that the function does not accept named arguments at all. Which is mainly a problem because the docs tell you explicitly otherwise in two ways. First of all the docs say explicitly that all arguments are optional which implies for Python usually that I can pick and choose in which arguments I can pass by passing named arguments. And secondly, you print out the signature as Vector.__init__(x=0.0, y=0.0, z=0.0) which implies the same. I would have probably ignored all this and booked it under "that's for me to know and for you to find out", if it wasn't for the fact that the method does not raise a TypeError on attempts of feeding it with such unknown named arguments. Which can make this quite critical IMHO. Cheers, zipit
  • SceneSaverData document

    Cinema 4D SDK r23 c++
    5
    0 Votes
    5 Posts
    648 Views
    ferdinandF
    Hi, without further feedback, we will consider this thread as solved by tomorrow and flag it accordingly. Cheers, Ferdinand
  • Matrix and Vector access

    Cinema 4D SDK r23 python
    7
    0 Votes
    7 Posts
    1k Views
    ferdinandF
    Hey @datamilch, Thank you for reaching out to us. In general we prefer if users open new threads for their questions. You are of course welcome to link to an existing topic and say that your question relates to that. The reason for that is that even when the question of another user is right on-topic as it is here the case with your question (which in the most other cases will not be true), it still tends to derail a thread. I have not forked your question since you are on-topic. About your Question I think this thread can be a bit opaque for beginners as @Cairyn and @m_adam have approached this topic on a very technical level. The important thing to understand, is that both BaseObject.GetMg() and the fields of a c4d.Matrix, i.e., off, v1, v2, and v3 return a copy of the requested object, not an instance. In plain terms this means that the matrix/vector one retrieves is not the one used by the object/matrix but a copy of it. So, we can totally do this: >>> mg Matrix(v1: (1, 0, 0); v2: (0, 1, 0); v3: (0, 0, 1); off: (0, 0, 0)) >>> mg.off.x = 5 but it does not do what we think it would do, we changed the x-value of the returned copy, not the off vector used by the mg instance. >>> mg.off.x 0.0 >>> mg Matrix(v1: (1, 0, 0); v2: (0, 1, 0); v3: (0, 0, 1); off: (0, 0, 0)) But we can certainly set the x-component of the global offset of an object in one line. import c4d cube: c4d.BaseObject = c4d.BaseObject(c4d.Ocube) # ONE: Using parameter access # We set the the x component of the global position and the global rotation using parameter access. # There are also parameters for the relative, aka local, transform values, as well as special things # like a frozen transform. There are also functions on BaseObject which do the same thing but at # least I never use them. # See: https://developers.maxon.net/docs/py/2024_3_0/classic_resource/base_list/obase.html cube[c4d.ID_BASEOBJECT_GLOBAL_POSITION,c4d.VECTOR_X] = 9.9 cube[c4d.ID_BASEOBJECT_GLOBAL_ROTATION] = c4d.Vector(0, 0, c4d.utils.DegToRad(45)) # TWO: Use matrix and vector constructors # In three steps ... mg: c4d.Matrix = cube.GetMg() mg.off = c4d.Vector(9.9, mg.off.y, mg.off.z) cube.SetMg(mg) # ... or in two steps, although this is a bit stupid. mg: c4d.Matrix = cube.GetMg() cube.SetMg(c4d.Matrix(c4d.Vector(9.9, mg.off.y, mg.off.z), mg.v1, mg.v2, mg.v3)) # THREE: Using transforms # This is not exactly the same as the two other cases, but it is the most common operation. Here we # do not set the global x-position of #cube to 9.9, but we move it 9.9 units in the x-direction. # In code we often operate on objects with the identity transform/matrix, i.e., which "sit at origin # with the standard size and orientation". In that case transforms act the same as if we would just # set these values. The other case is that you have an object at (1, 2, 3) and then move it (3, 2, 1) # units, transforms also work for this. For the case where the object is at (1, 2, 3) and you want # to _set_ it to (9.9, 2, 3) a transform won't work unless you do the math. # Freshly instantiated objects have the identity transform, we can just pile transforms on top of # that to "set" the values. sphere: c4d.BaseObject = c4d.BaseObject(c4d.Osphere) # Just move it 9.9 units in the x-direction. sphere.SetMg(sphere.GetMg() * c4d.utils.MatrixMove(c4d.Vector(9.9, 0, 0))) # Or first move it 9.9 units in the x-direction and then rotate it 45 degrees around the z-axis. This # would also "pile" onto the previous transform we have already applied. Note that matrix # multiplication is also not commutative, i.e., first moving something and then rotating it (might) # yield something different than first rotating and then moving. sphere.SetMg(sphere.GetMg() * c4d.utils.MatrixMove(c4d.Vector(9.9, 0, 0)) * c4d.utils.MatrixRotZ(c4d.utils.DegToRad(45))) Cheers, Ferdinand
  • Create New Take Using Python

    Moved Cinema 4D SDK
    9
    0 Votes
    9 Posts
    2k Views
    D
    @m_adam Thanks for your help. Apologies for not following the rules. I'm struggling with the rules of Python at the moment so it's not surprising! Will try to be a better poster in future.
  • R23 usd/tbb version

    Cinema 4D SDK r23
    12
    0 Votes
    12 Posts
    3k Views
    r_giganteR
    Hi @rsodre, a quick update from Pixar that hopefully shall address your issue From: Ivan Kolev [email protected] Subject: Re: [PixarAnimationStudios/USD] Deadlock loading usd (#1341) Date: 22 March 2021 at 11:53:37 CET We resolved this by switching our plugin to refer to the copy of libtbb.dylib included with C4D's USD module, using install_name_tool -change As our plugin runs on 3 platforms and on 3 hosts (3dsMax/Maya/C4D), our approach to TBB usage is to rely on its full backward compatibility: we compile/link against the oldest version that does the job for us (4.4) and expect that the hosts provide newer versions. In case of C4D we didn't do that because C4D doesn't include TBB in its main application, though some of its external modules do include their own copy of TBB. Similar to the other modules, we included our (old 4.4) copy of TBB. But this was no problem until now, the copies of TBB carried by C4D's modules haven't interfered in any harmful way. And the new USD module in R23 didn't change that. The source of the problem here is probably the fact that our plugin links to our own static copy of USD, which causes USD to be loaded twice, along with two different copies of TBB (and maybe the version mismatch is not important). So, linking against C4D's copy of TBB resolved the TBB deadlock problem, but we have now a new duplicate symbol problem, which I opened a new issue about: #1479 Cheers, R
  • 0 Votes
    19 Posts
    2k Views
    ManuelM
    hi, never say never. Sorry for the delay, this is a "unusual" case ^^ I did try several options (observable, notification, message etc) I finished using the function AddEventNotification witch is private. (so i had to figure out how it was working) The shader and the viewport is updated but with a small latency. We can try to improve that solution if you want or you can go with your own. Below the code for both the ObjectData and the Shader. The shader need to register to be notified. (this is automatic, nothing to add on the ObjectData's side) Than you need to check the message in Message I feel that the important part is to remove the notification and re/add it. (not sure what it can do if you don't do it ^^) class pc12019_object : public ObjectData { INSTANCEOF(pc12019_object, ObjectData); public: static NodeData* Alloc() { return NewObjClear(pc12019_object); } BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh) override { return BaseObject::Alloc(Ocube); } Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags) override { if (!description->LoadDescription(Obase)) return false; const DescID* singleid = description->GetSingleDescID(); const DescID cid = DescLevel(OBJ_COLOR, DTYPE_COLOR, 0); if (!singleid || cid.IsPartOf(*singleid, nullptr)) { BaseContainer bc = GetCustomDataTypeDefault(DTYPE_COLOR); bc.SetString(DESC_NAME, "Color"_s); bc.SetData(DESC_GUIOPEN, true); description->SetParameter(cid, bc, DescLevel(ID_OBJECTPROPERTIES)); } flags |= DESCFLAGS_DESC::LOADED; return SUPER::GetDDescription(node, description, flags); } }; class pc12019_shader : public ShaderData { INSTANCEOF(pc12019_shader, ShaderData); public: static NodeData* Alloc() { return NewObjClear(pc12019_shader); } Vector Output(BaseShader* sh, ChannelData* cd) override { return color; } Bool Read(GeListNode* node, HyperFile* hf, Int32 level) override { // need to read the color return true; } Bool Write(GeListNode* node, HyperFile* hf) override { // need to write the color return true; } Bool CopyTo(NodeData* dest, GeListNode* snode, GeListNode* dnode, COPYFLAGS flags, AliasTrans* trn) override { pc12019_shader* destShader = static_cast<pc12019_shader*>(dest); destShader->color = color; return true; } Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags) override { if (!description->LoadDescription(Xbase)) return false; const DescID* singleid = description->GetSingleDescID(); DescID cid = DescLevel(SH_OBJECTLINK, DTYPE_BASELISTLINK, 0); if (!singleid || cid.IsPartOf(*singleid, nullptr)) { BaseContainer bc = GetCustomDataTypeDefault(DTYPE_BASELISTLINK); bc.SetString(DESC_NAME, "Link"_s); bc.SetInt32(DESC_CUSTOMGUI, CUSTOMGUI_LINKBOX); BaseContainer ac; ac.SetInt32(Obase, 1); bc.SetContainer(DESC_ACCEPT, ac); description->SetParameter(cid, bc, DescLevel(ID_SHADERPROPERTIES)); } flags |= DESCFLAGS_DESC::LOADED; return SUPER::GetDDescription(node, description, flags); } INITRENDERRESULT InitRender(BaseShader* sh, const InitRenderStruct& irs) override { iferr_scope_handler { err.DiagOutput(); return INITRENDERRESULT::UNKNOWNERROR; }; if (irs.doc == nullptr) return INITRENDERRESULT::OK; BaseContainer* bcShader = sh->GetDataInstance(); if (bcShader == nullptr) return INITRENDERRESULT::UNKNOWNERROR; BaseObject * linkedObject = bcShader->GetObjectLink(SH_OBJECTLINK, irs.doc); if (linkedObject == nullptr) return INITRENDERRESULT::OK; RemoveNotification(sh, linkedObject); AddNotification(sh, linkedObject); GeData data; linkedObject->GetParameter(OBJ_COLOR, data, DESCFLAGS_GET::NONE); color = data.GetVector(); return INITRENDERRESULT::OK; } Bool Init(GeListNode* node) override { BaseMaterial* mat = static_cast<BaseMaterial*>(node); BaseContainer* bc = mat->GetDataInstance(); bc->SetLink(SH_OBJECTLINK, nullptr); return true; } void Free(GeListNode* node) override { GeData data; BaseObject* op = static_cast<BaseObject*>(node); if (op == nullptr) return; BaseDocument* doc = node->GetDocument(); if (doc == nullptr) return; op->GetParameter(SH_OBJECTLINK, data, DESCFLAGS_GET::NONE); BaseList2D* linkedObject = data.GetLink(doc); RemoveNotification(node, linkedObject); } Bool RemoveNotification(GeListNode* node, BaseList2D* linkedObject) { if ((node == nullptr) || (linkedObject == nullptr)) return false; BaseObject* op = static_cast<BaseObject*>(node); if (op == nullptr) return false; BaseDocument* doc = op->GetDocument(); if (doc == nullptr) return false; if (linkedObject->FindEventNotification(doc, op, NOTIFY_EVENT::CACHE)) { return linkedObject->RemoveEventNotification(doc, op, NOTIFY_EVENT::CACHE); } return true; } Bool AddNotification(GeListNode* node, BaseList2D* linkedObject) { BaseObject* op = static_cast<BaseObject*>(node); if (op == nullptr) return false; BaseDocument* doc = op->GetDocument(); if (doc == nullptr) return false; if (!linkedObject->FindEventNotification(doc, op, NOTIFY_EVENT::MESSAGE)) { return linkedObject->AddEventNotification(op, NOTIFY_EVENT::MESSAGE, NOTIFY_EVENT_FLAG::NONE, nullptr); } return true; } Bool Message(GeListNode* node, Int32 type, void* data) override { if (type == MSG_NOTIFY_EVENT) { NotifyEventData *eventData = static_cast<NotifyEventData*>(data); // as we can add several notification we check if we received the right one if (eventData->eventid == NOTIFY_EVENT::MESSAGE) { NotifyEventMsg* eventMsg = static_cast<NotifyEventMsg*>(eventData->event_data); // Checks if the message that the object is fowarding us if the right one. (MSG_DESCRIPTION_POSTSETPARAMETER) if (eventMsg->msg_id == MSG_DESCRIPTION_POSTSETPARAMETER) { DescriptionPostSetValue* dpsv = static_cast<DescriptionPostSetValue*>(eventMsg->msg_data); const Int32 id = dpsv->descid[0][0].id; // Checks if the parameter that have been change is part of the message. if (id == OBJ_COLOR) { // ask the shader to update itself. node->SetDirty(DIRTYFLAGS::ALL); node->Message(MSG_DESCRIPTION_POSTSETPARAMETER); // this will trigger the mat update and the viewport update. (with a small delay) } } } return true; } return SUPER::Message(node, type, data); } private: Vector color = Vector(1); }; Cheers, Manuel
  • RDATA_PATH not working with Render Settings

    Cinema 4D SDK r23 python
    3
    1
    0 Votes
    3 Posts
    423 Views
    M
    Hi @blastframe as demonstrated in tokensystem_render_r17.py you should always operate on the BaseContainer. Cheers, Maxime.
  • FieldList, and how to properly use it

    Cinema 4D SDK r20 r21 s22 r23 c++
    8
    0 Votes
    8 Posts
    953 Views
    fwilleke80F
    Thank you!
  • Compare only parts of two BaseContainers()

    Cinema 4D SDK r20 r21 s22 r23 c++
    6
    0 Votes
    6 Posts
    632 Views
    fwilleke80F
    Nice, Manuel, thank you! I guess, I'll try the SetDParameter() approach, too, in good time. Cheers, Frank
  • VideoPost final render buffer

    Cinema 4D SDK c++ r23
    6
    0 Votes
    6 Posts
    926 Views
    r_giganteR
    @rsodre please refrain from discussing NDA-protected topics.
  • json.dumps truncated in R23 Console

    Cinema 4D SDK python r23
    7
    0 Votes
    7 Posts
    734 Views
    ?
    Excellent, thank you for following up, @m_adam !
  • 0 Votes
    9 Posts
    2k Views
    ferdinandF
    Hi @jochemdk, okay, I then took the liberty to close the question You can of course still post here. Cheers, Ferdinand
  • R23 plugin windows 10 error

    Cinema 4D SDK r23 c++ windows
    7
    0 Votes
    7 Posts
    1k Views
    ManuelM
    @adam_k_garner said in R23 plugin windows 10 error: . Any idea why this ONE person had the issue on Windows 10? I've move your other question to a new post. Let's try to fix your issue there if we can help Cheers, Manuel
  • Cinema 4D R23 / macOS - pip install broken

    Cinema 4D SDK python r23 macos
    7
    0 Votes
    7 Posts
    2k Views
    a_blockA
    Hi, sorry, for bumping this thread. With the new S26 I have again problems installing pip in C4D's python on MacOS (Big Sur, x86). Funnily so, it works in c4dpy, but then the modules are only available in c4dpy, not inside C4D (probably expected). But when trying to do the same with C4D's python, regardless, if I try to use get-pip.py or .../python --ensure-pip -default-pip I end up with "Defaulting to user installation because normal site-packages is not writeable" as the main error and then in the following something along the lines "User base directory is not specified". The latter sounds a bit like, I could maybe simply specify a user base directory somehow? In R25 for example it worked nicely. Sorry, if this a stupid question. Pretty sure, I overlooked something in the docs somewhere. Cheers and thanks for any help in advance, Andreas
  • Different behavior on Mac for Commanddata options

    Cinema 4D SDK r23 python
    6
    0 Votes
    6 Posts
    677 Views
    ManuelM
    hi That's already mentioned in our application documentation. https://help.maxon.net/us/index.html#PREFSINTERFACE-PREF_INTERFACE_MAIN_GROUP Where do you think we should mention it ? Cheers, Manuel
  • OBJ Export Options

    Cinema 4D SDK
    10
    0 Votes
    10 Posts
    2k Views
    .
    Thanks for looking at it Manuel. Sounds like your getting the same behavior I'm seeing. I'll add something to my script to parse it out. Thanks Manuel and Cairyn for taking time to help. .del
  • (Python) Help making Pip work in Cinema 4D

    Cinema 4D SDK
    4
    2
    0 Votes
    4 Posts
    1k Views
    ferdinandF
    Hi, without further feedback, we will consider this thread as solved by Wednesday and flag it accordingly. Cheers, Ferdinand
  • Compiling my plugin on R23

    Cinema 4D SDK
    6
    1
    0 Votes
    6 Posts
    1k Views
    P
    Ok, success. Copying the plugin folder from pc to mac was the issue!