ToolData Highlight Objects on Hover? [SOLVED]
On 26/02/2015 at 13:05, xxxxxxxx wrote:
Is it possible to highlight objects on hover w/ a Python ToolData plugin? Basically I'm looking to add the behavior you see in the Move/Scale/Rotate/Select tools where the edges of objects light up when you hover over them so that you know which object you're going to select.
I've overloaded the Draw method to return c4d.TOOLDRAW_HIGHLIGHTS, but it doesn't have any impact.
def Draw(self, doc, data, bd, bh, bt, flags) : """Draw highlights for the object under the cursor.""" return c4d.TOOLDRAW_HANDLES | c4d.TOOLDRAW_AXIS | c4d.TOOLDRAW_HIGHLIGHTS
On 27/02/2015 at 08:23, xxxxxxxx wrote:
GetCursorInfo() is called every time the mouse is moved. You could check there if there is an object under the cursor. Then you could use the BIT_HIGHLIGHT bit of an object to make it highlighted in the viewport. Don't forget to delete this bit for objects no longer selected. The BIT_HIGHLIGHT is marked as private so it's behavior may change in the future and only limited support can be given.
On 27/02/2015 at 11:50, xxxxxxxx wrote:
@Sebastian - thanks for that! Is this a different behavior from the C++ SDK? It seems like it handles it automatically in the PickTool example file.
For anyone that's trying to get object highlighting to work in their ToolData plugin, just drop in these methods:
def MouseToView(self, mouse_x, mouse_y, width, height) : """Clips mouse_x & mouse_y to view dimensions view_x, view_y = self.MouseToView(mouse_x, mouse_y, width, height)""" if (mouse_x is None) or (mouse_y is None) : return None, None view_x = int(mouse_x) if view_x > width: view_x = width view_y = int(mouse_y) if view_y > height: view_y = height return view_x, view_y def GetViewData(self, bd) : """Retrieve helpful view information. frame, left, right, top, bottom, width, height = self.GetViewData(bd) """ if bd is None: return None, None, None, None, None, None, None #Get View Data frame = bd.GetFrame() left = frame["cl"] right = frame["cr"] top = frame["ct"] bottom = frame["cb"] width = right - left + 1 height = bottom - top + 1 return frame, left, right, top, bottom, width, height def GetObjectUnderCursor(self, bd, doc, x, y, rad=2) : """Return the object under the cursor. Limitation: Only works w/ OGL turned on""" frame, left, right, top, bottom, width, height = self.GetViewData(bd) view_x, view_y = self.MouseToView(x, y, width, height) nearest_objects = c4d.utils.ViewportSelect().PickObject(bd, doc, view_x, view_y, rad=rad, flags=c4d.VIEWPORT_PICK_FLAGS_OGL_ONLY_TOPMOST_WITH_OBJ) if nearest_objects: return nearest_objects return None def Draw(self, doc, data, bd, bh, bt, flags) : """Ensure the highlighting is active.""" return c4d.TOOLDRAW_HIGHLIGHTS def GetCursorInfo(self, doc, data, bd, x, y, bc) : """Highlight the objects under the cursor.""" hover_obj = self.GetObjectUnderCursor(bd, doc, x, y) #They're the same object or None, so no need to update highlighting if self.last_hover == hover_obj: return True #Clear out the highlighting on the old objects if self.last_hover is not None: if self.last_hover.IsAlive() : self.last_hover.DelBit(c4d.BIT_HIGHLIGHT) self.last_hover = None #Highlight the object under the cursor, and store it for later comparison if (hover_obj is not None) and hover_obj.IsAlive() : self.last_hover = hover_obj hover_obj.SetBit(c4d.BIT_HIGHLIGHT) #Update the views. c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_ANIMATION) return True
On 02/03/2015 at 00:35, xxxxxxxx wrote:
do you mean the PickObjectTool plugin? This plugin is not based on ToolData but on DescriptionToolData.
On 03/03/2015 at 12:28, xxxxxxxx wrote:
That's the one, I suppose that would explain the difference in behavior. I wish we had access to the DescriptionToolData class in Python.