From a93ddea2d538120f00cb955a526b39824ddda7c2 Mon Sep 17 00:00:00 2001 From: vhirtham Date: Wed, 10 Mar 2021 09:41:06 +0100 Subject: [PATCH 1/5] Add from_file and write_to_file to SpatialData --- environment.yml | 1 + setup.cfg | 1 + weldx/geometry.py | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/environment.yml b/environment.yml index 3fe7ef3e8..7a66ae0e3 100644 --- a/environment.yml +++ b/environment.yml @@ -16,6 +16,7 @@ dependencies: - asdf>=2.7 - openpyxl - fs + - meshio # graph packages - networkx # Code quality diff --git a/setup.cfg b/setup.cfg index 12248a674..0c3bb0c59 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,7 @@ install_requires = fs ipywidgets k3d + meshio include_package_data = True diff --git a/weldx/geometry.py b/weldx/geometry.py index 17534ade8..a8c6ababc 100644 --- a/weldx/geometry.py +++ b/weldx/geometry.py @@ -6,6 +6,7 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Dict, List, Tuple, Union +import meshio import numpy as np import pint from xarray import DataArray @@ -2328,6 +2329,26 @@ def __post_init__(self): if not self.triangles.ndim == 2: raise ValueError("SpatialData triangulation must be a 2d array") + @staticmethod + def from_file(file_name: str) -> "SpatialData": + """Create an instance from a file. + + Parameters + ---------- + file_name : + Name of the source file. + + Returns + ------- + SpatialData: + New `SpatialData` instance + + """ + mesh = meshio.read(file_name) + triangles = mesh.cells_dict.get("triangle") + + return SpatialData(mesh.points, triangles) + @staticmethod def from_geometry_raster(geometry_raster: np.ndarray) -> "SpatialData": """Triangulate rasterized Geometry Profile. @@ -2399,3 +2420,17 @@ def plot( label=label, show_wireframe=show_wireframe, ) + + def write_to_file(self, file_name: str): + """Write spatial data into a file. + + The extension prescribes the output format. + + Parameters + ---------- + file_name : str + Name of the file + + """ + mesh = meshio.Mesh(points=self.coordinates, cells={"triangle": self.triangles}) + mesh.write(file_name) From f2b19d81dfa6801f16598b48cc313045895445ca Mon Sep 17 00:00:00 2001 From: vhirtham Date: Wed, 10 Mar 2021 13:13:31 +0100 Subject: [PATCH 2/5] Add test and more type hints --- tests/test_geometry.py | 36 ++++++++++++++++++++++++++++++++++++ weldx/geometry.py | 11 +++++++---- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/tests/test_geometry.py b/tests/test_geometry.py index 4cef4f63f..713386991 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -2,6 +2,8 @@ import copy import math +from pathlib import Path +from tempfile import TemporaryDirectory from typing import List, Union import numpy as np @@ -2927,3 +2929,37 @@ def test_class_creation_exceptions(arguments, exception_type, test_name): """ with pytest.raises(exception_type): SpatialData(*arguments) + + @staticmethod + @pytest.mark.parametrize( + "filename", + ["test.ply", "test.stl", "test.vtk", Path("test.stl")], + ) + def test_read_write_file(filename: Union[str, Path]): + """Test the `from_file` and `write_to_file` functions. + + The test simply creates a `SpatialData` instance, writes it to a file and reads + it back. The result is compared to the original object. + + Parameters + ---------- + filename : + Name of the file + + Returns + ------- + + """ + points = [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]] + triangles = [[0, 1, 2], [2, 3, 0]] + + data = SpatialData(points, triangles) + with TemporaryDirectory(dir=Path(__file__).parent) as tmpdirname: + filepath = f"{tmpdirname}/{filename}" + if isinstance(filename, Path): + filepath = Path(filepath) + data.write_to_file(filepath) + data_read = SpatialData.from_file(filepath) + + assert np.allclose(data.coordinates, data_read.coordinates) + assert np.allclose(data.triangles, data_read.triangles) diff --git a/weldx/geometry.py b/weldx/geometry.py index a8c6ababc..7aedcde39 100644 --- a/weldx/geometry.py +++ b/weldx/geometry.py @@ -5,6 +5,7 @@ import math from dataclasses import dataclass from typing import TYPE_CHECKING, Dict, List, Tuple, Union +from pathlib import Path import meshio import numpy as np @@ -2330,7 +2331,7 @@ def __post_init__(self): raise ValueError("SpatialData triangulation must be a 2d array") @staticmethod - def from_file(file_name: str) -> "SpatialData": + def from_file(file_name: Union[str, Path]) -> "SpatialData": """Create an instance from a file. Parameters @@ -2421,16 +2422,18 @@ def plot( show_wireframe=show_wireframe, ) - def write_to_file(self, file_name: str): + def write_to_file(self, file_name: Union[str, Path]): """Write spatial data into a file. The extension prescribes the output format. Parameters ---------- - file_name : str + file_name : Name of the file """ - mesh = meshio.Mesh(points=self.coordinates, cells={"triangle": self.triangles}) + mesh = meshio.Mesh( + points=self.coordinates.data, cells={"triangle": self.triangles} + ) mesh.write(file_name) From c02b6eca752bef78f6768c0a0e6dad1c0dfed068 Mon Sep 17 00:00:00 2001 From: vhirtham Date: Wed, 10 Mar 2021 13:29:15 +0100 Subject: [PATCH 3/5] Fix issues --- tests/test_geometry.py | 3 --- weldx/geometry.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_geometry.py b/tests/test_geometry.py index 713386991..587a1b769 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -2946,9 +2946,6 @@ def test_read_write_file(filename: Union[str, Path]): filename : Name of the file - Returns - ------- - """ points = [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]] triangles = [[0, 1, 2], [2, 3, 0]] diff --git a/weldx/geometry.py b/weldx/geometry.py index 7aedcde39..ecbbc822a 100644 --- a/weldx/geometry.py +++ b/weldx/geometry.py @@ -4,8 +4,8 @@ import copy import math from dataclasses import dataclass -from typing import TYPE_CHECKING, Dict, List, Tuple, Union from pathlib import Path +from typing import TYPE_CHECKING, Dict, List, Tuple, Union import meshio import numpy as np From 41d523a458d4ed258d2280c7927371c842137b05 Mon Sep 17 00:00:00 2001 From: vhirtham Date: Wed, 10 Mar 2021 13:43:06 +0100 Subject: [PATCH 4/5] Update .typo-ci.yml --- .typo-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.typo-ci.yml b/.typo-ci.yml index 5f5bf17e2..c8ebe4a4f 100644 --- a/.typo-ci.yml +++ b/.typo-ci.yml @@ -30,6 +30,7 @@ excluded_words: - shutil - functools - boltons + - meshio # matplotlib ---------------------------------- - gca - mpl @@ -118,6 +119,9 @@ excluded_words: - numpydoc # markdown / latex ---------------------------- - cdot + # file extensions ----------------------------- + - vtk + - stl # other --------------------------------------- - addopts - csm From 2da9e4f86d1b0668514f1918333b285871f40f16 Mon Sep 17 00:00:00 2001 From: vhirtham Date: Wed, 10 Mar 2021 14:06:32 +0100 Subject: [PATCH 5/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d825667a1..cc752260c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ pending [ASDF #916](https://github.com/asdf-format/asdf/issues/916) [[#224]](https://github.com/BAMWelDX/weldx/pull/224) - set minimum Python version to 3.8 [[#229]](https://github.com/BAMWelDX/weldx/pull/229)[[#255]](https://github.com/BAMWelDX/weldx/pull/255) - only import some packages upon first use [[#247]](https://github.com/BAMWelDX/weldx/pull/247) +- Add [meshio](https://pypi.org/project/meshio/) as new dependency [#265](https://github.com/BAMWelDX/weldx/pull/265) ## 0.2.2 (30.11.2020)