diff --git a/Geometry/clash.py b/Geometry/clash.py index b6ae67f..9a96ab6 100644 --- a/Geometry/clash.py +++ b/Geometry/clash.py @@ -1,7 +1,12 @@ from concurrent.futures import ProcessPoolExecutor, as_completed from typing import List, Tuple, Any, Optional -import pymesh +try: + import pymesh +except ImportError: + from Geometry.mocks import mypymesh + + pymesh = mypymesh from speckle_automate import AutomationContext @@ -10,7 +15,7 @@ from Geometry.mesh import cast def detect_clashes_old( - reference_elements: List[Element], latest_elements: List[Element], _tolerance: float + reference_elements: List[Element], latest_elements: List[Element], _tolerance: float ) -> list[tuple[str, str, float]]: """ Detect clashes between two sets of mesh elements using Pymesh. @@ -41,11 +46,11 @@ def detect_clashes_old( continue intersection = pymesh.boolean( - ref_pymesh, latest_pymesh, operation="intersection" + latest_pymesh, operation="intersection" ) if ( - intersection and intersection.volume > 0 + intersection and intersection.volume > 0 ): # TODO: could tolerance relate to this? severity = intersection.volume / min( ref_pymesh.volume, latest_pymesh.volume @@ -57,7 +62,7 @@ def detect_clashes_old( def check_for_clash( - ref_element: Element, latest_element: Element + ref_element: Element, latest_element: Element ) -> Optional[tuple[Any, Any, Any]]: """ Check for a clash between two elements and calculate the severity of the clash. @@ -78,7 +83,7 @@ def check_for_clash( continue intersection = pymesh.boolean( - ref_pymesh, latest_pymesh, operation="intersection" + latest_pymesh, operation="intersection" ) if intersection and intersection.volume > 0: severity = intersection.volume / min( @@ -89,7 +94,7 @@ def check_for_clash( def detect_clashes( - reference_elements: List[Element], latest_elements: List[Element], _tolerance: float + reference_elements: List[Element], latest_elements: List[Element], _tolerance: float ) -> List[Tuple[str, str, float]]: """ Detect clashes between two sets of mesh elements using parallel processing. @@ -118,10 +123,10 @@ def detect_clashes( def detect_and_report_clashes( - reference_elements: list[Element], - latest_elements: list[Element], - tolerance: float, - automate_context: AutomationContext, + reference_elements: list[Element], + latest_elements: list[Element], + tolerance: float, + automate_context: AutomationContext, ) -> list[tuple[str, str, float]]: clashes = detect_clashes(reference_elements, latest_elements, tolerance) diff --git a/Geometry/mesh.py b/Geometry/mesh.py index 75fe0fe..1b59123 100644 --- a/Geometry/mesh.py +++ b/Geometry/mesh.py @@ -1,11 +1,16 @@ -from typing import Union, Type, TYPE_CHECKING +from typing import Union, Type +try: + import pymesh +except ImportError: + from Geometry.mocks import mypymesh -import pymesh - + pymesh = mypymesh import trimesh +from Geometry.helpers import triangulate_face + class MockPyMesh: def __init__(self, vertices, faces): @@ -39,7 +44,7 @@ def pymesh_to_trimesh(mesh: pymesh.Mesh) -> trimesh.Trimesh: def cast( - mesh: Union[trimesh.Trimesh, pymesh.Mesh], target_type: Type + mesh: Union[trimesh.Trimesh, pymesh.Mesh], target_type: Type ) -> Union[trimesh.Trimesh, pymesh.Mesh]: """ Casts a mesh object to a specified type. @@ -74,7 +79,7 @@ def speckle_mesh_to_trimesh(input_mesh: SpeckleMesh) -> trimesh.Trimesh: face_vertex_count = input_mesh.faces[i] i += 1 # Skip the vertex count - face_vertex_indices = input_mesh.faces[i : i + face_vertex_count] + face_vertex_indices = input_mesh.faces[i: i + face_vertex_count] face_vertices = [ Vector.from_list(vertices[idx].tolist()) for idx in face_vertex_indices diff --git a/Geometry/mocks.py b/Geometry/mocks.py new file mode 100644 index 0000000..935d809 --- /dev/null +++ b/Geometry/mocks.py @@ -0,0 +1,12 @@ +class mypymesh: + def __init__(self, vertices, faces): + self.vertices = vertices + self.faces = faces + + @staticmethod + def boolean(_other, _operation): + return mypymesh([], []) + + @property + def volume(self): + return 0 diff --git a/poetry.lock b/poetry.lock index 3b1cafd..fe871b5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -774,19 +774,6 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" -[[package]] -name = "pymesh" -version = "1.0.2" -description = "Library for manipulating (Translate, Rotate and Scale) 3D data using numpy." -optional = false -python-versions = "*" -files = [ - {file = "pymesh-1.0.2.tar.gz", hash = "sha256:7032cd5c53cd9d93b31b6033bfdf7a61ca482ce4dc10d70411a1f392df095deb"}, -] - -[package.dependencies] -numpy = "*" - [[package]] name = "pytest" version = "7.4.3" @@ -1287,4 +1274,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "5e736eb0d2aeb78aaf6b2252f4f3e011b6bca230716f2d0e07c29d3b3dc796ce" +content-hash = "3abedc1c21df21ba5ab28f1ea6dc49c8a84c768e0f8f155e5c619ca3fd023765" diff --git a/pyproject.toml b/pyproject.toml index 7cae34d..ff104e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ readme = "README.md" python = "^3.10" specklepy = "2.17.11" trimesh = "^4.0.4" -pymesh = "^1.0.2" [tool.poetry.group.dev.dependencies] black = "^23.3.0" @@ -23,11 +22,11 @@ build-backend = "poetry.core.masonry.api" [tool.ruff] select = [ - "E", # pycodestyle - "F", # pyflakes - "UP", # pyupgrade - "D", # pydocstyle - "I", # isort + "E", # pycodestyle + "F", # pyflakes + "UP", # pyupgrade + "D", # pydocstyle + "I", # isort ] [tool.ruff.pydocstyle]