[Bf-blender-cvs] [e89949d] temp_custom_loop_normals: First use of txdata to transfer custom normals...

Bastien Montagne noreply at git.blender.org
Thu Jan 15 16:21:04 CET 2015


Commit: e89949d0a7deeb47d3ecd1533942e7b0eca46e48
Author: Bastien Montagne
Date:   Wed Jan 14 22:41:35 2015 +0100
Branches: temp_custom_loop_normals
https://developer.blender.org/rBe89949d0a7deeb47d3ecd1533942e7b0eca46e48

First use of txdata to transfer custom normals...

Had to add a pre/post process helper to txdata, since with clnors
we want to operate on regular normals data, but store results in
'compressed' clnor data.

Note things seems to be working basically, but the whole branch needs to
re-check how/when it's using (custom)lnors (same goes for master, actually!).

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

M	intern/cycles/blender/blender_session.cpp
M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_data_transfer.h
M	source/blender/blenkernel/intern/data_transfer.c
M	source/blender/blenkernel/intern/mesh_remap.c
M	source/blender/editors/object/object_data_transfer.c
M	source/blender/makesrna/intern/rna_modifier.c

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

diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index a8958db..eb3f54a 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -794,7 +794,7 @@ void BlenderSession::get_progress(float& progress, double& total_time, double& r
 	if(background && samples_per_tile && tile_total)
 		progress = ((float)sample / (float)(tile_total * samples_per_tile));
 	else if(!background && samples > 0 && total_samples != USHRT_MAX)
-		progress = ((double)samples) / total_samples;
+		progress = ((float)samples) / total_samples;
 	else
 		progress = 0.0;
 }
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index f11aad2..f3f1e0a 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -397,6 +397,8 @@ enum {
 	CD_FAKE_BWEIGHT     = CD_FAKE | CD_BWEIGHT,  /* *sigh*. */
 	CD_FAKE_UV          = CD_FAKE | CD_MLOOPUV,  /* UV flag, because we handle both loop's UVs and poly's textures. */
 
+	CD_FAKE_LNOR        = CD_FAKE | CD_CUSTOMLOOPNORMAL,  /* Because we play with clnor and temp lnor layers here. */
+
 	CD_FAKE_SHARP       = CD_FAKE | 200,  /* Sharp flag for edges, smooth flag for faces. */
 };
 
diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h
index d31804b..cea093a 100644
--- a/source/blender/blenkernel/BKE_data_transfer.h
+++ b/source/blender/blenkernel/BKE_data_transfer.h
@@ -57,6 +57,7 @@ enum {
 	DT_TYPE_FREESTYLE_EDGE          = 1 << 12,
 
 	DT_TYPE_VCOL                    = 1 << 16,
+	DT_TYPE_LNOR                    = 1 << 17,
 
 	DT_TYPE_UV                      = 1 << 24,
 	DT_TYPE_SHARP_FACE              = 1 << 25,
@@ -67,7 +68,7 @@ enum {
 	DT_TYPE_VERT_ALL                = DT_TYPE_MDEFORMVERT | DT_TYPE_SHAPEKEY | DT_TYPE_SKIN | DT_TYPE_BWEIGHT_VERT,
 	DT_TYPE_EDGE_ALL                = DT_TYPE_SHARP_EDGE | DT_TYPE_SEAM | DT_TYPE_CREASE | DT_TYPE_BWEIGHT_EDGE |
 	                                  DT_TYPE_FREESTYLE_EDGE,
-	DT_TYPE_LOOP_ALL                = DT_TYPE_VCOL | DT_TYPE_UV,
+	DT_TYPE_LOOP_ALL                = DT_TYPE_VCOL | DT_TYPE_LNOR | DT_TYPE_UV,
 	DT_TYPE_POLY_ALL                = DT_TYPE_UV | DT_TYPE_SHARP_FACE | DT_TYPE_FREESTYLE_FACE,
 };
 
@@ -85,7 +86,7 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type);
 #define DT_DATATYPE_IS_EDGE(_dt) \
 	ELEM(_dt, DT_TYPE_CREASE, DT_TYPE_SHARP_EDGE, DT_TYPE_SEAM, DT_TYPE_BWEIGHT_EDGE, DT_TYPE_FREESTYLE_EDGE)
 #define DT_DATATYPE_IS_LOOP(_dt) \
-	ELEM(_dt, DT_TYPE_UV, DT_TYPE_VCOL)
+	ELEM(_dt, DT_TYPE_UV, DT_TYPE_VCOL, DT_TYPE_LNOR)
 #define DT_DATATYPE_IS_POLY(_dt) \
 	ELEM(_dt, DT_TYPE_UV, DT_TYPE_SHARP_FACE, DT_TYPE_FREESTYLE_FACE)
 
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index d41c747..64271cf 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -47,6 +47,7 @@
 #include "BKE_data_transfer.h"
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
 #include "BKE_mesh_remap.h"
 #include "BKE_object.h"
@@ -79,6 +80,9 @@ CustomDataMask BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types
 		else if (cddata_type == CD_FAKE_UV) {
 			cddata_mask |= CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV;
 		}
+		else if (cddata_type == CD_FAKE_LNOR) {
+			cddata_mask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
+		}
 	}
 
 	return cddata_mask;
@@ -143,6 +147,9 @@ bool BKE_object_data_transfer_get_dttypes_capacity(
 				*r_threshold = true;
 				ret = true;
 				break;
+			case DT_TYPE_LNOR:
+				ret = true;
+				break;
 			case DT_TYPE_SHARP_FACE:
 				*r_threshold = true;
 				ret = true;
@@ -217,6 +224,8 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
 
 		case DT_TYPE_VCOL:
 			return CD_MLOOPCOL;
+		case DT_TYPE_LNOR:
+			return CD_FAKE_LNOR;
 
 		default:
 			BLI_assert(0);
@@ -242,6 +251,110 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
 
 /* ********** */
 
+/* Generic pre/post processing, only used by custom loop normals currently. */
+
+static void data_transfer_dtdata_type_preprocess(
+        Object *ob_src, Object *UNUSED(ob_dst), DerivedMesh *dm_src, DerivedMesh *dm_dst, Mesh *me_dst,
+        const int dtdata_type, const bool dirty_nors_dst, void **r_prepost_data)
+{
+	*r_prepost_data = NULL;
+
+	if (dtdata_type == DT_TYPE_LNOR) {
+		/* Compute custom normals into regular loop normals, which will be used for the transfer. */
+		Mesh *me_src = ob_src->data;
+
+		MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+		const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+		MEdge *edges_dst = dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge;
+		const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge;
+		MPoly *polys_dst = dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly;
+		const int num_polys_dst = dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly;
+		MLoop *loops_dst = dm_dst ? dm_dst->getLoopArray(dm_dst) : me_dst->mloop;
+		const int num_loops_dst = dm_dst ? dm_dst->getNumLoops(dm_dst) : me_dst->totloop;
+		CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+		CustomData *ldata_dst = dm_dst ? dm_dst->getLoopDataLayout(dm_dst) : &me_dst->ldata;
+
+		const bool use_mesh_src_autosmooth = (me_src->flag & ME_AUTOSMOOTH) != 0;
+		const bool use_mesh_dst_autosmooth = (me_dst->flag & ME_AUTOSMOOTH) != 0;
+		const float split_angle_src = use_mesh_src_autosmooth ? me_src->smoothresh : M_PI;
+		const float split_angle_dst = use_mesh_dst_autosmooth ? me_dst->smoothresh : M_PI;
+
+		dm_src->calcLoopNormals(dm_src, split_angle_src);
+
+		if (dm_dst) {
+			dm_dst->calcLoopNormals(dm_dst, split_angle_dst);
+		}
+		else {
+			float (*poly_nors_dst)[3];
+			float (*loop_nors_dst)[3];
+			short (*custom_nors_dst)[2] = use_mesh_dst_autosmooth ? CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL) : NULL;
+
+			/* Cache poly nors into a temp CDLayer. */
+			poly_nors_dst = CustomData_get_layer(pdata_dst, CD_NORMAL);
+			if (!poly_nors_dst) {
+				poly_nors_dst = CustomData_add_layer(pdata_dst, CD_NORMAL, CD_CALLOC, NULL, num_polys_dst);
+				CustomData_set_layer_flag(pdata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+			}
+			if (dirty_nors_dst) {
+				BKE_mesh_calc_normals_poly(verts_dst, num_verts_dst, loops_dst, polys_dst,
+										   num_loops_dst, num_polys_dst, poly_nors_dst, true);
+			}
+			/* Cache loop nors into a temp CDLayer. */
+			loop_nors_dst = CustomData_get_layer(ldata_dst, CD_NORMAL);
+			if (!loop_nors_dst) {
+				loop_nors_dst = CustomData_add_layer(ldata_dst, CD_NORMAL, CD_CALLOC, NULL, num_loops_dst);
+				CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY);
+			}
+			if (dirty_nors_dst) {
+				BKE_mesh_normals_loop_split(verts_dst, num_verts_dst, edges_dst, num_edges_dst,
+											loops_dst, loop_nors_dst, num_loops_dst,
+											polys_dst, (const float (*)[3])poly_nors_dst, num_polys_dst,
+											split_angle_dst, NULL, custom_nors_dst, NULL);
+			}
+		}
+	}
+}
+
+static void data_transfer_dtdata_type_postprocess(
+        Object *UNUSED(ob_src), Object *UNUSED(ob_dst), DerivedMesh *UNUSED(dm_src), DerivedMesh *dm_dst, Mesh *me_dst,
+        const int dtdata_type, const bool changed, void *UNUSED(prepost_data))
+{
+	if (dtdata_type == DT_TYPE_LNOR) {
+		/* Bake edited destination loop normals into custom normals again. */
+		MVert *verts_dst = dm_dst ? dm_dst->getVertArray(dm_dst) : me_dst->mvert;
+		const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert;
+		MEdge *edges_dst = dm_dst ? dm_dst->getEdgeArray(dm_dst) : me_dst->medge;
+		const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge;
+		MPoly *polys_dst = dm_dst ? dm_dst->getPolyArray(dm_dst) : me_dst->mpoly;
+		const int num_polys_dst = dm_dst ? dm_dst->getNumPolys(dm_dst) : me_dst->totpoly;
+		MLoop *loops_dst = dm_dst ? dm_dst->getLoopArray(dm_dst) : me_dst->mloop;
+		const int num_loops_dst = dm_dst ? dm_dst->getNumLoops(dm_dst) : me_dst->totloop;
+		CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata;
+		CustomData *ldata_dst = dm_dst ? dm_dst->getLoopDataLayout(dm_dst) : &me_dst->ldata;
+
+		const float (*poly_nors_dst)[3] = CustomData_get_layer(pdata_dst, CD_NORMAL);
+		float (*loop_nors_dst)[3] = CustomData_get_layer(ldata_dst, CD_NORMAL);
+		short (*custom_nors_dst)[2] = CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL);
+
+		BLI_assert(poly_nors_dst);
+
+		if (!changed) {
+			return;
+		}
+
+		if (!custom_nors_dst) {
+			custom_nors_dst = CustomData_add_layer(ldata_dst, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops_dst);
+		}
+
+		BKE_mesh_normals_loop_custom_set(verts_dst, num_verts_dst, edges_dst, num_edges_dst,
+		                                 loops_dst, loop_nors_dst, NULL, num_loops_dst,
+		                                 polys_dst, poly_nors_dst, num_polys_dst,
+		                                 custom_nors_dst, false);
+	}
+}
+
+/* ********** */
+
 static MeshRemapIslandsCalc data_transfer_get_loop_islands_generator(const int cddata_type)
 {
 	switch (cddata_type) {
@@ -799,6 +912,10 @@ static bool data_transfer_layersmapping_generate(
 		if (cddata_type == CD_FAKE_UV) {
 			cddata_type = CD_MLOOPUV;
 		}
+		else if (cddata_type == CD_FAKE_LNOR) {
+			/* Preprocess should have generated it, Postprocess will convert it back to CD_CUSTOMLOOPNORMAL. */
+			cddata_type = CD_NORMAL;
+		}
 
 		if (!(cddata_type & CD_FAKE)) {
 			cd_src = dm_src->getLoopDataLayout(dm_src);
@@ -1008,6 +1125,7 @@ bool BKE_object_data_transfer_dm(
 	/* Check all possible data types.
 	 * Note item mappings and dest mix weights are cached. */
 	for (i = 0; i < DT_TYPE_MAX; i++) {
+		void *prepost_data;
 		const int dtdata_type = 1 << i;
 		int cddata_type;
 		int fromlayers, tolayers, fromto_idx;
@@ -1016,6 +1134,9 @@ bool BKE_object_data_transfer_dm(
 			continue;
 		}
 
+		data_transfer_d

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list