nmwsharp / polyscope

A C++ & Python viewer for 3D data like meshes and point clouds
https://polyscope.run
MIT License
1.76k stars 190 forks source link

Random crashes with `ValueError: Attribute a_vertexNormals has no buffer attached` #264

Closed classner closed 5 months ago

classner commented 5 months ago

Hi!

Thanks a lot for the amazing package! I use it to visualize a scene with a point cloud (one color quantity attached) and a few of camera views (images attached). Unpredictably, the visualizer is crashing with the error ValueError: Attribute a_vertexNormals has no buffer attached. It is unfortunately not perfectly reproducible. In case it matters: I'm running polyscope on MacOS with the PyPI build, on version 2.1.0.

nmwsharp commented 5 months ago

Uh oh, that's no good, thanks for reporting. This is the first I've heard of this bug.

Two questions to help me debug:

classner commented 5 months ago

Found a reproducer! It happens only when the camera views have been added to the scene (it doesn't matter whether they're enabled or not). Then the crash happens when clicking the scene, as you pointed above: probably something goes wrong when initializing the buffer for picking things. Nothing interesting in the logs (no error message) except for "compiling shader program", the last one is:

[polyscope] compiling shader program $PROGRAMNAME: MESH#  $RULES: MESH_PROPAGATE_PICK_SIMPLE#   $DEFAULTS: GLSL_VERSION# GLOBAL_FRAGMENT_FILTER# SHADE_COLOR# LIGHT_PASSTHRU# 
Program text:

// tag ${ GLSL_VERSION }$
// from rule: GLSL_VERSION
#version 330 core

        uniform mat4 u_modelView;
        uniform mat4 u_projMatrix;

        in uint a_faceInds;

        in vec3 a_vertexPositions;
        in vec3 a_vertexNormals;
        in vec3 a_barycoord;
        out vec3 a_barycoordToFrag;
        out vec3 a_vertexNormalToFrag;

// tag ${ VERT_DECLARATIONS }$
// from rule: MESH_PROPAGATE_PICK_SIMPLE

          in vec3 a_vertexColors[3];
          in vec3 a_faceColor;
          flat out vec3 vertexColors[3];
          flat out vec3 faceColor;

        void main()
        {
            gl_Position = u_projMatrix * u_modelView * vec4(a_vertexPositions,1.);

            a_vertexNormalToFrag = mat3(u_modelView) * a_vertexNormals;
            a_barycoordToFrag = a_barycoord;

// tag ${ VERT_ASSIGNMENTS }$
// from rule: MESH_PROPAGATE_PICK_SIMPLE

          for(int i = 0; i < 3; i++) {
              vertexColors[i] = a_vertexColors[i];
          }
          faceColor = a_faceColor;

        }

Program text:

// tag ${ GLSL_VERSION }$
// from rule: GLSL_VERSION
#version 330 core

        in vec3 a_vertexNormalToFrag;
        in vec3 a_barycoordToFrag;

        layout(location = 0) out vec4 outputF;

// tag ${ FRAG_DECLARATIONS }$
// from rule: MESH_PROPAGATE_PICK_SIMPLE

          flat in vec3 vertexColors[3];
          flat in vec3 faceColor;

        void main()
        {
           float depth = gl_FragCoord.z;

// tag ${ GLOBAL_FRAGMENT_FILTER_PREP }$

// tag ${ GLOBAL_FRAGMENT_FILTER }$
// from rule: GLOBAL_FRAGMENT_FILTER
// do nothing, for now

           // Shading
           vec3 shadeNormal = a_vertexNormalToFrag;

// tag ${ GENERATE_SHADE_VALUE }$
// from rule: MESH_PROPAGATE_PICK_SIMPLE

          // Parameters defining the pick shape (in barycentric 0-1 units)
          float vertRadius = 0.2;

          vec3 shadeColor = faceColor;

          // Test vertices and corners
          for(int i = 0; i < 3; i++) {
              if(a_barycoordToFrag[i] > 1.0-vertRadius) {
                shadeColor = vertexColors[i];
              }
          }

// tag ${ GENERATE_SHADE_COLOR }$
// from rule: SHADE_COLOR
vec3 albedoColor = shadeColor;

           // Handle the wireframe

// tag ${ APPLY_WIREFRAME }$

           // Lighting

// tag ${ PERTURB_SHADE_NORMAL }$

// tag ${ GENERATE_LIT_COLOR }$
// from rule: LIGHT_PASSTHRU
vec3 litColor = albedoColor;

           // Set alpha
           float alphaOut = 1.0;

// tag ${ GENERATE_ALPHA }$

// tag ${ PERTURB_LIT_COLOR }$

           // Write output
           litColor *= alphaOut; // premultiplied alpha
           outputF = vec4(litColor, alphaOut);
        }
classner commented 5 months ago

Hi Nicholas!

Any leads on this? :) Just checking in since it's been a recurring issue for me... I am pretty confident your hunch about building the picking buffers is correct!

nmwsharp commented 5 months ago

Thanks for the helpful info! Looks like that was indeed almost-certainly the underlying problem.

Should be fixed in the main repo as of #267. It sounds like you're using Polyscope via Python on PyPi---I'll need to rebuild wheels and deploy a new version for the fixes to propagate there, I should be able to do that in the next few days.

classner commented 5 months ago

That is fantastic - thanks so much for looking into it! :)