Fix T54202: Cycles crash rendering empty mesh volume after recent optimization.
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 2 Mar 2018 21:38:59 +0000 (22:38 +0100)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Fri, 2 Mar 2018 22:10:27 +0000 (23:10 +0100)
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh_volume.cpp

index 23b855acdc951bac76bcf3714e1150e1e0900071..47d24970949eeef220f4df29d71565f62957239b 100644 (file)
@@ -561,8 +561,9 @@ void Mesh::clear(bool preserve_voxel_data)
        subd_attributes.clear();
        attributes.clear(preserve_voxel_data);
 
        subd_attributes.clear();
        attributes.clear(preserve_voxel_data);
 
+       used_shaders.clear();
+
        if(!preserve_voxel_data) {
        if(!preserve_voxel_data) {
-               used_shaders.clear();
                geometry_flags = GEOMETRY_NONE;
        }
 
                geometry_flags = GEOMETRY_NONE;
        }
 
index be43154fd93e4791d1b72d018facfd3bca5e2706..f2347c7961094d331555bca7ce9f2b49f3c3b231 100644 (file)
@@ -393,9 +393,6 @@ void VolumeMeshBuilder::convert_quads_to_tris(const vector<QuadData> &quads,
 
 /* ************************************************************************** */
 
 
 /* ************************************************************************** */
 
-/* For debugging: render the created mesh using the default diffuse shader. */
-//#define RENDER_DIFFUSE
-
 struct VoxelAttributeGrid {
        float *data;
        int channels;
 struct VoxelAttributeGrid {
        float *data;
        int channels;
@@ -443,6 +440,8 @@ void MeshManager::create_volume_mesh(Scene *scene,
                return;
        }
 
                return;
        }
 
+       /* Compute padding. */
+       Shader *volume_shader = NULL;
        int pad_size = 0;
 
        foreach(Shader *shader, mesh->used_shaders) {
        int pad_size = 0;
 
        foreach(Shader *shader, mesh->used_shaders) {
@@ -450,12 +449,20 @@ void MeshManager::create_volume_mesh(Scene *scene,
                        continue;
                }
 
                        continue;
                }
 
+               volume_shader = shader;
+
                if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
                        pad_size = max(1, pad_size);
                }
                else if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
                        pad_size = max(2, pad_size);
                }
                if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
                        pad_size = max(1, pad_size);
                }
                else if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
                        pad_size = max(2, pad_size);
                }
+
+               break;
+       }
+
+       if(!volume_shader) {
+               return;
        }
 
        /* Compute start point and cell size from transform. */
        }
 
        /* Compute start point and cell size from transform. */
@@ -477,6 +484,7 @@ void MeshManager::create_volume_mesh(Scene *scene,
        volume_params.cell_size = cell_size;
        volume_params.pad_size = pad_size;
 
        volume_params.cell_size = cell_size;
        volume_params.pad_size = pad_size;
 
+       /* Build bounding mesh around non-empty volume cells. */
        VolumeMeshBuilder builder(&volume_params);
        const float isovalue = mesh->volume_isovalue;
 
        VolumeMeshBuilder builder(&volume_params);
        const float isovalue = mesh->volume_isovalue;
 
@@ -540,26 +548,22 @@ void MeshManager::create_volume_mesh(Scene *scene,
                }
        }
 
                }
        }
 
+       /* Create mesh. */
        vector<float3> vertices;
        vector<int> indices;
        vector<float3> face_normals;
        builder.create_mesh(vertices, indices, face_normals);
 
        vector<float3> vertices;
        vector<int> indices;
        vector<float3> face_normals;
        builder.create_mesh(vertices, indices, face_normals);
 
-#ifdef RENDER_DIFFUSE
-       int shader = mesh->used_shaders[0]->id;
-#else
-       int shader = mesh->shader[0];
-#endif
-
        mesh->clear(true);
        mesh->reserve_mesh(vertices.size(), indices.size()/3);
        mesh->clear(true);
        mesh->reserve_mesh(vertices.size(), indices.size()/3);
+       mesh->used_shaders.push_back(volume_shader);
 
        for(size_t i = 0; i < vertices.size(); ++i) {
                mesh->add_vertex(vertices[i]);
        }
 
        for(size_t i = 0; i < indices.size(); i += 3) {
 
        for(size_t i = 0; i < vertices.size(); ++i) {
                mesh->add_vertex(vertices[i]);
        }
 
        for(size_t i = 0; i < indices.size(); i += 3) {
-               mesh->add_triangle(indices[i], indices[i + 1], indices[i + 2], shader, false);
+               mesh->add_triangle(indices[i], indices[i + 1], indices[i + 2], 0, false);
        }
 
        Attribute *attr_fN = mesh->attributes.add(ATTR_STD_FACE_NORMAL);
        }
 
        Attribute *attr_fN = mesh->attributes.add(ATTR_STD_FACE_NORMAL);
@@ -569,6 +573,7 @@ void MeshManager::create_volume_mesh(Scene *scene,
                fN[i] = face_normals[i];
        }
 
                fN[i] = face_normals[i];
        }
 
+       /* Print stats. */
        VLOG(1) << "Memory usage volume mesh: "
                        << ((vertices.size() + face_normals.size())*sizeof(float3) + indices.size()*sizeof(int))/(1024.0*1024.0)
                        << "Mb.";
        VLOG(1) << "Memory usage volume mesh: "
                        << ((vertices.size() + face_normals.size())*sizeof(float3) + indices.size()*sizeof(int))/(1024.0*1024.0)
                        << "Mb.";