[Bf-blender-cvs] [4567be7] bake-cycles: Cycles-Bake: normal swizzle, and OBJECT and WORLD normal spaces
Dalai Felinto
noreply at git.blender.org
Wed Apr 23 02:47:18 CEST 2014
Commit: 4567be7da3b967aa26829a628b331d0df66ce6dd
Author: Dalai Felinto
Date: Fri Feb 21 18:38:40 2014 -0300
https://developer.blender.org/rB4567be7da3b967aa26829a628b331d0df66ce6dd
Cycles-Bake: normal swizzle, and OBJECT and WORLD normal spaces
The user can now decide between the normal_space (OBJECT, WORLD)
The user can now decide on the swizzle (+X,+Y,+Z):
* normal_r, normal_g, normal_b
+ barebones code for TANGENT normal space
Though this is not working, thus it's disabled in operator enum.
===================================================================
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/source/blender/editors/object/object_bake_new.c b/source/blender/editors/object/object_bake_new.c
index 25d3e34..346eb07 100644
--- a/source/blender/editors/object/object_bake_new.c
+++ b/source/blender/editors/object/object_bake_new.c
@@ -208,7 +208,11 @@ static int bake_exec(bContext *C, wmOperator *op)
Render *re = RE_NewRender(scene->id.name);
float *result;
- BakePixel *pixel_array;
+
+ BakePixel *pixel_array_low = NULL;
+ BakePixel *pixel_array_high = NULL;
+ BakePixel *pixel_array_render = NULL;
+
const int width = RNA_int_get(op->ptr, "width");
const int height = RNA_int_get(op->ptr, "height");
const int num_pixels = width * height;
@@ -218,6 +222,15 @@ static int bake_exec(bContext *C, wmOperator *op)
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");
+ bool is_cage;
+ bool is_tangent;
+
+ int normal_space = RNA_enum_get(op->ptr, "normal_space");
+ int normal_swizzle[] = {
+ RNA_enum_get(op->ptr, "normal_r"),
+ RNA_enum_get(op->ptr, "normal_g"),
+ RNA_enum_get(op->ptr, "normal_b")
+ };
char filepath[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filepath);
@@ -246,7 +259,7 @@ static int bake_exec(bContext *C, wmOperator *op)
RE_test_break_cb(re, NULL, bake_break);
RE_SetReports(re, op->reports);
- pixel_array = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels");
+ pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
/**
@@ -284,22 +297,58 @@ static int bake_exec(bContext *C, wmOperator *op)
elif ... (vertex color?)
*/
-
- /* get the mesh as it arrives in the renderer */
- 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_low, pixel_array, width, height);
+ is_cage = ob_high && (ob_high->type == OB_MESH);
+ is_tangent = pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT;
/* high-poly to low-poly baking */
- if (ob_high && (ob_high->type == OB_MESH))
+ if (is_cage)
{
+ ModifierData *md, *nmd;
+ TriangulateModifierData *tmd;
+ ListBase modifiers_tmp;
+ ListBase modifiers_original = ob_low->modifiers;
+
+ BLI_listbase_clear(&modifiers_tmp);
+
+ for (md = ob_low->modifiers.first; md; md = md->next) {
+ /* Edge Split cannot be applied in the cage,
+ otherwise we loose interpolated normals */
+ if (md->type == eModifierType_EdgeSplit)
+ continue;
+
+ nmd = modifier_new(md->type);
+ BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
+ modifier_copyData(md, nmd);
+ BLI_addtail(&modifiers_tmp, nmd);
+ }
+
+ /* temporarily replace the modifiers */
+ ob_low->modifiers = modifiers_tmp;
+
+ /* 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);
+
+ /* populate the pixel array with the face data */
+ RE_populate_bake_pixels(me_low, pixel_array_low, width, height);
+
/* 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;
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);
+ 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);
+ pixel_array_render = pixel_array_high;
+ }
+ 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);
+ pixel_array_render = pixel_array_low;
+ }
/* make sure low poly doesn't render, and high poly renders */
restrict_render_high = (ob_high->restrictflag & OB_RESTRICT_RENDER);
@@ -308,18 +357,56 @@ static int bake_exec(bContext *C, wmOperator *op)
ob_low->restrictflag |= OB_RESTRICT_RENDER;
ob_render = ob_high;
- BKE_libblock_free(bmain, me_high);
+ /* reverting data back */
+ ob_low->modifiers = modifiers_original;
+
+ while ((md = BLI_pophead(&modifiers_tmp))) {
+ modifier_free(md);
+ }
}
else {
+ /* get the mesh as it arrives in the renderer */
+ 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_low, pixel_array_low, width, height);
+ 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, num_pixels, depth, pass_type, result);
+ 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, num_pixels, depth, pass_type, result);
+ ok = RE_internal_bake(re, ob_render, pixel_array_render, num_pixels, depth, pass_type, result);
+
+ /* normal space conversion */
+ if (pass_type == SCE_PASS_NORMAL) {
+ switch (normal_space) {
+ case R_BAKE_SPACE_WORLD:
+ {
+ /* Cycles internal format */
+ if (normal_swizzle[0] == OB_NEGX &&
+ normal_swizzle[1] == OB_NEGY &&
+ normal_swizzle[2] == OB_NEGZ)
+ break;
+ else
+ RE_normal_world_to_world(pixel_array_low, num_pixels, depth, result, normal_swizzle);
+ break;
+ }
+ case R_BAKE_SPACE_OBJECT:
+ RE_normal_world_to_object(pixel_array_low, num_pixels, depth, result, ob_low, normal_swizzle);
+ break;
+ case R_BAKE_SPACE_TANGENT:
+ RE_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle);
+ break;
+ default:
+ break;
+ }
+
+ }
if (!ok) {
BKE_report(op->reports, RPT_ERROR, "Problem baking object map");
@@ -329,7 +416,7 @@ static int bake_exec(bContext *C, wmOperator *op)
/* save the result */
if (is_external) {
/* save it externally */
- ok = write_external_bake_pixels(filepath, pixel_array, result, width, height, depth, is_linear, margin);
+ ok = write_external_bake_pixels(filepath, pixel_array_render, result, width, height, depth, is_linear, margin);
if (!ok) {
char *error = NULL;
error = BLI_sprintfN("Problem saving baked map in \"%s\".", filepath);
@@ -371,11 +458,19 @@ static int bake_exec(bContext *C, wmOperator *op)
RE_SetReports(re, NULL);
/* garbage collection */
- MEM_freeN(pixel_array);
- MEM_freeN(result);
+ MEM_freeN(pixel_array_low);
+
+ if (pixel_array_high) {
+ MEM_freeN(pixel_array_high);
+ }
+ MEM_freeN(result);
BKE_libblock_free(bmain, me_low);
+ if (me_high) {
+ BKE_libblock_free(bmain, me_high);
+ }
+
#if 0
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -434,6 +529,23 @@ static int bake_exec(bContext *C, wmOperator *op)
return op_result;
}
+static EnumPropertyItem normal_swizzle_items[] = {
+ {OB_POSX, "POS_X", 0, "+X", ""},
+ {OB_POSY, "POS_Y", 0, "+Y", ""},
+ {OB_POSZ, "POS_Z", 0, "+Z", ""},
+ {OB_NEGX, "NEG_X", 0, "-X", ""},
+ {OB_NEGY, "NEG_Y", 0, "-Y", ""},
+ {OB_NEGZ, "NEG_Z", 0, "-Z", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem normal_space_items[] = {
+ {R_BAKE_SPACE_WORLD, "WORLD", 0, "World", "Bake the normals in world space"},
+ {R_BAKE_SPACE_OBJECT, "OBJECT", 0, "Object", "Bake the normals in object space"},
+ //{R_BAKE_SPACE_TANGENT, "TANGENT", 0, "Tangent", "Bake the normals in tangent space"},
+ {0, NULL, 0, NULL, NULL}
+};
+
void OBJECT_OT_bake(wmOperatorType *ot)
{
/* identifiers */
@@ -456,4 +568,8 @@ void OBJECT_OT_bake(wmOperatorType *ot)
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);
+ ot->prop = RNA_def_enum(ot->srna, "normal_space", normal_space_items, R_BAKE_SPACE_WORLD, "Normal Space", "Choose normal space for baking");
+ ot->prop = RNA_def_enum(ot->srna, "normal_r", normal_swizzle_items, OB_NEGX, "R", "Axis to bake in red channel");
+ ot->prop = RNA_def_enum(ot->srna, "normal_g", normal_swizzle_items, OB_NEGY, "G", "Axis to bake in green channel");
+ ot->prop = RNA_def_enum(ot->srna, "normal_b", normal_swizzle_items, OB_NEGZ, "B", "Axis to bake in blue channel");
}
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index 32658c1..395dcb8 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -51,10 +51,16 @@ 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_from_object(struct Mesh *me_low, struct Mesh *me_high,
+ struct BakePixel pixel_array_from[], struct BakePixel pixel_array_to[],
+ 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, cons
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list