Skip to content

Bug located in ...Body.Tesselate() #2178

@ZachDerocher

Description

@ZachDerocher

🔍 Before submitting the issue

  • I have searched among the existing issues
  • I am using a Python virtual environment

🐞 Description of the bug

The tesselate() command fails when performing a computationally-intensive tessellation.
I am able to tessellate a body in Speos for running optical simulation, but the same part fails to tessellate in pyansys-geometry.

Also, when tessellating multiple bodies in sequence, as soon as one body fails to tessellate in this way, all subsequent bodies also fail (even if those subsequent tessellations can be completely successfully in an isolated script run).

Here is an example of the error message:

{
"name": "TypeError",
"message": "Indices must be either a mask or an integer array-like",
"stack": "---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[6], line 127
125 matching_names = [x for x in all_names if body_name==x]
126 if len(matching_names) == 1:
--> 127 create_body([body_name], component)
128 already_loaded.append(body_name)
129 else:

Cell In[6], line 39, in create_body(body_names, component)
36 used_names.append(body_name_ref)
38 # mesh the geometry
---> 39 mesh = _body.tessellate(
40 merge=True if MESH_BY_BODY else False,
41 tess_options=TessellationOptions(
42 surface_deviation=0.001, # in meters
43 angle_deviation=0.8, # in radians
44 max_edge_length=0.0, # in meters
45 watertight=True#max_aspect_ratio=2.0,
46 )
47 )
48 # extract mesh information for pySpeos
49 if not MESH_BY_BODY:

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\misc\checks.py:77, in ensure_design_is_active..wrapper(self, *args, **kwargs)
72 raise GeometryRuntimeError(
73 "The design has been closed on the backend. Cannot perform any operations on it."
74 )
76 # Finally, call method
---> 77 return method(self, *args, **kwargs)

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\designer\body.py:1818, in Body.tessellate(self, merge, tess_options)
1814 @ensure_design_is_active
1815 def tessellate( # noqa: D102
1816 self, merge: bool = False, tess_options: TessellationOptions | None = None
1817 ) -> Union["PolyData", "MultiBlock"]:
-> 1818 return self._template.tessellate(
1819 merge, self.parent_component.get_world_transform(), tess_options
1820 )

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\misc\checks.py:479, in graphics_required..wrapper(*args, **kwargs)
477 def wrapper(*args, **kwargs):
478 run_if_graphics_required()
--> 479 return method(*args, **kwargs)

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\designer\body.py:1287, in MasterBody.tessellate(self, merge, transform, tess_options)
1285 if not self._tessellation:
1286 if tess_options is not None:
-> 1287 response = self._grpc_client.services.bodies.get_tesellation_with_options(
1288 id=self.id,
1289 options=tess_options,
1290 )
1291 else:
1292 response = self._grpc_client.services.bodies.get_tesellation(
1293 id=self.id,
1294 backend_version=self._grpc_client.backend_version,
1295 )

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\errors.py:96, in protect_grpc..wrapper(*args, **kwargs)
94 # Capture gRPC exceptions
95 try:
---> 96 out = func(*args, **kwargs)
97 except (_InactiveRpcError, _MultiThreadedRendezvous) as error: # pragma: no cover
98 raise GeometryExitedError(
99 f"Geometry service connection terminated: {error.details()}"
100 ) from None

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\_grpc\_services\v0\bodies.py:638, in GRPCBodyServiceV0.get_tesellation_with_options(self, **kwargs)
636 for elem in resp:
637 for face_id, face_tess in elem.face_tessellation.items():
--> 638 tess_map[face_id] = from_grpc_tess_to_pd(face_tess)
640 return {"tessellation": tess_map}

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\misc\checks.py:479, in graphics_required..wrapper(*args, **kwargs)
477 def wrapper(*args, **kwargs):
478 run_if_graphics_required()
--> 479 return method(*args, **kwargs)

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\ansys\geometry\core\_grpc\_services\v0\conversions.py:346, in from_grpc_tess_to_pd(tess)
343 import numpy as np
344 import pyvista as pv
--> 346 return pv.PolyData(var_inp=np.array(tess.vertices).reshape(-1, 3), faces=tess.faces)

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\pyvista\core\pointset.py:834, in PolyData.init(self, var_inp, faces, n_faces, lines, n_lines, strips, n_strips, deep, force_ext, force_float, verts, n_verts)
832 if not isinstance(v, _vtk.vtkCellArray):
833 try:
--> 834 v = CellArray(v)
835 except CellSizeError as err:
836 # Raise an additional error so user knows which property triggered the error
837 msg = f'{k} cell array size is invalid.'

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\pyvista\core\cell.py:663, in CellArray.init(self, cells, n_cells, deep)
661 self.__connectivity: _vtk.vtkIdTypeArray | None = None
662 if cells is not None:
--> 663 self.cells = cells # type: ignore[assignment]
665 # deprecated 0.44.0, convert to error in 0.47.0, remove 0.48.0
666 for k, v in (('n_cells', n_cells), ('deep', deep)):

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\pyvista\core\cell.py:690, in CellArray.cells(self, cells)
687 @cells.setter
688 def cells(self: Self, cells: CellsLike) -> None:
689 cells = np.asarray(cells)
--> 690 vtk_idarr = numpy_to_idarr(cells, deep=False, return_ind=False)
691 self.ImportLegacyFormat(vtk_idarr)
692 imported_size = self.GetNumberOfConnectivityEntries()

File c:\Users\zderoche\DocumentsLocal\Projects\Stanley\CONFIDENTIAL_demo_run_sim_using_SpaceClaim\.venv\lib\site-packages\pyvista\core\utilities\cells.py:96, in numpy_to_idarr(ind, deep, return_ind)
94 if not issubclass(ind.dtype.type, (np.bool_, np.integer)):
95 msg = 'Indices must be either a mask or an integer array-like'
---> 96 raise TypeError(msg)
98 if ind.dtype == np.bool_:
99 ind = ind.nonzero()[0].astype(pyvista.ID_TYPE)

TypeError: Indices must be either a mask or an integer array-like"
}

📝 Steps to reproduce

Import a complex cad object using geometry interfaces or spaceclaim geometry services.
Then, tessellate the bodies (possibly using very demanding tessellation options).

repro data and code can be found here (private repo; reach out to [email protected] for access regarding this bug fix)
https://github.com/ZachDerocher/PySpeos-CameraSimDemo

Note: to reproduce the issue with Ansys sample data, I had to set the tessellation options to be very fine. However, with the customer's real CAD, the error occured with default tessellation options. And, in that case, the Speos meshing (in Speos UI) does work.

💻 Which operating system are you using?

Windows

📀 Which ANSYS version are you using?

Speos 2025R2 SP1
pyspeos 0.6.0

🐍 Which Python version are you using?

3.10

📦 Installed packages

aiohappyeyeballs==2.6.1
aiohttp==3.12.14
aiosignal==1.4.0
altgraph==0.17.4
ansys-api-dbu==0.3.22
ansys-api-geometry==0.4.65
ansys-api-platform-instancemanagement==1.1.3
ansys-api-speos==0.15.2
ansys-geometry-core==0.11.0
ansys-platform-instancemanagement==1.1.2
ansys-speos-core==0.6.0
ansys-tools-path==0.7.3
ansys-tools-visualization-interface==0.11.0
anyio==4.9.0
argon2-cffi==25.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==3.0.0
async-timeout==5.0.1
attrs==25.3.0
beartype==0.21.0
beautifulsoup4==4.13.4
bleach==6.2.0
certifi==2025.7.14
cffi==1.17.1
charset-normalizer==3.4.2
click==8.2.1
clr_loader==0.2.7.post0
colorama==0.4.6
comm==0.2.2
comtypes==1.4.11
contourpy==1.3.2
cycler==0.12.1
dataclasses-json==0.6.7
debugpy==1.8.15
decorator==5.2.1
defusedxml==0.7.1
Deprecated==1.2.18
docker==7.1.0
exceptiongroup==1.3.0
executing==2.2.0
fastjsonschema==2.21.1
flexcache==0.3
flexparser==0.4
fonttools==4.59.0
fqdn==1.5.1
frozenlist==1.7.0
geomdl==5.4.0
grpcio==1.70.0
grpcio-health-checking==1.67.1
idna==3.10
imageio==2.37.0
importlib_metadata==8.7.0
ipykernel==6.29.5
ipympl==0.9.7
ipython==8.37.0
ipywidgets==8.1.7
isoduration==20.11.0
jedi==0.19.2
Jinja2==3.1.6
jsonpointer==3.0.0
jsonschema==4.24.1
jsonschema-specifications==2025.4.1
jupyter-events==0.12.0
jupyter_client==8.6.3
jupyter_core==5.8.1
jupyter_server==2.16.0
jupyter_server_proxy==4.4.0
jupyter_server_terminals==0.5.3
jupyterlab_pygments==0.3.0
jupyterlab_widgets==3.0.15
kiwisolver==1.4.8
MarkupSafe==3.0.2
marshmallow==3.26.1
matplotlib==3.10.3
matplotlib-inline==0.1.7
mistune==3.1.3
more-itertools==10.7.0
msgpack==1.1.1
multidict==6.6.3
mypy_extensions==1.1.0
narwhals==1.47.1
nbclient==0.10.2
nbconvert==7.16.6
nbformat==5.10.4
nest-asyncio==1.6.0
numpy==2.2.6
opencv-python==4.12.0.88
overrides==7.7.0
packaging==25.0
pandas==2.3.1
pandocfilters==1.5.1
parso==0.8.4
pefile==2023.2.7
pillow==11.3.0
Pint==0.24.4
platformdirs==4.3.8
plotly==6.2.0
pooch==1.8.2
prometheus_client==0.22.1
prompt_toolkit==3.0.51
propcache==0.3.2
protobuf==5.29.5
psutil==7.0.0
pure_eval==0.2.3
pycparser==2.22
pygltflib==1.16.4
Pygments==2.19.2
pyinstaller==6.14.2
pyinstaller-hooks-contrib==2025.8
pyparsing==3.2.3
PyQt5==5.15.11
PyQt5-Qt5==5.15.2
PyQt5_sip==12.17.0
python-dateutil==2.9.0.post0
python-json-logger==3.3.0
pythonnet==3.0.5
pytz==2025.2
pyvista==0.45.3
pywin32==311
pywin32-ctypes==0.2.3
pywinpty==2.0.15
PyYAML==6.0.2
pyzmq==27.0.0
referencing==0.36.2
requests==2.32.4
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rpds-py==0.26.0
scipy==1.15.3
scooby==0.10.1
semver==3.0.4
Send2Trash==1.8.3
simpervisor==1.0.0
six==1.17.0
sniffio==1.3.1
soupsieve==2.7
stack-data==0.6.3
terminado==0.18.1
tinycss2==1.4.0
tornado==6.5.1
traitlets==5.14.3
trame==3.10.2
trame-client==3.9.1
trame-common==1.0.0
trame-server==3.5.0
trame-vtk==2.9.0
trame-vuetify==3.0.1
types-python-dateutil==2.9.0.20250708
typing-inspect==0.9.0
typing_extensions==4.14.1
tzdata==2025.2
uri-template==1.3.0
urllib3==2.5.0
vtk==9.4.2
wcwidth==0.2.13
webcolors==24.11.1
webencodings==0.5.1
websocket-client==1.8.0
websockets==15.0.1
widgetsnbextension==4.0.14
wrapt==1.17.2
wslink==2.3.4
yarl==1.20.1
zipp==3.23.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions