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

    Redraw GeUserArea during object movement

    SDK Help
    0
    12
    877
    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 26/10/2015 at 02:40, xxxxxxxx wrote:

      Hello,

      I guess you are using a GeDialog? You can trigger the user area redraw when you catch the core message EVMSG_ASYNCEDITORMOVE.

      Best wishes,
      Sebastian

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

        On 28/10/2015 at 16:38, xxxxxxxx wrote:

        Hi Sebastian,

        thanks, EVMSG_ASYNCEDITORMOVE helps (I don't know how I missed that one), but unfortunatelly, I forgot to add one important detail in my previous question - before drawing to user area, I need to do some (quite heavy) precomputations. Obviously, I cannot do those in GeUserArea::DrawMsg, so I do this in separate thread and in DrawMsg, I only use already computed data. Now, when I call Redraw during EVMSG_ASYNCEDITORMOVE, it can use only data calculated from previous object matrix (as thread doing precomputations just started recalculating with the new matrix). This isn't much of a problem with continuous moving with object, but when user quickly moves with object and then stop moving (without releasing mouse button), I have no way to redraw area...

        So, what I really nead is calling redraw between MOVE_START and MOVE_END even when there is no MOVE_CONTINUE being sent...

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

          On 29/10/2015 at 01:53, xxxxxxxx wrote:

          Hello,

          a GUI update (and the redraw of a user area) should only be triggered from the main thread. If the user keeps the mouse pressed the main thread is typically stopped so there is no way to safely trigger the redraw.

          Best wishes,
          Sebastian

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

            On 29/10/2015 at 03:19, xxxxxxxx wrote:

            I do the Redraw(true) which works fine for GeUserArea drawing from threads.
            about mouse movement, you can check if the mouse button is held and not moving "to take decisions about drawing".

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

              On 29/10/2015 at 04:41, xxxxxxxx wrote:

              @S_Bach:
              Ok, I was hoping in some king of message called periodically during mouse polling... I will try some alternative approaches, but most of the remaining possibilities are quite unsafe (e. g. windows hooks).

              @MohamedSakr
              Yes, Redraw(true) works from threads, but (at least for me) it does not redraw immediatelly. Instead, it seems to only schedule the redraw internally in C4D (as Sebastian said, it can be done only from main thread). In my case (user moving with object), this results in actual redraw being done once user release mouse button (ie once C4D stops polling mouse messages and main thread starts working normally).

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

                On 29/10/2015 at 05:54, xxxxxxxx wrote:

                you can draw while mouse is dragging
                there is asynctest.cpp example in the SDK, it does exactly this "draw to a BaseBitmap, then Redraw when mouse event is dragging"

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

                  On 29/10/2015 at 09:40, xxxxxxxx wrote:

                  Yes, but this is unfortunatelly slightly different - in asynctest.cpp, the user area handles the messages in InputEvent and has all control over how everything is processed (polling loop is executed there). In my case, everything is done in scene viewport, so C4D handles message polling and it only calls messages like EVMSG_ASYNCEDITORMOVE while doing this. I can catch some mouse-related events in SceneHook, but no mouse moving and nothing that would allow me draw when mouse is not moving.

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

                    On 29/10/2015 at 09:52, xxxxxxxx wrote:

                    if I understand correctly, there is:
                    virtual Bool SceneHook::AddToExecution(BaseSceneHook* node, PriorityList* list);

                    EXECUTIONFLAGS_INDRAG EXECUTIONFLAGS_INMOVE

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

                      On 29/10/2015 at 10:31, xxxxxxxx wrote:

                      Yes, but Execute() is then called in separate thread:

                      virtual EXECUTIONRESULT[URL-REMOVED] Execute(BaseSceneHook[URL-REMOVED]* node, BaseDocument[URL-REMOVED]* doc, BaseThread[URL-REMOVED]* bt, LONG priority, EXECUTIONFLAGS[URL-REMOVED] flags)_<_h4_>_

                      Called at the point in the priority pipeline specified by AddToExecution()[URL-REMOVED], or by \_L">RegisterSceneHookPlugin()[URL-REMOVED].

                      Important:  This function is called in a thread context. Please see the important information[URL-REMOVED] about threading.

                      So I can only use Redraw(true), which will be blocked by C4D untill moving finishes... Also, I would be in similar situation as with EVMSG_ASYNCEDITORMOVE...


                      [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

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

                        On 29/10/2015 at 17:33, xxxxxxxx wrote:

                        here is a quote from the function help description:
                        "By default this function returns FALSE. Then C4D will call Execute() at the priority specified in the _<_span title="bool c4d_scenehook::registerscenehookpluginlOng id, const &str, lOng info, allocator g, lOng priority, lOng disklevel, void emulation=null"_>_RegisterSceneHookPlugin() function.

                        If you override this function and return TRUE, then you can insert your own points of execution in the list by calling for example:
                           _list_ ->[Add(tag, EXECUTION_ANIMATION, 0)](); _list_ ->[Add(tag, EXECUTION_GENERATOR, 0)]();
                        CINEMA 4D will then call Execute() two times."
                        so it should call Execute at the point you specify, in that case:
                        list->Add(node, EXECUTIONFLAGS_INDRAG, 0);
                        list->Add(node, EXECUTIONFLAGS_INMOVE, 0);

                        this should work I guess, also I can see examples that are already doing a SceneHook during object drag "like Arnold IPR"

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

                          On 06/11/2015 at 06:11, xxxxxxxx wrote:

                          @Firielentul , you were correct, I tested what I wrote here and it didn't work.
                          but there is a solution:
                          you want to draw one more time after MOVE_CONTINUE finishes, this can be done with 2 flags.

                          pseudo code:

                            
                          if id == MOVE_CONTINUE:  
                              current_flag = a  
                          else  
                              current_flag = b  
                            
                          if prev_flag == a and current_flag == b:  
                              Redraw()  
                          prev_flag = current_flag  
                          
                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post