Skip to content

Commit

Permalink
add a wrapper for cascadio
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedh committed Mar 11, 2024
1 parent 48162d2 commit 6bd0a14
Show file tree
Hide file tree
Showing 7 changed files with 10,656 additions and 4 deletions.
2 changes: 2 additions & 0 deletions docs/content/install.md
Expand Up @@ -71,6 +71,8 @@ Trimesh has a lot of soft-required upstream packages, and we try to make sure th
|`pyinstrument`| A sampling based profiler for performance tweaking. | | `test`|
|`vhacdx`| A binding for VHACD which provides convex decompositions | | `recommend`|
|`manifold3d`| A binding for the Manifold mesh boolean engine | | `recommend`|
|`openctm`| A binding for OpenCTM loaders enabling `.ctm` loading | | `recommend`|
|`cascadio`| A binding for OpenCASCADE enabling `.STEP` loading | | `recommend`|

## Adding A Dependency

Expand Down
10,542 changes: 10,542 additions & 0 deletions models/box_sides.STEP

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions pyproject.toml
Expand Up @@ -5,7 +5,7 @@ requires = ["setuptools >= 61.0", "wheel"]
[project]
name = "trimesh"
requires-python = ">=3.7"
version = "4.1.8"
version = "4.2.0"
authors = [{name = "Michael Dawson-Haggerty", email = "mikedh@kerfed.com"}]
license = {file = "LICENSE.md"}
description = "Import, export, process, analyze and view triangular meshes."
Expand Down Expand Up @@ -88,8 +88,9 @@ recommend = [
"pyglet<2",
"psutil",
"scikit-image",
"python-fcl",
"openctm",
"python-fcl", # do collision checks
"openctm", # load `CTM` compressed models
"cascadio", # load `STEP` files
"manifold3d>=2.3.0"
]

Expand Down
21 changes: 21 additions & 0 deletions tests/test_step.py
@@ -0,0 +1,21 @@
try:
import generic as g
except BaseException:
from . import generic as g


class STEPTests(g.unittest.TestCase):
def test_basic(self):
try:
import cascadio # noqa
except BaseException:
g.log.error("failed to get cascadio!", exc_info=True)
return

s = g.get_mesh("box_sides.STEP")
assert len(s.geometry) == 10


if __name__ == "__main__":
g.trimesh.util.attach_to_log()
g.unittest.main()
72 changes: 72 additions & 0 deletions trimesh/exchange/cascade.py
@@ -0,0 +1,72 @@
import os
import tempfile

from ..typed import BinaryIO, Dict, Optional

# used as an intermediate format
from .gltf import load_glb


def load_step(
file_obj: BinaryIO,
file_type,
tol_linear: Optional[float] = None,
tol_angular: Optional[float] = None,
tol_relative: Optional[bool] = False,
merge_primitives: bool = True,
**kwargs,
) -> Dict:
"""
Use `cascadio` a packaged version of OpenCASCADE
to load a STEP file using GLB as an intermediate.
Parameters
-----------
file_obj
STEP file to load.
**kwargs
Passed to `cascadio.step_to_glb`
Returns
----------
kwargs
Keyword arguments for a Scene.
"""
# TODO : update upstream `cascadio` to accept bytes objects
# so that we don't need to write a temporary file to disc!
with tempfile.TemporaryDirectory() as F:
# temporarily copy the STEP
stepfile = os.path.join(F, "data.step")
with open(stepfile, "wb") as f:
f.write(file_obj.read())

# where to save the converted GLB
glbfile = os.path.join(F, "converted.glb")

# the arguments for cascadio are not optional so
# filter out any `None` value arguments here
cascadio_kwargs = {
"merge_primitives": bool(merge_primitives),
"tol_linear": tol_linear,
"tol_angular": tol_angular,
"tol_relative": tol_relative,
}
# run the conversion
cascadio.step_to_glb(
stepfile,
glbfile,
**{k: v for k, v in cascadio_kwargs.items() if v is not None},
)

with open(glbfile, "rb") as f:
# return the parsed intermediate file
return load_glb(file_obj=f, merge_primitives=merge_primitives, **kwargs)


try:
# wheels for most platforms: `pip install cascadio`
import cascadio

_cascade_loaders = {"stp": load_step, "step": load_step}
except BaseException:
_cascade_loaders = {}
2 changes: 2 additions & 0 deletions trimesh/exchange/load.py
Expand Up @@ -13,6 +13,7 @@
from ..util import log, now
from . import misc
from .binvox import _binvox_loaders
from .cascade import _cascade_loaders
from .dae import _collada_loaders
from .gltf import _gltf_loaders
from .misc import _misc_loaders
Expand Down Expand Up @@ -655,6 +656,7 @@ def _parse_file_args(
mesh_loaders.update(_threedxml_loaders)
mesh_loaders.update(_three_loaders)
mesh_loaders.update(_xyz_loaders)
mesh_loaders.update(_cascade_loaders)

# collect loaders which return voxel types
voxel_loaders = {}
Expand Down
14 changes: 13 additions & 1 deletion trimesh/typed.py
@@ -1,5 +1,16 @@
from pathlib import Path
from typing import IO, Any, Dict, Iterable, List, Optional, Sequence, Tuple, Union
from typing import (
IO,
Any,
BinaryIO,
Dict,
Iterable,
List,
Optional,
Sequence,
Tuple,
Union,
)

# our default integer and floating point types
from numpy import float64, int64
Expand All @@ -22,6 +33,7 @@
"Iterable",
"Loadable",
"IO",
"BinaryIO",
"List",
"Dict",
"Any",
Expand Down

0 comments on commit 6bd0a14

Please sign in to comment.