Redraw GeUserArea during object movement
-
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 -
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...
-
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 -
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". -
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). -
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" -
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.
-
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 -
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.
-
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"
-
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