Commit: cde725e26fb6c96d6fb241cd053cd3c57c45bebc
Author: Bastien Montagne
Date:   Fri Oct 16 21:28:22 2015 +0200
Branches: blender-v2.76a-release
https://developer.blender.org/rBcde725e26fb6c96d6fb241cd053cd3c57c45bebc

Fix T46508: data_transfer of normals fails in case objects are transformed.

The final stage of the process (copying/interpolating new dst cddata from src 
cddata)
was simply broken in normal case, where we need to convert from source to 
destination
object space.

This patch is a bit verbose, but I cannot see how to avoid it really.

To think this code is in master since over 6 months and it only gets reported 
now... :/

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

M       source/blender/blenkernel/BKE_customdata.h
M       source/blender/blenkernel/intern/customdata.c
M       source/blender/blenkernel/intern/data_transfer.c
M       source/blender/blenkernel/intern/data_transfer_intern.h
M       source/blender/blenkernel/intern/deform.c

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

diff --git a/source/blender/blenkernel/BKE_customdata.h 
b/source/blender/blenkernel/BKE_customdata.h
index 3e78475..a7c5c21 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -472,6 +472,8 @@ typedef struct CustomDataTransferLayerMap {
        size_t data_offset;  /* Offset of actual data we transfer (in element 
contained in data_src/dst). */
        uint64_t data_flag;  /* For bitflag transfer, flag(s) to affect in 
transfered data. */
 
+       void *interp_data;   /* Opaque pointer, to be used by specific interp 
callback (e.g. transformspace for normals). */
+
        cd_datatransfer_interp interp;
 } CustomDataTransferLayerMap;
 
diff --git a/source/blender/blenkernel/intern/customdata.c 
b/source/blender/blenkernel/intern/customdata.c
index f14feee..7149b24 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -61,6 +61,8 @@
 #include "BKE_mesh_remap.h"
 #include "BKE_multires.h"
 
+#include "data_transfer_intern.h"
+
 #include "bmesh.h"
 
 #include <math.h>
@@ -3913,6 +3915,38 @@ static void customdata_data_transfer_interp_generic(
        MEM_freeN(tmp_dst);
 }
 
+/* Normals are special, we need to take care of source & destination spaces... 
*/
+void customdata_data_transfer_interp_normal_normals(
+        const CustomDataTransferLayerMap *laymap, void *data_dst,
+        const void **sources, const float *weights, const int count,
+        const float mix_factor)
+{
+       const int data_type = laymap->data_type;
+       const int mix_mode = laymap->mix_mode;
+
+       SpaceTransform *space_transform = laymap->interp_data;
+
+       const LayerTypeInfo *type_info = layerType_getInfo(data_type);
+       cd_interp interp_cd = type_info->interp;
+
+       float tmp_dst[3];
+
+       BLI_assert(data_type == CD_NORMAL);
+
+       if (!sources) {
+               /* Not supported here, abort. */
+               return;
+       }
+
+       interp_cd(sources, weights, NULL, count, tmp_dst);
+       if (space_transform) {
+               /* tmp_dst is in source space so far, bring it back in 
destination space. */
+               BLI_space_transform_invert_normal(space_transform, tmp_dst);
+       }
+
+       CustomData_data_mix_value(data_type, tmp_dst, data_dst, mix_mode, 
mix_factor);
+}
+
 void CustomData_data_transfer(const MeshPairRemap *me_remap, const 
CustomDataTransferLayerMap *laymap)
 {
        MeshPairRemapItem *mapit = me_remap->items;
diff --git a/source/blender/blenkernel/intern/data_transfer.c 
b/source/blender/blenkernel/intern/data_transfer.c
index 53b6f4a..0baf7e3 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -428,7 +428,7 @@ void data_transfer_layersmapping_add_item(
         ListBase *r_map, const int cddata_type, const int mix_mode, const 
float mix_factor, const float *mix_weights,
         const void *data_src, void *data_dst, const int data_src_n, const int 
data_dst_n,
         const size_t elem_size, const size_t data_size, const size_t 
data_offset, const uint64_t data_flag,
-        cd_datatransfer_interp interp)
+        cd_datatransfer_interp interp, void *interp_data)
 {
        CustomDataTransferLayerMap *item = MEM_mallocN(sizeof(*item), __func__);
 
@@ -450,17 +450,18 @@ void data_transfer_layersmapping_add_item(
        item->data_flag = data_flag;
 
        item->interp = interp;
+       item->interp_data = interp_data;
 
        BLI_addtail(r_map, item);
 }
 
 static void data_transfer_layersmapping_add_item_cd(
         ListBase *r_map, const int cddata_type, const int mix_mode, const 
float mix_factor, const float *mix_weights,
-        void *data_src, void *data_dst)
+        void *data_src, void *data_dst, cd_datatransfer_interp interp, void 
*interp_data)
 {
        data_transfer_layersmapping_add_item(
                r_map, cddata_type, mix_mode, mix_factor, mix_weights, 
data_src, data_dst,
-               0, 0, 0, 0, 0, 0, NULL);
+               0, 0, 0, 0, 0, 0, interp, interp_data);
 }
 
 /* Note: All those layer mapping handlers return false *only* if they were 
given invalid parameters.
@@ -473,7 +474,8 @@ static bool 
data_transfer_layersmapping_cdlayers_multisrc_to_dst(
         ListBase *r_map, const int cddata_type, const int mix_mode, const 
float mix_factor, const float *mix_weights,
         const int num_elem_dst, const bool use_create, const bool use_delete,
         CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst,
-        const int tolayers, bool *use_layers_src, const int num_layers_src)
+        const int tolayers, bool *use_layers_src, const int num_layers_src,
+        cd_datatransfer_interp interp, void *interp_data)
 {
        void *data_src, *data_dst = NULL;
        int idx_src = num_layers_src;
@@ -527,7 +529,7 @@ static bool 
data_transfer_layersmapping_cdlayers_multisrc_to_dst(
                                                data_dst = 
CustomData_get_layer_n(cd_dst, cddata_type, idx_src);
                                        }
                                        
data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, 
mix_factor, mix_weights,
-                                                                               
data_src, data_dst);
+                                                                               
data_src, data_dst, interp, interp_data);
                                }
                        }
                        break;
@@ -571,7 +573,7 @@ static bool 
data_transfer_layersmapping_cdlayers_multisrc_to_dst(
                                                data_dst = 
CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
                                        }
                                        
data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, 
mix_factor, mix_weights,
-                                                                               
data_src, data_dst);
+                                                                               
data_src, data_dst, interp, interp_data);
                                }
                        }
 
@@ -599,7 +601,8 @@ static bool data_transfer_layersmapping_cdlayers(
         ListBase *r_map, const int cddata_type, const int mix_mode, const 
float mix_factor, const float *mix_weights,
         const int num_elem_dst, const bool use_create, const bool use_delete,
         CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst,
-        const int fromlayers, const int tolayers)
+        const int fromlayers, const int tolayers,
+        cd_datatransfer_interp interp, void *interp_data)
 {
        int idx_src, idx_dst;
        void *data_src, *data_dst = NULL;
@@ -626,7 +629,7 @@ static bool data_transfer_layersmapping_cdlayers(
 
                if (r_map) {
                        data_transfer_layersmapping_add_item_cd(r_map, 
cddata_type, mix_mode, mix_factor, mix_weights,
-                                                               data_src, 
data_dst);
+                                                               data_src, 
data_dst, interp, interp_data);
                }
        }
        else if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
@@ -719,7 +722,7 @@ static bool data_transfer_layersmapping_cdlayers(
 
                if (r_map) {
                        data_transfer_layersmapping_add_item_cd(
-                               r_map, cddata_type, mix_mode, mix_factor, 
mix_weights, data_src, data_dst);
+                               r_map, cddata_type, mix_mode, mix_factor, 
mix_weights, data_src, data_dst, interp, interp_data);
                }
        }
        else if (fromlayers == DT_LAYERS_ALL_SRC) {
@@ -734,7 +737,8 @@ static bool data_transfer_layersmapping_cdlayers(
                ret = data_transfer_layersmapping_cdlayers_multisrc_to_dst(
                        r_map, cddata_type, mix_mode, mix_factor, mix_weights,
                        num_elem_dst, use_create, use_delete, cd_src, cd_dst, 
use_dupref_dst,
-                       tolayers, use_layers_src, num_src);
+                       tolayers, use_layers_src, num_src,
+                       interp, interp_data);
 
                if (use_layers_src) {
                        MEM_freeN(use_layers_src);
@@ -751,10 +755,14 @@ static bool data_transfer_layersmapping_cdlayers(
 static bool data_transfer_layersmapping_generate(
         ListBase *r_map, Object *ob_src, Object *ob_dst, DerivedMesh *dm_src, 
DerivedMesh *dm_dst, Mesh *me_dst,
         const int elem_type, int cddata_type, int mix_mode, float mix_factor, 
const float *mix_weights,
-        const int num_elem_dst, const bool use_create, const bool use_delete, 
const int fromlayers, const int tolayers)
+        const int num_elem_dst, const bool use_create, const bool use_delete, 
const int fromlayers, const int tolayers,
+        SpaceTransform *space_transform)
 {
        CustomData *cd_src, *cd_dst;
 
+       cd_datatransfer_interp interp = NULL;
+       void *interp_data = NULL;
+
        if (elem_type == ME_VERT) {
                if (!(cddata_type & CD_FAKE)) {
                        cd_src = dm_src->getVertDataLayout(dm_src);
@@ -763,7 +771,8 @@ static bool data_transfer_layersmapping_generate(
                        if (!data_transfer_layersmapping_cdlayers(r_map, 
cddata_type, mix_mode, mix_factor, mix_weights,
                                                                  num_elem_dst, 
use_create, use_delete,
                                                                  cd_src, 
cd_dst, dm_dst != NULL,
-                                                                 fromlayers, 
tolayers))
+                                                                 fromlayers, 
tolayers,
+                                                                 interp, 
interp_data))
                        {
                                /* We handle specific source selection cases 
here. */
                                return false;
@@ -795,7 +804,7 @@ static bool data_transfer_layersmapping_generate(
                                                                     
dm_src->getNumVerts(dm_src),
                                                                     dm_dst ? 
dm_dst->getNumVerts(dm_dst) : me_dst->totvert,
                                                                     elem_size, 
data_size, data_offset, data_flag,
-                                                                    
data_transfer_interp_char);
+                                                                    
data_transfer_interp_char, interp_data);
                        }
                        return true;
                }
@@ -827,7 +836,8 @@ static bool data_transfer_layersmapping_generate(
                        if (!data_transfer_layersmapping_cdlayers(r_map, 
cddata_type, mix_mode, mix_factor, mix_weights,
                                                                  num_elem_dst, 
use_create, use_delete,
                                                                  cd_src, 
cd_dst, dm_dst != NULL,
-                                                                 fromlayers, 
tolayers))
+                                                                 fromlayers, 
tolayers,
+                                                                 interp, 
interp_data))
                        {
                                /* We handle specific source selection cases 
here. */
                                return false;
@@ -859,7 +869,7 @@ static bool data_transfer_layersmapping_generate(
                                                                     
dm_src->getNumEdges(dm_src),
                                                                     dm_dst ? 
dm_dst->getNumEdges(dm_dst) : me_dst->totedge,
                                                                     elem_size, 
data_size, data_offset,

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to