示例#1
0
def fill_vtk_unstructured_grid_results(model: pyNastranH5, vtk_ugrid: vtk.vtkUnstructuredGrid,
                                       eids: np.ndarray) -> None:
    point_data = vtk_ugrid.GetPointData()
    cell_data = vtk_ugrid.GetCellData()
    for i, res in model.results.items():
        if res.location == 'node':
            names, resultsi = res.get_results()
            for name, result in zip(names, resultsi):
                print(name)
                #name = 'cat'
                result.SetName(name)
                point_data.AddArray(result)

                # remove
                #point_data.SetActiveVectors(name)
                #point_data.SetVectors(result)
        elif res.location == 'element':
            res.eids = eids
            names, resultsi = res.get_results()
            for name, result in zip(names, resultsi):
                print(name)
                #name = 'cat'
                result.SetName(name)
                cell_data.AddArray(result)
                #cell_data.SetScalars(result)
        else:
            raise NotImplementedError(res)
示例#2
0
def add_user_geometry(alt_grid: vtk.vtkUnstructuredGrid,
                      geom_grid: vtk.vtkUnstructuredGrid, xyz: np.ndarray,
                      nid_map: Dict[int, int], nnodes: int, bars: np.ndarray,
                      tris: np.ndarray, quads: np.ndarray, nelements: int,
                      nbars: int, ntris: int, nquads: int) -> vtk.vtkPoints:
    """helper method for ``_add_user_geometry``"""
    # set points
    points = numpy_to_vtk_points(xyz, dtype='<f')

    if nelements > 0:
        for i in range(nnodes):
            elem = vtk.vtkVertex()
            elem.GetPointIds().SetId(0, i)
            alt_grid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())
            geom_grid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())
    else:
        for i in range(nnodes):
            elem = vtk.vtkVertex()
            elem.GetPointIds().SetId(0, i)
            alt_grid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())

    if nbars:
        for i, bar in enumerate(bars[:, 1:]):
            g1 = nid_map[bar[0]]
            g2 = nid_map[bar[1]]
            elem = vtk.vtkLine()
            elem.GetPointIds().SetId(0, g1)
            elem.GetPointIds().SetId(1, g2)
            geom_grid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())

    if ntris:
        for i, tri in enumerate(tris[:, 1:]):
            g1 = nid_map[tri[0]]
            g2 = nid_map[tri[1]]
            g3 = nid_map[tri[2]]
            elem = vtk.vtkTriangle()
            elem.GetPointIds().SetId(0, g1)
            elem.GetPointIds().SetId(1, g2)
            elem.GetPointIds().SetId(2, g3)
            geom_grid.InsertNextCell(5, elem.GetPointIds())

    if nquads:
        for i, quad in enumerate(quads[:, 1:]):
            g1 = nid_map[quad[0]]
            g2 = nid_map[quad[1]]
            g3 = nid_map[quad[2]]
            g4 = nid_map[quad[3]]
            elem = vtk.vtkQuad()
            point_ids = elem.GetPointIds()
            point_ids.SetId(0, g1)
            point_ids.SetId(1, g2)
            point_ids.SetId(2, g3)
            point_ids.SetId(3, g4)
            geom_grid.InsertNextCell(9, elem.GetPointIds())

    alt_grid.SetPoints(points)
    if nelements > 0:
        geom_grid.SetPoints(points)
    return points
示例#3
0
def _add_nastran_lines_to_grid(alt_grid: vtk.vtkUnstructuredGrid,
                               nid_map: Dict[int, int],
                               name: str, lines, model: BDF, nid_to_pid_map=None):
    """used to create MPC lines"""
    nlines = lines.shape[0]
    #nids = np.unique(lines)
    #nnodes = len(nids)
    nnodes = nlines * 2
    if nnodes == 0:
        return
    #self.gui.follower_nodes[name] = lines.ravel()
    points = vtk.vtkPoints()
    points.SetNumberOfPoints(nnodes)

    j = 0
    etype = 3 # vtkLine
    #nid_map = self.gui.nid_map
    #alt_grid = self.gui.alt_grids[name]
    for nid1, nid2 in lines:
        try:
            unused_i1 = nid_map[nid1]
        except KeyError:
            model.log.warning('nid=%s does not exist' % nid1)
            continue
        try:
            unused_i2 = nid_map[nid2]
        except KeyError:
            model.log.warning('nid=%s does not exist' % nid2)
            continue

        if nid1 not in model.nodes or nid2 not in model.nodes:
            continue
        node = model.nodes[nid1]
        point = node.get_position()
        points.InsertPoint(j, *point)

        node = model.nodes[nid2]
        point = node.get_position()
        points.InsertPoint(j + 1, *point)

        elem = vtk.vtkLine()
        point_ids = elem.GetPointIds()
        point_ids.SetId(0, j)
        point_ids.SetId(1, j + 1)
        alt_grid.InsertNextCell(etype, point_ids)
        j += 2
    alt_grid.SetPoints(points)
示例#4
0
def create_highlighted_actors(
        gui,
        grid: vtk.vtkUnstructuredGrid,
        all_nodes=None,
        nodes=None,
        set_node_scalars=True,
        all_elements=None,
        elements=None,
        set_element_scalars=True,
        add_actors: bool = False) -> List[vtk.vtkLODActor]:
    """creates nodes & element highlighted objects"""
    actors = []
    nnodes = 0
    nelements = 0
    if nodes is not None:
        nnodes = len(nodes)
        assert len(all_nodes) >= nnodes

    if elements is not None:
        nelements = len(elements)
        assert len(all_elements) >= nelements
    assert nnodes + nelements > 0

    if nnodes:
        point_ids = np.searchsorted(all_nodes, nodes)
        output_data = grid.GetPoints().GetData()
        points_array = vtk_to_numpy(output_data)  # yeah!

        point_array2 = points_array[point_ids, :]
        points2 = numpy_to_vtk_points(point_array2)

        ugrid = create_unstructured_point_grid(points2, nnodes)
        if set_node_scalars:
            point_ids_array = numpy_to_vtk(nodes)
            ugrid.GetPointData().SetScalars(point_ids_array)
        actor = create_highlighted_actor(gui,
                                         ugrid,
                                         representation='points',
                                         add_actor=add_actors)
        actors.append(actor)

    if nelements:
        cell_ids = np.searchsorted(all_elements, elements)

        selection_node = create_vtk_selection_node_by_cell_ids(cell_ids)
        ugrid = extract_selection_node_from_grid_to_ugrid(grid, selection_node)
        if set_element_scalars:
            element_ids_array = numpy_to_vtk(elements)
            ugrid.GetPointData().SetScalars(None)
            ugrid.GetCellData().SetScalars(element_ids_array)
        actor = create_highlighted_actor(gui,
                                         ugrid,
                                         representation='wire',
                                         add_actor=add_actors)
        actors.append(actor)
    return actors
示例#5
0
def add_lines(grid: vtk.vtkUnstructuredGrid, nids, eids_lines: np.ndarray,
              nid_offset: int) -> int:
    """adds line elements to the vtkUnstructuredGrid"""
    nelements = 0
    if eids_lines is not None:
        nelements = eids_lines.shape[0]
        eids = eids_lines[:, 0]
        elem_nids = eids_lines[:, 1:]
        #inids = np.searchsorted(nids, elem_nids)
        node_ids = elem_nids + nid_offset
        for unused_eid, node_idsi in zip(eids, node_ids):
            elem = vtkLine()
            point_ids = elem.GetPointIds()
            point_ids.SetId(0, node_idsi[0])
            point_ids.SetId(1, node_idsi[1])
            grid.InsertNextCell(3, point_ids)
    return nelements
def _elements_to_vtk(vtk_ugrid: vtk.vtkUnstructuredGrid,
                     etype_nids: np.ndarray,
                     cell_offsets_array: np.ndarray,
                     cell_types_array: np.ndarray):
    # Create the array of cells
    nelements = len(cell_offsets_array)
    cells_id_type = numpy_to_vtkIdTypeArray(etype_nids, deep=1)
    vtk_cells = vtk.vtkCellArray()
    vtk_cells.SetCells(nelements, cells_id_type)

    # Cell types
    deep = False
    vtk_cell_types = numpy_to_vtk(
        cell_types_array, deep=deep,
        array_type=vtk.vtkUnsignedCharArray().GetDataType())

    vtk_cell_offsets = numpy_to_vtk(cell_offsets_array, deep=deep,
                                    array_type=vtk.VTK_ID_TYPE)

    #grid = vtk.vtkUnstructuredGrid()
    vtk_ugrid.SetCells(vtk_cell_types, vtk_cell_offsets, vtk_cells)
示例#7
0
def add_quads(grid: vtk.vtkUnstructuredGrid, nids, eids_quads: np.ndarray,
              nid_offset: int) -> int:
    """adds quad elements to the vtkUnstructuredGrid"""
    nelements = 0
    if eids_quads is not None:
        nelements = eids_quads.shape[0]
        eids = eids_quads[:, 0]
        elem_nids = eids_quads[:, 1:]
        #inids = np.searchsorted(nids, elem_nids)
        #print(inids)
        node_ids = elem_nids + nid_offset
        #node_ids = inids # + nid_offset + 1
        for unused_eid, node_idsi in zip(eids, node_ids):
            elem = vtkQuad()
            point_ids = elem.GetPointIds()
            point_ids.SetId(0, node_idsi[0])
            point_ids.SetId(1, node_idsi[1])
            point_ids.SetId(2, node_idsi[2])
            point_ids.SetId(3, node_idsi[3])
            grid.InsertNextCell(9, point_ids)
    return nelements
示例#8
0
def create_filtered_point_ugrid(ugrid: vtk.vtkUnstructuredGrid, nids,
                                nids2) -> vtk.vtkUnstructuredGrid:
    """
    We need to filter the nodes that were filtered by the
    numpy setdiff1d, so we don't show extra points

    """
    #unused_pointsu = ugrid.GetPoints()
    output_data = ugrid.GetPoints().GetData()
    points_array = vtk_to_numpy(output_data)  # yeah!

    isort_nids = np.argsort(nids)
    nids = nids[isort_nids]
    inids = np.searchsorted(nids, nids2)

    points_array_sorted = points_array[isort_nids, :]
    point_array2 = points_array_sorted[inids, :]
    points2 = numpy_to_vtk_points(point_array2)

    npoints = len(nids2)
    ugrid = create_unstructured_point_grid(points2, npoints)
    return ugrid
示例#9
0
def add_hexas(grid: vtk.vtkUnstructuredGrid, nids, eids_hexas: np.ndarray,
              nid_offset: int) -> int:
    """adds hex elements to the vtkUnstructuredGrid"""
    nelements = 0
    if eids_hexas is not None:
        nelements = eids_hexas.shape[0]
        eids = eids_hexas[:, 0]
        elem_nids = eids_hexas[:, 1:]
        #inids = np.searchsorted(nids, elem_nids)
        node_ids = elem_nids + nid_offset
        for unused_eid, node_idsi in zip(eids, node_ids):
            elem = vtkHexahedron()
            point_ids = elem.GetPointIds()
            point_ids.SetId(0, node_idsi[0])
            point_ids.SetId(1, node_idsi[1])
            point_ids.SetId(2, node_idsi[2])
            point_ids.SetId(3, node_idsi[3])
            point_ids.SetId(4, node_idsi[4])
            point_ids.SetId(5, node_idsi[5])
            point_ids.SetId(6, node_idsi[6])
            point_ids.SetId(7, node_idsi[7])
            grid.InsertNextCell(elem.GetCellType(), point_ids)
    return nelements
示例#10
0
def create_vtk_cells_of_constant_element_types(grid: vtk.vtkUnstructuredGrid,
                                               elements_list, etypes_list):
    """
    Adding constant type elements is overly complicated enough as in
    ``create_vtk_cells_of_constant_element_type``.  Now we extend
    this to multiple element types.

    grid : vtk.vtkUnstructuredGrid()
        the unstructured grid
    elements_list : List[elements, ...]
        elements : (nelements, nnodes_per_element) int ndarray
            the elements to add
    etypes_list : List[etype, ...]
        etype : int
            the VTK flag as defined in
            ``create_vtk_cells_of_constant_element_type``

    """
    if isinstance(etypes_list, list) and len(etypes_list) == 1:
        create_vtk_cells_of_constant_element_type(grid, elements_list[0],
                                                  etypes_list[0])
        return

    dtype = get_numpy_idtype_for_vtk()

    cell_offsets_list2 = []
    cell_types_list2 = []
    elements_list2 = []
    nelements = 0
    noffsets = 0
    for element, etype in zip(elements_list, etypes_list):
        nelement, nnodes_per_element = element.shape

        nnodesp1 = nnodes_per_element + 1  # TODO: was 4; for a tri???
        cell_offset = np.arange(0, nelement,
                                dtype='int32') * nnodesp1 + noffsets
        noffset = nelement * nnodesp1

        cell_type = np.ones(nelement, dtype='int32') * etype
        assert len(cell_offset) == nelement

        nnodesp1 = nnodes_per_element + 1
        element_vtk = np.zeros((nelement, nnodesp1), dtype=dtype)
        element_vtk[:, 0] = nnodes_per_element  # 3 nodes/tri
        element_vtk[:, 1:] = element

        cell_offsets_list2.append(cell_offset)
        cell_types_list2.append(cell_type)
        elements_list2.append(element_vtk.ravel())
        nelements += nelement
        noffsets += noffset

    cell_types_array = np.hstack(cell_types_list2)
    cell_offsets_array = np.hstack(cell_offsets_list2)
    elements_array = np.hstack(elements_list2)

    # Create the array of cells
    cells_id_type = numpy_to_vtkIdTypeArray(elements_array.ravel(), deep=1)
    vtk_cells = vtk.vtkCellArray()
    vtk_cells.SetCells(nelements, cells_id_type)

    # Cell types
    vtk_cell_types = numpy_to_vtk(
        cell_types_array,
        deep=0,
        array_type=vtk.vtkUnsignedCharArray().GetDataType())

    vtk_cell_offsets = numpy_to_vtk(cell_offsets_array,
                                    deep=0,
                                    array_type=vtkConstants.VTK_ID_TYPE)

    grid.SetCells(vtk_cell_types, vtk_cell_offsets, vtk_cells)
示例#11
0
def get_inside_point_ids(
    gui,
    ugrid: vtk.vtkUnstructuredGrid,
    ugrid_flipped: vtk.vtkUnstructuredGrid,
    model_name: str,
    representation: str = 'points'
) -> Tuple[vtk.vtkUnstructuredGrid, List[int]]:
    """
    The points that are returned from the frustum, despite being
    defined as inside are not all inside.  The cells are correct
    though.  If you determine the cells outside the volume and the
    points associated with that, and boolean the two, you can find
    the points that are actually inside.

    In other words, ``points`` corresponds to the points inside the
    volume and barely outside.  ``point_ids_flipped`` corresponds to
    the points entirely outside the volume.

    Parameters
    ==========
    ugrid : vtk.vtkUnstructuredGrid()
        the "inside" grid
    ugrid_flipped : vtk.vtkUnstructuredGrid()
        the outside grid

    Returns
    =======
    ugrid : vtk.vtkUnstructuredGrid()
        an updated grid that has the correct points
    nids : (n, ) int ndarray
        the node_ids

    """
    nids = None
    points = ugrid.GetPointData()
    if points is None:
        return ugrid, nids

    ids = points.GetArray('Ids')
    if ids is None:
        return ugrid, nids

    # all points associated with the correctly selected cells are returned
    # but we get extra points for the cells that are inside and out
    point_ids = vtk_to_numpy(ids)
    nids = gui.get_node_ids(model_name, point_ids)

    # these are the points outside the box/frustum (and also include the bad point)
    points_flipped = ugrid_flipped.GetPointData()
    ids_flipped = points_flipped.GetArray('Ids')
    point_ids_flipped = vtk_to_numpy(ids_flipped)
    nids_flipped = gui.get_node_ids(model_name, point_ids_flipped)
    #nids = gui.gui.get_reverse_node_ids(model_name, point_ids_flipped)

    # setA - setB
    nids2 = np.setdiff1d(nids, nids_flipped, assume_unique=True)

    #narrays = points.GetNumberOfArrays()
    #for iarray in range(narrays):
    #name = points.GetArrayName(iarray)
    #print('iarray=%s name=%r' % (iarray, name))

    #------------------
    if representation == 'points':
        # we need to filter the nodes that were filtered by the
        # numpy setdiff1d, so we don't show extra points
        ugrid = create_filtered_point_ugrid(ugrid, nids, nids2)

    nids = nids2
    return ugrid, nids
示例#12
0
def create_vtk_cells_of_constant_element_type(grid: vtk.vtkUnstructuredGrid,
                                              elements: np.ndarray,
                                              etype: int) -> None:
    """
    Adding constant type elements is overly complicated.

    Parameters
    ----------
    grid : vtk.vtkUnstructuredGrid()
        the unstructured grid
    elements : (nelements, nnodes_per_element) int ndarray
        the elements to add
    etype : int
        VTK cell type

    Notes
    -----
    The documentation in this method is triangle-specific as it was
    developed for a tri mesh.  It's more general than that though.

    """
    nelements, nnodes_per_element = elements.shape
    _check_shape(etype, elements, nnodes_per_element)

    # We were careful about how we defined the arrays, so the data
    # is contiguous when we ravel it.  Otherwise, you need to
    # deepcopy the arrays (deep=1).  However, numpy_to_vtk isn't so
    # good, so we could use np.copy, which is better, but it's
    # ultimately unnecessary.

    #nodes = numpy_to_vtk(elements, deep=0, array_type=vtk.VTK_ID_TYPE)
    # (nnodes_per_element + 1)  # TODO: was 4; for a tri...didn't seem to crash???
    # int8:  [-128 to 127]
    # int32: [-2_147_483_648 to 2_147_483_647]  # 2.1 billion
    # int64: [-9223372036854775808 to 9223372036854775807]
    cell_offsets = np.arange(0, nelements, dtype='int32') * (nnodes_per_element + 1)
    assert len(cell_offsets) == nelements

    # Create the array of cells
    vtk_cells = vtk.vtkCellArray()

    dtype = get_numpy_idtype_for_vtk()

    elements_vtk = np.zeros((nelements, nnodes_per_element + 1), dtype=dtype)
    elements_vtk[:, 0] = nnodes_per_element # 3 nodes/tri element
    elements_vtk[:, 1:] = elements

    cells_id_type = numpy_to_vtkIdTypeArray(elements_vtk.ravel(), deep=1)
    vtk_cells.SetCells(nelements, cells_id_type)

    # Cell types
    # 5 = vtkTriangle().GetCellType()
    cell_types = np.full(nelements, etype, dtype='int8')
    vtk_cell_types = numpy_to_vtk(
        cell_types, deep=0,
        array_type=vtk.vtkUnsignedCharArray().GetDataType())

    vtk_cell_offsets = numpy_to_vtk(cell_offsets, deep=0,
                                    array_type=vtkConstants.VTK_ID_TYPE)

    grid.SetCells(vtk_cell_types, vtk_cell_offsets, vtk_cells)
def fill_vtk_unstructured_grid(geom_model: BDF,
                               vtk_ugrid: vtk.vtkUnstructuredGrid,
                               add_property=True,
                               add_material=True):
    #cell_type_point = 1 # vtk.vtkVertex().GetCellType()
    #cell_type_line = 3 # vtk.vtkLine().GetCellType()
    #cell_type_tri3 = 5
    #cell_type_tri6 = 22
    #cell_type_quad4 = 9
    #cell_type_quad8 = 23
    #cell_type_tetra4 = 10
    #cell_type_tetra10 = 24
    #cell_type_pyram5 = 14 # vtk.vtkPyramid().GetCellType()
    #cell_type_pyram13 = 27 # vtk.vtkQuadraticPyramid().GetCellType()
    #cell_type_hexa8 = 12
    #cell_type_hexa20 = 25
    #cell_type_penta6 = 13
    #cell_type_penta15 = 26
    #nodes, node_ids, nid_map, idtype = _load_nodes(geom_model)
    nodes = geom_model._nodes
    node_ids = geom_model._node_ids
    #nid_map = geom_model._nid_map
    idtype = geom_model._idtype
    vtk_points = numpy_to_vtk_points(nodes, points=None, dtype='<f', deep=1)

    vtk_ugrid.SetPoints(vtk_points)

    etype_nids, cell_offsets_array, cell_types_array, eids, pids = _load_elements(
        geom_model, node_ids, idtype=idtype)
    nelements = len(eids)

    # build the grid
    _elements_to_vtk(vtk_ugrid, etype_nids, cell_offsets_array, cell_types_array)

    # fill the grid with results
    #point_data = vtk_ugrid.GetPointData()

    cell_data = vtk_ugrid.GetCellData()
    eid_array = numpy_to_vtk(eids, deep=0, array_type=None)
    eid_array.SetName('ElementID')
    cell_data.AddArray(eid_array)

    if add_property:
        pid_array = numpy_to_vtk(pids, deep=0, array_type=None)
        pid_array.SetName('PropertyID')
        cell_data.AddArray(pid_array)

    #if add_property:
        #pid_array = numpy_to_vtk(pids, deep=0, array_type=None)
        #pid_array.SetName('PropertyID')
        #cell_data.AddArray(pid_array)

    if add_material:
        psolid_mids = np.full(nelements, -1, dtype='int64')
        pshell_mids = np.full((nelements, 4), -1, dtype='int64')
        thickness = np.full(nelements, np.nan, dtype='float32')
        upids = np.unique(pids)
        is_solid = False
        is_shell = False
        for pid in upids:
            ipid = np.where(pid == pids)
            prop = geom_model.properties[pid]
            if prop.type == 'PSOLID':
                is_solid = True
                psolid_mids[ipid] = prop.mid
            elif prop.type == 'PSHELL':
                is_shell = True
                thickness[ipid] = prop.t
                for imid, mid in enumerate([prop.mid1, prop.mid2, prop.mid3, prop.mid4]):
                    if mid is None:
                        continue
                    pshell_mids[ipid, imid] = mid
            else:
                geom_model.log.warning(f'skipping:\n{prop}')

        if is_solid:
            mid_array = numpy_to_vtk(psolid_mids, deep=0, array_type=None)
            mid_array.SetName('Solid Material')
            cell_data.AddArray(mid_array)

        if is_shell:
            thickness_array = numpy_to_vtk(thickness, deep=0, array_type=None)
            thickness_array.SetName('Shell Thickness')
            cell_data.AddArray(thickness_array)
            for imid in range(4):
                mids = pshell_mids[:, imid]
                shell_mid_array = numpy_to_vtk(mids, deep=0, array_type=None)
                thickness_array.SetName(f'Shell Material {imid+1}')
                cell_data.AddArray(shell_mid_array)
    #print(point_data)
    return eids