Example O3: Highlight a particle

../../../_images/python_script_highlight_example.png
from ovito.vis import ViewportOverlayInterface
from ovito.data import DataCollection
from ovito.qt_compat import QtCore, QtGui
from traits.api import Range

class HighlightParticleOverlay(ViewportOverlayInterface):

    # Adjustable user parameter that selects which particle to highlight:
    particle_index = Range(value=0, low=0, label='Particle index')

    def render(self, canvas: ViewportOverlayInterface.Canvas, data: DataCollection, **kwargs):

        # Determine world-space radius of the particle.
        radius = 0.0
        if 'Radius' in data.particles:
            radius = data.particles['Radius'][self.particle_index]
        if radius <= 0 and data.particles.particle_types is not None:
            particle_type = data.particles.particle_types[self.particle_index]
            radius = data.particles.particle_types.type_by_id(particle_type).radius
        if radius <= 0:
            radius = data.particles.vis.radius

        # Project center of the particle to screen space.
        positions = data.particles.positions
        xy = canvas.project_location(positions[self.particle_index])
        if xy is None:
            return

        # Calculate screen-space size of the particle as a fraction of the canvas height.
        screen_radius = canvas.project_length(positions[self.particle_index], radius)

        # Convert everything to logical pixel coordinates used by the QPainter.
        x = xy[0] * canvas.logical_size[0]
        y = (1 - xy[1]) * canvas.logical_size[1]
        screen_radius *= canvas.logical_size[1]

        # Start drawing using a QPainter.
        with canvas.qt_painter() as painter:
            # Draw a dashed circle around the particle.
            pen = QtGui.QPen(QtCore.Qt.DashLine)
            pen.setWidth(3)
            pen.setColor(QtGui.QColor(0,0,255))
            painter.setPen(pen)
            painter.drawEllipse(QtCore.QPointF(x, y), screen_radius, screen_radius)

            # Draw an arrow pointing at the particle.
            arrow_shape = QtGui.QPolygonF()
            arrow_shape.append(QtCore.QPointF(0,0))
            arrow_shape.append(QtCore.QPointF(10,10))
            arrow_shape.append(QtCore.QPointF(10,5))
            arrow_shape.append(QtCore.QPointF(40,5))
            arrow_shape.append(QtCore.QPointF(40,-5))
            arrow_shape.append(QtCore.QPointF(10,-5))
            arrow_shape.append(QtCore.QPointF(10,-10))
            painter.setPen(QtGui.QPen())
            painter.setBrush(QtGui.QBrush(QtGui.QColor(255,0,0)))
            painter.translate(QtCore.QPointF(x, y))
            painter.rotate(-45.0)
            painter.translate(QtCore.QPointF(screen_radius,0))
            painter.scale(2,2)
            painter.drawPolygon(arrow_shape)