[Bf-blender-cvs] [4a70561bbdc] master: Fix T97164: Voxel remesh only supports vertex float color attributes.

Joseph Eagar noreply at git.blender.org
Wed Apr 13 09:48:15 CEST 2022


Commit: 4a70561bbdc97aa40c5817a573bf3515e3f95769
Author: Joseph Eagar
Date:   Wed Apr 13 00:46:36 2022 -0700
Branches: master
https://developer.blender.org/rB4a70561bbdc97aa40c5817a573bf3515e3f95769

Fix T97164: Voxel remesh only supports vertex float
            color attributes.

Voxel remesher now supports all color attribute
types.

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

M	source/blender/blenkernel/BKE_attribute.h
M	source/blender/blenkernel/intern/attribute.c
M	source/blender/blenkernel/intern/mesh_remesh_voxel.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index 62469a28eb1..f3a29736bc8 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -65,7 +65,7 @@ struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id,
                                               int type,
                                               AttributeDomain domain);
 
-AttributeDomain BKE_id_attribute_domain(struct ID *id, const struct CustomDataLayer *layer);
+AttributeDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer);
 int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer);
 bool BKE_id_attribute_required(struct ID *id, struct CustomDataLayer *layer);
 bool BKE_id_attribute_rename(struct ID *id,
diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c
index a25d00d4bff..307868ce6d9 100644
--- a/source/blender/blenkernel/intern/attribute.c
+++ b/source/blender/blenkernel/intern/attribute.c
@@ -292,7 +292,7 @@ int BKE_id_attributes_length(const ID *id, AttributeDomainMask domain_mask, Cust
   return length;
 }
 
-AttributeDomain BKE_id_attribute_domain(ID *id, const CustomDataLayer *layer)
+AttributeDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *layer)
 {
   DomainInfo info[ATTR_DOMAIN_NUM];
   get_domains(id, info);
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
index 3c7992ec3d7..f28588e5605 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
@@ -23,11 +23,13 @@
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
+#include "BKE_attribute.h"
 #include "BKE_bvhutils.h"
 #include "BKE_customdata.h"
 #include "BKE_editmesh.h"
 #include "BKE_lib_id.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
 #include "BKE_mesh_remesh_voxel.h" /* own include */
 #include "BKE_mesh_runtime.h"
 
@@ -365,30 +367,139 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
   BVHTreeFromMesh bvhtree = {nullptr};
   BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
 
-  int tot_color_layer = CustomData_number_of_layers(&source->vdata, CD_PROP_COLOR);
+  int i = 0;
+  const CustomDataLayer *layer;
 
-  for (int layer_n = 0; layer_n < tot_color_layer; layer_n++) {
-    const char *layer_name = CustomData_get_layer_name(&source->vdata, CD_PROP_COLOR, layer_n);
-    CustomData_add_layer_named(
-        &target->vdata, CD_PROP_COLOR, CD_CALLOC, nullptr, target->totvert, layer_name);
+  MeshElemMap *source_lmap = nullptr;
+  int *source_lmap_mem = nullptr;
+  MeshElemMap *target_lmap = nullptr;
+  int *target_lmap_mem = nullptr;
 
-    MPropCol *target_color = (MPropCol *)CustomData_get_layer_n(
-        &target->vdata, CD_PROP_COLOR, layer_n);
+  while (layer = BKE_id_attribute_from_index(
+             const_cast<ID *>(&source->id), i++, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL)) {
+    AttributeDomain domain = BKE_id_attribute_domain(&source->id, layer);
+
+    CustomData *target_cdata = domain == ATTR_DOMAIN_POINT ? &target->vdata : &target->ldata;
+    const CustomData *source_cdata = domain == ATTR_DOMAIN_POINT ? &source->vdata : &source->ldata;
+
+    /* Check attribute exists in target. */
+    int layer_i = CustomData_get_named_layer_index(target_cdata, layer->type, layer->name);
+    if (layer_i == -1) {
+      int elem_num = domain == ATTR_DOMAIN_POINT ? target->totvert : target->totloop;
+
+      CustomData_add_layer_named(
+          target_cdata, layer->type, CD_CALLOC, nullptr, elem_num, layer->name);
+      layer_i = CustomData_get_named_layer_index(target_cdata, layer->type, layer->name);
+    }
+
+    size_t data_size = CustomData_sizeof(layer->type);
+    void *target_data = target_cdata->layers[layer_i].data;
+    void *source_data = layer->data;
     MVert *target_verts = (MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
-    const MPropCol *source_color = (const MPropCol *)CustomData_get_layer_n(
-        &source->vdata, CD_PROP_COLOR, layer_n);
-    for (int i = 0; i < target->totvert; i++) {
-      BVHTreeNearest nearest;
-      nearest.index = -1;
-      nearest.dist_sq = FLT_MAX;
-      BLI_bvhtree_find_nearest(
-          bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
-      if (nearest.index != -1) {
-        copy_v4_v4(target_color[i].color, source_color[nearest.index].color);
+
+    if (domain == ATTR_DOMAIN_POINT) {
+      for (int i = 0; i < target->totvert; i++) {
+        BVHTreeNearest nearest;
+        nearest.index = -1;
+        nearest.dist_sq = FLT_MAX;
+        BLI_bvhtree_find_nearest(
+            bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
+
+        if (nearest.index != -1) {
+          memcpy(POINTER_OFFSET(target_data, (size_t)i * data_size),
+                 POINTER_OFFSET(source_data, (size_t)nearest.index * data_size),
+                 data_size);
+        }
+      }
+    }
+    else {
+      /* Lazily init vertex -> loop maps. */
+      if (!source_lmap) {
+        const MPoly *source_polys = (MPoly *)CustomData_get_layer(&source->pdata, CD_MPOLY);
+        const MLoop *source_loops = (MLoop *)CustomData_get_layer(&source->ldata, CD_MLOOP);
+        const MPoly *target_polys = (MPoly *)CustomData_get_layer(&target->pdata, CD_MPOLY);
+        const MLoop *target_loops = (MLoop *)CustomData_get_layer(&target->ldata, CD_MLOOP);
+
+        BKE_mesh_vert_loop_map_create(&source_lmap,
+                                      &source_lmap_mem,
+                                      source_polys,
+                                      source_loops,
+                                      source->totvert,
+                                      source->totpoly,
+                                      source->totloop);
+
+        BKE_mesh_vert_loop_map_create(&target_lmap,
+                                      &target_lmap_mem,
+                                      target_polys,
+                                      target_loops,
+                                      target->totvert,
+                                      target->totpoly,
+                                      target->totloop);
+      }
+
+      for (int i = 0; i < target->totvert; i++) {
+        BVHTreeNearest nearest;
+        nearest.index = -1;
+        nearest.dist_sq = FLT_MAX;
+        BLI_bvhtree_find_nearest(
+            bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
+
+        if (nearest.index == -1) {
+          continue;
+        }
+
+        MeshElemMap *source_loops = source_lmap + nearest.index;
+        MeshElemMap *target_loops = target_lmap + i;
+
+        if (target_loops->count == 0 || source_loops->count == 0) {
+          continue;
+        }
+
+        /*
+         * Average color data for loops around the source vertex into
+         * the first target loop around the target vertex
+         */
+
+        CustomData_interp(source_cdata,
+                          target_cdata,
+                          source_loops->indices,
+                          nullptr,
+                          nullptr,
+                          source_loops->count,
+                          target_loops->indices[0]);
+
+        void *elem = POINTER_OFFSET(target_data, (size_t)target_loops->indices[0] * data_size);
+
+        /* Copy to rest of target loops. */
+        for (int j = 1; j < target_loops->count; j++) {
+          memcpy(POINTER_OFFSET(target_data, (size_t)target_loops->indices[j] * data_size),
+                 elem,
+                 data_size);
+        }
       }
     }
   }
+
+  MEM_SAFE_FREE(source_lmap);
+  MEM_SAFE_FREE(source_lmap_mem);
+  MEM_SAFE_FREE(target_lmap);
+  MEM_SAFE_FREE(target_lmap_mem);
   free_bvhtree_from_mesh(&bvhtree);
+
+  /* Transfer active/render color attributes */
+
+  CustomDataLayer *active_layer = BKE_id_attributes_active_color_get(&source->id);
+  CustomDataLayer *render_layer = BKE_id_attributes_render_color_get(&source->id);
+
+  if (active_layer) {
+    BKE_id_attributes_active_color_set(
+        &target->id, BKE_id_attributes_color_find(&target->id, active_layer->name));
+  }
+
+  if (render_layer) {
+    BKE_id_attributes_render_color_set(
+        &target->id, BKE_id_attributes_color_find(&target->id, render_layer->name));
+  }
 }
 
 struct Mesh *BKE_mesh_remesh_voxel_fix_poles(const Mesh *mesh)



More information about the Bf-blender-cvs mailing list