changeset 25871:d8e7532edf5f

Don't render with lighting if dimensions of normals don't match. * gl-render.cc: Check dimensions of facenormals and vertexnormals and only render with lighting if dimensions match dimensions of coordinates. * graphics.cc (surface::properties::update_face_normals): Move calculation of constant out of loop.
author Markus Mützel <markus.muetzel@gmx.de>
date Sun, 09 Sep 2018 18:01:06 +0200
parents afab7be1466a
children c22a310c3294
files libinterp/corefcn/gl-render.cc libinterp/corefcn/graphics.cc
diffstat 2 files changed, 27 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/gl-render.cc	Sun Sep 09 14:08:35 2018 +0200
+++ b/libinterp/corefcn/gl-render.cc	Sun Sep 09 18:01:06 2018 +0200
@@ -2392,7 +2392,15 @@
 
     NDArray c;
     const NDArray vn = props.get_vertexnormals ().array_value ();
+    dim_vector vn_dims = vn.dims ();
+    bool has_vertex_normals = ((vn_dims(0) == z.rows ()) &&
+                               (vn_dims(1) == z.columns ()) &&
+                               (vn_dims(2) == 3));
     const NDArray fn = props.get_facenormals ().array_value ();
+    dim_vector fn_dims = fn.dims ();
+    bool has_face_normals = ((fn_dims(0) == z.rows () - 1) &&
+                             (fn_dims(1) == z.columns () - 1) &&
+                             (fn_dims(2) == 3));
 
     // FIXME: handle transparency
     Matrix a;
@@ -2402,14 +2410,18 @@
                     (props.facecolor_is ("interp") ? 2 :
                      (props.facecolor_is ("texturemap") ? 3 : -1))));
     int fl_mode = (props.facelighting_is ("none") ? 0 :
-                   (props.facelighting_is ("flat") ? 1 : 2));
+                   (props.facelighting_is ("flat") ?
+                    (has_face_normals ? 1 : 0) :
+                    (has_vertex_normals ? 2 : 0)));
     int fa_mode = (props.facealpha_is_double () ? 0 :
                    (props.facealpha_is ("flat") ? 1 : 2));
     int ec_mode = (props.edgecolor_is_rgb () ? 0 :
                    (props.edgecolor_is ("flat") ? 1 :
                     (props.edgecolor_is ("interp") ? 2 : -1)));
     int el_mode = (props.edgelighting_is ("none") ? 0 :
-                   (props.edgelighting_is ("flat") ? 1 : 2));
+                   (props.edgelighting_is ("flat") ?
+                    (has_face_normals ? 1 : 0) :
+                    (has_vertex_normals ? 2 : 0)));
     int ea_mode = (props.edgealpha_is_double () ? 0 :
                    (props.edgealpha_is ("flat") ? 1 : 2));
     int bfl_mode = (props.backfacelighting_is ("lit") ? 0 :
--- a/libinterp/corefcn/graphics.cc	Sun Sep 09 14:08:35 2018 +0200
+++ b/libinterp/corefcn/graphics.cc	Sun Sep 09 18:01:06 2018 +0200
@@ -9527,13 +9527,18 @@
       if (x.columns () != p || y.rows () != q)
         return;
 
-      NDArray n (dim_vector (q-1, p-1, 3), 0.0);
-
       bool x_mat = (x.rows () == q);
       bool y_mat = (y.columns () == p);
-      
-      double dx = x(1,1) - x(0,0);
-      double dy = y(1,1) - y(0,0);
+
+      double dx, dy;
+      dx = dy = 1;
+      if (x_mat)
+        dx = x(0,1) - x(0,0);
+      if (y_mat)
+        dy = y(1,0) - y(0,0);
+
+      double nz = 2 * dx * dy;
+      NDArray n (dim_vector (q-1, p-1, 3), nz);
 
       int i1, i2, j1, j2;
       i1 = i2 = 0;
@@ -9555,22 +9560,20 @@
                   j2 = j + 1;
                 }
 
-              double& nx = n(j, i, 0);
-              double& ny = n(j, i, 1);
-              double& nz = n(j, i, 2);
+              double& nx = n(j,i,0);
+              double& ny = n(j,i,1);
 
               // calculate face normal with Newell's method
               // https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal#Newell.27s_Method
               
               nx = dy * (z(j1,i1) + z(j2,i1) - z(j1,i2) - z(j2,i2));
               ny = dx * (z(j1,i1) + z(j1,i2) - z(j2,i1) - z(j2,i2));
-              nz = 2 * dx * dy;
 
               double d = std::max (std::max (fabs (nx), fabs (ny)), fabs (nz));
 
               nx /= d;
               ny /= d;
-              nz /= d;
+              n(j,i,2) /= d;
             }
         }
       facenormals = n;