Example #1
0
    def add_data_to_dataset(self, dataset, data):
        """Add point and cell data to the dataset."""
        dm = DatasetManager(dataset=dataset)
        for key, val in six.iteritems(data):
            if val.mode == 'vertex':
                aux = self._reshape(val.data, self.dim)
                dm.add_array(aux, key, 'point')

            elif val.mode == 'cell':
                aux = self._reshape(val.data, self.dim)
                dm.add_array(aux, key, 'cell')
Example #2
0
    def _find_stiff_elements(self):
        if (self._first_time_stiff_elements):
            self._first_time_stiff_elements = False
            self._surface_grid = type(self.inputs[0].outputs[0])()
            self._surface_grid.copy_structure(self.inputs[0].outputs[0])

            if (self._surface_grid.points.data_type == 'double'):
                # tvtk.DataSetSurfaceFilter produces surface points as float
                # so we need to convert input points from doubles to floats
                # if necessary
                float_points = array(self._surface_grid.points, 'float32')
                self._surface_grid.points = float_points

            self._dataset_manager = DatasetManager(dataset=self._surface_grid)
            surface_points = self._get_surface_points()
            self._add_stiff_elements(surface_points)
Example #3
0
    def get_mat_id(self, mat_id_name='mat_id'):
        """
        Get material ID numbers of the underlying mesh elements.
        """
        if self.source is not None:
            dm = DatasetManager(dataset=self.source.outputs[0])

            mat_id = dm.cell_scalars[mat_id_name]
            return mat_id
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        # Call cell_picked() when a cell is clicked.
        self.scene.picker.cellpicker.add_observer("EndPickEvent",
                                                  self.cell_picked)
        self.scene.picker.pick_type = 'cell_picker'
        self.scene.picker.tolerance = 0.0
        self.scene.picker.show_gui = False

        self._input_grid.deep_copy(self.inputs[0].outputs[0])

        self._current_grid = self._input_grid
        self._dataset_manager = DatasetManager(dataset=self._input_grid)
        self._set_outputs([self._current_grid])

        # Filter for masking.
        self._extract_cells_filter.set_input(self._input_grid)
Example #5
0
    def create_source(self):
        """
        Create a VTK source from data in a SfePy-supported file.

        Notes
        -----
        All data need to be set here, otherwise time stepping will not
        work properly - data added by user later will be thrown away on
        time step change.
        """
        if self.io is None:
            self.read_common(self.filename)

        dataset = self.create_dataset()

        try:
            out = self.io.read_data(self.step)
        except ValueError:
            out = None

        if out is not None:
            self.add_data_to_dataset(dataset, out)

        if self.mat_id_name is not None:
            mat_id = self.mesh.cmesh.cell_groups
            if self.single_color:
                rm = mat_id.min(), mat_id.max()
                mat_id[mat_id > rm[0]] = rm[1]

            dm = DatasetManager(dataset=dataset)
            dm.add_array(mat_id, self.mat_id_name, 'cell')

        src = VTKDataSource(data=dataset)
#        src.print_traits()
#        debug()
        return src
Example #6
0
    def create_source(self):
        """
        Create a VTK source from data in a SfePy-supported file.

        Notes
        -----
        All data need to be set here, otherwise time stepping will not
        work properly - data added by user later will be thrown away on
        time step change.
        """
        if self.io is None:
            self.read_common(self.filename)

        dataset = self.create_dataset()

        try:
            out = self.io.read_data(self.step)
        except ValueError:
            out = None

        if out is not None:
            self.add_data_to_dataset(dataset, out)

        if self.mat_id_name is not None:
            mat_id = self.mesh.cmesh.cell_groups
            if self.single_color:
                rm = mat_id.min(), mat_id.max()
                mat_id[mat_id > rm[0]] = rm[1]

            dm = DatasetManager(dataset=dataset)
            dm.add_array(mat_id, self.mat_id_name, 'cell')

        src = VTKDataSource(data=dataset)
        #        src.print_traits()
        #        debug()
        return src
    def _find_stiff_elements(self):
        if (self._first_time_stiff_elements):
            self._first_time_stiff_elements = False
            self._surface_grid = type(self.inputs[0].outputs[0])()
            self._surface_grid.copy_structure(self.inputs[0].outputs[0])

            if (self._surface_grid.points.data_type == 'double'):
                # tvtk.DataSetSurfaceFilter produces surface points as float
                # so we need to convert input points from doubles to floats
                # if necessary
                float_points = array(self._surface_grid.points, 'float32')
                self._surface_grid.points = float_points

            self._dataset_manager = DatasetManager(dataset=self._surface_grid)
            surface_points = self._get_surface_points()
            self._add_stiff_elements(surface_points)
Example #8
0
    def add_data_to_dataset(self, dataset, data):
        """Add point and cell data to the dataset."""
        dm = DatasetManager(dataset=dataset)
        for key, val in six.iteritems(data):
            if val.mode == 'vertex':
                aux = self._reshape(val.data, self.dim)
                dm.add_array(aux, key, 'point')

            elif val.mode == 'cell':
                aux = self._reshape(val.data, self.dim)
                dm.add_array(aux, key, 'cell')
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        # Call cell_picked() when a cell is clicked.
        self.scene.picker.cellpicker.add_observer("EndPickEvent", self.cell_picked)
        self.scene.picker.pick_type = 'cell_picker'
        self.scene.picker.tolerance = 0.0
        self.scene.picker.show_gui = False

        self._input_grid.deep_copy(self.inputs[0].outputs[0])

        self._current_grid = self._input_grid
        self._dataset_manager = DatasetManager(dataset=self._input_grid)
        self._set_outputs([self._current_grid])

        # Filter for masking.
        self._extract_cells_filter.set_input(self._input_grid)
Example #10
0
def add_subdomains_surface(obj,
                           position,
                           mat_id_name='mat_id',
                           threshold_limits=(None, None),
                           **kwargs):
    dm = DatasetManager(dataset=obj.outputs[0])
    mat_id = dm.cell_scalars[mat_id_name]

    rm = mat_id.min(), mat_id.max()

    active = mlab.pipeline.set_active_attribute(obj)
    active.cell_scalars_name = mat_id_name

    aa = mlab.pipeline.set_active_attribute(obj)
    aa.cell_scalars_name = mat_id_name

    threshold = mlab.pipeline.threshold(aa)
    threshold.threshold_filter.progress = 1.0
    if threshold_limits[0] is not None:
        threshold.lower_threshold = threshold_limits[0] + 0.1
    if threshold_limits[1] is not None:
        threshold.upper_threshold = threshold_limits[1] - 0.1

    threshold.auto_reset_lower = False
    threshold.auto_reset_upper = False

    surface = mlab.pipeline.surface(threshold, opacity=0.3)
    surface.actor.actor.position = position

    module_manager = surface.parent
    lm = module_manager.scalar_lut_manager
    lm.lut_mode = 'Blues'
    if (rm[1] - rm[0]) == 1:
        lm.reverse_lut = True

    surface2 = mlab.pipeline.surface(active, opacity=0.2)
    surface2.actor.actor.position = position

    module_manager = surface2.parent
    module_manager.scalar_lut_manager.lut_mode = 'Blues'

    return surface, surface2
Example #11
0
    def add_data_to_dataset(self, dataset, data):
        """Add point and cell data to the dataset."""
        dim = self.dim
        sym = (dim + 1) * dim // 2

        dm = DatasetManager(dataset=dataset)
        for key, val in six.iteritems(data):
            vd = val.data
            ##             print vd.shape
            if val.mode == 'vertex':
                if vd.shape[1] == 1:
                    aux = vd.reshape((vd.shape[0], ))

                elif vd.shape[1] == 2:
                    zz = nm.zeros((vd.shape[0], 1), dtype=vd.dtype)
                    aux = nm.c_[vd, zz]

                elif vd.shape[1] == 3:
                    aux = vd

                else:
                    raise ValueError('unknown vertex data format! (%s)'\
                                     % vd.shape)

                dm.add_array(aux, key, 'point')

            elif val.mode == 'cell':
                ne, aux, nr, nc = vd.shape
                if (nr == 1) and (nc == 1):
                    aux = vd.reshape((ne, ))

                elif (nr == dim) and (nc == 1):
                    if dim == 3:
                        aux = vd.reshape((ne, dim))
                    else:
                        zz = nm.zeros((vd.shape[0], 1), dtype=vd.dtype)
                        aux = nm.c_[vd.squeeze(), zz]

                elif (((nr == sym) or (nr == (dim * dim))) and (nc == 1)) \
                         or ((nr == dim) and (nc == dim)):
                    vd = vd.squeeze()

                    if dim == 3:
                        if nr == sym:
                            aux = vd[:, [0, 3, 4, 3, 1, 5, 4, 5, 2]]
                        elif nr == (dim * dim):
                            aux = vd[:, [0, 3, 4, 6, 1, 5, 7, 8, 2]]
                        else:
                            aux = vd.reshape((vd.shape[0], dim * dim))
                    else:
                        zz = nm.zeros((vd.shape[0], 1), dtype=vd.dtype)
                        if nr == sym:
                            aux = nm.c_[vd[:, [0, 2]], zz, vd[:, [2, 1]], zz,
                                        zz, zz, zz]
                        elif nr == (dim * dim):
                            aux = nm.c_[vd[:, [0, 2]], zz, vd[:, [3, 1]], zz,
                                        zz, zz, zz]
                        else:
                            aux = nm.c_[vd[:, 0, [0, 1]], zz, vd[:, 1, [0, 1]],
                                        zz, zz, zz, zz]

                dm.add_array(aux, key, 'cell')
class BoundaryMarkerEditor(Filter):
    """
    Edit the boundary marker of a Triangle surface mesh. To use: select the label to
    assign, hover your cursor over the cell you wish to edit, and press 'p'.
    """

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

    _current_grid = Instance(tvtk.UnstructuredGrid, allow_none=False)
    _input_grid = Instance(tvtk.UnstructuredGrid, args=(), allow_none=False)
    _extract_cells_filter = Instance(tvtk.ExtractCells, args=(), allow_none=False)
    _dataset_manager = Instance(DatasetManager, allow_none=False)
    _cell_mappings = List

    label_to_apply = Range(0,255)
    select_coplanar_cells = Bool
    epsilon = Range(0.0, 1.0, 0.0001)
    mask_labels = Bool
    labels_to_mask = List(label_to_apply)

    # Saving file
    output_file = File
    save = Button

    ######################################################################
    # The view.
    ######################################################################
    traits_view = \
        View(
            Group(
                Item(name='label_to_apply'),
                Item(name='select_coplanar_cells'),
                Item(name='epsilon', enabled_when='select_coplanar_cells', label='Tolerance'),
                Item(name='mask_labels'),
                Group(
                    Item(name='labels_to_mask', style='custom', editor=ListEditor(rows=3)),
                    show_labels=False,
                    show_border=True,
                    label='Labels to mask',
                    enabled_when='mask_labels==True'
                ),
                Group(
                    Item(name='output_file'),
                    Item(name='save', label='Save'),
                    show_labels=False,
                    show_border=True,
                    label='Save changes to file (give only a basename, without the file extension)'
                )
            ),
            height=500,
            width=600
        )

    ######################################################################
    # `Filter` interface.
    ######################################################################
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        # Call cell_picked() when a cell is clicked.
        self.scene.picker.cellpicker.add_observer("EndPickEvent", self.cell_picked)
        self.scene.picker.pick_type = 'cell_picker'
        self.scene.picker.tolerance = 0.0
        self.scene.picker.show_gui = False

        self._input_grid.deep_copy(self.inputs[0].outputs[0])

        self._current_grid = self._input_grid
        self._dataset_manager = DatasetManager(dataset=self._input_grid)
        self._set_outputs([self._current_grid])

        # Filter for masking.
        self._extract_cells_filter.set_input(self._input_grid)

    def update_data(self):
        self.data_changed = True

    ######################################################################
    # Non-public interface.
    ######################################################################

    def cell_picked(self, object, event):
        cell_id = self.scene.picker.cellpicker.cell_id
        self.modify_cell(cell_id, self.label_to_apply)

        if (self.select_coplanar_cells):
            self.modify_neighbouring_cells(cell_id)

        if (self.mask_labels):
            self.perform_mask()

        self._dataset_manager.activate(self._input_grid.cell_data.scalars.name, 'cell')
        self._dataset_manager.update()
        self.pipeline_changed = True

    def get_all_cell_neigbours(self, cell_id, cell):
        neighbour_cell_ids = array([], dtype=int)

        for i in range(cell.number_of_edges):
            # Get points belonging to ith edge
            edge_point_ids = cell.get_edge(i).point_ids

            # Find neigbours which share the edge
            current_neighbour_cell_ids = tvtk.IdList()
            self._current_grid.get_cell_neighbors(cell_id, edge_point_ids, current_neighbour_cell_ids)
            neighbour_cell_ids = append(neighbour_cell_ids, array(current_neighbour_cell_ids))

        return neighbour_cell_ids.tolist()

    def modify_neighbouring_cells(self, cell_id):
        cell = self._current_grid.get_cell(cell_id)

        cell_normal = [0,0,0]
        cell.compute_normal(cell.points[0], cell.points[1], cell.points[2], cell_normal)

        cells_pending = self.get_all_cell_neigbours(cell_id, cell)
        cells_visited = [cell_id]

        while (len(cells_pending) > 0):
            current_cell_id = cells_pending.pop()

            if (current_cell_id not in cells_visited):
                cells_visited.append(current_cell_id)
                current_cell = self._current_grid.get_cell(current_cell_id)

                current_cell_normal = [0,0,0]
                current_cell.compute_normal(current_cell.points[0], current_cell.points[1], current_cell.points[2], current_cell_normal)

                if (dot(cell_normal, current_cell_normal) > (1-self.epsilon)):
                    self.modify_cell(current_cell_id, self.label_to_apply)
                    cells_pending.extend(self.get_all_cell_neigbours(current_cell_id, current_cell))

    def _mask_labels_changed(self):
        if (self.mask_labels):
            self.perform_mask()
            self._current_grid = self._extract_cells_filter.output
        else:
            self._current_grid = self._input_grid

        self._set_outputs([self._current_grid])
        self.pipeline_changed = True

    def _labels_to_mask_changed(self):
        self.perform_mask()

    def _labels_to_mask_items_changed(self):
        self.perform_mask()

    def perform_mask(self):
        labels_array = self._input_grid.cell_data.get_array(self._input_grid.cell_data.scalars.name)
        in_masked = map(lambda x: x in self.labels_to_mask, labels_array)

        unmasked_cells_list = tvtk.IdList()
        cell_ids = range(self._input_grid.number_of_cells)
        # _cell_mappings is indexed by cell_id of the original input grid, and each value
        # is the new cell_id of the corresponding cell in the masked grid
        self._cell_mappings = map(lambda masked,cell_id: None if masked else unmasked_cells_list.insert_next_id(cell_id), in_masked, cell_ids)

        self._extract_cells_filter.set_cell_list(unmasked_cells_list)
        self._extract_cells_filter.update()
        self.pipeline_changed = True

    def modify_cell(self, cell_id, value):
        if (self.mask_labels):
            cell_id = self._cell_mappings.index(cell_id) # Adjust cell_id if masked
        self._input_grid.cell_data.get_array(self._input_grid.cell_data.scalars.name)[cell_id] = value


    def _save_fired(self):
        from mayavi_amcg.triangle_writer import TriangleWriter
        if (self.output_file):
            writer = TriangleWriter(self._input_grid, self.output_file)
            writer.write()
            print "#### Saved ####"
Example #13
0
    def add_data_to_dataset(self, dataset, data):
        """Add point and cell data to the dataset."""
        dim = self.dim
        sym = (dim + 1) * dim / 2

        dm = DatasetManager(dataset=dataset)
        for key, val in data.iteritems():
            vd = val.data
##             print vd.shape
            if val.mode == 'vertex':
                if vd.shape[1] == 1:
                    aux = vd.reshape((vd.shape[0],))

                elif vd.shape[1] == 2:
                    zz = nm.zeros((vd.shape[0], 1), dtype=vd.dtype)
                    aux = nm.c_[vd, zz]

                elif vd.shape[1] == 3:
                    aux = vd

                else:
                    raise ValueError('unknown vertex data format! (%s)'\
                                     % vd.shape)

                dm.add_array(aux, key, 'point')

            elif val.mode == 'cell':
                ne, aux, nr, nc = vd.shape
                if (nr == 1) and (nc == 1):
                    aux = vd.reshape((ne,))

                elif (nr == dim) and (nc == 1):
                    if dim == 3:
                        aux = vd.reshape((ne, dim))
                    else:
                        zz = nm.zeros((vd.shape[0], 1), dtype=vd.dtype);
                        aux = nm.c_[vd.squeeze(), zz]

                elif (((nr == sym) or (nr == (dim * dim))) and (nc == 1)) \
                         or ((nr == dim) and (nc == dim)):
                    vd = vd.squeeze()

                    if dim == 3:
                        if nr == sym:
                            aux = vd[:,[0,3,4,3,1,5,4,5,2]]
                        elif nr == (dim * dim):
                            aux = vd[:,[0,3,4,6,1,5,7,8,2]]
                        else:
                            aux = vd.reshape((vd.shape[0], dim*dim))
                    else:
                        zz = nm.zeros((vd.shape[0], 1), dtype=vd.dtype);
                        if nr == sym:
                            aux = nm.c_[vd[:,[0,2]], zz, vd[:,[2,1]],
                                        zz, zz, zz, zz]
                        elif nr == (dim * dim):
                            aux = nm.c_[vd[:,[0,2]], zz, vd[:,[3,1]],
                                        zz, zz, zz, zz]
                        else:
                            aux = nm.c_[vd[:,0,[0,1]], zz, vd[:,1,[0,1]],
                                        zz, zz, zz, zz]

                dm.add_array(aux, key, 'cell')
Example #14
0
class BoundaryMarkerEditor(Filter):
    """
    Edit the boundary marker of a Triangle surface mesh. To use: select the label to
    assign, hover your cursor over the cell you wish to edit, and press 'p'.
    """

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

    _current_grid = Instance(tvtk.UnstructuredGrid, allow_none=False)
    _input_grid = Instance(tvtk.UnstructuredGrid, args=(), allow_none=False)
    _extract_cells_filter = Instance(tvtk.ExtractCells,
                                     args=(),
                                     allow_none=False)
    _dataset_manager = Instance(DatasetManager, allow_none=False)
    _cell_mappings = List

    label_to_apply = Range(0, 255)
    select_coplanar_cells = Bool
    epsilon = Range(0.0, 1.0, 0.0001)
    mask_labels = Bool
    labels_to_mask = List(label_to_apply)

    # Saving file
    output_file = File
    save = Button

    ######################################################################
    # The view.
    ######################################################################
    traits_view = \
        View(
            Group(
                Item(name='label_to_apply'),
                Item(name='select_coplanar_cells'),
                Item(name='epsilon', enabled_when='select_coplanar_cells', label='Tolerance'),
                Item(name='mask_labels'),
                Group(
                    Item(name='labels_to_mask', style='custom', editor=ListEditor(rows=3)),
                    show_labels=False,
                    show_border=True,
                    label='Labels to mask',
                    enabled_when='mask_labels==True'
                ),
                Group(
                    Item(name='output_file'),
                    Item(name='save', label='Save'),
                    show_labels=False,
                    show_border=True,
                    label='Save changes to file (give only a basename, without the file extension)'
                )
            ),
            height=500,
            width=600
        )

    ######################################################################
    # `Filter` interface.
    ######################################################################
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        # Call cell_picked() when a cell is clicked.
        self.scene.picker.cellpicker.add_observer("EndPickEvent",
                                                  self.cell_picked)
        self.scene.picker.pick_type = 'cell_picker'
        self.scene.picker.tolerance = 0.0
        self.scene.picker.show_gui = False

        self._input_grid.deep_copy(self.inputs[0].outputs[0])

        self._current_grid = self._input_grid
        self._dataset_manager = DatasetManager(dataset=self._input_grid)
        self._set_outputs([self._current_grid])

        # Filter for masking.
        self._extract_cells_filter.set_input(self._input_grid)

    def update_data(self):
        self.data_changed = True

    ######################################################################
    # Non-public interface.
    ######################################################################

    def cell_picked(self, object, event):
        cell_id = self.scene.picker.cellpicker.cell_id
        self.modify_cell(cell_id, self.label_to_apply)

        if (self.select_coplanar_cells):
            self.modify_neighbouring_cells(cell_id)

        if (self.mask_labels):
            self.perform_mask()

        self._dataset_manager.activate(self._input_grid.cell_data.scalars.name,
                                       'cell')
        self._dataset_manager.update()
        self.pipeline_changed = True

    def get_all_cell_neigbours(self, cell_id, cell):
        neighbour_cell_ids = array([], dtype=int)

        for i in range(cell.number_of_edges):
            # Get points belonging to ith edge
            edge_point_ids = cell.get_edge(i).point_ids

            # Find neigbours which share the edge
            current_neighbour_cell_ids = tvtk.IdList()
            self._current_grid.get_cell_neighbors(cell_id, edge_point_ids,
                                                  current_neighbour_cell_ids)
            neighbour_cell_ids = append(neighbour_cell_ids,
                                        array(current_neighbour_cell_ids))

        return neighbour_cell_ids.tolist()

    def modify_neighbouring_cells(self, cell_id):
        cell = self._current_grid.get_cell(cell_id)

        cell_normal = [0, 0, 0]
        cell.compute_normal(cell.points[0], cell.points[1], cell.points[2],
                            cell_normal)

        cells_pending = self.get_all_cell_neigbours(cell_id, cell)
        cells_visited = [cell_id]

        while (len(cells_pending) > 0):
            current_cell_id = cells_pending.pop()

            if (current_cell_id not in cells_visited):
                cells_visited.append(current_cell_id)
                current_cell = self._current_grid.get_cell(current_cell_id)

                current_cell_normal = [0, 0, 0]
                current_cell.compute_normal(current_cell.points[0],
                                            current_cell.points[1],
                                            current_cell.points[2],
                                            current_cell_normal)

                if (dot(cell_normal, current_cell_normal) >
                    (1 - self.epsilon)):
                    self.modify_cell(current_cell_id, self.label_to_apply)
                    cells_pending.extend(
                        self.get_all_cell_neigbours(current_cell_id,
                                                    current_cell))

    def _mask_labels_changed(self):
        if (self.mask_labels):
            self.perform_mask()
            self._current_grid = self._extract_cells_filter.output
        else:
            self._current_grid = self._input_grid

        self._set_outputs([self._current_grid])
        self.pipeline_changed = True

    def _labels_to_mask_changed(self):
        self.perform_mask()

    def _labels_to_mask_items_changed(self):
        self.perform_mask()

    def perform_mask(self):
        labels_array = self._input_grid.cell_data.get_array(
            self._input_grid.cell_data.scalars.name)
        in_masked = map(lambda x: x in self.labels_to_mask, labels_array)

        unmasked_cells_list = tvtk.IdList()
        cell_ids = range(self._input_grid.number_of_cells)
        # _cell_mappings is indexed by cell_id of the original input grid, and each value
        # is the new cell_id of the corresponding cell in the masked grid
        self._cell_mappings = map(
            lambda masked, cell_id: None
            if masked else unmasked_cells_list.insert_next_id(cell_id),
            in_masked, cell_ids)

        self._extract_cells_filter.set_cell_list(unmasked_cells_list)
        self._extract_cells_filter.update()
        self.pipeline_changed = True

    def modify_cell(self, cell_id, value):
        if (self.mask_labels):
            cell_id = self._cell_mappings.index(
                cell_id)  # Adjust cell_id if masked
        self._input_grid.cell_data.get_array(
            self._input_grid.cell_data.scalars.name)[cell_id] = value

    def _save_fired(self):
        from mayavi_amcg.triangle_writer import TriangleWriter
        if (self.output_file):
            writer = TriangleWriter(self._input_grid, self.output_file)
            writer.write()
            print "#### Saved ####"
class MeshDiagnostics(Filter):
    """
    Identifies stiff elements of a solid mesh.
    Also includes diagnostics from vtkMeshQuality:
    <http://www.vtk.org/doc/release/5.0/html/a01739.html>
    """

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

    _dataset_manager = Instance(DatasetManager, allow_none=False)
    _surface_grid = Instance(tvtk.PointSet, allow_none=False)

    stiff_elements = Bool
    _first_time_stiff_elements = Bool(True)

    _mesh_quality_filter = Instance(tvtk.MeshQuality, args=(), allow_none=False)

    tet_quality_measure = Enum('Edge ratio', 'Aspect ratio', 'Radius ratio', 'Min angle', 'Frobenius norm', 'Volume')
    triangle_quality_measure = Enum('Edge ratio', 'Aspect ratio', 'Radius ratio', 'Min angle', 'Frobenius norm')
    quad_quality_measure = Enum('Edge ratio', 'Aspect ratio', 'Radius ratio', 'Min angle', 'Med Frobenius norm', 'Max Frobenius norm')
    hex_quality_measure = Enum('Edge ratio')

    tet_stats = triangle_stats = quad_stats = hex_stats = Tuple(Float,Float,Float,Float,Float)

    ######################################################################
    # The view.
    ######################################################################
    stats_editor = TupleEditor(labels=['Minimum','Average','Maximum','Variance','Number of cells'])
    traits_view = \
        View(
            Item(name='stiff_elements'),
            Group(
                Group(
                    Item(name='tet_quality_measure'),
                    Item(name='tet_stats', style='custom', editor=stats_editor),
                    label='Tetrahedron quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                Group(
                    Item(name='triangle_quality_measure'),
                    Item(name='triangle_stats', style='custom', editor=stats_editor),
                    label='Triangle quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                Group(
                    Item(name='quad_quality_measure'),
                    Item(name='quad_stats', style='custom', editor=stats_editor),
                    label='Quadrilateral quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                Group(
                    Item(name='hex_quality_measure'),
                    Item(name='hex_stats', style='custom', editor=stats_editor),
                    label='Hexahedron quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                enabled_when='stiff_elements==False',
                show_border=False
            ),
            width=300
        )

    """
    Hexahedron quality measure    - EdgeRatio

    Quadrilateral quality measure - EdgeRatio
                                  - AspectRatio
                                  - RadiusRatio
                                  - MinAngle
                                  - MedFrobeniusNorm
                                  - MaxFrobeniusNorm

    Tetrahedron quality measure   - EdgeRatio
                                  - AspectRatio
                                  - RadiusRatio
                                  - MinAngle
                                  - FrobeniusNorm
                                  - Volume (compatibility mode on/off)

    Triangle quality measure      - EdgeRatio
                                  - AspectRatio
                                  - RadiusRatio
                                  - MinAngle
                                  - FrobeniusNorm
    """

    ######################################################################
    # `Filter` interface.
    ######################################################################
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        self._mesh_quality_filter.set_input(self.inputs[0].outputs[0])
        for type in ['tet','triangle','quad','hex']:
            self._change_quality_measure(type, 'Edge ratio')
        self._mesh_quality_filter.update()
        self._set_outputs([self._mesh_quality_filter.output])

    def update_data(self):
        self.data_changed = True

    ######################################################################
    # Non-public interface.
    ######################################################################

    def _stiff_elements_changed(self, value):
        if (value):
            self._find_stiff_elements()
            self._set_outputs([self._surface_grid])
        else:
            self._set_outputs([self._mesh_quality_filter.output])

    def _tet_quality_measure_changed(self, value):
        self._change_quality_measure('tet', value)

    def _change_quality_measure(self, cell_type, quality_measure):
        if (quality_measure == 'Volume'):
            self._mesh_quality_filter.compatibility_mode = True
            self._mesh_quality_filter.volume = True
        else:
            self._mesh_quality_filter.compatibility_mode = False
            self._mesh_quality_filter.volume = False
            quality_measure_names = {'Edge ratio':'edge_ratio', 'Aspect ratio':'aspect_ratio', 'Radius ratio':'radius_ratio',
                   'Min angle':'min_angle', 'Frobenius norm':'frobenius_norm', 'Max Frobenius norm':'max_frobenius_norm',
                   'Med Frobenius norm':'med_frobenius_norm'}
            setattr(self._mesh_quality_filter, '%s_quality_measure' %cell_type, quality_measure_names.get(quality_measure))

        self._mesh_quality_filter.update()
        self._set_outputs([self._mesh_quality_filter.output])

        cell_type_fullnames = {'tet':'Tetrahedron', 'triangle':'Triangle', 'quad':'Quadrilateral', 'hex':'Hexahedron'}
        stats = self._mesh_quality_filter.output.field_data.get_array('Mesh %s Quality' %cell_type_fullnames.get(cell_type))[0]
        setattr(self, '%s_stats' %cell_type, stats)

    def _find_stiff_elements(self):
        if (self._first_time_stiff_elements):
            self._first_time_stiff_elements = False
            self._surface_grid = type(self.inputs[0].outputs[0])()
            self._surface_grid.copy_structure(self.inputs[0].outputs[0])

            if (self._surface_grid.points.data_type == 'double'):
                # tvtk.DataSetSurfaceFilter produces surface points as float
                # so we need to convert input points from doubles to floats
                # if necessary
                float_points = array(self._surface_grid.points, 'float32')
                self._surface_grid.points = float_points

            self._dataset_manager = DatasetManager(dataset=self._surface_grid)
            surface_points = self._get_surface_points()
            self._add_stiff_elements(surface_points)

    def _get_surface_points(self):
        surface_filter = tvtk.DataSetSurfaceFilter()
        surface_filter.set_input(self._surface_grid)
        surface_filter.update()
        return surface_filter.output.points

    def _add_stiff_elements(self, surface_points):
        stiff_elements = []
        surface_points = Set(surface_points)

        for i in range(self._surface_grid.number_of_cells):
            cell = self._surface_grid.get_cell(i)
            points = Set(cell.points)
            val = int(points.issubset(surface_points))
            stiff_elements.append(val)

        array_name = 'Stiff Elements'
        self._dataset_manager.add_array(array(stiff_elements), array_name, 'cell')
        self._dataset_manager.activate(array_name, 'cell')
Example #16
0
class MeshDiagnostics(Filter):
    """
    Identifies stiff elements of a solid mesh.
    Also includes diagnostics from vtkMeshQuality:
    <http://www.vtk.org/doc/release/5.0/html/a01739.html>
    """

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

    _dataset_manager = Instance(DatasetManager, allow_none=False)
    _surface_grid = Instance(tvtk.PointSet, allow_none=False)

    stiff_elements = Bool
    _first_time_stiff_elements = Bool(True)

    _mesh_quality_filter = Instance(tvtk.MeshQuality,
                                    args=(),
                                    allow_none=False)

    tet_quality_measure = Enum('Edge ratio', 'Aspect ratio', 'Radius ratio',
                               'Min angle', 'Frobenius norm', 'Volume')
    triangle_quality_measure = Enum('Edge ratio', 'Aspect ratio',
                                    'Radius ratio', 'Min angle',
                                    'Frobenius norm')
    quad_quality_measure = Enum('Edge ratio', 'Aspect ratio', 'Radius ratio',
                                'Min angle', 'Med Frobenius norm',
                                'Max Frobenius norm')
    hex_quality_measure = Enum('Edge ratio')

    tet_stats = triangle_stats = quad_stats = hex_stats = Tuple(
        Float, Float, Float, Float, Float)

    ######################################################################
    # The view.
    ######################################################################
    stats_editor = TupleEditor(labels=[
        'Minimum', 'Average', 'Maximum', 'Variance', 'Number of cells'
    ])
    traits_view = \
        View(
            Item(name='stiff_elements'),
            Group(
                Group(
                    Item(name='tet_quality_measure'),
                    Item(name='tet_stats', style='custom', editor=stats_editor),
                    label='Tetrahedron quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                Group(
                    Item(name='triangle_quality_measure'),
                    Item(name='triangle_stats', style='custom', editor=stats_editor),
                    label='Triangle quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                Group(
                    Item(name='quad_quality_measure'),
                    Item(name='quad_stats', style='custom', editor=stats_editor),
                    label='Quadrilateral quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                Group(
                    Item(name='hex_quality_measure'),
                    Item(name='hex_stats', style='custom', editor=stats_editor),
                    label='Hexahedron quality measure',
                    show_labels=False,
                    show_border=True,
                ),
                enabled_when='stiff_elements==False',
                show_border=False
            ),
            width=300
        )
    """
    Hexahedron quality measure    - EdgeRatio

    Quadrilateral quality measure - EdgeRatio
                                  - AspectRatio
                                  - RadiusRatio
                                  - MinAngle
                                  - MedFrobeniusNorm
                                  - MaxFrobeniusNorm

    Tetrahedron quality measure   - EdgeRatio
                                  - AspectRatio
                                  - RadiusRatio
                                  - MinAngle
                                  - FrobeniusNorm
                                  - Volume (compatibility mode on/off)

    Triangle quality measure      - EdgeRatio
                                  - AspectRatio
                                  - RadiusRatio
                                  - MinAngle
                                  - FrobeniusNorm
    """

    ######################################################################
    # `Filter` interface.
    ######################################################################
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        self._mesh_quality_filter.set_input(self.inputs[0].outputs[0])
        for type in ['tet', 'triangle', 'quad', 'hex']:
            self._change_quality_measure(type, 'Edge ratio')
        self._mesh_quality_filter.update()
        self._set_outputs([self._mesh_quality_filter.output])

    def update_data(self):
        self.data_changed = True

    ######################################################################
    # Non-public interface.
    ######################################################################

    def _stiff_elements_changed(self, value):
        if (value):
            self._find_stiff_elements()
            self._set_outputs([self._surface_grid])
        else:
            self._set_outputs([self._mesh_quality_filter.output])

    def _tet_quality_measure_changed(self, value):
        self._change_quality_measure('tet', value)

    def _change_quality_measure(self, cell_type, quality_measure):
        if (quality_measure == 'Volume'):
            self._mesh_quality_filter.compatibility_mode = True
            self._mesh_quality_filter.volume = True
        else:
            self._mesh_quality_filter.compatibility_mode = False
            self._mesh_quality_filter.volume = False
            quality_measure_names = {
                'Edge ratio': 'edge_ratio',
                'Aspect ratio': 'aspect_ratio',
                'Radius ratio': 'radius_ratio',
                'Min angle': 'min_angle',
                'Frobenius norm': 'frobenius_norm',
                'Max Frobenius norm': 'max_frobenius_norm',
                'Med Frobenius norm': 'med_frobenius_norm'
            }
            setattr(self._mesh_quality_filter,
                    '%s_quality_measure' % cell_type,
                    quality_measure_names.get(quality_measure))

        self._mesh_quality_filter.update()
        self._set_outputs([self._mesh_quality_filter.output])

        cell_type_fullnames = {
            'tet': 'Tetrahedron',
            'triangle': 'Triangle',
            'quad': 'Quadrilateral',
            'hex': 'Hexahedron'
        }
        stats = self._mesh_quality_filter.output.field_data.get_array(
            'Mesh %s Quality' % cell_type_fullnames.get(cell_type))[0]
        setattr(self, '%s_stats' % cell_type, stats)

    def _find_stiff_elements(self):
        if (self._first_time_stiff_elements):
            self._first_time_stiff_elements = False
            self._surface_grid = type(self.inputs[0].outputs[0])()
            self._surface_grid.copy_structure(self.inputs[0].outputs[0])

            if (self._surface_grid.points.data_type == 'double'):
                # tvtk.DataSetSurfaceFilter produces surface points as float
                # so we need to convert input points from doubles to floats
                # if necessary
                float_points = array(self._surface_grid.points, 'float32')
                self._surface_grid.points = float_points

            self._dataset_manager = DatasetManager(dataset=self._surface_grid)
            surface_points = self._get_surface_points()
            self._add_stiff_elements(surface_points)

    def _get_surface_points(self):
        surface_filter = tvtk.DataSetSurfaceFilter()
        surface_filter.set_input(self._surface_grid)
        surface_filter.update()
        return surface_filter.output.points

    def _add_stiff_elements(self, surface_points):
        stiff_elements = []
        surface_points = Set(surface_points)

        for i in range(self._surface_grid.number_of_cells):
            cell = self._surface_grid.get_cell(i)
            points = Set(cell.points)
            val = int(points.issubset(surface_points))
            stiff_elements.append(val)

        array_name = 'Stiff Elements'
        self._dataset_manager.add_array(array(stiff_elements), array_name,
                                        'cell')
        self._dataset_manager.activate(array_name, 'cell')
Example #17
0
 def setUp(self):
     self.data = make_data()
     self.dm = DatasetManager(dataset=self.data)
     return