[Bf-blender-cvs] [8172712] master: Fix T46508: data_transfer of normals fails in case objects are transformed.

Bastien Montagne noreply at git.blender.org
Fri Oct 16 22:00:09 CEST 2015


Commit: 8172712841975014e28219da91a41c7c5b074d5a
Author: Bastien Montagne
Date:   Fri Oct 16 21:28:22 2015 +0200
Branches: master
https://developer.blender.org/rB8172712841975014e28219da91a41c7c5b074d5a

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 28aaec8..43d23e9 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. @@




More information about the Bf-blender-cvs mailing list