Пример #1
0
    def test_handler_warning(self):
        handlers = {
            "TraitDict": TraitDict,
            "TraitList": TraitList,
            "TraitTuple": TraitTuple,
            "TraitMap": lambda: TraitMap({}),
            "TraitPrefixList": lambda: TraitPrefixList("one", "two"),
            "TraitPrefixMap": lambda: TraitPrefixMap({}),
        }

        for name, handler_factory in handlers.items():
            with self.subTest(handler=name):
                with warnings.catch_warnings(record=True):
                    warnings.simplefilter("error", DeprecationWarning)

                    with self.assertRaises(DeprecationWarning) as cm:
                        handler_factory()
                self.assertIn(name, str(cm.exception))
Пример #2
0
class TransformData(Filter):
    """Performs a linear transformation to input data using a
    tvtk.BoxWidget.  This does not work with
    ImageData/StructuredPoints/RectilinearGrid.
    """

    # The version of this class.  Used for persistence.
    __version__ = 0

    # The widget that we use to perform the transformation.
    widget = Instance(tvtk.ThreeDWidget, allow_none=False, record=True)

    # The filter we manage.
    filter = Instance(tvtk.Object, allow_none=False)

    # The transform.
    transform = Property

    # Update the data immediately or at the end of the interaction.
    update_mode = Trait('semi-interactive',
                        TraitMap({
                            'interactive': 'InteractionEvent',
                            'semi-interactive': 'EndInteractionEvent'
                        }),
                        desc='speed at which the data should be updated')

    input_info = PipelineInfo(
        datasets=['poly_data', 'structured_grid', 'unstructured_grid'],
        attribute_types=['any'],
        attributes=['any'])

    output_info = PipelineInfo(
        datasets=['poly_data', 'structured_grid', 'unstructured_grid'],
        attribute_types=['any'],
        attributes=['any'])

    ########################################
    # View related code.

    # Reset the transformation.
    reset = Button("Reset Transformation")

    view = View(Group(
        Group(Item('update_mode'), ),
        Group(Item('reset'),
              Item(name='widget', style='custom', resizable=True),
              show_labels=False)),
                resizable=True)

    ########################################
    # Private traits.
    _transform = Instance(tvtk.Transform, allow_none=False)

    _first = Bool(True)

    _observer_id = Int(-1)

    ######################################################################
    # `object` interface.
    ######################################################################
    def __get_pure_state__(self):
        d = super(TransformData, self).__get_pure_state__()
        for name in ('_first', '_observer_id'):
            d.pop(name, None)
        d['matrix'] = cPickle.dumps(self._transform.matrix)
        return d

    def __set_pure_state__(self, state):
        mat = state.pop('matrix')
        super(TransformData, self).__set_pure_state__(state)
        state_pickler.set_state(self, state)
        self._transform.set_matrix(cPickle.loads(mat))
        self.widget.set_transform(self._transform)

    ######################################################################
    # `Filter` interface.
    ######################################################################
    def setup_pipeline(self):
        self._transform = tvtk.Transform()
        self.widget = tvtk.BoxWidget(place_factor=1.1)
        self.filter = tvtk.TransformFilter()
        super(TransformData, self).setup_pipeline()

    def update_pipeline(self):
        # Do nothing if there is no input.
        inputs = self.inputs
        if len(inputs) == 0:
            return

        inp = inputs[0].outputs[0]
        if inp.is_a('vtkImageData') or inp.is_a('vtkRectilinearGrid'):
            error('Transformation not supported for '\
                  'ImageData/StructuredPoints/RectilinearGrid')
            return

        # Set the input for the widget and place it if this hasn't
        # been done before.
        w = self.widget
        w.input = inp
        if self._first:
            w.place_widget()
            self._first = False

        # By default we set the input to the first output of the first
        # input.
        fil = self.filter
        fil.input = inp
        fil.transform = self._transform
        fil.update()
        self._set_outputs([fil.output])

    def update_data(self):
        # Do nothing if there is no input.
        if len(self.inputs) == 0:
            return

        self.filter.update()
        # Propagate the data_changed event.
        self.data_changed = True

    ######################################################################
    # Non-public interface.
    ######################################################################
    def _get_transform(self):
        return self._transform

    def _on_interaction_event(self, obj, event):
        tfm = self._transform
        self.widget.get_transform(tfm)
        f = self.filter
        f.transform = tfm
        f.update()
        self.render()
        recorder = self.recorder
        if recorder is not None:
            state = {}
            state['elements'] = tfm.matrix.__getstate__()['elements']
            name = recorder.get_script_id(self)
            recorder.record('%s.transform.matrix.__setstate__(%s)'\
                            %(name, state))
            recorder.record('%s.widget.set_transform(%s.transform)'\
                            %(name, name))
            recorder.record('%s.filter.update()' % name)

    def _widget_changed(self, old, new):
        if old is not None:
            old.on_trait_change(self.render, remove=True)
            old.remove_observer(self._observer_id)
            self.widgets.remove(old)
        new.on_trait_change(self.render)
        self._observer_id = new.add_observer(self.update_mode_,
                                             self._on_interaction_event)
        self.widgets.append(new)
        if len(self.inputs) > 0:
            new.input = self.inputs[0].output[0]

    def _filter_changed(self, old, new):
        if old is not None:
            old.on_trait_change(self.render, remove=True)
        new.on_trait_change(self.render)
        transform = self.transform
        if transform is not None:
            new.transform = transform
        if len(self.inputs) > 0:
            inp = self.inputs[0].outputs[0]
            new.input = inp
            self.outputs = [new.output]

    def _reset_fired(self):
        self._transform.identity()
        self.widget.place_widget()
        self.filter.update()
        self.render()

    def _update_mode_changed(self, old, new):
        w = self.widget
        if w is not None:
            w.remove_observer(self._observer_id)
            self._observer_id = w.add_observer(self.update_mode_,
                                               self._on_interaction_event)
            self.render()
class ImplicitWidgets(Component):

    # The version of this class.  Used for persistence.
    __version__ = 0

    # The widget type to use.
    widget_mode = Enum('Box', 'Sphere', 'Plane','ImplicitPlane',
                       desc='the implicit widget to use')

    # The actual poly data source widget.
    widget = Instance(tvtk.ThreeDWidget, record=True)

    update_mode = Trait('semi-interactive',
                        TraitMap({'interactive':'InteractionEvent',
                                  'semi-interactive': 'EndInteractionEvent'}),
                        desc='speed at which the data should be updated')

    implicit_function = Instance(tvtk.ImplicitFunction, allow_none=False)

    ########################################
    # Private traits.

    _first = Bool(True)
    _busy = Bool(False)
    _observer_id = Int(-1)
    _bounds = Any

    # The actual widgets.
    _widget_dict = Dict(Str, Instance(tvtk.ThreeDWidget,
                        allow_none=False))

    # The actual implicit functions.
    _implicit_function_dict = Dict(Str, Instance(tvtk.ImplicitFunction,
                                   allow_none=False))

    ########################################
    # View related traits.
    ########################################
     # Create the UI for the traits.
    view = View(Group(Item(name='widget_mode'), Item(name='widget',
                            style='custom', resizable=True),
                            label='Widget Source', show_labels=False),
                            resizable=True)

    #####################################################################
    # `object` interface
    ######################################################################
    def __init__(self, **traits):
        # Call parent class' init.
        super(ImplicitWidgets, self).__init__(**traits)

        # Initialize the source to the default widget's instance from
        # the dictionary if needed.
        if 'widget_mode' not in traits:
            self._widget_mode_changed(self.widget_mode)

    ######################################################################
    # `Base` interface
    ######################################################################
    def __get_pure_state__(self):
        d = super(ImplicitWidgets, self).__get_pure_state__()
        for attr in ('_first', '_busy', '_observer_id', 'widget',
                     'implicit_function'):
            d.pop(attr, None)
        # The box widget requires a transformation matrix to be pickled.
        tfm = tvtk.Transform()
        w = self._widget_dict['Box']
        w.get_transform(tfm)
        d['matrix'] = pickle.dumps(tfm.matrix)
        return d

    def __set_pure_state__(self, state):
        # Pop the transformation matrix for the box widget.
        mat = state.pop('matrix')
        # Now set their state.
        set_state(self, state, first=['widget_mode'], ignore=['*'])
        # Set state of rest of the attributes ignoring the widget_mode.
        set_state(self, state, ignore=['widget_mode'])

        # Set the transformation for Box widget.
        tfm = tvtk.Transform()
        tfm.set_matrix(pickle.loads(mat))
        w = self._widget_dict['Box']
        w.set_transform(tfm)

        # Some widgets need some cajoling to get their setup right.
        w = self.widget
        # Set the input.
        if len(self.inputs) > 0:
            self.configure_input(w, self.inputs[0].outputs[0])
        w.update_traits()
        mode = self.widget_mode
        if mode == 'Plane':
            wd = state._widget_dict[mode]
            w.origin = wd.origin
            w.normal = wd.normal
            w.update_placement()
        self.update_implicit_function()
        # Set the widgets trait so that the widget is rendered if needed.
        self.widgets = [w]

    ######################################################################
    # `Component` interface
    ######################################################################
    def setup_pipeline(self):
        """Override this method so that it *creates* the tvtk
        pipeline.
        """
        # Setup the widgets.
        self.widgets = [self.widget]

    def update_pipeline(self):
        """Override this method so that it *updates* the tvtk pipeline
        when data upstream is known to have changed.

        This method is invoked (automatically) when any of the inputs
        sends a `pipeline_changed` event.
        """
        if len(self.inputs) == 0:
            return
        inp = self.inputs[0].outputs[0]
        w = self.widget
        self.configure_input(w, inp)

        dsh = DataSetHelper(self.inputs[0].outputs[0])
        self._bounds = dsh.get_bounds()

        if self._first:
            w.place_widget(self._bounds)
            self._first = False

        # Set our output.
        if self.outputs != [inp]:
            self.outputs = [inp]
        else:
            self.data_changed = True

        self.pipeline_changed = True

    def update_data(self):
        """Override this method so that it flushes the vtk pipeline if
        that is necessary.

        This method is invoked (automatically) when any of the inputs
        sends a `data_changed` event.
        """
        self.data_changed = True

    ######################################################################
    # `SourceWidget` interface
    ######################################################################
    def update_implicit_function(self):
        """Update the implicit_function from the widget data.
        """
        dispatch = {'Sphere': 'get_sphere', 'Box': 'get_planes',
                    'Plane': 'get_plane', 'ImplicitPlane': 'get_plane'}
        method = getattr(self.widget, dispatch[self.widget_mode])
        method(self.implicit_function)

    ######################################################################
    # Non-public traits.
    ######################################################################
    def _widget_changed(self, old, value):
        if len(self.inputs) > 0:
            self.configure_input(value, self.inputs[0].outputs[0])
            if self._bounds:
                value.place_widget(self._bounds)
            else:
                value.place_widget()
        self.implicit_function = self._implicit_function_dict[self.widget_mode]

        if old is not None:
            self._connect(old, remove=True)
        self._connect(value, remove=False)
        self.widgets = [value]

    def _connect(self, value, remove=False):
        """Wire up event handlers or tear them down given a widget
        `value`.  If `remove` is True, then tear them down."""
        if remove and self._observer_id > 0:
                value.remove_observer(self._observer_id)
        else:
            self._observer_id = value.add_observer(self.update_mode_,
                                                   self._on_interaction_event)
        if isinstance(value, tvtk.PlaneWidget) or \
            isinstance(value, tvtk.ImplicitPlaneWidget):
            value.on_trait_change(self._on_alignment_set,
                                  'normal_to_x_axis', remove=remove)
            value.on_trait_change(self._on_alignment_set,
                                  'normal_to_y_axis', remove=remove)
            value.on_trait_change(self._on_alignment_set,
                                  'normal_to_z_axis', remove=remove)

        value.on_trait_change(self._on_widget_trait_changed,
                              remove=remove)
        value.on_trait_change(self.render, remove=remove)

    def _on_interaction_event(self, obj, event):
        self.update_implicit_function()

    def _update_mode_changed(self, old, new):
        w = self.widget
        if w is not None:
            w.remove_observer(self._observer_id)
            self._observer_id = w.add_observer(self.update_mode_,
                    self._on_interaction_event)

            w.on_trait_change(self.render)
            self.render()

    def _on_widget_trait_changed(self):
        if (not self._busy) and (self.update_mode != 'non-interactive'):
            self._busy = True
            self.implicit_function = self._implicit_function_dict[self.widget_mode]
            self.update_implicit_function()
            self.render()
            self._busy = False

    def _on_alignment_set(self):
        """Event handler when the widget's normal is reset (if
        applicable)."""
        w = self.widget
        w.place_widget(self._bounds)
        w.update_traits()
        self.render()

    def _scene_changed(self, old, new):
        super(ImplicitWidgets, self)._scene_changed(old, new)
        self._foreground_changed_for_scene(None, new.foreground)

    def _widget_mode_changed(self, value):
        """This method is invoked (automatically) when the `source`
        trait is changed.
        """
        self.widget = self._widget_dict[self.widget_mode]

    def __widget_dict_default(self):
        """Default value for source dict."""
        w = {'Box':tvtk.BoxWidget(place_factor = 0.9),
             'Sphere':tvtk.SphereWidget(place_factor = 0.9),
             'Plane':tvtk.PlaneWidget(place_factor = 0.9),
             'ImplicitPlane':
                tvtk.ImplicitPlaneWidget(place_factor=0.9,
                                         draw_plane=False)}
        return w

    def __implicit_function_dict_default(self):
        """Default value for source dict."""
        ip = {'Box':tvtk.Planes(),
              'Sphere':tvtk.Sphere(),
              'Plane':tvtk.Plane(),
              'ImplicitPlane': tvtk.Plane()}
        return ip