Commit: 394c5318c6fe981f94fc78f312fc0295209288dc Author: Dalai Felinto Date: Fri Apr 17 12:25:37 2015 -0300 Branches: master https://developer.blender.org/rB394c5318c6fe981f94fc78f312fc0295209288dc
Bake-API: reduce memory footprint when baking more than one object (Fix T41092) Combine all the highpoly pixel arrays into a single array with a lookup object_id for each of the highpoly objects. Note: This changes the Bake API, external engines should refer to the bake_api.c for the latest API. Many thanks for Sergey Sharybin for the complete review, changes suggestion and feedback. (you rock!) Reviewers: sergey Subscribers: pildanovak, marcclintdion, monio, metalliandy, brecht Maniphest Tasks: T41092 Differential Revision: https://developer.blender.org/D772 =================================================================== M intern/cycles/blender/addon/__init__.py M intern/cycles/blender/addon/engine.py M intern/cycles/blender/blender_python.cpp M intern/cycles/blender/blender_session.cpp M intern/cycles/blender/blender_session.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/makesrna/intern/rna_render.c M source/blender/render/extern/include/RE_bake.h M source/blender/render/extern/include/RE_engine.h M source/blender/render/intern/source/bake_api.c M source/blender/render/intern/source/external_engine.c =================================================================== diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index 5b0c6a8..9c78e0c 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -65,8 +65,8 @@ class CyclesRender(bpy.types.RenderEngine): def render(self, scene): engine.render(self) - def bake(self, scene, obj, pass_type, pixel_array, num_pixels, depth, result): - engine.bake(self, obj, pass_type, pixel_array, num_pixels, depth, result) + def bake(self, scene, obj, pass_type, object_id, pixel_array, num_pixels, depth, result): + engine.bake(self, obj, pass_type, object_id, pixel_array, num_pixels, depth, result) # viewport render def view_update(self, context): diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index e50a8e4..4187e23 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -59,11 +59,11 @@ def render(engine): _cycles.render(engine.session) -def bake(engine, obj, pass_type, pixel_array, num_pixels, depth, result): +def bake(engine, obj, pass_type, object_id, pixel_array, num_pixels, depth, result): import _cycles session = getattr(engine, "session", None) if session is not None: - _cycles.bake(engine.session, obj.as_pointer(), pass_type, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer()) + _cycles.bake(engine.session, obj.as_pointer(), pass_type, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer()) def reset(engine, data, scene): diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index b952109..200003f 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -189,9 +189,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args) PyObject *pysession, *pyobject; PyObject *pypixel_array, *pyresult; const char *pass_type; - int num_pixels, depth; + int num_pixels, depth, object_id; - if(!PyArg_ParseTuple(args, "OOsOiiO", &pysession, &pyobject, &pass_type, &pypixel_array, &num_pixels, &depth, &pyresult)) + if(!PyArg_ParseTuple(args, "OOsiOiiO", &pysession, &pyobject, &pass_type, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult)) return NULL; BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession); @@ -208,7 +208,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args) python_thread_state_save(&session->python_thread_state); - session->bake(b_object, pass_type, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result); + session->bake(b_object, pass_type, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result); python_thread_state_restore(&session->python_thread_state); diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index bdacea0..8975146 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -511,18 +511,22 @@ void BlenderSession::render() sync = NULL; } -static void populate_bake_data(BakeData *data, BL::BakePixel pixel_array, const int num_pixels) +static void populate_bake_data(BakeData *data, const int object_id, BL::BakePixel pixel_array, const int num_pixels) { BL::BakePixel bp = pixel_array; int i; for(i=0; i < num_pixels; i++) { - data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy()); + if(bp.object_id() == object_id) { + data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy()); + } else { + data->set_null(i); + } bp = bp.next(); } } -void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, const size_t num_pixels, const int /*depth*/, float result[]) +void BlenderSession::bake(BL::Object b_object, const string& pass_type, const int object_id, BL::BakePixel pixel_array, const size_t num_pixels, const int /*depth*/, float result[]) { ShaderEvalType shader_type = get_shader_type(pass_type); size_t object_index = OBJECT_NONE; @@ -578,7 +582,7 @@ void BlenderSession::bake(BL::Object b_object, const string& pass_type, BL::Bake BakeData *bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); - populate_bake_data(bake_data, pixel_array, num_pixels); + populate_bake_data(bake_data, object_id, pixel_array, num_pixels); /* set number of samples */ session->tile_manager.set_samples(session_params.samples); diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index b6fc709..708776d 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -52,7 +52,7 @@ public: /* offline render */ void render(); - void bake(BL::Object b_object, const string& pass_type, BL::BakePixel pixel_array, const size_t num_pixels, const int depth, float pixels[]); + void bake(BL::Object b_object, const string& pass_type, const int object_id, BL::BakePixel pixel_array, const size_t num_pixels, const int depth, float pixels[]); void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile); void write_render_tile(RenderTile& rtile); diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index c520136..4bbac0f 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -55,6 +55,11 @@ void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float d m_dvdy[i] = dvdy; } +void BakeData::set_null(int i) +{ + m_primitive[i] = -1; +} + int BakeData::object() { return m_object; diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h index 9ff10da..14d975a 100644 --- a/intern/cycles/render/bake.h +++ b/intern/cycles/render/bake.h @@ -31,6 +31,7 @@ public: ~BakeData(); void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy); + void set_null(int i); int object(); size_t size(); uint4 data(int i); diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index d492a4b..578335a 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -574,6 +574,7 @@ static int bake( float *result = NULL; BakePixel *pixel_array_low = NULL; + BakePixel *pixel_array_high = NULL; const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL); const bool is_noncolor = is_noncolor_pass(pass_type); @@ -682,6 +683,7 @@ static int bake( } pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); + pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels"); /* get the mesh as it arrives in the renderer */ @@ -755,8 +757,6 @@ static int bake( /* initialize highpoly_data */ highpoly[i].ob = ob_iter; highpoly[i].restrict_flag = ob_iter->restrictflag; - highpoly[i].pixel_array = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly"); - /* triangulating so BVH returns the primitive_id that will be used for rendering */ highpoly[i].tri_mod = ED_object_modifier_add( @@ -790,7 +790,7 @@ static int bake( /* 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, highpoly, tot_highpoly, num_pixels, ob_cage != NULL, + 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)) { BKE_report(reports, RPT_ERROR, "Error handling selected objects"); @@ -799,8 +799,8 @@ static int bake( /* the baking itself */ for (i = 0; i < tot_highpoly; i++) { - ok = RE_bake_engine(re, highpoly[i].ob, highpoly[i].pixel_array, num_pixels, - depth, pass_type, result); + ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high, + num_pixels, depth, pass_type, result); if (!ok) { BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2); goto cage_cleanup; @@ -826,7 +826,7 @@ cage_cleanup: ob_low->restrictflag &= ~OB_RESTRICT_RENDER; if (RE_bake_has_engine(re)) { - ok = RE_bake_engine(re, ob_low, pixel_array_low, num_pixels, depth, pass_type, result); + ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, result); } else { BKE_report(reports, RPT_ERROR, "Current render engine does not support baking"); @@ -990,9 +990,6 @@ cleanup: for (i = 0; i < tot_highpoly; i++) { highpoly[i].ob->restrictflag = highpoly[i].restrict_flag; - if (highpoly[i].pixel_array) - MEM_freeN(highpoly[i].pixel_array); - if (highpoly[i].tri_mod) ED_object_modifier_remove(reports, bmain, highpoly[i].ob, highpoly[i].tri_mod); @@ -1010,6 +1007,9 @@ cleanup: if (pixel_array_low) MEM_freeN(pixel_array_low); + if (pixel_array_high) + MEM_freeN(pixel_array_high); + if (bake_images.data) MEM_freeN(bake_images.data); diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 2f2d725..dbb572b 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -154,8 +154,10 @@ static void engine_render(RenderEngine *engine, struct Scene *scene) RNA_parameter_list_free(&list); } -static void engine_bake(RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type, - const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result) +static void engine_bake(RenderEngine *engine, struct Scene *scene, + struct Object *object, const int pass_type, + const int object_id, const struct BakePixel *pixel_array, + const int n @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-blender-cvs
