Geometry Nodes: add empty material slot to new meshes

This fixes T88455 by adding an empty material slot to newly
generated meshes. This allows the object to overwrite the
"default" material without any extra nodes. Technically,
all polygons reference the material index 0 already, so it
makes sense to add a material slot for this material index.

Differential Revision: https://developer.blender.org/D11439
This commit is contained in:
Jacques Lucke 2021-06-01 15:24:29 +02:00
parent 8a63466ca3
commit 6583fb67c6
12 changed files with 37 additions and 0 deletions

View File

@ -113,6 +113,7 @@ void BKE_id_material_clear(struct Main *bmain, struct ID *id);
struct Material *BKE_object_material_get_eval(struct Object *ob, short act);
int BKE_object_material_count_eval(struct Object *ob);
void BKE_id_material_eval_assign(struct ID *id, int slot, struct Material *material);
void BKE_id_material_eval_ensure_default_slot(struct ID *id);
/* rendering */

View File

@ -770,6 +770,7 @@ int BKE_object_material_count_eval(Object *ob)
void BKE_id_material_eval_assign(ID *id, int slot, Material *material)
{
BLI_assert(slot >= 1);
Material ***materials_ptr = BKE_id_material_array_p(id);
short *len_ptr = BKE_id_material_len_p(id);
if (ELEM(NULL, materials_ptr, len_ptr)) {
@ -793,6 +794,21 @@ void BKE_id_material_eval_assign(ID *id, int slot, Material *material)
(*materials_ptr)[slot_index] = material;
}
/**
* Add an empty material slot if the id has no material slots. This material slot allows the
* material to be overwritten by object-linked materials.
*/
void BKE_id_material_eval_ensure_default_slot(ID *id)
{
short *len_ptr = BKE_id_material_len_p(id);
if (len_ptr == NULL) {
return;
}
if (*len_ptr == 0) {
BKE_id_material_eval_assign(id, 1, NULL);
}
}
Material *BKE_gpencil_material(Object *ob, short act)
{
Material *ma = BKE_object_material_get(ob, act);

View File

@ -21,6 +21,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_spline.hh"
@ -296,6 +297,7 @@ static void geo_node_curve_to_mesh_exec(GeoNodeExecParams params)
Mesh *mesh = curve_to_mesh_calculate(*curve_set.get_curve_for_read(),
(profile_curve == nullptr) ? vert_curve : *profile_curve);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "UI_interface.h"
@ -214,6 +215,7 @@ static void geo_node_mesh_primitive_circle_exec(GeoNodeExecParams params)
}
Mesh *mesh = create_circle_mesh(radius, verts_num, fill_type);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
BLI_assert(BKE_mesh_is_valid(mesh));

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "UI_interface.h"
@ -561,6 +562,7 @@ static void geo_node_mesh_primitive_cone_exec(GeoNodeExecParams params)
Mesh *mesh = create_cylinder_or_cone_mesh(
radius_top, radius_bottom, depth, verts_num, fill_type);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
/* Transform the mesh so that the base of the cone is at the origin. */
BKE_mesh_translate(mesh, float3(0.0f, 0.0f, depth * 0.5f), false);

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "bmesh.h"
@ -64,6 +65,7 @@ static void geo_node_mesh_primitive_cube_exec(GeoNodeExecParams params)
const float size = params.extract_input<float>("Size");
Mesh *mesh = create_cube_mesh(size);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "UI_interface.h"
@ -75,6 +76,7 @@ static void geo_node_mesh_primitive_cylinder_exec(GeoNodeExecParams params)
/* The cylinder is a special case of the cone mesh where the top and bottom radius are equal. */
Mesh *mesh = create_cylinder_or_cone_mesh(radius, radius, depth, verts_num, fill_type);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "UI_interface.h"
@ -167,6 +168,7 @@ static void geo_node_mesh_primitive_grid_exec(GeoNodeExecParams params)
Mesh *mesh = create_grid_mesh(verts_x, verts_y, size_x, size_y);
BLI_assert(BKE_mesh_is_valid(mesh));
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "bmesh.h"
@ -67,6 +68,7 @@ static void geo_node_mesh_primitive_ico_sphere_exec(GeoNodeExecParams params)
const float radius = params.extract_input<float>("Radius");
Mesh *mesh = create_ico_sphere_mesh(subdivisions, radius);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "UI_interface.h"
@ -165,6 +166,7 @@ static void geo_node_mesh_primitive_line_exec(GeoNodeExecParams params)
const int count = params.extract_input<int>("Count");
mesh = create_line_mesh(start, delta, count);
}
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}

View File

@ -17,6 +17,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "UI_interface.h"
@ -296,6 +297,7 @@ static void geo_node_mesh_primitive_uv_sphere_exec(GeoNodeExecParams params)
const float radius = params.extract_input<float>("Radius");
Mesh *mesh = create_uv_sphere_mesh(radius, segments_num, rings_num);
BKE_id_material_eval_ensure_default_slot(&mesh->id);
params.set_output("Geometry", GeometrySet::create_with_mesh(mesh));
}

View File

@ -23,6 +23,7 @@
#include "node_geometry_util.hh"
#include "BKE_lib_id.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_volume.h"
@ -134,6 +135,7 @@ static void create_mesh_from_volume(GeometrySet &geometry_set_in,
if (mesh == nullptr) {
return;
}
BKE_id_material_eval_ensure_default_slot(&mesh->id);
MeshComponent &dst_component = geometry_set_out.get_component_for_write<MeshComponent>();
dst_component.replace(mesh);
}