diff --git a/.bumpversion.cfg b/.bumpversion.cfg deleted file mode 100644 index 288b5ef8088..00000000000 --- a/.bumpversion.cfg +++ /dev/null @@ -1,29 +0,0 @@ -[bumpversion] -current_version = 2.1.0 -message = Bump version to {new_version} -commit = True -tag = True - -[bumpversion:file:setup.py] -search = version="{current_version}" -replace = version="{new_version}" - -[bumpversion:file:src/compas/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:src/compas_blender/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:src/compas_ghpython/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:src/compas_rhino/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:CHANGELOG.md] -search = Unreleased -replace = [{new_version}] {now:%Y-%m-%d} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78564ace0e5..10e1fa60fdb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,10 +15,11 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.8', '3.9', '3.10'] + python: ["3.9", "3.10", "3.11", "3.12"] steps: - - uses: compas-dev/compas-actions.build@v3 + - uses: compas-dev/compas-actions.build@v4 with: + invoke_lint: true + invoke_test: true python: ${{ matrix.python }} - invoke_lint: true \ No newline at end of file diff --git a/.github/workflows/ironpython.yml b/.github/workflows/ironpython.yml index e802f95eb94..472d4f91cfd 100644 --- a/.github/workflows/ironpython.yml +++ b/.github/workflows/ironpython.yml @@ -14,10 +14,10 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 - - name: "[RPC tests] Set up CPython 3.8" + - name: "[RPC tests] Set up CPython 3.9" uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: "[RPC tests] Install CPython dependencies" run: | python -m pip install --upgrade pip diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2cfac61a67b..57436e45b69 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ on: push: tags: - - 'v*' + - "v*" name: Create Release @@ -11,20 +11,21 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.8', '3.9', '3.10'] + python: ["3.9", "3.10", "3.11", "3.12"] steps: - - uses: compas-dev/compas-actions.build@v3 + - uses: compas-dev/compas-actions.build@v4 with: - python: ${{ matrix.python }} invoke_lint: true + invoke_test: true + python: ${{ matrix.python }} check_import: true publish: needs: build runs-on: windows-latest steps: - - uses: compas-dev/compas-actions.publish@v2 + - uses: compas-dev/compas-actions.publish@v3 with: pypi_token: ${{ secrets.PYPI }} github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f2d5c59112..8a10422f9ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,14 +24,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed bug in `compas.topology.orientation.unify_cycles`. * Fixed bug in `Mesh.thickened`. * Fixed various bugs in `compas.geometry.Quaternion`. - +* Changed repo config to `pyproject.toml`. ### Removed * Removed `compas.scene.SceneObjectNode`, functionalities merged into `compas.scene.SceneObject`. * Removed `compas.scene.SceneTree`, functionalities merged into `compas.scene.Scene`. - ## [2.1.0] 2024-03-01 ### Added @@ -52,7 +51,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - ## [2.0.4] 2024-02-12 ### Added @@ -63,7 +61,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed - ## [2.0.3] 2024-02-09 ### Added diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 165e2d448ac..00000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,24 +0,0 @@ -graft src - -prune .github -prune docs -prune libs -prune samples -prune tests -prune temp - -include LICENSE -include README.md -include AUTHORS.md -include CHANGELOG.md -include requirements.txt -include conftest.py -include pyproject.toml - -exclude requirements-dev.txt -exclude pytest.ini .bumpversion.cfg .editorconfig -exclude tasks.py -exclude CONTRIBUTING.md -exclude .gitpod.yml - -global-exclude *.py[cod] __pycache__ *.dylib *.nb[ic] .DS_Store diff --git a/conftest.py b/conftest.py index 3e378e97e3e..88062fab2d3 100644 --- a/conftest.py +++ b/conftest.py @@ -1,8 +1,9 @@ -import pytest -import compas import math + import numpy +import pytest +import compas from compas.geometry import allclose @@ -16,9 +17,6 @@ def pytest_ignore_collect(path): if "ghpython" in str(path): return True - if "matlab" in str(path): - return True - if str(path).endswith("_cli.py"): return True diff --git a/pyproject.toml b/pyproject.toml index 91814cd4427..b46a88b7298 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,26 +1,159 @@ -[tool.black] -line-length = 120 +[build-system] +requires = ["setuptools>=66.0"] +build-backend = "setuptools.build_meta" + +# ============================================================================ +# project info +# ============================================================================ + +[project] +name = "compas" +description = "The main COMPAS framework library." +keywords = ["architecture", "engineering", "fabrication", "construction"] +authors = [{ name = "tom van mele", email = "tom.v.mele@gmail.com" }] +license = { file = "LICENSE" } +readme = "README.md" +requires-python = ">=3.9" +dynamic = ['dependencies', 'optional-dependencies', 'version'] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Topic :: Scientific/Engineering", + "Operating System :: Unix", + "Operating System :: POSIX", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] + +[project.urls] +Homepage = "https://compas-dev.github.io/compas" +Documentation = "https://compas-dev.github.io/compas" +Repository = "https://github.com/compas-dev/compas.git" +Changelog = "https://github.com/compas-dev/compas/blob/main/CHANGELOG.md" +Issues = "https://github.com/compas-dev/compas/issues" +Forum = "https://forum.compas-framework.org/" + +[project.scripts] +compas_rpc = "compas.rpc.__main__:main" + +# ============================================================================ +# setuptools config +# ============================================================================ + +[tool.setuptools] +package-dir = { "" = "src" } +include-package-data = true +zip-safe = false + +[tool.setuptools.dynamic] +version = { attr = "compas.__version__" } +dependencies = { file = "requirements.txt" } +optional-dependencies = { dev = { file = "requirements-dev.txt" } } + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] +"compas.colors.cmcrameri" = ["*.txt"] +"compas.data.samples" = ["*.obj", "*.stl", "*.off", "*.ply", "*.json"] + +# ============================================================================ +# replace pytest.ini +# ============================================================================ [tool.pytest.ini_options] minversion = "6.0" -testpaths = ["tests"] -python_files = [ - "test_*.py", - "tests.py" +testpaths = ["tests", "src/compas"] +python_files = ["test_*.py", "*_test.py", "test.py"] +addopts = ["-ra", "--strict-markers", "--doctest-glob=*.rst", "--tb=short"] +doctest_optionflags = [ + "NORMALIZE_WHITESPACE", + "IGNORE_EXCEPTION_DETAIL", + "ALLOW_UNICODE", + "ALLOW_BYTES", + "NUMBER", ] -addopts = "-ra --strict --doctest-modules --doctest-glob=*.rst --tb=short" -doctest_optionflags= "NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL ALLOW_UNICODE ALLOW_BYTES NUMBER" -filterwarnings = "ignore::DeprecationWarning" - -[tool.isort] -line_length = 120 -multi_line_output = 3 -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true -force_single_line = true -ensure_newline_before_comments = true -known_first_party = "compas" -default_section = "THIRDPARTY" -forced_separate = "test_compas" -skip = ["__init__.py"] + +# ============================================================================ +# replace bumpversion.cfg +# ============================================================================ + +[tool.bumpversion] +current_version = "2.1.0" +message = "Bump version to {new_version}" +commit = true +tag = true + +[[tool.bumpversion.files]] +filename = "src/compas/__init__.py" +search = "{current_version}" +replace = "{new_version}" + +[[tool.bumpversion.files]] +filename = "src/compas_blender/__init__.py" +search = "{current_version}" +replace = "{new_version}" + +[[tool.bumpversion.files]] +filename = "src/compas_ghpython/__init__.py" +search = "{current_version}" +replace = "{new_version}" + +[[tool.bumpversion.files]] +filename = "src/compas_rhino/__init__.py" +search = "{current_version}" +replace = "{new_version}" + +[[tool.bumpversion.files]] +filename = "CHANGELOG.md" +search = "Unreleased" +replace = "[{new_version}] {now:%Y-%m-%d}" + +# ============================================================================ +# replace setup.cfg +# ============================================================================ + +[tool.black] +# we should set this to 179 +line-length = 120 + +[tool.ruff] +# we should set this to 179 +line-length = 120 +indent-width = 4 +target-version = "py39" + +[tool.ruff.lint] +# we should add "I" +select = ["E", "F"] +# we should remove this +ignore = ["E501"] + +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["I001"] +"tests/*" = ["I001"] +"tasks.py" = ["I001"] + +[tool.ruff.lint.isort] +force-single-line = true +known-first-party = [ + "compas", + "compas_blender", + "compas_ghpython", + "compas_rhino", +] + +[tool.ruff.lint.pydocstyle] +convention = "numpy" + +[tool.ruff.lint.pycodestyle] +# we should set this to 179 +max-doc-length = 120 + +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = "dynamic" diff --git a/requirements-dev.txt b/requirements-dev.txt index def0bbb150b..a1579931b3b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,14 +1,9 @@ attrs >=17.4 -black -bump2version >=1.0.1 -check-manifest >=0.36 -compas_invocations -doc8 -flake8 -importlib_metadata <5.0 +black >=22.12.0 +bump-my-version +compas_invocations2 invoke >=0.14 -isort +ruff sphinx_compas2_theme twine wheel --e . diff --git a/requirements.txt b/requirements.txt index d7bf5d5b9ca..11f9a773638 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,4 @@ jsonschema networkx >= 3.0 numpy >= 1.15.4 scipy >= 1.1 -typing_extensions watchdog; sys_platform != 'emscripten' diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index e7f4c1234c9..00000000000 --- a/setup.cfg +++ /dev/null @@ -1,17 +0,0 @@ -[bdist_wheel] -universal = 1 - -[flake8] -max-line-length = 120 -extend-ignore = - # See https://github.com/PyCQA/pycodestyle/issues/373 - E203, - # Only keep black line length check because flake8 forces it on comments as well - E501, - -[doc8] -max-line-length = 120 -ignore = D001 - -[pydocstyle] -convention = numpy diff --git a/setup.py b/setup.py deleted file mode 100644 index 2a2fbb3cc24..00000000000 --- a/setup.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -*- encoding: utf-8 -*- -# flake8: noqa -from __future__ import print_function - -import io -from os import path - -from setuptools import setup - - -here = path.abspath(path.dirname(__file__)) - - -def read(*names, **kwargs): - return io.open(path.join(here, *names), encoding=kwargs.get("encoding", "utf8")).read() - - -long_description = read("README.md") -requirements = [r for r in read("requirements.txt").split("\n") if r] -optional_requirements = {} - -setup( - name="COMPAS", - version="2.1.0", - description="The COMPAS framework", - long_description=long_description, - long_description_content_type="text/markdown", - url="http://compas.dev", - author="Tom Van Mele", - author_email="van.mele@arch.ethz.ch", - license="MIT", - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Topic :: Scientific/Engineering", - "License :: OSI Approved :: MIT License", - "Operating System :: Unix", - "Operating System :: POSIX", - "Operating System :: Microsoft :: Windows", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: Implementation :: CPython", - ], - keywords=["architecture", "engineering", "fabrication", "construction"], - project_urls={ - "Documentation": "http://compas.dev", - "Forum": "https://forum.compas-framework.org/", - "Repository": "https://github.com/compas-dev/compas", - "Issues": "https://github.com/compas-dev/compas/issues", - }, - packages=[ - "compas", - "compas_rhino", - "compas_blender", - "compas_ghpython", - ], - package_dir={"": "src"}, - package_data={"compas": ["data/schemas/*.json"]}, - data_files=[], - include_package_data=True, - zip_safe=False, - install_requires=requirements, - python_requires=">=2.7", - extras_require={"numba": ["numba"]}, - entry_points={"console_scripts": ["compas_rpc=compas.rpc.__main__:main"]}, - ext_modules=[], - cmdclass={}, -) diff --git a/src/compas/__init__.py b/src/compas/__init__.py index ad40d3d75cc..d5e2de51abe 100644 --- a/src/compas/__init__.py +++ b/src/compas/__init__.py @@ -1,7 +1,6 @@ from __future__ import print_function import os -from distutils.version import LooseVersion import compas._os from compas._os import ( @@ -23,8 +22,6 @@ __email__ = "tom.v.mele@gmail.com" __version__ = "2.1.0" -version = LooseVersion(compas.__version__) -versionstring = version.vstring.split("-")[0] HERE = compas._os.realpath(os.path.dirname(__file__)) """str: Path to the location of the compas package.""" diff --git a/src/compas/colors/color.py b/src/compas/colors/color.py index 61d71986139..61f82d713f0 100644 --- a/src/compas/colors/color.py +++ b/src/compas/colors/color.py @@ -912,8 +912,8 @@ def lighten(self, factor=10): factor = 1.0 + factor / 100 - h, l, s = self.hls - r, g, b = colorsys.hls_to_rgb(h, min(1.0, l * factor), s) + hue, luminance, saturation = self.hls + r, g, b = colorsys.hls_to_rgb(hue, min(1.0, luminance * factor), saturation) self.r = r self.g = g self.b = b @@ -963,8 +963,8 @@ def darken(self, factor=10): factor = 1.0 - factor / 100 - h, l, s = self.hls - r, g, b = colorsys.hls_to_rgb(h, max(0.0, l * factor), s) + hue, luminance, saturation = self.hls + r, g, b = colorsys.hls_to_rgb(hue, max(0.0, luminance * factor), saturation) self.r = r self.g = g self.b = b @@ -1038,8 +1038,8 @@ def saturate(self, factor=10): factor = 1.0 + factor / 100 - h, l, s = self.hls - r, g, b = colorsys.hls_to_rgb(h, l, min(1.0, s * factor)) + hue, luminance, saturation = self.hls + r, g, b = colorsys.hls_to_rgb(hue, luminance, min(1.0, saturation * factor)) self.r = r self.g = g self.b = b @@ -1089,8 +1089,8 @@ def desaturate(self, factor=10): factor = 1.0 - factor / 100 - h, l, s = self.hls - r, g, b = colorsys.hls_to_rgb(h, l, max(0.0, s * factor)) + hue, luminance, saturation = self.hls + r, g, b = colorsys.hls_to_rgb(hue, luminance, max(0.0, saturation * factor)) self.r = r self.g = g self.b = b diff --git a/src/compas/datastructures/cell_network/cell_network.py b/src/compas/datastructures/cell_network/cell_network.py index 4c5b7f068b8..2a439c5c751 100644 --- a/src/compas/datastructures/cell_network/cell_network.py +++ b/src/compas/datastructures/cell_network/cell_network.py @@ -227,15 +227,7 @@ def __from_data__(cls, data): return cell_network - def __init__( - self, - default_vertex_attributes=None, - default_edge_attributes=None, - default_face_attributes=None, - default_cell_attributes=None, - name=None, - **kwargs - ): + def __init__(self, default_vertex_attributes=None, default_edge_attributes=None, default_face_attributes=None, default_cell_attributes=None, name=None, **kwargs): # fmt: skip super(CellNetwork, self).__init__(kwargs, name=name) self._max_vertex = -1 self._max_face = -1 diff --git a/src/compas/datastructures/mesh/mesh.py b/src/compas/datastructures/mesh/mesh.py index 7be50338ef7..702affd543d 100644 --- a/src/compas/datastructures/mesh/mesh.py +++ b/src/compas/datastructures/mesh/mesh.py @@ -235,14 +235,7 @@ def __from_data__(cls, data): return mesh - def __init__( - self, - default_vertex_attributes=None, - default_edge_attributes=None, - default_face_attributes=None, - name=None, - **kwargs - ): + def __init__(self, default_vertex_attributes=None, default_edge_attributes=None, default_face_attributes=None, name=None, **kwargs): # fmt: skip super(Mesh, self).__init__(kwargs, name=name) self._max_vertex = -1 self._max_face = -1 diff --git a/src/compas/datastructures/volmesh/volmesh.py b/src/compas/datastructures/volmesh/volmesh.py index 15e4b8c5405..eca7cbbce39 100644 --- a/src/compas/datastructures/volmesh/volmesh.py +++ b/src/compas/datastructures/volmesh/volmesh.py @@ -202,15 +202,7 @@ def __from_data__(cls, data): return volmesh - def __init__( - self, - default_vertex_attributes=None, - default_edge_attributes=None, - default_face_attributes=None, - default_cell_attributes=None, - name=None, - **kwargs - ): + def __init__(self, default_vertex_attributes=None, default_edge_attributes=None, default_face_attributes=None, default_cell_attributes=None, name=None, **kwargs): # fmt: skip super(VolMesh, self).__init__(kwargs, name=name) self._max_vertex = -1 self._max_face = -1 diff --git a/src/compas/rpc/__init__.py b/src/compas/rpc/__init__.py index 5fb7058af67..c34107367d5 100644 --- a/src/compas/rpc/__init__.py +++ b/src/compas/rpc/__init__.py @@ -2,10 +2,11 @@ COMPAS runs in many different environments, but in some environments the availablity of libraries is limited. For example, when running COMPAS in an IronPython-based environment like Rhino/Grasshopper, plenty of CPython libraries such as `numpy` and `scipy` are not available. -To workaround this limitation, COMPAS provides a mechanisms to access the functionality of a CPython environment seemlessly from any other Python environment through a "Remote Procedure Call" or RPC. +To workaround this limitation, COMPAS provides a mechanisms to access the functionality of a CPython environment +seemlessly from any other Python environment through a "Remote Procedure Call" or RPC. Through RPC, COMPAS can be used as a server for remote clients, and as a client for remote servers. -A typical use case is to run algorithms that require packages like ``numpy`` or ``scipy`` on a remote server, when working in Rhino. -Or to use COMPAS in a browser application. +A typical use case is to run algorithms that require packages like ``numpy`` or ``scipy`` on a remote server, +when working in Rhino. Or to use COMPAS in a browser application. """ from __future__ import absolute_import diff --git a/src/compas/scene/sceneobject.py b/src/compas/scene/sceneobject.py index 3c8607e36da..3f53a59ca27 100644 --- a/src/compas/scene/sceneobject.py +++ b/src/compas/scene/sceneobject.py @@ -84,18 +84,8 @@ def __new__(cls, item, **kwargs): sceneobject_cls = get_sceneobject_cls(item, **kwargs) return super(SceneObject, cls).__new__(sceneobject_cls) - def __init__( - self, - item, # type: compas.geometry.Geometry | compas.datastructures.Datastructure - name=None, # type: str | None - color=None, # type: compas.colors.Color | None - opacity=1.0, # type: float - show=True, # type: bool - frame=None, # type: compas.geometry.Frame | None - transformation=None, # type: compas.geometry.Transformation | None - context=None, # type: str | None - **kwargs # type: dict - ): # type: (...) -> None + def __init__(self, item, name=None, color=None, opacity=1.0, show=True, frame=None, transformation=None, context=None, **kwargs): # fmt: skip + # type: (compas.geometry.Geometry | compas.datastructures.Datastructure, str | None, compas.colors.Color | None, float, bool, compas.geometry.Frame | None, compas.geometry.Transformation | None, str | None, dict) -> None name = name or item.name super(SceneObject, self).__init__(name=name, **kwargs) # the scene object needs to store the context diff --git a/tasks.py b/tasks.py index 9362999db4a..2313ff2f6af 100644 --- a/tasks.py +++ b/tasks.py @@ -2,10 +2,10 @@ import os -from compas_invocations import build -from compas_invocations import docs -from compas_invocations import style -from compas_invocations import tests +from compas_invocations2 import build +from compas_invocations2 import docs +from compas_invocations2 import style +from compas_invocations2 import tests from invoke import Collection ns = Collection( diff --git a/tests/compas/datastructures/test_mesh.py b/tests/compas/datastructures/test_mesh.py index 427412f244f..2d2f9764da3 100644 --- a/tests/compas/datastructures/test_mesh.py +++ b/tests/compas/datastructures/test_mesh.py @@ -10,7 +10,8 @@ from compas.geometry import Polygon from compas.geometry import Polyhedron from compas.geometry import Translation -from compas.geometry import allclose + +from compas.tolerance import TOL @pytest.fixture @@ -1018,7 +1019,7 @@ def test_area(): assert mesh.area() == 6 mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.area() == 22.802429316496635 + assert TOL.is_close(mesh.area(), 22.802429316496635) def test_centroid(): @@ -1029,7 +1030,7 @@ def test_centroid(): assert mesh.centroid() == [0.0, 0.0, 0.5] mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.centroid() == [2.508081952064351, 2.554046390557884, 1.2687133268242006] + assert TOL.is_allclose(mesh.centroid(), [2.508081952064351, 2.554046390557884, 1.2687133268242006]) def test_normal(): @@ -1040,11 +1041,14 @@ def test_normal(): assert mesh.normal() == [0.0, 0.0, 0.0] mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.normal() == [ - -2.380849234996509e-06, - 4.1056122145028854e-05, - 0.8077953732329284, - ] + assert TOL.is_allclose( + mesh.normal(), + [ + -2.380849234996509e-06, + 4.1056122145028854e-05, + 0.8077953732329284, + ], + ) # -------------------------------------------------------------------------- @@ -1078,22 +1082,28 @@ def test_vertex_neighborhood_centroid(): def test_vertex_normal(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.vertex_normal(0) == [ - -0.7875436283909406, - 0.07148692938164082, - 0.6120985642103861, - ] - assert mesh.vertex_normal(5) == [ - -0.482011312317331, - -0.32250183520381565, - 0.814651864963369, - ] + assert TOL.is_allclose( + mesh.vertex_normal(0), + [ + -0.7875436283909406, + 0.07148692938164082, + 0.6120985642103861, + ], + ) + assert TOL.is_allclose( + mesh.vertex_normal(5), + [ + -0.482011312317331, + -0.32250183520381565, + 0.814651864963369, + ], + ) def test_vertex_curvature(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.vertex_curvature(0) == 0.0029617825994936453 - assert mesh.vertex_curvature(5) == 0.036193074384009094 + assert TOL.is_close(mesh.vertex_curvature(0), 0.0029617825994936453) + assert TOL.is_close(mesh.vertex_curvature(5), 0.036193074384009094) def test_face_coordinates(): @@ -1114,39 +1124,44 @@ def test_face_coordinates(): def test_face_normal(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert allclose( + assert TOL.is_allclose( mesh.face_normal(0), [0.5435358481001584, -0.16248515023849733, 0.8235091728584537], - tol=1e-6, ) def test_face_centroid(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_centroid(0) == [ - 3.94185334444046, - 2.024157851934433, - 1.3333333134651184, - ] + assert TOL.is_allclose( + mesh.face_centroid(0), + [ + 3.94185334444046, + 2.024157851934433, + 1.3333333134651184, + ], + ) def test_face_center(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_center(0) == [ - 3.944329439044577, - 2.0258867968680776, - 1.332040166602369, - ] + assert TOL.is_allclose( + mesh.face_center(0), + [ + 3.944329439044577, + 2.0258867968680776, + 1.332040166602369, + ], + ) def test_face_area(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_area(0) == 0.3374168482414756 + assert TOL.is_close(mesh.face_area(0), 0.3374168482414756) def test_face_flatness(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_flatness(0) == 0.23896112582475654 + assert TOL.is_close(mesh.face_flatness(0), 0.23896112582475654) mesh = Mesh.from_obj(compas.get("faces.obj")) assert mesh.face_flatness(0) == 0 @@ -1154,7 +1169,7 @@ def test_face_flatness(): def test_face_aspect_ratio(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_aspect_ratio(0) == 1.2813792520925738 + assert TOL.is_close(mesh.face_aspect_ratio(0), 1.2813792520925738) mesh = Mesh.from_obj(compas.get("faces.obj")) assert mesh.face_aspect_ratio(0) == 1 @@ -1162,7 +1177,7 @@ def test_face_aspect_ratio(): def test_face_skewness(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_skewness(0) == 0.2432393485343291 + assert TOL.is_close(mesh.face_skewness(0), 0.2432393485343291) mesh = Mesh.from_obj(compas.get("faces.obj")) assert mesh.face_skewness(0) == 0 @@ -1170,7 +1185,7 @@ def test_face_skewness(): def test_face_curvature(): mesh = Mesh.from_obj(compas.get("quadmesh.obj")) - assert mesh.face_curvature(0) == 0.0035753184898039566 + assert TOL.is_close(mesh.face_curvature(0), 0.0035753184898039566) mesh = Mesh.from_obj(compas.get("faces.obj")) assert mesh.face_curvature(0) == 0 diff --git a/tests/compas/test_iotools.py b/tests/compas/test_iotools.py index 59a03962074..2154559add3 100644 --- a/tests/compas/test_iotools.py +++ b/tests/compas/test_iotools.py @@ -56,7 +56,7 @@ def test_open_file_object_text(path_text): def test_open_file_memory_stream(): - text = b"All Gaul is divided into three parts, one of which the Belgae inhabit, the Aquitani another, those who in their own language are called Celts, in our Gauls, the third." + text = b"All Gaul is divided into three parts, one of which the Belgae inhabit, the Aquitani another, those who in their own language are called Celts, in our Gauls, the third." # noqa: E501 data = io.BytesIO(text) with _iotools.open_file(data, mode="rb") as f: assert f.read() == text