Cycles: Fix shading with autosmooth and custom normals
New logic of split_faces was leaving mesh in a proper state from Blender's point of view, but Cycles wanted loop normals to be "flushed" to vertex normals. Now we do such a flush from Cycles side again, so we don't leave bad meshes behind. Thanks Bastien for assistance here!
This commit is contained in:
parent
2c30fd83f1
commit
36c4fc1ea9
Notes:
blender-bot
2023-02-14 08:47:25 +01:00
Referenced by issue #50876, Cycles Crash - Cycles crashes before sampling when certain meshes have autosmooth enabled.
|
@ -777,6 +777,15 @@ static void create_mesh(Scene *scene,
|
|||
int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
|
||||
bool smooth = f->use_smooth() || use_loop_normals;
|
||||
|
||||
if(use_loop_normals) {
|
||||
BL::Array<float, 12> loop_normals = f->split_normals();
|
||||
for(int i = 0; i < n; i++) {
|
||||
N[vi[i]] = make_float3(loop_normals[i * 3],
|
||||
loop_normals[i * 3 + 1],
|
||||
loop_normals[i * 3 + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create triangles.
|
||||
*
|
||||
* NOTE: Autosmooth is already taken care about.
|
||||
|
|
|
@ -79,7 +79,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
|
|||
me.calc_normals_split();
|
||||
}
|
||||
else {
|
||||
me.split_faces();
|
||||
me.split_faces(false);
|
||||
}
|
||||
}
|
||||
if(subdivision_type == Mesh::SUBDIVISION_NONE) {
|
||||
|
|
|
@ -131,7 +131,7 @@ bool BKE_mesh_uv_cdlayer_rename(struct Mesh *me, const char *old_name, const cha
|
|||
|
||||
float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3];
|
||||
|
||||
void BKE_mesh_split_faces(struct Mesh *mesh);
|
||||
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
|
||||
|
||||
struct Mesh *BKE_mesh_new_from_object(struct Main *bmain, struct Scene *sce, struct Object *ob,
|
||||
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
|
||||
|
|
|
@ -2338,7 +2338,7 @@ static void split_faces_split_new_edges(
|
|||
* NOTE: Will leave CD_NORMAL loop data layer which is
|
||||
* used by render engines to set shading up.
|
||||
*/
|
||||
void BKE_mesh_split_faces(Mesh *mesh)
|
||||
void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
|
||||
{
|
||||
const int num_polys = mesh->totpoly;
|
||||
|
||||
|
@ -2392,7 +2392,9 @@ void BKE_mesh_split_faces(Mesh *mesh)
|
|||
/* Note: after this point mesh is expected to be valid again. */
|
||||
|
||||
/* CD_NORMAL is expected to be temporary only. */
|
||||
CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop);
|
||||
if (free_loop_normals) {
|
||||
CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop);
|
||||
}
|
||||
|
||||
if (lnors_spacearr) {
|
||||
/* Also frees new_verts/edges temp data, since we used its memarena to allocate them. */
|
||||
|
|
|
@ -619,7 +619,7 @@ static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob)
|
|||
ED_object_editmode_load(ob);
|
||||
|
||||
Mesh *me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0);
|
||||
BKE_mesh_split_faces(me);
|
||||
BKE_mesh_split_faces(me, true);
|
||||
|
||||
return me;
|
||||
}
|
||||
|
|
|
@ -209,6 +209,11 @@ static void rna_Mesh_flip_normals(Mesh *mesh)
|
|||
DAG_id_tag_update(&mesh->id, 0);
|
||||
}
|
||||
|
||||
static void rna_Mesh_split_faces(Mesh *mesh, int free_loop_normals)
|
||||
{
|
||||
BKE_mesh_split_faces(mesh, free_loop_normals != 0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void RNA_api_mesh(StructRNA *srna)
|
||||
|
@ -240,8 +245,10 @@ void RNA_api_mesh(StructRNA *srna)
|
|||
func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split");
|
||||
RNA_def_function_ui_description(func, "Free split vertex normals");
|
||||
|
||||
func = RNA_def_function(srna, "split_faces", "BKE_mesh_split_faces");
|
||||
func = RNA_def_function(srna, "split_faces", "rna_Mesh_split_faces");
|
||||
RNA_def_function_ui_description(func, "Split faces based on the edge angle");
|
||||
RNA_def_boolean(func, "free_loop_normals", 1, "Free Loop Notmals",
|
||||
"Free loop normals custom data layer");
|
||||
|
||||
func = RNA_def_function(srna, "calc_tangents", "rna_Mesh_calc_tangents");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
|
|
Loading…
Reference in New Issue