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

Reply via email to