Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Problems with R16 [SOLVED]

    SDK Help
    0
    16
    1.1k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 10/10/2014 at 05:13, xxxxxxxx wrote:

      Andreas:
      Sure, where can I send it? And yep, I have changed the code and am not running with __LEGACY_API (though I do have some typedefs and #defines used myself).

      Niklas: Shouldn't bt be the main thread here? It's not explicitly stated but I may want to check this myself. How do I get a pointer to the C4D main thread or is it the main thread if bt is nullptr?

      Thanks for the tip about GetVector(id) as well but I have this element intialised correctly and the id is also correct and it is definetly a VECTOR element (and if it wasn't shouldn't that break point also be triggered in R13?)

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 10/10/2014 at 05:24, xxxxxxxx wrote:

        We mailed already, that address would be fine.

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 10/10/2014 at 05:58, xxxxxxxx wrote:

          Ok, at least I could find the culprit for the vector and Niklas was right. Although in the Init() of my object the vector was correctly initialised, I have a macro command where that element was set as a float! When I generated my object without the macro...no trigger 🙂

          Thanks for that Niklas! Worth an entry in the docs I'd say..

          Still the problem with GetInputState persists. Why is it triggering a break in R16 but not in R13 (during debugging). Hope you find a clue Andreas. Thanks for the effort!

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 10/10/2014 at 06:21, xxxxxxxx wrote:

            Glad it helped. 🙂

            Afaik, Execute() is not called from the main thread. The main thread would not have pointer (the OS
            thread ID is 0 for the main thread). You can use GeIsMainThread() to check if you're in the main thread
            at any time.

            Afaik (again), the BaseThread pointer is only passed so you can call TestBreak(). For instance, you
            can tell the RenderDocument() function by returning True from your own C4DThread::TestDBreak()
            implementation and passing the C4DThread's BaseThread pointer to the RenderDocument()
            function.

            I've never tried to use BaseThread::TestBreak() from Execute(), maybe that returns True already
            if ESC is pressed or something like that. 🙂

            Best,
            -Niklas

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 10/10/2014 at 06:45, xxxxxxxx wrote:

              Thanks Niklas. And again right, it's definetly not the main thread (just checked with GeIsMainThread). Also I found the threading information in the docs stating that SceneHookData::Execute is indeed called in a threaded context and probably that's not necessarily the main thread. Makes sense.

              Furthermore it seems the TestBreak call does not crash now anymore! Re-run several times now without a crash triggering so I guess that solved that issue already (so glad!).

              In my own threads (executed within Execute of the scene hook) I override TestDBreak and that's also where I am calling GetInputState checking for a the ESC key (always triggering a break...very annoying! :). I guess I could pass the bt to the thread class and simply check for a break with it as  bt->TestBreak does indeed work when the user hits ESC (if I remember correctly).

              At the beginning of the Execute however I also need the left mouse button so I kind of don't get around using GetInputState. Is there an alternative to it? (though I surely can outcomment it for debugging purposes with a preprocessor directive)

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 10/10/2014 at 06:45, xxxxxxxx wrote:

                Niklas is right (of course I might add).
                The first breakpoint is triggered, because GetInputState() is called from a thread.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 10/10/2014 at 06:49, xxxxxxxx wrote:

                  Thanks Andreas for confirming. I guess if there is no alternative I will go with my _DEBUG preprocessor solution to avoid the break points.

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 10/10/2014 at 06:51, xxxxxxxx wrote:

                    I've noted two things for SDK Docs:
                    - a hint on internal breakpoint for using wrong datatype functions for a certain ID
                    - some more explanation on threading, the dos and don'ts, plus info on the threadcontext PluginStart gets called in

                    Katachi, do you mind, marking this as solved?

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 10/10/2014 at 06:55, xxxxxxxx wrote:

                      Thanks both of you and yep, consider it solved!

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 10/10/2014 at 09:45, xxxxxxxx wrote:

                        Glad I could help. 🙂

                        @Andreas: good to read you're taking notes on things to be added to the documentation! 🙂

                        Originally posted by xxxxxxxx

                        so I kind of don't get around using GetInputState. Is there an alternative to it? (though I surely can outcomment it for debugging purposes with a preprocessor directive)

                        Maybe you can get this data from the main thread (eg. in a MessageData plugin) and request it
                        from a scene hook.

                        I did not try to compile this code, it is completely from scratch! Just to give you an idea of
                        what I'm talking about. It might need to a bit of performance adjusting, like "only re-get the
                        input state if at least 200 milliseconds passed since the last time the state was retreived".

                        Edit : AAAAaaaand you should probably add a lock/semaphore to the InputStateData structure, or
                        return a copy of the data from GetRecentInputState(). 🙂

                        >
                        > /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        > /// RecentInputState.h
                        > /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        >
                        > #include "c4d.h"
                        > #pragma once
                        >
                        > struct InputStateData
                        > {
                        > Int32 timestamp; // current timestamp returned by GeGetMilliSeconds();
                        > BaseContainer bc; // filled by GetInputState();
                        > InputStateData() : timestamp(-1), bc() { }
                        > };
                        >
                        > const InputStateData* GetRecentInputState(Int32 pluginid);
                        > Bool RegisterRecentInputStateHook(Int32 pluginid, Int32 askdevice, Int32 askchannel);
                        >
                        > /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        > /// RecentInputState.cpp
                        > /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        >
                        > #include "RecentInputState.h"
                        >
                        > #include "c4d.h"
                        > #include "HashMap.h"
                        >
                        > class InputStateHook;
                        > static maxon::HashMap<Int32, InputStateHook*> g_map;
                        >
                        > class InputStateHook : public MessageData
                        > {
                        > public:
                        > InputStateHook(Int32 askdevice, Int32 askchannel);
                        > virtual const InputStateData* GetData() const;
                        > virtual Bool CoreMessage(Int32 id, const BaseContainer& msg) override;
                        > private:
                        > Int32 _askdevice, _askchannel;
                        > InputStateData _data;
                        > };
                        >
                        > InputStateHook::InputStateHook(Int32 askdevice, Int32 askchannel)
                        > : _askdevice(askdevice), _askchannel(askchannel)
                        > {
                        > }
                        >
                        > Bool InputStateHook::CoreMessage(Int32 id, const BaseContainer& msg)
                        > {
                        > if (GetInputState(_askdevice, _askchannel, _data.bc))
                        > {
                        > _data.timestamp = GeGetMilliSeconds();
                        > }
                        > return true;
                        > }
                        >
                        > const InputStateData* InputStateHook::GetData() const
                        > {
                        > if (_data.timestamp > 0)
                        > return &_data;
                        > else
                        > return nullptr;
                        > }
                        >
                        > static const InputStateHook* GetRecentInputState(Int32 pluginid)
                        > {
                        > maxon::HashMap<Int32, InputStateHook*>::Entry* entry = g_map.FindEntry(pluginid);
                        > if (entry && entry->GetValue())
                        > {
                        > InputStateHook* hook = entry->GetValue();
                        > return hook->GetData();
                        > }
                        > return nullptr;
                        > }
                        >
                        > Bool RegisterRecentInputStateHook(Int32 pluginid, Int32 askdevice, Int32 askchannel)
                        > {
                        > InputStateHook* hook = NewObj(InputStateHook, askdevice, askchannel);
                        > if (hook)
                        > {
                        > String name = "InputStateHook:" + String::IntToString(askdevice) +
                        > String::IntToString(askchannel);
                        > Bool success = RegisterMessagePlugin(pluginid, name, 0, hook);
                        > if (success)
                        > g_map.Put(pluginid, hook);
                        > return success;
                        > }
                        > return false;
                        > }

                        Best,
                        -Niklas

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          On 10/10/2014 at 10:02, xxxxxxxx wrote:

                          Hey Niklas, thanks. That's quite a clever workaround idea!

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post