• Select several files in LoadDialog()

    r21 python
    3
    0 Votes
    3 Posts
    357 Views
    B
    @r_gigante Ah gotcha. Thanks for the confirmation.
  • What is Vector.GetLengthSquared() really meant for?

    r21 python
    5
    0 Votes
    5 Posts
    864 Views
    CairynC
    @zipit said in What is Vector.GetLengthSquared() really meant for?: My major point was that there are certain programming assumptions (multiplication is better than division, never take the square root if avoidable, cubic complexity is uncomputable, etc.) that should be taken with a grain of salt due to the fact that they rely on a certain "state" of hardware. I.e. all these three do not really hold true anymore to the extent they once did. (...) That goes without saying... ultimately, any effort towards optimization needs to be checked for effectivity. Nevertheless, I was curious and abused a plugin of mine to execute some timer checks in C++, just for comparison (code excerpt only): using namespace std::chrono; Vector v(100.0, 100.0, 100.0); float f; milliseconds ms1, ms2, diff; ms1 = duration_cast<milliseconds>( system_clock::now().time_since_epoch() ); for (int i = 0; i < 100000000; i++) { f = 0; // v.GetLength(); } ms2 = duration_cast<milliseconds>( system_clock::now().time_since_epoch() ); diff = ms2 - ms1; GePrint(maxon::String("Time counter Empty:") + maxon::String::IntToString(diff.count())); ms1 = duration_cast<milliseconds>( system_clock::now().time_since_epoch() ); for (int i = 0; i < 100000000; i++) { f = v.GetLength(); } ms2 = duration_cast<milliseconds>( system_clock::now().time_since_epoch() ); diff = ms2 - ms1; GePrint(maxon::String("Time counter GetLength:") + maxon::String::IntToString(diff.count())); ms1 = duration_cast<milliseconds>( system_clock::now().time_since_epoch() ); for (int i = 0; i < 100000000; i++) { f = v.GetSquaredLength(); } ms2 = duration_cast<milliseconds>( system_clock::now().time_since_epoch() ); diff = ms2 - ms1; GePrint(maxon::String("Time counter GetSquaredLength:") + maxon::String::IntToString(diff.count())); Switching off all optimizations, I get (for multiple button presses): Time counter Empty:185 Time counter GetLength:921 Time counter GetSquaredLength:228 Time counter Empty:184 Time counter GetLength:922 Time counter GetSquaredLength:228 Time counter Empty:183 Time counter GetLength:921 Time counter GetSquaredLength:228 Time counter Empty:183 Time counter GetLength:922 Time counter GetSquaredLength:228 Time counter Empty:185 Time counter GetLength:921 Time counter GetSquaredLength:228 Time counter Empty:183 Time counter GetLength:921 Time counter GetSquaredLength:227 That is far more like what I expected (double so if you consider that the loop with a constant assignment already takes 185ms). Considering that I had to up the loop count to a hundred million to get measurable results, it is practically guaranteed that any difference between GetLength and GetLengthSquared in the Python sample is drowned in the Python interpreter's overhead, and any result from my initial tests must be attributed to sheer randomness.
  • UVW values inconsistency

    r21 s22 c++ python
    4
    0 Votes
    4 Posts
    898 Views
    rsodreR
    @r_gigante good to know, thanks!
  • Edge To Spline Modeling Command

    sdk r20 c++
    3
    0 Votes
    3 Posts
    914 Views
    J
    Thanks for the response, that was exactly what I needed. John Thomas
  • CloseDocument ?

    2
    0 Votes
    2 Posts
    431 Views
    CairynC
    Just check it manually: if currDoc.GetChanged() : c4d.gui.MessageDialog(c4d.plugins.GeLoadString(IDS_MSG_PROJECTCHANGED)) else : c4d.documents.KillDocument(currDoc) # works but ignores change status
  • Plugin ID Collision starting by Itself

    3
    0 Votes
    3 Posts
    571 Views
    ManuelM
    hi, no problem. By the way, the first register. The second show the collide message so it can't register. But that doesn't unload the first one. That's why your plugin was still working. Cheers, Manuel
  • Retrieving Viewport Camera Matrix

    r20 sdk c++
    9
    0 Votes
    9 Posts
    2k Views
    J
    Thanks for the detailed response @r_gigante, sorry about the late post. I wasn't trying to move an object into the camera view, I was just trying to get the information about a cameras perspective so that if necessary I could create an object that would have an orientation parallel to it. John Thomas
  • GetUserDataContainer() and UserData Values

    9
    0 Votes
    9 Posts
    1k Views
    ManuelM
    hi, ha, i was not setting any value. So yes, they are in the BaseContainer at id c4d.ID_USERDATA (=700) to filter the groups or separator you just have to check the type in the descLevel and compare with DTYPE_SEPARATOR or DTYPE_GROUP or either use DescId.IsPartOf like: for descId, parameterBc in op.GetUserDataContainer(): print(c4d.DESCID_DYNAMICSUB.IsPartOf(descId)) # Will print True for all of them Cheers, Manuel
  • c4d.CallButton(myTagPSR,c4d.ID_CA_CONSTRAINT_TAG_PSR_ADD)

    python
    6
    0 Votes
    6 Posts
    887 Views
    M
    Gload you solved your issue, if you have any questions, please feel free to open a new topic. Ho and I forget the most important, welcome in the plugincafe community Cheers, Maxime.
  • OBJ Export Options

    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
  • Different behavior on Mac for Commanddata options

    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
  • Dump/Restore UserDataContainer

    4
    0 Votes
    4 Posts
    667 Views
    indexofrefractionI
    i finally succeeded in saving a BaseList2D userdata description (not the values) then loading and re-applying / cloning the full definition to a different BaseList2D, and finally copy over the values from the source to the target BaseList2D here is a similar topic for saving / loading the values (not the description) here: https://developers.maxon.net/forum/topic/11960/advice-for-saving-user-data/8 I made a comment there about copying the userdata values
  • Advice for Saving User Data?

    8
    0 Votes
    8 Posts
    1k Views
    indexofrefractionI
    @zipit said in Advice for Saving User Data?: # Write the data back. for cid, value in bc: descid = (c4d.ID_USERDATA, cid) # Check if the type of the element in op at the given descid matches # the data type we want to write, i.e. if the structure of the user # data has not changed. if isinstance(value, type(op[descid])): op[descid] = value a notice about the code part above : this gave me type errors and i solved it by not iterating through the bc, but instead through the ops UserData and skipping any DTYPE_GROUP and DTYPE_SEPARATOR (could be done also when reading the values, ofc) for descid, _ in op.GetUserDataContainer(): uid = descid[1].id dtype = descid[1].dtype name = _[c4d.DESC_NAME] value = bc[uid] print " uid={} dtype={} name={!r}".format(uid, dtype, name) if dtype == c4d.DTYPE_GROUP or dtype == c4d.DTYPE_SEPARATOR: pass elif dtype == c4d.DTYPE_SUBCONTAINER: pass # DTYPE_SUBCONTAINER - should never happen? elif isinstance(value, type(op[descid])): op[descid] = value else: pass # TYPE MISMATCH - should never happen?
  • id PluginMessage () when the scene loaded

    python sdk
    12
    0 Votes
    12 Posts
    2k Views
    ManuelM
    hi, sorry I was focused on calling a command and not a script. Even if it's pretty simple, it's not as simple as i expected to run a python script, sorry about that. Be careful that you need to create the script and relaunch c4d to be able to find it by its name. The idea is to retrieve the ID of the script and use callCommand to execute it. (as you can do with any commandData IDs) you can retrieve the ScriptList with GetScriptHead witch return a GeListHead So you can retrieve the first with GetFirst and compare the name. If you find one, you can simply return it's IDs using GetDynamicScriptID and return it. You now just have to use CallCommand with this ID. (be aware that this CallCommand will create an undo step in the undo stack) So your script will be executed when a new document is loaded. #include "maxon/apibase.h" #include "maxon/errorbase.h" #include "maxon/errortypes.h" #include "maxon/file_utilities.h" #include "maxon/application.h" #include "c4d_general.h" #include "c4d_commanddata.h" #include "c4d_baseplugin.h" #include "c4d_scenehookdata.h" #include "c4d_baselist.h" static Int32 GetScriptID(const maxon::String& scriptName) { iferr_scope; // check all script // Retrieves the script head BaseList2D* scriptHead = static_cast<BaseList2D*>(GetScriptHead(0)->GetFirst()); // for all script for (BaseList2D* script = scriptHead; script != nullptr; script = script->GetNext()) { // retrieves the name of the script maxon::String name = script->GetName(); // if the name match the argument, return the id of the script if (name.IsEqual(scriptName)) return GetDynamicScriptID(script); } // return NOTOK if no script founded. return NOTOK; } class pc12835_scenehook : public SceneHookData { public: static NodeData* Alloc() { return NewObjClear(pc12835_scenehook); } Bool Message(GeListNode* node, Int32 type, void* data) override { if (type == MSG_DOCUMENTINFO) { DocumentInfoData* const msg = static_cast<DocumentInfoData*>(data); if (msg == nullptr) return false; // switch message sub-type switch (msg->type) { case MSG_DOCUMENTINFO_TYPE_LOAD: { // define my script name maxon::String scriptName = "myscript"_s; // search the ID of the scrip const Int32 scriptID = GetScriptID(scriptName); // if the script have been founded, execute it. if (scriptID != NOTOK) CallCommand(scriptID); break; } case MSG_DOCUMENTINFO_TYPE_UNDO: case MSG_DOCUMENTINFO_TYPE_REDO: { ApplicationOutput("undo or redo done"_s); break; } } return true; } return SceneHookData::Message(node, type, data); }; }; Of course you need to register your sceneHookData with RegisterSceneHookPlugin Cheers, Manuel
  • Python, tool attributes and hotkeys

    s22 python sdk
    8
    0 Votes
    8 Posts
    2k Views
    John_DoJ
    @m_magalhaes Yes please, and sorry for the delay :3
  • 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
    525 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
    505 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()