Commit: 45553cfaf1a92294f376a9428259410e2b632983
Author: Dalai Felinto
Date: Wed May 27 08:11:07 2015 -0300
Branches: fix-bake-dupli
https://developer.blender.org/rB45553cfaf1a92294f376a9428259410e2b632983
Bake-API: changes required to handle duplicated objects
===================================================================
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/source/blender/editors/object/object_bake_api.c
b/source/blender/editors/object/object_bake_api.c
index 68ef1f1..969c46d 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -46,6 +46,7 @@
#include "BLI_math_geom.h"
#include "BLI_path_util.h"
+#include "BKE_anim.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
@@ -548,6 +549,73 @@ static size_t initialize_internal_images(BakeImages
*bake_images, ReportList *re
return tot_size;
}
+static ModifierData *bake_triangulate_modifier(Main *bmain, Scene *scene,
Object *ob, ReportList *reports)
+{
+ ModifierData *tri_mod;
+ TriangulateModifierData *tmd;
+
+ /* triangulating so BVH returns the primitive_id that will be used for
rendering */
+ tri_mod = ED_object_modifier_add(
+ reports, bmain, scene, ob,
+ "TmpTriangulate", eModifierType_Triangulate);
+
+ tmd = (TriangulateModifierData *)tri_mod;
+ tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
+ tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;
+
+ return tri_mod;
+}
+
+/* get the lookup mesh id, creates one entry if necessary */
+static int bake_mesh_get(Main *bmain, Scene *scene, BakeHighPolyMesh **meshes,
Object *ob, ReportList *reports)
+{
+ BakeHighPolyMesh *mesh;
+ int i = 0;
+
+ while ((mesh = meshes[i])) {
+ if (mesh->ob == ob) {
+ return i;
+ }
+ i++;
+ }
+
+ mesh = MEM_callocN(sizeof(BakeHighPolyMesh), "Bake Mesh Lookup Entry");
+ mesh->ob = ob;
+ mesh->restrict_flag = ob->restrictflag;
+ mesh->tri_mod = bake_triangulate_modifier(bmain, scene, ob, reports);
+
+ mesh->me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0);
+ BKE_mesh_split_faces(mesh->me);
+ BKE_mesh_tessface_ensure(mesh->me);
+
+ meshes[i] = mesh;
+ return i;
+}
+
+static void bake_highpoly_setup(
+ Main *bmain, Scene *scene,
+ BakeHighPolyData *highpoly,
+ BakeHighPolyMesh **meshes,
+ Object *ob, float obmat[4][4],
+ const char *name, const bool is_dupli,
+ ReportList *reports)
+{
+ /* initialize highpoly_data */
+ highpoly->ob = ob;
+ highpoly->name = name;
+
+ if (!is_dupli) {
+ highpoly->ob->restrictflag &= ~OB_RESTRICT_RENDER;
+ }
+
+ /* lowpoly to highpoly transformation matrix */
+ copy_m4_m4(highpoly->obmat, obmat);
+ invert_m4_m4(highpoly->imat, highpoly->obmat);
+
+ highpoly->is_flip_object = is_negative_m4(obmat);
+ highpoly->mesh_lookup_id = bake_mesh_get(bmain, scene, meshes, ob,
reports);
+}
+
static int bake(
Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase
*selected_objects, ReportList *reports,
const ScenePassType pass_type, const int margin,
@@ -564,6 +632,8 @@ static int bake(
BakeHighPolyData *highpoly = NULL;
int tot_highpoly;
+ int tot_dupli;
+ int tot_mesh_objects;
char restrict_flag_low = ob_low->restrictflag;
char restrict_flag_cage = 0;
@@ -586,6 +656,9 @@ static int bake(
int tot_materials;
int i;
+ ListBase **dupli_list_arr = NULL;
+ BakeHighPolyMesh **meshes_lookup_arr = NULL;
+
RE_bake_engine_set_engine_parameters(re, bmain, scene);
if (!RE_bake_has_engine(re)) {
@@ -658,6 +731,7 @@ static int bake(
if (is_selected_to_active) {
CollectionPointerLink *link;
tot_highpoly = 0;
+ tot_dupli = 0;
for (link = selected_objects->first; link; link = link->next) {
Object *ob_iter = link->ptr.data;
@@ -665,7 +739,10 @@ static int bake(
if (ob_iter == ob_low)
continue;
- tot_highpoly ++;
+ if ((ob_iter->transflag & OB_DUPLI) == 0)
+ tot_highpoly ++;
+ else
+ tot_dupli ++;
}
if (is_cage && custom_cage[0] != '\0') {
@@ -680,6 +757,34 @@ static int bake(
ob_cage->restrictflag |= OB_RESTRICT_RENDER;
}
}
+
+ if (tot_dupli > 0) {
+ DupliObject *dob;
+ int i = 0;
+ dupli_list_arr = MEM_callocN(sizeof(ListBase *) *
tot_dupli, "bake dupli object lists");
+
+ for (link = selected_objects->first; link; link =
link->next) {
+ Object *ob_iter = link->ptr.data;
+
+ if (ob_iter == ob_low)
+ continue;
+
+ if ((ob_iter->transflag & OB_DUPLI) == 0) {
+ dupli_list_arr[i] =
object_duplilist(bmain->eval_ctx, scene, ob_iter);
+
+ for (dob = dupli_list_arr[i]->first;
dob; dob = dob->next) {
+ if (dob->ob->type == 'MESH') {
+ tot_highpoly ++;
+ }
+ }
+ i++;
+ }
+ }
+ }
+
+ tot_mesh_objects = tot_highpoly + tot_dupli;
+ /* we overallocate in case all objects are unique */
+ meshes_lookup_arr = MEM_callocN(sizeof(BakeHighPolyMesh *) *
tot_mesh_objects, "Bake Mesh Lookup All");
}
pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake
pixels low poly");
@@ -700,7 +805,8 @@ static int bake(
CollectionPointerLink *link;
ModifierData *md, *nmd;
ListBase modifiers_tmp, modifiers_original;
- int i = 0;
+ int i = 0; /* highpoly object index */
+ int j = 0; /* duplilist index */
/* prepare cage mesh */
if (ob_cage) {
@@ -748,58 +854,86 @@ static int bake(
/* populate highpoly array */
for (link = selected_objects->first; link; link = link->next) {
- TriangulateModifierData *tmd;
Object *ob_iter = link->ptr.data;
if (ob_iter == ob_low)
continue;
- /* initialize highpoly_data */
- highpoly[i].ob = ob_iter;
- highpoly[i].restrict_flag = ob_iter->restrictflag;
+ if ((ob_iter->transflag & OB_DUPLI) == 0) {
+ bake_highpoly_setup(bmain, scene, &highpoly[i],
meshes_lookup_arr, ob_iter, ob_iter->obmat, ob_iter->id.name, false, reports);
+ unit_m4(highpoly[i].mat);
+ i++;
+ }
+ else {
+ DupliObject *dob;
+ float imat[4][4];
+ invert_m4_m4(imat, ob_iter->obmat);
+ for (dob = dupli_list_arr[j]->first; dob; dob =
dob->next) {
+ if (dob->ob->type == 'MESH') {
+ float obmat[4][4];
- /* triangulating so BVH returns the primitive_id that
will be used for rendering */
- highpoly[i].tri_mod = ED_object_modifier_add(
- 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;
+ /* calculate the corresponding
global matrix */
+ mul_m4_m4m4(obmat,
ob_iter->obmat, dob->mat);
- highpoly[i].me = BKE_mesh_new_from_object(bmain, scene,
highpoly[i].ob, 1, 2, 0, 0);
- highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER;
- BKE_mesh_split_faces(highpoly[i].me);
- BKE_mesh_tessface_ensure(highpoly[i].me);
+ bake_highpoly_setup(bmain,
scene, &highpoly[i], meshes_lookup_arr, dob->ob, obmat, ob_iter->id.name, true,
reports);
- /* lowpoly to highpoly transformation matrix */
- copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
- invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
- unit_m4(highpoly[i].mat);
+ /* calculate the baking matrix
(from the original object to the dupli) */
+ mul_m4_m4m4(highpoly[i].imat,
imat, dob->mat);
- highpoly[i].is_flip_object =
is_negative_m4(highpoly[i].ob->obmat);
+ i++;
+ }
+ }
+ free_object_duplilist(dupli_list_arr[j]);
+ j++;
+ }
+ }
- i++;
+ if (dupli_list_arr)
+ MEM_freeN(dupli_list_arr);
+
+ /* get real mesh count */
+ for (i = 0; i < tot_mesh_objects; i++) {
+ if (meshes_lookup_arr[i] == NULL) {
+ break;
+ }
}
+ tot_mesh_objects = i;
+
BLI_assert(i == tot_highpoly);
+ BLI_assert(j == tot_dupli);
ob_low->restrictflag |= OB_RESTRICT_RENDER;
/* populate the pixel arrays with the corresponding face data
for each high poly object */
if (!RE_bake_pixels_populate_from_objects(
- me_low, pixel_array_low, pixel_array_high,
highpoly, tot_highpoly, num_pixels, ob_cage != NULL,
- cage_extrusion, ob_low->obmat, (ob_cage ?
ob_cage->obmat : ob_low->obmat), me_cage))
+ me_low, pixel_array_low, pixel_array_high,
+ meshes_lookup_arr, tot_mesh_objects,
+ highpoly, tot_highpoly,
+ num_pixels, ob_cage != NULL,
+ cage_extrusion, ob_low->obmat,
+ (ob_cage ? ob_cage->obmat : ob_low->obmat),
me_cage))
{
BKE_report(reports, RPT_ERROR, "Error handling selected
objects");
goto cage_cleanup;
}
+ /* free some memory before the baking */
+ if (meshes_lookup_arr) {
+ for (i = 0; i < tot_mesh_objects; i++) {
+ if (meshes_lookup_arr[i]->me) {
+ BKE_libblock_free(bmain,
meshes_lookup_arr[i]->me);
+ meshes_lookup_arr[i]->me = NULL;
+ }
+ }
+ }
+
/* the baking itself */
for (i = 0; i < tot_highpoly; i++) {
ok = RE_bake_engine(re, highpoly[i].ob, i,
pixel_array_high,
num_pixels, depth, pass_type,
highpoly[i].mat, result);
if (!ok) {
- BKE_reportf(reports, RPT_ERROR, "Error baking
from object \"%s\"", highpoly[i].ob->id.name + 2);
+ BKE_reportf(reports, RPT_ERROR, "Error baking
from object \"%s\"", highpoly[i].name + 2);
goto cage_cleanup;
}
}
@@ -984,18 +1118,28 @@ cage_cleanup:
cleanup:
- if (highpoly) {
+ if (highpoly)
+ MEM_freeN(highpoly);
+
+ if (meshes_lookup_arr) {
int i;
- for (i = 0; i < tot_highpoly; i++) {
- highpoly[i].ob->restrictflag =
highpoly[i].restrict_flag;
+ for (i = 0; i < tot_mesh_objects; i++) {
+ if (meshes_lookup_arr[i]) {
+
+ meshes_lookup_arr[i]->ob->restrictflag =
meshes_lookup_arr[i]->restrict_flag;
- if (highpoly[i].tri_mod)
- ED_object_modifier_remove(reports, bmain,
highpoly[i].ob, highpoly[i].tri_mod);
+ if (meshes_lookup_arr[i]->tri_mod) {
+ ED_object_modifier_remove(reports,
bmain, meshes_lookup_arr[i]->ob, meshes_lookup_arr[i]->tri_mod);
+ }
- if (highpoly[i].me)
- BKE_libblock_free(bmain, highpoly[i].me);
+ if (meshes_lookup_arr[i]->me) {
+ BKE_libblock_free(bmain,
meshes_lookup_arr[i]->me);
+ }
+
+ MEM_freeN(meshes_lookup_arr[i]);
+ }
}
- MEM_freeN(highpoly);
+ MEM_freeN(meshes_lookup_arr);
}
ob_low->restrictflag = restrict_flag_low;
diff --git a/source/blender/render/extern/include/RE_bake.h
b/source/blender/render/extern/include/RE_bake.h
index e226333..a987aea 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/bl
@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs