Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using 4D data for a mesh an IndexError happens when the selected Shape layer doesn't have any points at the current frame. #6870

Closed
odinsbane opened this issue Apr 25, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@odinsbane
Copy link
Contributor

odinsbane commented Apr 25, 2024

🐛 Bug Report

I created two meshes that have 4 dimensions, [t, z, y, x]. The time slider can be used to change mesh vertexes that are shown. If the mesh in the layers selection pane doesn't have any points in the current time frame then an IndexError is thrown.

Everything still appears ok, but the error is annoying.

File ~/linux-desktop/napari/napari-venv/lib/python3.10/site-packages/napari/layers/surface/surface.py:677, in Surface._get_value_3d(self=<Surface layer 'Test'>, start_point=<class 'numpy.ndarray'> (4,) float64, end_point=<class 'numpy.ndarray'> (4,) float64, dims_displayed=[1, 2, 3])
    670 start_position, ray_direction = nd_line_segment_to_displayed_data_ray(
    671     start_point=start_point,
    672     end_point=end_point,
    673     dims_displayed=dims_displayed,
    674 )
    676 # get the mesh triangles
--> 677 mesh_triangles = self._data_view[self._view_faces]
        self._data_view = <class 'numpy.ndarray'> (4, 3) int64
        self._view_faces = <class 'numpy.ndarray'> (0, 3) float64
        self = <Surface layer 'Test' at 0x7f5c0452f5b0>
    679 # get the triangles intersection
    680 intersection_index, intersection = find_nearest_triangle_intersection(
    681     ray_position=start_position,
    682     ray_direction=ray_direction,
    683     triangles=mesh_triangles,
    684 )

IndexError: arrays used as indices must be of integer (or boolean) type

As can be seen, self._view_faces is a float64. This only occurs if the select layer has no points in the current frame.

💡 Steps to Reproduce

Here is an example. I was updating the nD_surface.py example

import numpy as np

import napari

# create the viewer and window
viewer = napari.Viewer(ndisplay=3)

def triangles( t ):
    o = t*4;

    data = [[t, 0, 0, 0], [t, 0, 20, 10], [t, 10, 0, -10], [t, 10, 10, -10]]
    faces = [[0 + o, 1 + o, 2 + o], [1 + o, 2 + o, 3 + o]]
    return data, faces

data = []
faces = []
for t in range(10):
    di, fi = triangles( t )
    data += di
    faces += fi
data = np.array(data)
faces = np.array(faces)
values = np.linspace(0, 1, len(data))

# add the surface
layer = viewer.add_surface((data, faces, values))

d2, f2 = triangles(0)
l2 = viewer.add_surface(
    (np.array(d2) + 1, np.array(f2), np.linspace(0, 1, len(d2))) )
l2.name = "Test"

if __name__ == '__main__':
    napari.run()

That will show errors until either, the slider is moved to timepoint 1 and "Test" has points in the frame, or the other layer is selected.

💡 Expected Behavior

I do not expect any errors to be thrown.

🌎 Environment

napari version 0.4.19.post1
WSL2 Ubuntu on Windows 10

Installed through python3 -m venv napari-env then ./naprai-env/bin/pip install napari[all]

I can provide more details.

I also clones the main branch, and installed it into the same environment using pip install -e napari-clone/ and I have the same results.

💡 Additional Context

I can see the issue in the current main when there are no faces being shown self._view_faces = np.zeros((0, 3)) causes self._view_faces to become a float64. This can be fixed by changing it to self._view_faces = np.zeros((0, 3), dtype=int) although maybe the real issue is why it only happens if the layer is selected in the layers panel.

@odinsbane odinsbane added the bug Something isn't working label Apr 25, 2024
psobolewskiPhD pushed a commit to psobolewskiPhD/napari that referenced this issue Apr 26, 2024
# Description

During development of napari#6780 I have found that
`napari.utils.misc.is_iterable` function wrongly return that object is
iterable, when it does not have `__iter__` method. This PR fixes it and
is extracted from napari#6870 to reduce diff.

This PR adds basic tests, fix handling affine in split_channels (as
affine could be `Affine` or `np.ndarray`).

---------

Co-authored-by: Lorenzo Gaifas <brisvag@gmail.com>
jni pushed a commit that referenced this issue May 15, 2024
…ertices (#6874)

This makes two small updates. One, it makes sure that mesh indices are
integer which causes issues 6870 and two it checks if there are any
displayed vertices before updating the normals that causes issue 6872.

# References and relevant issues

#6872
#6870


# Description

It fixes the two bugs described above. **Bug #6872 is not present in the
0.4.19 release!**

---------

Co-authored-by: Matt <m.b.smith-5@umcutrecht.nl>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>
@jni
Copy link
Member

jni commented May 15, 2024

Fixed by #6874

@jni jni closed this as completed May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants