Skip to content

Commit

Permalink
Merge pull request #1086 from nschloe/polygons
Browse files Browse the repository at this point in the history
Polygons
  • Loading branch information
nschloe authored Apr 29, 2021
2 parents 2e46a6c + 0525557 commit b1753bd
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 65 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ This document only describes _breaking_ changes in meshio. If you are interested
fixes, enhancements etc., best follow [the meshio project on
GitHub](https://github.com/nschloe/meshio).

## v4.4.0 (Apr 29, 2021)

- Polygons are now stored as `"polygon"` cell blocks, not `"polygonN"` (where `N` is the
number of nodes per polygon). One can simply retrieve the number of points via
`cellblock.data.shape[1]`.


## v4.0.0 (Feb 18, 2020)

- `mesh.cells` used to be a dictionary of the form
Expand Down
18 changes: 16 additions & 2 deletions meshio/_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,24 @@ def __init__(

def __repr__(self):
lines = ["<meshio mesh object>", f" Number of points: {len(self.points)}"]
special_cells = [
"polygon",
"polyhedron",
"VTK_LAGRANGE_CURVE",
"VTK_LAGRANGE_TRIANGLE",
"VTK_LAGRANGE_QUADRILATERAL",
"VTK_LAGRANGE_TETRAHEDRON",
"VTK_LAGRANGE_HEXAHEDRON",
"VTK_LAGRANGE_WEDGE",
"VTK_LAGRANGE_PYRAMID",
]
if len(self.cells) > 0:
lines.append(" Number of cells:")
for tpe, elems in self.cells:
lines.append(f" {tpe}: {len(elems)}")
for cell_type, elems in self.cells:
string = cell_type
if cell_type in special_cells:
string += f"({elems.shape[1]})"
lines.append(f" {string}: {len(elems)}")
else:
lines.append(" No cells.")

Expand Down
41 changes: 16 additions & 25 deletions meshio/ply/_ply.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,17 @@
numpy_to_ply_dtype = {np.dtype(v): k for k, v in ply_to_numpy_dtype.items()}


_cell_type_to_count = {"vertex": 1, "line": 2, "triangle": 3, "quad": 4}


def cell_type_to_count(cell_type):
if cell_type in _cell_type_to_count:
return _cell_type_to_count[cell_type]

match = re.fullmatch(r"polygon(\d+)", cell_type)
if match:
return int(match.group(1))


_cell_type_from_count = {val: key for (key, val) in _cell_type_to_count.items()}


def cell_type_from_count(count):
"""Reverse of ``cell_type_to_count``, defaults to ``"polygon" + str(counr)``
if unknown."""
return _cell_type_from_count.get(count) or "polygon" + str(count)
if count == 1:
return "vertex"
elif count == 2:
return "line"
elif count == 3:
return "triangle"
elif count == 4:
return "quad"

return "polygon"


def read(filename):
Expand Down Expand Up @@ -145,7 +137,6 @@ def read_buffer(f):
f"got `{line}`"
)

# read header
if is_binary:
mesh = _read_binary(
f,
Expand Down Expand Up @@ -210,7 +201,7 @@ def _read_ascii(
}
cell_data = {}

# the faces must be read line-by-line
# polygons must be read line-by-line
polygons = collections.defaultdict(list)
for k in range(num_cells):
line = f.readline().decode("utf-8").strip()
Expand Down Expand Up @@ -445,9 +436,11 @@ def write(filename, mesh, binary=True): # noqa: C901
pd.append(value)

num_cells = 0
legal_cell_types = ["vertex", "line", "triangle", "quad", "polygon"]
for cell_type, c in mesh.cells:
if cell_type_to_count(cell_type):
if cell_type in legal_cell_types:
num_cells += c.data.shape[0]

if num_cells > 0:
fh.write(f"element face {num_cells:d}\n".encode("utf-8"))

Expand All @@ -474,9 +467,7 @@ def write(filename, mesh, binary=True): # noqa: C901
if cell_dtype is not None:
ply_type = numpy_to_ply_dtype[cell_dtype]
fh.write(
"property list {} {} vertex_indices\n".format(
"uint8", ply_type
).encode("utf-8")
f"property list uint8 {ply_type} vertex_indices\n".encode("utf-8")
)

# TODO other cell data
Expand All @@ -489,7 +480,7 @@ def write(filename, mesh, binary=True): # noqa: C901

# cells
for cell_type, data in mesh.cells:
if cell_type_to_count(cell_type) is None:
if cell_type not in legal_cell_types:
warnings.warn(
'cell_type "{}" is not supported by ply format - skipping'
)
Expand Down
18 changes: 11 additions & 7 deletions meshio/vtk/_vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,12 +586,17 @@ def translate_cells(data, types, cell_data_raw):
cell = data[cell_idx]

cell_type = vtk_to_meshio_type[vtk_cell_type]
if cell_type == "polygon":
cell_type += str(data[offsets[idx]])

if len(cells) > 0 and cells[-1].type == cell_type:
if (
len(cells) > 0
and cells[-1].type == cell_type
# the following check if needed for polygons; key can be equal, but
# still needs to go into a new block
and len(cell) == len(cells[-1].data[-1])
):
cells[-1].data.append(cell)
else:
# open up a new cell block
cells.append(CellBlock(cell_type, [cell]))

# convert data to numpy arrays
Expand Down Expand Up @@ -752,15 +757,14 @@ def _write_cells(f, cells, binary):
f.write(f"CELL_TYPES {total_num_cells}\n".encode("utf-8"))
if binary:
for c in cells:
key_ = c.type[:7] if c.type[:7] == "polygon" else c.type
vtk_type = meshio_to_vtk_type[key_]
vtk_type = meshio_to_vtk_type[c.type]
np.full(len(c.data), vtk_type, dtype=np.dtype(">i4")).tofile(f, sep="")
f.write(b"\n")
else:
# ascii
for c in cells:
key_ = c.type[:7] if c.type[:7] == "polygon" else c.type
np.full(len(c.data), meshio_to_vtk_type[key_]).tofile(f, sep="\n")
vtk_type = meshio_to_vtk_type[c.type]
np.full(len(c.data), vtk_type).tofile(f, sep="\n")
f.write(b"\n")


Expand Down
36 changes: 8 additions & 28 deletions meshio/vtu/_vtu.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def _cells_from_data(connectivity, offsets, types, cell_data_raw):
start_cn[items + 1],
_vtk_to_meshio_order(types[start], sz, dtype=offsets.dtype) - sz,
)
cells.append(CellBlock(meshio_type + str(sz), connectivity[indices]))
cells.append(CellBlock(meshio_type, connectivity[indices]))

# Store cell data for this set of cells
for name, d in cell_data_raw.items():
Expand Down Expand Up @@ -668,9 +668,10 @@ def write(filename, mesh, binary=True, compression="zlib", header_type=None):
# in certain places.
is_polyhedron_grid = False
for c in mesh.cells:
if c.type[:10] == "polyhedron":
if c.type.startswith("polyhedron"):
is_polyhedron_grid = True
break

# The current implementation cannot mix polyhedral cells with other cell types.
# To write such meshes, represent all cells as polyhedra.
if is_polyhedron_grid:
Expand Down Expand Up @@ -908,31 +909,9 @@ def _polyhedron_face_cells(face_cells):

# types
types_array = []
for k, v in mesh.cells:
# For polygon and polyhedron grids, the number of nodes is part of the cell
# type key. This part must be stripped away.
special_cells = [
"polygon",
"polyhedron",
"VTK_LAGRANGE_CURVE",
"VTK_LAGRANGE_TRIANGLE",
"VTK_LAGRANGE_QUADRILATERAL",
"VTK_LAGRANGE_TETRAHEDRON",
"VTK_LAGRANGE_HEXAHEDRON",
"VTK_LAGRANGE_WEDGE",
"VTK_LAGRANGE_PYRAMID",
]
key_ = None
for string in special_cells:
if k.startswith(string):
key_ = string

if key_ is None:
# No special treatment
key_ = k

# further adaptions for polyhedron
if k.startswith("polyhedron"):
for key, v in mesh.cells:
# some adaptions for polyhedron
if key.startswith("polyhedron"):
# Get face-cell relation on the vtu format. See comments in helper
# function for more information of how to specify this.
faces_loc, faceoffsets_loc = _polyhedron_face_cells(v)
Expand All @@ -944,8 +923,9 @@ def _polyhedron_face_cells(face_cells):
assert faces is not None
faces += faces_loc
faceoffsets += faceoffsets_loc
key = "polyhedron"

types_array.append(np.full(len(v), meshio_to_vtk_type[key_]))
types_array.append(np.full(len(v), meshio_to_vtk_type[key]))

types = np.concatenate(
types_array
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = meshio
version = 4.3.13
version = 4.4.0
author = Nico Schlömer et al.
author_email = [email protected]
description = I/O for many mesh formats
Expand Down
4 changes: 2 additions & 2 deletions test/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@
[
("triangle", [[0, 1, 2], [4, 5, 6]]),
("quad", [[0, 1, 2, 3]]),
("polygon5", [[1, 4, 5, 6, 2]]),
("polygon6", [[0, 3, 7, 8, 9, 10], [1, 3, 7, 8, 9, 10]]),
("polygon", [[1, 4, 5, 6, 2]]),
("polygon", [[0, 3, 7, 8, 9, 10], [1, 3, 7, 8, 9, 10]]),
],
)

Expand Down
1 change: 1 addition & 0 deletions test/test_ply.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
helpers.add_point_data(helpers.tri_mesh, 1, dtype=int),
helpers.add_point_data(helpers.tri_mesh, 1, dtype=float),
helpers.line_mesh,
helpers.polygon_mesh,
# helpers.add_cell_data(helpers.tri_mesh, [("a", (), np.float64)]),
# helpers.add_cell_data(helpers.tri_mesh, [("a", (2,), np.float64)]),
# helpers.add_cell_data(helpers.tri_mesh, [("a", (3,), np.float64)]),
Expand Down

0 comments on commit b1753bd

Please sign in to comment.