[Bf-blender-cvs] [5e6f3b85646] master: Geometry Nodes: take materials into account when joining geometries

Jacques Lucke noreply at git.blender.org
Wed May 19 11:03:06 CEST 2021


Commit: 5e6f3b85646fe96031c3eafe65e9bc7b55468685
Author: Jacques Lucke
Date:   Wed May 19 11:02:25 2021 +0200
Branches: master
https://developer.blender.org/rB5e6f3b85646fe96031c3eafe65e9bc7b55468685

Geometry Nodes: take materials into account when joining geometries

Materials are now kept intact when using the Join Geometry node
or when realizing instaces.

===================================================================

M	source/blender/blenkernel/BKE_material.h
M	source/blender/blenkernel/intern/geometry_set_instances.cc
M	source/blender/blenkernel/intern/material.c
M	source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 96aae2d2d42..ef1de891bfe 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -109,6 +109,7 @@ void BKE_id_material_clear(struct Main *bmain, struct ID *id);
 /* eval api */
 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);
 
 /* rendering */
 
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index b6ee0337dbf..97892075eca 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -15,6 +15,7 @@
  */
 
 #include "BKE_geometry_set_instances.hh"
+#include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_wrapper.h"
 #include "BKE_modifier.h"
@@ -361,6 +362,8 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
   int64_t cd_dirty_poly = 0;
   int64_t cd_dirty_edge = 0;
   int64_t cd_dirty_loop = 0;
+  VectorSet<Material *> materials;
+
   for (const GeometryInstanceGroup &set_group : set_groups) {
     const GeometrySet &set = set_group.geometry_set;
     const int tot_transforms = set_group.transforms.size();
@@ -374,6 +377,10 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
       cd_dirty_poly |= mesh.runtime.cd_dirty_poly;
       cd_dirty_edge |= mesh.runtime.cd_dirty_edge;
       cd_dirty_loop |= mesh.runtime.cd_dirty_loop;
+      for (const int slot_index : IndexRange(mesh.totcol)) {
+        Material *material = mesh.mat[slot_index];
+        materials.add(material);
+      }
     }
     if (convert_points_to_vertices && set.has_pointcloud()) {
       const PointCloud &pointcloud = *set.get_pointcloud_for_read();
@@ -396,6 +403,10 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
       break;
     }
   }
+  for (const int i : IndexRange(materials.size())) {
+    Material *material = materials[i];
+    BKE_id_material_eval_assign(&new_mesh->id, i + 1, material);
+  }
   new_mesh->runtime.cd_dirty_vert = cd_dirty_vert;
   new_mesh->runtime.cd_dirty_poly = cd_dirty_poly;
   new_mesh->runtime.cd_dirty_edge = cd_dirty_edge;
@@ -409,6 +420,14 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
     const GeometrySet &set = set_group.geometry_set;
     if (set.has_mesh()) {
       const Mesh &mesh = *set.get_mesh_for_read();
+
+      Array<int> material_index_map(mesh.totcol);
+      for (const int i : IndexRange(mesh.totcol)) {
+        Material *material = mesh.mat[i];
+        const int new_material_index = materials.index_of(material);
+        material_index_map[i] = new_material_index;
+      }
+
       for (const float4x4 &transform : set_group.transforms) {
         for (const int i : IndexRange(mesh.totvert)) {
           const MVert &old_vert = mesh.mvert[i];
@@ -438,6 +457,13 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
           MPoly &new_poly = new_mesh->mpoly[poly_offset + i];
           new_poly = old_poly;
           new_poly.loopstart += loop_offset;
+          if (old_poly.mat_nr >= 0 && old_poly.mat_nr < mesh.totcol) {
+            new_poly.mat_nr = material_index_map[new_poly.mat_nr];
+          }
+          else {
+            /* The material index was invalid before. */
+            new_poly.mat_nr = 0;
+          }
         }
 
         vert_offset += mesh.totvert;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 73afea98163..73a7a69f5a5 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -768,6 +768,31 @@ int BKE_object_material_count_eval(Object *ob)
   return len_p ? *len_p : 0;
 }
 
+void BKE_id_material_eval_assign(ID *id, int slot, Material *material)
+{
+  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)) {
+    BLI_assert_unreachable();
+    return;
+  }
+
+  const int slot_index = slot - 1;
+  const int old_length = *len_ptr;
+
+  if (slot_index >= old_length) {
+    /* Need to grow slots array. */
+    const int new_length = slot_index + 1;
+    *materials_ptr = MEM_reallocN(*materials_ptr, sizeof(void *) * new_length);
+    *len_ptr = new_length;
+    for (int i = old_length; i < new_length; i++) {
+      (*materials_ptr)[i] = NULL;
+    }
+  }
+
+  (*materials_ptr)[slot_index] = material;
+}
+
 Material *BKE_gpencil_material(Object *ob, short act)
 {
   Material *ma = BKE_object_material_get(ob, act);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index a6e78048ea6..915ebc1e1f2 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -14,6 +14,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_pointcloud.h"
@@ -57,6 +58,8 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent
   int64_t cd_dirty_edge = 0;
   int64_t cd_dirty_loop = 0;
 
+  VectorSet<Material *> materials;
+
   for (const MeshComponent *mesh_component : src_components) {
     const Mesh *mesh = mesh_component->get_for_read();
     totverts += mesh->totvert;
@@ -67,12 +70,22 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent
     cd_dirty_poly |= mesh->runtime.cd_dirty_poly;
     cd_dirty_edge |= mesh->runtime.cd_dirty_edge;
     cd_dirty_loop |= mesh->runtime.cd_dirty_loop;
+
+    for (const int slot_index : IndexRange(mesh->totcol)) {
+      Material *material = mesh->mat[slot_index];
+      materials.add(material);
+    }
   }
 
   const Mesh *first_input_mesh = src_components[0]->get_for_read();
   Mesh *new_mesh = BKE_mesh_new_nomain(totverts, totedges, 0, totloops, totpolys);
   BKE_mesh_copy_settings(new_mesh, first_input_mesh);
 
+  for (const int i : IndexRange(materials.size())) {
+    Material *material = materials[i];
+    BKE_id_material_eval_assign(&new_mesh->id, i + 1, material);
+  }
+
   new_mesh->runtime.cd_dirty_vert = cd_dirty_vert;
   new_mesh->runtime.cd_dirty_poly = cd_dirty_poly;
   new_mesh->runtime.cd_dirty_edge = cd_dirty_edge;
@@ -88,6 +101,13 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent
       continue;
     }
 
+    Array<int> material_index_map(mesh->totcol);
+    for (const int i : IndexRange(mesh->totcol)) {
+      Material *material = mesh->mat[i];
+      const int new_material_index = materials.index_of(material);
+      material_index_map[i] = new_material_index;
+    }
+
     for (const int i : IndexRange(mesh->totvert)) {
       const MVert &old_vert = mesh->mvert[i];
       MVert &new_vert = new_mesh->mvert[vert_offset + i];
@@ -113,6 +133,13 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent
       MPoly &new_poly = new_mesh->mpoly[poly_offset + i];
       new_poly = old_poly;
       new_poly.loopstart += loop_offset;
+      if (old_poly.mat_nr >= 0 && old_poly.mat_nr < mesh->totcol) {
+        new_poly.mat_nr = material_index_map[new_poly.mat_nr];
+      }
+      else {
+        /* The material index was invalid before. */
+        new_poly.mat_nr = 0;
+      }
     }
 
     vert_offset += mesh->totvert;



More information about the Bf-blender-cvs mailing list