[Bf-blender-cvs] [893358c] bake-cycles: Cycles-Bake: Active to select and cage extrusion

Dalai Felinto noreply at git.blender.org
Wed Apr 23 02:47:14 CEST 2014


Commit: 893358cb50bf92ccb6a93163db6128e04aa38cb9
Author: Dalai Felinto
Date:   Mon Feb 17 23:22:11 2014 -0300
https://developer.blender.org/rB893358cb50bf92ccb6a93163db6128e04aa38cb9

Cycles-Bake: Active to select and cage extrusion

New parameters:
* use_selected_to_active=False
* cage_extrusion=0.0

Selected and active are baked using local coordinates.
So they don't need to be in the same location.

Also, the cage always look inwards.

Note, I tested with XNormal and things seem good.
The object normals, however, are coded differently:

Cycles RGB = XNormal R(1-B)G
XNormal RGB = Cycles RB(1-G)

To be investigated ...

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

M	intern/cycles/blender/blender_session.cpp
M	source/blender/editors/object/object_bake_new.c
M	source/blender/render/extern/include/RE_bake.h
M	source/blender/render/intern/source/bake_new.c

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

diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index c1a04f2..759c3e3 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -534,7 +534,7 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::Bake
 
 	/* update scene */
 	sync->sync_camera(b_render, b_engine.camera_override(), width, height);
-	sync->sync_data(b_v3d, b_engine.camera_override(), "");
+	sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state);
 
 	/* get buffer parameters */
 	SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
diff --git a/source/blender/editors/object/object_bake_new.c b/source/blender/editors/object/object_bake_new.c
index d255f2b..25d3e34 100644
--- a/source/blender/editors/object/object_bake_new.c
+++ b/source/blender/editors/object/object_bake_new.c
@@ -57,6 +57,7 @@
 #include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
+#include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_multires.h"
 #include "BKE_report.h"
@@ -189,9 +190,19 @@ static int bake_exec(bContext *C, wmOperator *op)
 	int op_result = OPERATOR_CANCELLED;
 	bool ok = false;
 	Scene *scene = CTX_data_scene(C);
-	Object *object = CTX_data_active_object(C);
-	Mesh *me = NULL;
 
+	/* selected to active (high to low) */
+	Object *ob_render = NULL;
+	Object *ob_low = CTX_data_active_object(C);
+	Object *ob_high = NULL;
+
+	bool restrict_render_low = (ob_low->restrictflag & OB_RESTRICT_RENDER);
+	bool restrict_render_high = false;
+
+	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);
@@ -205,10 +216,29 @@ static int bake_exec(bContext *C, wmOperator *op)
 	const int margin = RNA_int_get(op->ptr, "margin");
 	const bool is_external = RNA_boolean_get(op->ptr, "is_save_external");
 	const bool is_linear = is_data_pass(pass_type);
+	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");
+
 	char filepath[FILE_MAX];
-	int need_undeformed = 0;
 	RNA_string_get(op->ptr, "filepath", filepath);
 
+	if (use_selected_to_active) {
+		CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects)
+		{
+			if (ob_iter == ob_low)
+				continue;
+
+			ob_high = ob_iter;
+			break;
+		}
+		CTX_DATA_END;
+
+		if (ob_high == NULL) {
+			BKE_report(op->reports, RPT_ERROR, "No valid selected object");
+			return OPERATOR_CANCELLED;
+		}
+	}
+
 	RE_engine_bake_set_engine_parameters(re, bmain, scene);
 
 	G.is_break = FALSE;
@@ -256,18 +286,40 @@ static int bake_exec(bContext *C, wmOperator *op)
 
 
 	/* get the mesh as it arrives in the renderer */
-
-	//int apply_modifiers, int settings (1=preview, 2=render), int calc_tessface, int calc_undeformed
-	me = BKE_mesh_new_from_object(bmain, scene, object, 1, 2, 1, 0);
-	//TODO delete the mesh afterwards
+	me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
 
 	/* populate the pixel array with the face data */
-	RE_populate_bake_pixels(me, pixel_array, width, height);
+	RE_populate_bake_pixels(me_low, pixel_array, width, height);
+
+	/* high-poly to low-poly baking */
+	if (ob_high && (ob_high->type == OB_MESH))
+	{
+		/* triangulating it makes life so much easier ... */
+		tri_mod = ED_object_modifier_add(op->reports, bmain, scene, ob_high, "TmpTriangulate", eModifierType_Triangulate);
+
+		me_high = BKE_mesh_new_from_object(bmain, scene, ob_high, 1, 2, 1, 0);
+
+		RE_populate_bake_pixels_from_object(me_low, me_high, pixel_array, num_pixels, cage_extrusion);
+
+		/* make sure low poly doesn't render, and high poly renders */
+		restrict_render_high = (ob_high->restrictflag & OB_RESTRICT_RENDER);
+		ob_high->restrictflag &= ~OB_RESTRICT_RENDER;
+
+		ob_low->restrictflag |= OB_RESTRICT_RENDER;
+		ob_render = ob_high;
+
+		BKE_libblock_free(bmain, me_high);
+	}
+	else {
+		/* 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, object, pixel_array, num_pixels, depth, pass_type, result);
+		ok = RE_engine_bake(re, ob_render, pixel_array, num_pixels, depth, pass_type, result);
 	else
-		ok = RE_internal_bake(re, object, pixel_array, num_pixels, depth, pass_type, result);
+		ok = RE_internal_bake(re, ob_render, pixel_array, num_pixels, depth, pass_type, result);
 
 	if (!ok) {
 		BKE_report(op->reports, RPT_ERROR, "Problem baking object map");
@@ -302,11 +354,27 @@ static int bake_exec(bContext *C, wmOperator *op)
 		}
 	}
 
-	MEM_freeN(pixel_array);
-	MEM_freeN(result);
+	/* restore the restrict render settings */
+	if (!restrict_render_low)
+		ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
+	else
+		ob_low->restrictflag |= OB_RESTRICT_RENDER;
+
+	if (ob_high) {
+		if (restrict_render_high)
+			ob_high->restrictflag |= OB_RESTRICT_RENDER;
+
+		if (tri_mod)
+			ED_object_modifier_remove(op->reports, bmain, ob_high, tri_mod);
+	}
 
 	RE_SetReports(re, NULL);
 
+	/* garbage collection */
+	MEM_freeN(pixel_array);
+	MEM_freeN(result);
+
+	BKE_libblock_free(bmain, me_low);
 
 #if 0
 	Main *bmain = CTX_data_main(C);
@@ -386,4 +454,6 @@ void OBJECT_OT_bake(wmOperatorType *ot)
 	ot->prop = RNA_def_int(ot->srna, "width", 512, 1, INT_MAX, "Width", "Horizontal dimension of the baking map", 64, 4096);
 	ot->prop = RNA_def_int(ot->srna, "height", 512, 1, INT_MAX, "Height", "Vertical dimension of the baking map", 64, 4096);
 	ot->prop = RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin", "Extends the baked result as a post process filter", 0, 64);
+	ot->prop = RNA_def_boolean(ot->srna, "use_selected_to_active", false, "Selected to Active", "Bake shading on the surface of selected objects to the active object");
+	ot->prop = RNA_def_float(ot->srna, "cage_extrusion", 0.0, 0.0, 1.0, "Cage Extrusion", "", 0.0, 1.0);
 }
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index ae152d5..50849b7 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -50,6 +50,8 @@ bool RE_engine_bake(struct Render *re, struct Object *object, struct BakePixel p
 int RE_pass_depth(ScenePassType pass_type);
 bool RE_internal_bake(struct Render *re, struct Object *object, struct BakePixel pixel_array[], int num_pixels, int depth, ScenePassType pass_type, float result[]);
 
+void RE_populate_bake_pixels_from_object(struct Mesh *me_low, struct Mesh *me_high, struct BakePixel pixel_array[], const int num_pixels, const float cage_extrusion);
+
 void RE_populate_bake_pixels(struct Mesh *me, struct BakePixel pixel_array[], const int width, const int height);
 
 void RE_bake_margin(struct BakePixel pixel_array[], struct ImBuf *ibuf, const int margin, const int width, const int height);
diff --git a/source/blender/render/intern/source/bake_new.c b/source/blender/render/intern/source/bake_new.c
index 80e560f..e36ba20 100644
--- a/source/blender/render/intern/source/bake_new.c
+++ b/source/blender/render/intern/source/bake_new.c
@@ -44,6 +44,7 @@
 #include "DNA_meshdata_types.h"
 
 #include "BKE_customdata.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_mesh.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
@@ -52,6 +53,9 @@
 #include "BKE_scene.h"
 #include "BKE_library.h"
 
+#include "BKE_bvhutils.h"
+#include "BKE_DerivedMesh.h"
+
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 #include "IMB_colormanagement.h"
@@ -124,6 +128,231 @@ void RE_bake_margin(BakePixel pixel_array[], ImBuf *ibuf, const int margin, cons
 	MEM_freeN(mask_buffer);
 }
 
+typedef struct TriTessFace
+{
+	MVert *v1;
+	MVert *v2;
+	MVert *v3;
+} TriTessFace;
+
+/*
+ * This function returns the coordinate and normal of a barycentric u,v for a face defined by the primitive_id index.
+ */
+
+static void get_point_from_barycentric(TriTessFace *triangles, int primitive_id, float u, float v, float cage_extrusion, float r_co[3], float r_dir[3])
+{
+	float data[3][3];
+	float coord[3];
+	float dir[3];
+	float cage[3];
+
+	TriTessFace *mverts = &triangles[primitive_id];
+
+	copy_v3_v3(data[0], mverts->v1->co);
+	copy_v3_v3(data[1], mverts->v2->co);
+	copy_v3_v3(data[2], mverts->v3->co);
+
+	interp_barycentric_tri_v3(data, u, v, coord);
+
+	normal_short_to_float_v3(data[0], mverts->v1->no);
+	normal_short_to_float_v3(data[1], mverts->v2->no);
+	normal_short_to_float_v3(data[2], mverts->v3->no);
+
+	interp_barycentric_tri_v3(data, u, v, dir);
+	normalize_v3_v3(cage, dir);
+	mul_v3_fl(cage, cage_extrusion);
+
+	add_v3_v3(coord, cage);
+
+	normalize_v3_v3(dir, dir);
+	mul_v3_fl(dir, -1.0f);
+
+	copy_v3_v3(r_co, coord);
+	copy_v3_v3(r_dir, dir);
+}
+
+/*
+ * Transcribed from Christer Ericson's Real-Time Collision Detection
+ *
+ * Compute barycentric coordinates (u, v, w) for
+ * point p with respect to triangle (a, b, c)
+ *
+ */
+static void Barycentric(float p[3], float a[3], float b[3], float c[3], float *u, float *v, float *w)
+{
+	float v0[3], v1[3], v2[3];
+
+	sub_v3_v3v3(v0, b, a);
+	sub_v3_v3v3(v1, c, a);
+	sub_v3_v3v3(v2, p, a);
+
+    float d00 = dot_v3v3(v0, v0);
+    float d01 = dot_v3v3(v0, v1);
+    float d11 = dot_v3v3(v1, v1);
+    float d20 = dot_v3v3(v2, v0);
+    float d21 = dot_v3v3(v2, v1);
+    float denom = d00 * d11 - d01 * d01;
+
+    *v = (d11 * d20 - d01 * d21) / denom;
+    *w = (d00 * d21 - d01 * d20) / denom;
+
+    *u = 1.0f - *v - *w;
+}
+
+/*
+ * This function returns the barycentric u,v of a face for a coordinate. The face is defined by its index.
+ */
+static void get_barycentric_from_point(TriTessFace *triangles, int index, float co[3], int *primitive_id, float *u, float *v)
+{
+	float w;
+	TriTessFace *tri = &triangles[index];
+	Barycentric(co, tri->v1->co, tri->v2->co, tri->v3->co, u, v, &w);
+	*primitive_id = index;
+}
+
+/*
+ * This function populates pixel_array and returns TRUE if things are correct
+ */
+static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, TriTessFace *triangles, BakePixel *pixel_array, float co[3], float dir[3

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list