<commit_before>from __future__ import absolute_import, division, print_function

"""
This is for 3D selection in Glue 3d scatter plot viewer.
"""

import numpy as np

from glue.core import Data
from glue.config import viewer_tool
from glue.viewers.common.qt.tool import CheckableTool
from glue.core.edit_subset_mode import EditSubsetMode

from glue.core.roi import RectangularROI, CircularROI, PolygonalROI, Projected3dROI
from glue.core.subset import RoiSubsetState3d

from ..utils import as_matrix_transform
from ..extern.vispy.scene import Rectangle, Line, Ellipse

# Backward-compatibility for reading files
from .compat import MultiMaskSubsetState  # noqa
MultiElementSubsetState = MultiMaskSubsetState


class VispyMouseMode(CheckableTool):

    # this will create an abstract selection mode class to handle mouse events
    # instanced by lasso, rectangle, circular and point mode

    def __init__(self, viewer):
        super(VispyMouseMode, self).__init__(viewer)
        self._vispy_widget = viewer._vispy_widget
        self.current_visible_array = None

    def get_visible_data(self):
        visible = []
        # Loop over visible layer artists
        for layer_artist in self.viewer._layer_artist_container:
            # Only extract Data objects, not subsets
            if isinstance(layer_artist.layer, Data):
                visible.append(layer_artist.layer)
        visual = layer_artist.visual  # we only have one visual for each canvas
        return visible, visual

    def iter_data_layer_artists(self):
        for layer_artist in self.viewer._layer_artist_container:
            if isinstance(layer_artist.layer, Data):
                yield layer_artist

    def apply_roi(self, roi):
        x_att = self.viewer.state.x_att
        y_att = self.viewer.state.y_att
        z_att = self.viewer.state.z_att
        self.apply_subset_state(RoiSubsetState3d(x_att, y_att, z_att, roi))

    def apply_subset_state(self, subset_state):
        try:
            mode = self.viewer.session.edit_subset_mode
        except AttributeError:  # old versisons of glue
            mode = EditSubsetMode()
        mode.update(self.viewer._data, subset_state)

    def set_progress(self, value):
        if value < 0:
            self.viewer.show_status('')
        else:
            self.viewer.show_status('Calculating selection - {0}%'.format(int(value)))

    @property
    def projection_matrix(self):

        # Get first layer (maybe just get from viewer directly in future)
        layer_artist = next(self.iter_data_layer_artists())

        # Get transformation matrix and transpose
        transform = layer_artist.visual.get_transform(map_from='visual', map_to='canvas')
        return as_matrix_transform(transform).matrix.T


@viewer_tool
class LassoSelectionMode(VispyMouseMode):

    icon = 'glue_lasso'<commit_msg>Make sure undoing selections works<commit_after>from __future__ import absolute_import, division, print_function

"""
This is for 3D selection in Glue 3d scatter plot viewer.
"""

import numpy as np

from glue.core import Data
from glue.config import viewer_tool
from glue.viewers.common.qt.tool import CheckableTool
from glue.core.command import ApplySubsetState

from glue.core.roi import RectangularROI, CircularROI, PolygonalROI, Projected3dROI
from glue.core.subset import RoiSubsetState3d

from ..utils import as_matrix_transform
from ..extern.vispy.scene import Rectangle, Line, Ellipse

# Backward-compatibility for reading files
from .compat import MultiMaskSubsetState  # noqa
MultiElementSubsetState = MultiMaskSubsetState


class VispyMouseMode(CheckableTool):

    # this will create an abstract selection mode class to handle mouse events
    # instanced by lasso, rectangle, circular and point mode

    def __init__(self, viewer):
        super(VispyMouseMode, self).__init__(viewer)
        self._vispy_widget = viewer._vispy_widget
        self.current_visible_array = None

    def get_visible_data(self):
        visible = []
        # Loop over visible layer artists
        for layer_artist in self.viewer._layer_artist_container:
            # Only extract Data objects, not subsets
            if isinstance(layer_artist.layer, Data):
                visible.append(layer_artist.layer)
        visual = layer_artist.visual  # we only have one visual for each canvas
        return visible, visual

    def iter_data_layer_artists(self):
        for layer_artist in self.viewer._layer_artist_container:
            if isinstance(layer_artist.layer, Data):
                yield layer_artist

    def apply_roi(self, roi):
        x_att = self.viewer.state.x_att
        y_att = self.viewer.state.y_att
        z_att = self.viewer.state.z_att
        self.apply_subset_state(RoiSubsetState3d(x_att, y_att, z_att, roi))

    def apply_subset_state(self, subset_state):
        cmd = ApplySubsetState(data_collection=self.viewer._data,
                               subset_state=subset_state,
                               use_current=False)
        self.viewer.session.command_stack.do(cmd)

    def set_progress(self, value):
        if value < 0:
            self.viewer.show_status('')
        else:
            self.viewer.show_status('Calculating selection - {0}%'.format(int(value)))

    @property
    def projection_matrix(self):

        # Get first layer (maybe just get from viewer directly in future)
        layer_artist = next(self.iter_data_layer_artists())

        # Get transformation matrix and transpose
        transform = layer_artist.visual.get_transform(map_from='visual', map_to='canvas')
        return as_matrix_transform(transform).matrix.T


@viewer_tool
class LassoSelectionMode(VispyMouseMode):

    icon = 'glue_lasso'
{'fraction_non_alphanumeric': 0.07235232436211116, 'fraction_numerical': 0.002446696959105208, 'mean_word_length': 3.1773722627737224, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3860481', 'n_tokens_mistral': 1709, 'n_tokens_neox': 1647, 'n_words': 429}