[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