Manipulator (hwx.inspire.gui)#

class Manipulator(context=None, object=None)#

Bases: Drawable, ModelListener

Base class for interactive graphic objects.

They are typically used to edit Named objects when they are selected in Contexts. See Manipulator.popup.

See demos for examples.

Attribute Table#

Name

Type

context

property

shown

property

Method Table#

Name

Description

createDragPoint (self, **kwds)

Create a drag point at specified location.

createFlatArrow (self, **kwds)

Create a flat arrow with specified origin and direction.

createLinearRuler (self, **kwds)

Create a linear ruler.

createRef (self, pickable=True, **kwds)

Create a Manipulator.Ref.

draw (self, gfx)

Overload to render the graphics

drawHovered (self, ref)

Called when mouse moves over sub graphic.

drawUnhovered (self, ref)

Called when mouse leaves sub graphic.

getPointOnLine (self, event, origin, direction, snapping=True)

Return the closest apparent point to a line.

getPointOnPlane (self, event, origin, normal, snapping=True)

Get point where mouse intersects a plane.

getPointOnXyPlane (self, event, xform, snapping=True)

Returns the closest apparent point to a plane.

getSnapPoint (self, *args, **kwds)

See gui.SnapManager.getSnapPoint

getViewNormal (self)

Return a vector pointing from the camera to the eye.

getViewScaleAtPoint (self, pt)

Return a scale factor that is zoom/model independent.

hide (self)

Hide and deactivateModelListener.

isMouseOver (self)

Returns True if the mouse is over this manipulator and it is pickable.

isMouseOverAny ()

Is the mouse over any pickable manipulators.

onAnyMousePress (self, event)

onAnyMouseRelease (self, event)

onCameraMove (self, event)

onMouseDoubleClick (self, event)

onMouseDrag (self, event)

onMouseMove (self, event)

onMousePress (self, event)

onMouseRelease (self, event)

onObjectDeleted (self, obj)

Hide manipulator when its object is deleted.

onObjectModified (self, obj, attr)

Redraw manipulator when its object is modified.

popup (context, obj)

Create and show Manipulator for the selected object.

requireRedraw (self, now=False)

Call this when draw function dependencies change

setCursor (self, cursor)

Set the named cursor if it is not the current one.

setObject (self, obj)

Set object to be manipulated and show.

show (self)

Make visible and activateModelListener on the current object.

useRef (self, key=None, init={}, create=<function Drawable.createRef at 0x00000166BE4AA550>, **kwds)

Create ref or return existing one using cache key.

worldToScreen (self, pt)

For a given point get screen projection point in pixels.

Example

from hwx.inspire import GeneralObject, FeaturePlanar, Reference,     Location
from hwx.common import math

class TwoPoints(GeneralObject):
  feature   = Reference(FeaturePlanar)
  attachPoint = Location(wrt=feature)
  freePoint   = Location()

  def draw(self, gfx):
    pt1 = self.drawAttachment(gfx)
    gfx.polyline([pt1, self.freePoint], color='purple')

  # Separate func so manip can reuse the code below
  def drawAttachment(self, gfx, **kwds):
    bbox = self.feature.minBoundingBox
    dim  = bbox.y/16
    xform = math.Matrix44(origin=self.attachPoint, zv=self.feature.normal)
    with gfx.apply(xform, color='brown'):
      gfx.box(
        center=(0, 0, dim / 4),
        x=dim,
        y=dim,
        z=dim / 2,
        **kwds
      )

    return xform.origin + xform.z*dim/2

# Gui  ---------------------------------------------------------------------
from hwx.inspire import gui

class TwoPointsContext(gui.Context):
  def onActivate(self):
    self.setSelectable(TwoPoints)
    self.setPickable(FeaturePlanar)
    self.showHelpMessage()

  def showHelpMessage(self):
    if self.getSelectedObjects():
      super().showHelpMessage("Drag ends of object")
    else:
      super().showHelpMessage("Pick a feature")

  def onObjectPicked(self, obj, why):
    obj = TwoPoints(
      feature     = obj,
      attachPoint = obj.pickPoint,
      # Random point in space
      freePoint   = obj.pickPoint + obj.normal * obj.minBoundingBox.x
    )
    self.selectObjects(obj)
    self.clearPickList()

  def onSelectionChanged(self):
    # Base function calls popupManipulators
    super().onSelectionChanged()
    self.showHelpMessage()

  def popupManipulators(self, obj):
    DragEndsManipulator.popup(self, obj)

class DragEndsManipulator(gui.Manipulator):
  def _init(self):
    self.attachment = self.createRef(onMouseDrag=self.onDragAttachment)
    # DragPoint is a builtin ref/graphic that looks good for dragging a point
    self.freePoint = self.createDragPoint(onMouseDrag=self.onDragFreePoint)
    # Customize cursor
    self.freePoint.cursor = 'cursorMoveToolAlign-32.png'

  def draw(self, gfx):
    gfx.set(alwaysOnTop=False)
    # Draw identical attachment graphic on top of the existing graphic.
    # Manipulators default to drawing alwaysOnTop.
    # This makes the existing graphic "seem" to become interactive.
    self.object.drawAttachment(gfx, ref=self.attachment)
    self.freePoint.draw(gfx, self.object.freePoint)

  def onDragAttachment(self, event):
    # Keep attachment point stuck on a feature
    picker = gui.Picker(pickable=FeaturePlanar)
    feature = picker.pickAtPoint(event, returnOne=True)
    if not feature:
      # Mouse isn't over a feature so get the closest point on current one
      feature = picker.pickFeaturePoint(self.object.feature)

    self.object.feature     = feature
    self.object.attachPoint = feature.pickPoint

  def onDragFreePoint(self, event):
    # Move free point around space
    # TODO a better way to handle this is to show a move tool manipulator
    # when the point is clicked or double clicked.
    point = self.getSnapPoint()
    if not point:
      plane = self.object.freePoint, self.getViewNormal()
      point = self.getPointOnPlane(event, *plane, snapping=False)
    self.object.freePoint = point

# Test script --------------------------------------------------------------
from hwx import inspire
model = inspire.newModel()
model.createSolidBlock()
inspire.fitView()

TwoPointsContext.push()
show()#

Make visible and activateModelListener on the current object.

hide()#

Hide and deactivateModelListener.

setObject(obj)#

Set object to be manipulated and show.

Called by popup when an object is selected in the context.

Parameters:

obj (Named) –

onObjectModified(obj, attr)#

Redraw manipulator when its object is modified.

onObjectDeleted(obj)#

Hide manipulator when its object is deleted.

isMouseOver()#

Returns True if the mouse is over this manipulator and it is pickable.

createDragPoint(**kwds)#

Create a drag point at specified location.

Draw Args:

location (math.Point): location of the new drag point.

Returns:

DragPointDrawable

useDragPoint(**kwds)#

See useRef

createFlatArrow(**kwds)#

Create a flat arrow with specified origin and direction.

Draw Args:

origin (math.Point): arrow origin. direction (math.Vector): arrow direction.

Returns:

new created arrow.

Return type:

FlatArrowDrawable

useFlatArrow(**kwds)#

See useRef

createLinearRuler(**kwds)#

Create a linear ruler.

Draw Args:

pt1 (math.Point): one endpoint of ruler. pt2 (math.Point): one endpoint of ruler. axis (math.Vector): axis of the ruler.

Returns:

LinearRulerDrawable

useLinearRuler(**kwds)#

See useRef

useProxy(obj, cls=<class 'hwx.inspire.gui.Manipulator.Manipulator.NamedProxy'>)#

Used to draw a graphic representing a Named object in context.

This means: - The graphic gets picked/selected as the Named obj in context. - Context visualization affects like hover, highlight, transparency, …

get applied to the graphic.

Pass as gfx.sphere(…, ref=myproxy) into Manipulator’s drawn graphics.

The proxy is created on first call and the cached value is returned on subsequent calls. It exists until context is deactivated or delete called.

Parameters:
  • obj (Named) –

  • cls (type[Manipulator.NamedProxy]) – Subclass to create. Used to customize hover, highlight, selection, … effects. See NamedProxy.

Returns:

Manipulator.NamedProxy

activateModelListener(*typesOrObjects)#
Activates or start listening to the data model and call the handlers,

when the specified types are created, destroyed or modified.

Parameters:

*typesOrObjects (Part, BC, Motor, ...) – Types or objects to listen to. Sub classes of Named (Features are not supported).

createRef(pickable=True, **kwds)#

Create a Manipulator.Ref.

Required to make graphics pickable and override visualization effects outside of draw function.

Create refs in _init and use them in draw like:
def _init(self):

self.arrowRef = self.createRef(opacity=.5)

def draw(self, gfx):

gfx.arrow(…, ref=self.arrowRef)

Mouse event callbacks receive the hovered ref as event.picked:
def onMouseRelease(self, event):

print(‘You clicked’, event.picked)

Parameters:
  • pickable (bool) – Make graphics receive mouse events.

  • **kwds – Visualization effects like color, opacity, visible, … Mouse event handlers like onMouseRelease, onMouseDrag, … See Manipulator.Ref.

See useRef for an alternative way to create refs inside of draw.

Returns:

Manipulator.Ref

deactivateModelListener()#

Stops listening for data model changes.

draw(gfx)#

Overload to render the graphics

drawHovered(ref)#

Called when mouse moves over sub graphic.

Parameters:

ref (Manipulator.Ref) – Graphic to be drawn hovered.

drawUnhovered(ref)#

Called when mouse leaves sub graphic.

Parameters:

ref (Manipulator.Ref) – Graphic to be drawn unhovered.

getPointOnLine(event, origin, direction, snapping=True)#

Return the closest apparent point to a line.

Parameters:
  • event (Event) – Mouse event being handled.

  • origin (math.Point) – Origin of the line.

  • direction (math.Vector) – Line direction.

  • snapping (bool) – Give preference to snap points.

Returns:

math.Point None if the lines are parallel, or the closest point is out of view.

getPointOnPlane(event, origin, normal, snapping=True)#

Get point where mouse intersects a plane.

Parameters:
  • event (Event) – Mouse event being handled.

  • origin (math.Point) – Point on plane.

  • normal (math.Vector) – Plane normal. Use self.getViewNormal() for free dragging.

  • snapping (bool) – Give preference to snap points.

getPointOnXyPlane(event, xform, snapping=True)#

Returns the closest apparent point to a plane.

Parameters:
  • event (Event) – Mouse event being handled.

  • xform (Matrix44) – plane definition.

  • snapping (bool) – Give preference to snap points.

Returns:

math.Point

getSnapPoint(*args, **kwds)#

See gui.SnapManager.getSnapPoint

getViewNormal()#

Return a vector pointing from the camera to the eye.

getViewScaleAtPoint(pt)#

Return a scale factor that is zoom/model independent.

Used to scaleToScreen in one direction. For example we want the gradations of the LinearRuler a certain height independent of the view zoom, but because the length of the ruler changes we can not use scaleToScreen.

Parameters:

pt (math.Point) – view point.

Returns:

The scale factor.

Return type:

float

isModelListenerActive()#

Returns, True if the model listener is active else False.

modelListenerInactive()#

Context to temporarily disable all the callbacks.

onObjectCreated(obj)#

Implement if interested when an object is created.

Not directly supported for Features but you can detect geometry changes

using onObjectModified of the Part.features attribute.

This can be caused by:
  • Explicit object creation.

  • Undo of destroy.

  • Rollback/forward of construction history.

Parameters:

obj (Named) –

onPartAnimationPositionModified(part)#

Implemented if interested when a part’s animationPosition changes.

This is a temporary state that isn’t recorded in history.

Parameters:

part (Named) –

requireRedraw(now=False)#

Call this when draw function dependencies change

setCursor(cursor)#

Set the named cursor if it is not the current one.

Parameters:

cursor (str) – name of the cursor, one of “” : the default cursor (arrow) “MAIN” : show the user whhat context he is in ‘+’ : show an object can be added to the pick list ‘-’ : show an object can be removed from the pick list ‘+- : show an object can be toggled (windowMode) ‘x’ : show an object is in the pick list .png : the name of an icon file other : the name of a registered cursor

useRef(key=None, init={}, create=<function Drawable.createRef>, **kwds)#

Create ref or return existing one using cache key.

For use in draw functions to avoid overloading _init or if the number of refs is dynamic:

def draw(self, gfx):

arrowRef = self.useRef(‘arrow1’, onMouseRelease=…) gfx.arrow(…, ref=arrowRef)

Reusing refs is important to maintain visual state between draw calls.

Parameters:
  • key – Unique id for the ref to cache it. Defaults to a counter.

  • init (dict) – kwds passed to create.

  • create (type[Manipulator.Tool]) – Create a Ref subclass.

  • **kwds

    ref.setValues(**kwds)

    Returns:

    Manipulator.Ref

worldToScreen(pt)#

For a given point get screen projection point in pixels.

Parameters:

pt (math.Point) – Point for which we want to get the screen projection.

Returns:

screen projection point in pixels.

Return type:

math.Point