Пример #1
0
def test_update_actor():
    size = (15, 15)
    test_bounds = [0.0, 15, 0.0, 15, 0.0, 0.0]
    points = Points()
    points.InsertNextPoint(0, 0, 0)
    points.InsertNextPoint(size[0], 0, 0)
    points.InsertNextPoint(size[0], size[1], 0)
    points.InsertNextPoint(0, size[1], 0)

    # Create the polygon
    polygon = Polygon()
    polygon.GetPointIds().SetNumberOfIds(4)  # make a quad
    polygon.GetPointIds().SetId(0, 0)
    polygon.GetPointIds().SetId(1, 1)
    polygon.GetPointIds().SetId(2, 2)
    polygon.GetPointIds().SetId(3, 3)
    # Add the polygon to a list of polygons
    polygons = CellArray()
    polygons.InsertNextCell(polygon)
    # Create a PolyData
    polygonPolyData = PolyData()
    polygonPolyData.SetPoints(points)
    polygonPolyData.SetPolys(polygons)
    # Create a mapper and actor
    mapper = PolyDataMapper2D()
    mapper = set_input(mapper, polygonPolyData)
    actor = Actor2D()
    actor.SetMapper(mapper)
    compute_bounds(actor)
    npt.assert_equal(actor.GetMapper().GetInput().GetBounds(), test_bounds)
    updated_size = (35, 35)
    points.SetPoint(0, 0, 0, 0.0)
    points.SetPoint(1, updated_size[0], 0, 0.0)
    points.SetPoint(2, updated_size[0], updated_size[1], 0.0)
    points.SetPoint(3, 0, updated_size[1], 0.0)
    polygonPolyData.SetPoints(points)
    test_bounds = [0.0, 35.0, 0.0, 35.0, 0.0, 0.0]
    compute_bounds(actor)
    npt.assert_equal(None, update_actor(actor))
    npt.assert_equal(test_bounds, actor.GetMapper().GetInput().GetBounds())
Пример #2
0
class ImageContainer2D(UI):
    """A 2D container to hold an image.

    Currently Supports:
    - png and jpg/jpeg images

    Attributes
    ----------
    size: (float, float)
        Image size (width, height) in pixels.
    img : ImageData
        The image loaded from the specified path.

    """
    def __init__(self, img_path, position=(0, 0), size=(100, 100)):
        """Init class instance.

        Parameters
        ----------
        img_path : string
            URL or local path of the image
        position : (float, float), optional
            Absolute coordinates (x, y) of the lower-left corner of the image.
        size : (int, int), optional
            Width and height in pixels of the image.
        """
        super(ImageContainer2D, self).__init__(position)
        self.img = load_image(img_path, as_vtktype=True)
        self.set_img(self.img)
        self.resize(size)

    def _get_size(self):
        lower_left_corner = self.texture_points.GetPoint(0)
        upper_right_corner = self.texture_points.GetPoint(2)
        size = np.array(upper_right_corner) - np.array(lower_left_corner)
        return abs(size[:2])

    def _setup(self):
        """Setup this UI Component.

        Return an image as a 2D actor with a specific position.

        Returns
        -------
        :class:`vtkTexturedActor2D`
        """
        self.texture_polydata = PolyData()
        self.texture_points = Points()
        self.texture_points.SetNumberOfPoints(4)

        polys = CellArray()
        polys.InsertNextCell(4)
        polys.InsertCellPoint(0)
        polys.InsertCellPoint(1)
        polys.InsertCellPoint(2)
        polys.InsertCellPoint(3)
        self.texture_polydata.SetPolys(polys)

        tc = FloatArray()
        tc.SetNumberOfComponents(2)
        tc.SetNumberOfTuples(4)
        tc.InsertComponent(0, 0, 0.0)
        tc.InsertComponent(0, 1, 0.0)
        tc.InsertComponent(1, 0, 1.0)
        tc.InsertComponent(1, 1, 0.0)
        tc.InsertComponent(2, 0, 1.0)
        tc.InsertComponent(2, 1, 1.0)
        tc.InsertComponent(3, 0, 0.0)
        tc.InsertComponent(3, 1, 1.0)
        self.texture_polydata.GetPointData().SetTCoords(tc)

        texture_mapper = PolyDataMapper2D()
        texture_mapper = set_input(texture_mapper, self.texture_polydata)

        image = TexturedActor2D()
        image.SetMapper(texture_mapper)

        self.texture = Texture()
        image.SetTexture(self.texture)

        image_property = Property2D()
        image_property.SetOpacity(1.0)
        image.SetProperty(image_property)
        self.actor = image

        # Add default events listener to the VTK actor.
        self.handle_events(self.actor)

    def _get_actors(self):
        """Return the actors that compose this UI component."""
        return [self.actor]

    def _add_to_scene(self, scene):
        """Add all subcomponents or VTK props that compose this UI component.

        Parameters
        ----------
        scene : scene
        """
        scene.add(self.actor)

    def resize(self, size):
        """Resize the image.

        Parameters
        ----------
        size : (float, float)
            image size (width, height) in pixels.
        """
        # Update actor.
        self.texture_points.SetPoint(0, 0, 0, 0.0)
        self.texture_points.SetPoint(1, size[0], 0, 0.0)
        self.texture_points.SetPoint(2, size[0], size[1], 0.0)
        self.texture_points.SetPoint(3, 0, size[1], 0.0)
        self.texture_polydata.SetPoints(self.texture_points)

    def _set_position(self, coords):
        """Set the lower-left corner position of this UI component.

        Parameters
        ----------
        coords: (float, float)
            Absolute pixel coordinates (x, y).
        """
        self.actor.SetPosition(*coords)

    def scale(self, factor):
        """Scale the image.

        Parameters
        ----------
        factor : (float, float)
            Scaling factor (width, height) in pixels.
        """
        self.resize(self.size * factor)

    def set_img(self, img):
        """Modify the image used by the vtkTexturedActor2D.

        Parameters
        ----------
        img : imageData

        """
        self.texture = set_input(self.texture, img)
Пример #3
0
class Rectangle2D(UI):
    """A 2D rectangle sub-classed from UI."""
    def __init__(self,
                 size=(0, 0),
                 position=(0, 0),
                 color=(1, 1, 1),
                 opacity=1.0):
        """Initialize a rectangle.

        Parameters
        ----------
        size : (int, int)
            The size of the rectangle (width, height) in pixels.
        position : (float, float)
            Coordinates (x, y) of the lower-left corner of the rectangle.
        color : (float, float, float)
            Must take values in [0, 1].
        opacity : float
            Must take values in [0, 1].
        """
        super(Rectangle2D, self).__init__(position)
        self.color = color
        self.opacity = opacity
        self.resize(size)

    def _setup(self):
        """Set up this UI component.

        Creating the polygon actor used internally.
        """
        # Setup four points
        size = (1, 1)
        self._points = Points()
        self._points.InsertNextPoint(0, 0, 0)
        self._points.InsertNextPoint(size[0], 0, 0)
        self._points.InsertNextPoint(size[0], size[1], 0)
        self._points.InsertNextPoint(0, size[1], 0)

        # Create the polygon
        polygon = Polygon()
        polygon.GetPointIds().SetNumberOfIds(4)  # make a quad
        polygon.GetPointIds().SetId(0, 0)
        polygon.GetPointIds().SetId(1, 1)
        polygon.GetPointIds().SetId(2, 2)
        polygon.GetPointIds().SetId(3, 3)

        # Add the polygon to a list of polygons
        polygons = CellArray()
        polygons.InsertNextCell(polygon)

        # Create a PolyData
        self._polygonPolyData = PolyData()
        self._polygonPolyData.SetPoints(self._points)
        self._polygonPolyData.SetPolys(polygons)

        # Create a mapper and actor
        mapper = PolyDataMapper2D()
        mapper = set_input(mapper, self._polygonPolyData)

        self.actor = Actor2D()
        self.actor.SetMapper(mapper)

        # Add default events listener to the VTK actor.
        self.handle_events(self.actor)

    def _get_actors(self):
        """Get the actors composing this UI component."""
        return [self.actor]

    def _add_to_scene(self, scene):
        """Add all subcomponents or VTK props that compose this UI component.

        Parameters
        ----------
        scene : scene
        """
        scene.add(self.actor)

    def _get_size(self):
        # Get 2D coordinates of two opposed corners of the rectangle.
        lower_left_corner = np.array(self._points.GetPoint(0)[:2])
        upper_right_corner = np.array(self._points.GetPoint(2)[:2])
        size = abs(upper_right_corner - lower_left_corner)
        return size

    @property
    def width(self):
        return self._points.GetPoint(2)[0]

    @width.setter
    def width(self, width):
        self.resize((width, self.height))

    @property
    def height(self):
        return self._points.GetPoint(2)[1]

    @height.setter
    def height(self, height):
        self.resize((self.width, height))

    def resize(self, size):
        """Set the button size.

        Parameters
        ----------
        size : (float, float)
            Button size (width, height) in pixels.

        """
        self._points.SetPoint(0, 0, 0, 0.0)
        self._points.SetPoint(1, size[0], 0, 0.0)
        self._points.SetPoint(2, size[0], size[1], 0.0)
        self._points.SetPoint(3, 0, size[1], 0.0)
        self._polygonPolyData.SetPoints(self._points)
        mapper = PolyDataMapper2D()
        mapper = set_input(mapper, self._polygonPolyData)

        self.actor.SetMapper(mapper)

    def _set_position(self, coords):
        """Set the lower-left corner position of this UI component.

        Parameters
        ----------
        coords: (float, float)
            Absolute pixel coordinates (x, y).

        """
        self.actor.SetPosition(*coords)

    @property
    def color(self):
        """Get the rectangle's color."""
        color = self.actor.GetProperty().GetColor()
        return np.asarray(color)

    @color.setter
    def color(self, color):
        """Set the rectangle's color.

        Parameters
        ----------
        color : (float, float, float)
            RGB. Must take values in [0, 1].

        """
        self.actor.GetProperty().SetColor(*color)

    @property
    def opacity(self):
        """Get the rectangle's opacity."""
        return self.actor.GetProperty().GetOpacity()

    @opacity.setter
    def opacity(self, opacity):
        """Set the rectangle's opacity.

        Parameters
        ----------
        opacity : float
            Degree of transparency. Must be between [0, 1].

        """
        self.actor.GetProperty().SetOpacity(opacity)
Пример #4
0
class Button2D(UI):
    """A 2D overlay button and is of type vtkTexturedActor2D.

    Currently supports::

        - Multiple icons.
        - Switching between icons.

    """
    def __init__(self, icon_fnames, position=(0, 0), size=(30, 30)):
        """Init class instance.

        Parameters
        ----------
        icon_fnames : List(string, string)
            ((iconname, filename), (iconname, filename), ....)
        position : (float, float), optional
            Absolute coordinates (x, y) of the lower-left corner of the button.
        size : (int, int), optional
            Width and height in pixels of the button.

        """
        super(Button2D, self).__init__(position)

        self.icon_extents = dict()
        self.icons = self._build_icons(icon_fnames)
        self.icon_names = [icon[0] for icon in self.icons]
        self.current_icon_id = 0
        self.current_icon_name = self.icon_names[self.current_icon_id]
        self.set_icon(self.icons[self.current_icon_id][1])
        self.resize(size)

    def _get_size(self):
        lower_left_corner = self.texture_points.GetPoint(0)
        upper_right_corner = self.texture_points.GetPoint(2)
        size = np.array(upper_right_corner) - np.array(lower_left_corner)
        return abs(size[:2])

    def _build_icons(self, icon_fnames):
        """Convert file names to ImageData.

        A pre-processing step to prevent re-read of file names during every
        state change.

        Parameters
        ----------
        icon_fnames : List(string, string)
            ((iconname, filename), (iconname, filename), ....)

        Returns
        -------
        icons : List
            A list of corresponding ImageData.

        """
        icons = []
        for icon_name, icon_fname in icon_fnames:
            icons.append((icon_name, load_image(icon_fname, as_vtktype=True)))

        return icons

    def _setup(self):
        """Set up this UI component.

        Creating the button actor used internally.

        """
        # This is highly inspired by
        # https://github.com/Kitware/VTK/blob/c3ec2495b183e3327820e927af7f8f90d34c3474/Interaction/Widgets/vtkBalloonRepresentation.cxx#L47

        self.texture_polydata = PolyData()
        self.texture_points = Points()
        self.texture_points.SetNumberOfPoints(4)

        polys = CellArray()
        polys.InsertNextCell(4)
        polys.InsertCellPoint(0)
        polys.InsertCellPoint(1)
        polys.InsertCellPoint(2)
        polys.InsertCellPoint(3)
        self.texture_polydata.SetPolys(polys)

        tc = FloatArray()
        tc.SetNumberOfComponents(2)
        tc.SetNumberOfTuples(4)
        tc.InsertComponent(0, 0, 0.0)
        tc.InsertComponent(0, 1, 0.0)
        tc.InsertComponent(1, 0, 1.0)
        tc.InsertComponent(1, 1, 0.0)
        tc.InsertComponent(2, 0, 1.0)
        tc.InsertComponent(2, 1, 1.0)
        tc.InsertComponent(3, 0, 0.0)
        tc.InsertComponent(3, 1, 1.0)
        self.texture_polydata.GetPointData().SetTCoords(tc)

        texture_mapper = PolyDataMapper2D()
        texture_mapper = set_input(texture_mapper, self.texture_polydata)

        button = TexturedActor2D()
        button.SetMapper(texture_mapper)

        self.texture = Texture()
        button.SetTexture(self.texture)

        button_property = Property2D()
        button_property.SetOpacity(1.0)
        button.SetProperty(button_property)
        self.actor = button

        # Add default events listener to the VTK actor.
        self.handle_events(self.actor)

    def _get_actors(self):
        """Get the actors composing this UI component."""
        return [self.actor]

    def _add_to_scene(self, scene):
        """Add all subcomponents or VTK props that compose this UI component.

        Parameters
        ----------
        scene : scene

        """
        scene.add(self.actor)

    def resize(self, size):
        """Resize the button.

        Parameters
        ----------
        size : (float, float)
            Button size (width, height) in pixels.

        """
        # Update actor.
        self.texture_points.SetPoint(0, 0, 0, 0.0)
        self.texture_points.SetPoint(1, size[0], 0, 0.0)
        self.texture_points.SetPoint(2, size[0], size[1], 0.0)
        self.texture_points.SetPoint(3, 0, size[1], 0.0)
        self.texture_polydata.SetPoints(self.texture_points)

    def _set_position(self, coords):
        """Set the lower-left corner position of this UI component.

        Parameters
        ----------
        coords: (float, float)
            Absolute pixel coordinates (x, y).
        """
        self.actor.SetPosition(*coords)

    @property
    def color(self):
        """Get the button's color."""
        color = self.actor.GetProperty().GetColor()
        return np.asarray(color)

    @color.setter
    def color(self, color):
        """Set the button's color.

        Parameters
        ----------
        color : (float, float, float)
            RGB. Must take values in [0, 1].

        """
        self.actor.GetProperty().SetColor(*color)

    def scale(self, factor):
        """Scale the button.

        Parameters
        ----------
        factor : (float, float)
            Scaling factor (width, height) in pixels.

        """
        self.resize(self.size * factor)

    def set_icon_by_name(self, icon_name):
        """Set the button icon using its name.

        Parameters
        ----------
        icon_name : str

        """
        icon_id = self.icon_names.index(icon_name)
        self.set_icon(self.icons[icon_id][1])

    def set_icon(self, icon):
        """Modify the icon used by the vtkTexturedActor2D.

        Parameters
        ----------
        icon : imageData

        """
        self.texture = set_input(self.texture, icon)

    def next_icon_id(self):
        """Set the next icon ID while cycling through icons."""
        self.current_icon_id += 1
        if self.current_icon_id == len(self.icons):
            self.current_icon_id = 0
        self.current_icon_name = self.icon_names[self.current_icon_id]

    def next_icon(self):
        """Increment the state of the Button.

        Also changes the icon.
        """
        self.next_icon_id()
        self.set_icon(self.icons[self.current_icon_id][1])