diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 0467d2e96e5e..deb0ca34302c 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -1382,6 +1382,7 @@ def _generate_normals(polygons): v2 = np.empty((len(polygons), 3)) for poly_i, ps in enumerate(polygons): n = len(ps) + ps = np.asarray(ps) i1, i2, i3 = 0, n//3, 2*n//3 v1[poly_i, :] = ps[i1, :] - ps[i2, :] v2[poly_i, :] = ps[i2, :] - ps[i3, :] diff --git a/lib/mpl_toolkits/mplot3d/tests/test_art3d.py b/lib/mpl_toolkits/mplot3d/tests/test_art3d.py index f4f7067b76bb..174c12608ae9 100644 --- a/lib/mpl_toolkits/mplot3d/tests/test_art3d.py +++ b/lib/mpl_toolkits/mplot3d/tests/test_art3d.py @@ -3,7 +3,11 @@ import matplotlib.pyplot as plt from matplotlib.backend_bases import MouseEvent -from mpl_toolkits.mplot3d.art3d import Line3DCollection, _all_points_on_plane +from mpl_toolkits.mplot3d.art3d import ( + Line3DCollection, + Poly3DCollection, + _all_points_on_plane, +) def test_scatter_3d_projection_conservation(): @@ -85,3 +89,14 @@ def test_all_points_on_plane(): # All points lie on a plane points = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0], [1, 2, 0]]) assert _all_points_on_plane(*points.T) + + +def test_generate_normals(): + # Smoke test for https://github.com/matplotlib/matplotlib/issues/29156 + vertices = ((0, 0, 0), (0, 5, 0), (5, 5, 0), (5, 0, 0)) + shape = Poly3DCollection([vertices], edgecolors='r', shade=True) + + fig = plt.figure() + ax = fig.add_subplot(projection='3d') + ax.add_collection3d(shape) + plt.draw()