[Bf-blender-cvs] [d41d1ce] bake-cycles: Cycles-Bake: Support for multiple high-poly objects selected at once

Dalai Felinto noreply at git.blender.org
Fri Apr 25 07:05:23 CEST 2014


Commit: d41d1ceb5e549d35bc471d648c9c5e3aaaa26294
Author: Dalai Felinto
Date:   Thu Apr 24 14:43:10 2014 -0300
https://developer.blender.org/rBd41d1ceb5e549d35bc471d648c9c5e3aaaa26294

Cycles-Bake: Support for multiple high-poly objects selected at once

When using "selected to active" the user can now have more than one
highpoly object for a single lowpoly object.

Code note: instead of implementing a new BHV method to create a tree
with multiple meshes, we are casting the ray to the individual trees
(for each highpoly object) and comparing the distances. It could be
optimized with the BVH change, but it will do for now.

Also note: the same method can be used to implement 'Blockers'.

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

M	intern/cycles/kernel/kernel_displace.h
M	intern/cycles/render/bake.cpp
M	intern/cycles/render/bake.h
M	source/blender/editors/object/object_bake_api.c
M	source/blender/render/extern/include/RE_bake.h
M	source/blender/render/intern/source/bake_api.c

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

diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index 5631fe2..bc4bf1a 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -95,11 +95,8 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
 	int object = in.x;
 	int prim = in.y;
 
-	if(prim == -1) {
-		/* write output */
-		output[i] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+	if(prim == -1)
 		return;
-	}
 
 	float u = __uint_as_float(in.z);
 	float v = __uint_as_float(in.w);
diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp
index eb729d3..213f4fe 100644
--- a/intern/cycles/render/bake.cpp
+++ b/intern/cycles/render/bake.cpp
@@ -51,6 +51,10 @@ int BakeData::size() {
 	return m_num_pixels;
 }
 
+bool BakeData::is_valid(int i) {
+	return m_primitive[i] != -1;
+}
+
 uint4 BakeData::data(int i) {
 	return make_uint4(
 		m_object,
@@ -147,8 +151,11 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre
 		size_t index = i * depth;
 		float4 out = offset[k++];
 
-		for(size_t j=0; j < 4; j++)
-			result[index + j] = out[j];
+		if(bake_data->is_valid(i)) {
+			for(size_t j=0; j < 4; j++) {
+				result[index + j] = out[j];
+			}
+		}
 	}
 
 	m_is_baking = false;
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index 38ac51b..830a951 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -33,6 +33,7 @@ public:
 	int object();
 	int size();
 	uint4 data(int i);
+	bool is_valid(int i);
 
 private:
 	int m_object;
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index e8be555..fc0a7b2 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -282,21 +282,18 @@ static int bake_exec(bContext *C, wmOperator *op)
 	bool ok = false;
 	Scene *scene = CTX_data_scene(C);
 
-	/* selected to active (high to low) */
-	Object *ob_render = NULL;
 	Object *ob_low = CTX_data_active_object(C);
-	Object *ob_high = NULL;
+
+	BakeHighPolyData *highpoly;
+	int tot_highpoly;
 
 	Object *ob_custom_cage = NULL;
 
 	char restrict_flag_low = ob_low->restrictflag;
-	char restrict_flag_high;
 	char restrict_flag_cage;
 
 	Mesh *me_low = NULL;
-	Mesh *me_high = NULL;
 
-	ModifierData *tri_mod;
 	int pass_type = RNA_enum_get(op->ptr, "type");
 
 	Render *re = RE_NewRender(scene->id.name);
@@ -304,8 +301,6 @@ static int bake_exec(bContext *C, wmOperator *op)
 	float *result = NULL;
 
 	BakePixel *pixel_array_low = NULL;
-	BakePixel *pixel_array_high = NULL;
-	BakePixel *pixel_array_render = NULL;
 
 	const int depth = RE_pass_depth(pass_type);
 	const int margin = RNA_int_get(op->ptr, "margin");
@@ -317,7 +312,7 @@ static int bake_exec(bContext *C, wmOperator *op)
 	const bool use_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
 	const float cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
 
-	bool is_cage;
+	bool is_highpoly = false;
 	bool is_tangent;
 
 	BakeImage *images;
@@ -369,23 +364,24 @@ static int bake_exec(bContext *C, wmOperator *op)
 	}
 
 	if (use_selected_to_active) {
+		tot_highpoly = 0;
+
 		CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
 		{
 			if (ob_iter == ob_low)
 				continue;
 
-			ob_high = ob_iter;
-			break;
+			tot_highpoly ++;
 		}
 		CTX_DATA_END;
 
-		if (ob_high == NULL) {
-			BKE_report(op->reports, RPT_ERROR, "No valid selected object");
+		if (tot_highpoly == 0) {
+			BKE_report(op->reports, RPT_ERROR, "No valid selected objects");
 			op_result = OPERATOR_CANCELLED;
 			goto cleanup;
 		}
 		else {
-			restrict_flag_high = ob_high->restrictflag;
+			is_highpoly = true;
 		}
 	}
 
@@ -413,20 +409,17 @@ static int bake_exec(bContext *C, wmOperator *op)
 	pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
 	result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
 
-	is_cage = ob_high && (ob_high->type == OB_MESH);
-
-	/* high-poly to low-poly baking */
-	if (is_cage) {
+	if (is_highpoly) {
 		ModifierData *md, *nmd;
-		TriangulateModifierData *tmd;
 		ListBase modifiers_tmp, modifiers_original;
-		float mat_low2high[4][4];
-
-		if (ob_custom_cage) {
-			me_low = BKE_mesh_new_from_object(bmain, scene, ob_custom_cage, 1, 2, 1, 0);
-
-			invert_m4_m4(mat_low2high, ob_high->obmat);
-			mul_m4_m4m4(mat_low2high, mat_low2high, ob_custom_cage->obmat);
+		float mat_low[4][4];
+		int i = 0;
+		highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
+
+		/* prepare cage mesh */
+		if (ob_cage) {
+			me_low = BKE_mesh_new_from_object(bmain, scene, ob_cage, 1, 2, 1, 0);
+			copy_m4_m4(mat_low, ob_cage->obmat);
 		}
 		else {
 			modifiers_original = ob_low->modifiers;
@@ -453,55 +446,68 @@ static int bake_exec(bContext *C, wmOperator *op)
 
 			/* get the cage mesh as it arrives in the renderer */
 			me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
-
-			invert_m4_m4(mat_low2high, ob_high->obmat);
-			mul_m4_m4m4(mat_low2high, mat_low2high, ob_low->obmat);
+			copy_m4_m4(mat_low, ob_low->obmat);
 		}
 
-		/* populate the pixel array with the face data */
-		RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, images);
+		/* populate highpoly array */
+		CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
+		{
+			TriangulateModifierData *tmd;
 
-		/* triangulating it makes life so much easier ... */
-		tri_mod = ED_object_modifier_add(op->reports, bmain, scene, ob_high, "TmpTriangulate", eModifierType_Triangulate);
-		tmd = (TriangulateModifierData *)tri_mod;
-		tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
-		tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;
+			if (ob_iter == ob_low)
+				continue;
 
-		me_high = BKE_mesh_new_from_object(bmain, scene, ob_high, 1, 2, 1, 0);
+			/* initialize highpoly_data */
+			highpoly[i].ob = ob_iter;
+			highpoly[i].me = NULL;
+			highpoly[i].tri_mod = NULL;
+			highpoly[i].restrict_flag = ob_iter->restrictflag;
+			highpoly[i].pixel_array = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
 
-		if (is_tangent) {
-			pixel_array_high = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
-			RE_populate_bake_pixels_from_object(me_low, me_high, pixel_array_low, pixel_array_high, num_pixels, cage_extrusion, mat_low2high);
-			pixel_array_render = pixel_array_high;
 
-			/* we need the pixel array to get normals and tangents from the original mesh */
-			if (ob_custom_cage) {
-				BKE_libblock_free(bmain, me_low);
+			/* triangulating so BVH returns the primitive_id that will be used for rendering */
+			highpoly[i].tri_mod = ED_object_modifier_add(op->reports, bmain, scene, highpoly[i].ob, "TmpTriangulate", eModifierType_Triangulate);
+			tmd = (TriangulateModifierData *)highpoly[i].tri_mod;
+			tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
+			tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;
 
-				me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
-				RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, images);
-			}
+			highpoly[i].me = BKE_mesh_new_from_object(bmain, scene, highpoly[i].ob, 1, 2, 1, 0);
+			highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER;
 
-			/* need to make sure missed rays are masked out of the result */
-			RE_mask_bake_pixels(pixel_array_high, pixel_array_low, num_pixels);
-		}
-		else {
-			/* re-use the same BakePixel array */
-			RE_populate_bake_pixels_from_object(me_low, me_high, pixel_array_low, pixel_array_low, num_pixels, cage_extrusion, mat_low2high);
-			pixel_array_render = pixel_array_low;
+			/* lowpoly to highpoly transformation matrix */
+			invert_m4_m4(highpoly[i].mat_lowtohigh, highpoly[i].ob->obmat);
+			mul_m4_m4m4(highpoly[i].mat_lowtohigh, highpoly[i].mat_lowtohigh, mat_low);
+
+			i++;
 		}
+		CTX_DATA_END;
+
+		BLI_assert(i == tot_highpoly);
+
+		/* populate the pixel array with the face data */
+		RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, images);
 
-		/* make sure low poly doesn't render, and high poly renders */
-		ob_high->restrictflag &= ~OB_RESTRICT_RENDER;
 		ob_low->restrictflag |= OB_RESTRICT_RENDER;
 
-		ob_render = ob_high;
+		/* populate the pixel arrays with the corresponding face data for each high poly object */
+		RE_populate_bake_pixels_from_objects(me_low, pixel_array_low, highpoly, tot_highpoly, num_pixels, cage_extrusion);
+
+		/* the baking itself */
+		for (i = 0; i < tot_highpoly; i++) {
+			if (RE_engine_has_bake(re))
+				ok = RE_engine_bake(re, highpoly[i].ob, highpoly[i].pixel_array, num_pixels, depth, pass_type, result);
+			else
+				ok = RE_internal_bake(re, highpoly[i].ob, highpoly[i].pixel_array, num_pixels, depth, pass_type, result);
+
+			if (!ok)
+				break;
+		}
 
-		if (ob_custom_cage) {
-			ob_custom_cage->restrictflag |= OB_RESTRICT_RENDER;
+		/* reverting data back */
+		if (ob_cage) {
+			ob_cage->restrictflag |= OB_RESTRICT_RENDER;
 		}
 		else {
-			/* reverting data back */
 			ob_low->modifiers = modifiers_original;
 
 			while ((md = BLI_pophead(&modifiers_tmp))) {
@@ -515,17 +521,15 @@ static int bake_exec(bContext *C, wmOperator *op)
 
 		/* populate the pixel array with the face data */
 		RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, images);
-		pixel_array_render = pixel_array_low;
 
 		/* make sure low poly renders */
 		ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
-		ob_render = ob_low;
-	}
 
-	if (RE_engine_has_bake(re))
-		ok = RE_engine_bake(re, ob_render, pixel_array_render, num_pixels, depth, pass_type, result);
-	else
-		ok = RE_internal_bake(re, ob_render, pixel_array_render, num_pixels, depth, pass_type, result);
+		if (RE_engine_has_bake(re))
+			ok = RE_engine_bake(re, ob_low, pixel_array_low, num_pixels, depth, pass_type, result);
+		else
+			ok = RE_internal_bake(re, ob_low, pixel_array_low, num_pixels, depth, pass_type, result);
+	}
 
 	/* normal space conversion */
 	if (pass_type == SCE_PASS_NORMAL) {
@@ -565,7 +569,7 @@ static int bake_exec(bContext *C, wmOperator *op)
 			BakeImage *image = &images[i];
 
 			if (is_save_internal) {
-			

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list