BaseObject::GetHighlightHandle() always returns -1

On 24/08/2017 at 03:00, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   18 
Platform:    Mac  ;  Mac OSX  ; 
Language(s) :       PYTHON  ;


I'm currently using Python to write an ObjectData plugin. I'm also using the automated handle interface there (with GetHandleCount(), GetHandle(), and SetHandle()). When I draw the handles in Draw(), I want to highlight the handle that the mouse cursor is hovering over. But it doesn't work,  op.GetHighlightHandle(bd)  always returns -1.

Is there anything I could have done to break it, it anything I should do to make it work? Unfortunately, about 90% of the code can't be shown in public, otherwise I'd post it here.


On 25/08/2017 at 02:21, xxxxxxxx wrote:

Hi Frank,

If GetHighlightHandle() always returns -1, make sure GetHandleCount() returns the right number of handles, and that GetHandle() sets the handle information.
Also check the declaration of GetHandleCount()/GetHandle()/SetHandle() so that Cinema can call these functions:

def GetHandleCount(self, op)
def GetHandle(self, op, i, info)
def SetHandle(self, op, i, p, info)

For an example of how to deal with handles, look at Py-RoundedTube.

(PS: Please post Python related questions to the PYTHON Development sub-forum.)

On 29/08/2017 at 02:55, xxxxxxxx wrote:

Oops, yeah, sorry. Wrong sub forum.

Anyway, these three functions are all implemented and called. The handles work fine, too. Just the highlighting does not. I actually used Py-RoundedTube as a model for my plugin. The only difference is that my handles do not relate to values in the Description, but to values I store internally as class members. But that shouldn't make any difference, I guess.

On 30/08/2017 at 02:24, xxxxxxxx wrote:

In the C++ API source c4d_objectplugin.cpp you can see how GetHandleCount()/GetHandle()/SetHandle() are called from ObjectData::DetectHandle() and ObjectData::MoveHandle().

Also, check that the view Filter- >Highlight Handles is enabled, otherwise BaseObject::GetHighlightHandle() always returns -1.

On 03/11/2017 at 04:24, xxxxxxxx wrote:

I have to get back to this issue...

GetHandle(), SetHandle(), and GetHandleCount() are correctly called and return correct values. The "Highlight Handles" filter is enabled, too. Still, GetHighlightHandle() always returns -1.

Is it possible that this has something to do with the fact, that my plugin object is a PointObject (info = c4d.OBJECT_GENERATOR | c4d.OBJECT_POINTOBJECT on plugin registration)?

I even overwrote DetectHandle() and made it return always 1. And still, GetHighlightHandle() returns -1.


On 03/11/2017 at 11:25, xxxxxxxx wrote:

Hi Frank,

Indeed, GetHighlightHandle() returns -1 for point objects. They aren't supposed to have handles because their points are edited directly in point mode.

On 07/11/2017 at 02:53, xxxxxxxx wrote:

Have you considered that a generator that is a PointObject may want to change other things than just the point positions? We have points that make up the object's basic shape, and then a handle for each point that changes the shape at that point. I don't really get why GetHighlightHandle() has to return -1 in that case, where it could simply return the value internally given by DetectHandle() :cry:


On 07/11/2017 at 08:07, xxxxxxxx wrote:

I'll ask the developers if the behavior of BaseObject::GetHighlightHandle() with point objects is intended.

A solution is to implement ObjectData::DetectHandle() storing the index of the highlighted handle, then using it in Draw().

On 09/11/2017 at 04:47, xxxxxxxx wrote:

Trying to write my own DetectHandle() function now, and calling it from Draw(), as you suggested...

How would I query the mouse position, though? I tried with BaseDraw::GetInputEvent() and BaseDraw::GetInputState(). The first returns a correct mouse position, but only when I press the mouse button. The latter never returns any mouse position except (0;0), regardless of the channel I use. Of course, to detect a handle and highlight it, I'd have to monitor the mouse constantly.

Thanks for help!


On 09/11/2017 at 06:08, xxxxxxxx wrote:

Originally posted by xxxxxxxx

Trying to write my own DetectHandle() function now, and calling it from Draw(), as you suggested...

I will try to explain better my solution.

Usually implementing ObjectData::DetectHandle() is not needed if GetHandle()/SetHandle()/GetHandleCount() are overriden.
Cinema 4D calls ObjectData::DetectHandle() for object plugins and caches the highlight handle ID returned. This ID is, normally, returned by BaseObject::GetHighlightHandle().
But for point objects BaseObject::GetHighlightHandle() returns -1.
So, the solution is to implement ObjectData::DetectHandle() in point object data classes storing the highlight handle ID (in a member variable for instance).
This ID can then be accessed from ObjectData::Draw().

Note you can find the standard implementation of ObjectData::DetectHandle() in the C++ API c4d_objectplugin.cpp file.

On 10/11/2017 at 05:34, xxxxxxxx wrote:

Oh right, that makes sense. Thanks for the workaround, Yannick!

The only thing that makes me a bit nervous is that this method forces me to rely on the order of function calls that come in from Cinema. If that's to change one day, this workaround won't work anymore. But until then, everything is fine. Thanks again!