Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/object/object_bake_api.c18
-rw-r--r--source/blender/makesrna/intern/rna_render.c13
-rw-r--r--source/blender/render/extern/include/RE_bake.h7
-rw-r--r--source/blender/render/extern/include/RE_engine.h2
-rw-r--r--source/blender/render/intern/source/bake_api.c54
-rw-r--r--source/blender/render/intern/source/external_engine.c5
6 files changed, 55 insertions, 44 deletions
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index d492a4b9dda..578335a385b 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 2f2d72577d5..dbb572b7333 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 num_pixels, const int depth, void *result)
{
extern FunctionRNA rna_RenderEngine_bake_func;
PointerRNA ptr;
@@ -169,6 +171,7 @@ static void engine_bake(RenderEngine *engine, struct Scene *scene, struct Object
RNA_parameter_set_lookup(&list, "scene", &scene);
RNA_parameter_set_lookup(&list, "object", &object);
RNA_parameter_set_lookup(&list, "pass_type", &pass_type);
+ RNA_parameter_set_lookup(&list, "object_id", &object_id);
RNA_parameter_set_lookup(&list, "pixel_array", &pixel_array);
RNA_parameter_set_lookup(&list, "num_pixels", &num_pixels);
RNA_parameter_set_lookup(&list, "depth", &depth);
@@ -423,6 +426,8 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REQUIRED);
prop = RNA_def_enum(func, "pass_type", render_pass_type_items, 0, "Pass", "Pass to bake");
RNA_def_property_flag(prop, PROP_REQUIRED);
+ prop = RNA_def_int(func, "object_id", 0, 0, INT_MAX, "Object Id", "Id of the current object being baked in relation to the others", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_REQUIRED);
prop = RNA_def_pointer(func, "pixel_array", "BakePixel", "", "");
RNA_def_property_flag(prop, PROP_REQUIRED);
prop = RNA_def_int(func, "num_pixels", 0, 0, INT_MAX, "Number of Pixels", "Size of the baking batch", 0, INT_MAX);
@@ -816,6 +821,10 @@ static void rna_def_render_bake_pixel(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "primitive_id");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ prop = RNA_def_property(srna, "object_id", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "object_id");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
RNA_def_property_array(prop, 2);
RNA_def_property_float_sdna(prop, NULL, "uv");
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index ffc1246b878..e8a8986714d 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -50,14 +50,13 @@ typedef struct BakeImages {
} BakeImages;
typedef struct BakePixel {
- int primitive_id;
+ int primitive_id, object_id;
float uv[2];
float du_dx, du_dy;
float dv_dx, dv_dy;
} BakePixel;
typedef struct BakeHighPolyData {
- struct BakePixel *pixel_array;
struct Object *ob;
struct ModifierData *tri_mod;
struct Mesh *me;
@@ -72,7 +71,7 @@ typedef struct BakeHighPolyData {
bool RE_bake_has_engine(struct Render *re);
bool RE_bake_engine(
- struct Render *re, struct Object *object, const BakePixel pixel_array[],
+ struct Render *re, struct Object *object, const int object_id, const BakePixel pixel_array[],
const size_t num_pixels, const int depth, const ScenePassType pass_type, float result[]);
/* bake.c */
@@ -82,7 +81,7 @@ bool RE_bake_internal(
const size_t num_pixels, const int depth, const ScenePassType pass_type, float result[]);
bool RE_bake_pixels_populate_from_objects(
- struct Mesh *me_low, BakePixel pixel_array_from[],
+ struct Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[],
BakeHighPolyData highpoly[], const int tot_highpoly, const size_t num_pixels, const bool is_custom_cage,
const float cage_extrusion, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage);
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 4857c409f08..9d3c74163d5 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -88,7 +88,7 @@ typedef struct RenderEngineType {
void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene);
void (*render)(struct RenderEngine *engine, struct Scene *scene);
- void (*bake)(struct 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);
+ void (*bake)(struct RenderEngine *engine, struct Scene *scene, struct Object *object, const int pass_type, const int object_id, const struct BakePixel *pixel_array, const int num_pixels, const int depth, void *result);
void (*view_update)(struct RenderEngine *engine, const struct bContext *context);
void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index ecfb86c8d17..1f7555bc5c5 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -30,10 +30,11 @@
*
* The Bake API is fully implemented with Python rna functions. The operator expects/call a function:
*
- * ``def bake(scene, object, pass_type, pixel_array, num_pixels, depth, result)``
+ * ``def bake(scene, object, pass_type, object_id, pixel_array, num_pixels, depth, result)``
* - scene: current scene (Python object)
* - object: object to render (Python object)
* - pass_type: pass to render (string, e.g., "COMBINED", "AO", "NORMAL", ...)
+ * - object_id: index of object to bake (to use with the pixel_array)
* - pixel_array: list of primitive ids and barycentric coordinates to bake(Python object, see bake_pixel)
* - num_pixels: size of pixel_array, number of pixels to bake (int)
* - depth: depth of pixels to return (int, assuming always 4 now)
@@ -47,7 +48,7 @@
*
* \code{.c}
* struct BakePixel {
- * int primitive_id;
+ * int primitive_id, object_id;
* float uv[2];
* float du_dx, du_dy;
* float dv_dx, dv_dy;
@@ -55,7 +56,7 @@
* \endcode
*
* In python you have access to:
- * - ``primitive_id``, ``uv``, ``du_dx``, ``du_dy``, ``next``
+ * - ``primitive_id``, ``object_id``, ``uv``, ``du_dx``, ``du_dy``, ``next``
* - ``next()`` is a function that returns the next #BakePixel in the array.
*
* \note Pixels that should not be baked have ``primitive_id == -1``
@@ -126,12 +127,16 @@ static void store_bake_pixel(void *handle, int x, int y, float u, float v)
pixel = &bd->pixel_array[i];
pixel->primitive_id = bd->primitive_id;
+ /* At this point object_id is always 0, since this function runs for the
+ * lowpoly mesh only. The object_id lookup indices are set afterwards. */
+
copy_v2_fl2(pixel->uv, u, v);
pixel->du_dx = bd->du_dx;
pixel->du_dy = bd->du_dy;
pixel->dv_dx = bd->dv_dx;
pixel->dv_dy = bd->dv_dy;
+ pixel->object_id = 0;
}
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, char *mask)
@@ -271,7 +276,7 @@ static void calc_barycentric_from_point(
* This function populates pixel_array and returns TRUE if things are correct
*/
static bool cast_ray_highpoly(
- BVHTreeFromMesh *treeData, TriTessFace *triangles[], BakeHighPolyData *highpoly,
+ BVHTreeFromMesh *treeData, TriTessFace *triangles[], BakePixel *pixel_array, BakeHighPolyData *highpoly,
const float co[3], const float dir[3], const int pixel_id, const int tot_highpoly,
const float du_dx, const float du_dy, const float dv_dx, const float dv_dy)
{
@@ -322,22 +327,22 @@ static bool cast_ray_highpoly(
}
}
- for (i = 0; i < tot_highpoly; i++) {
- if (hit_mesh == i) {
- calc_barycentric_from_point(triangles[i], hits[i].index, hits[i].co, &primitive_id, uv);
- highpoly[i].pixel_array[pixel_id].primitive_id = primitive_id;
- copy_v2_v2(highpoly[i].pixel_array[pixel_id].uv, uv);
-
- /* the differentials are relative to the UV/image space, so the highpoly differentials
- * are the same as the low poly differentials */
- highpoly[i].pixel_array[pixel_id].du_dx = du_dx;
- highpoly[i].pixel_array[pixel_id].du_dy = du_dy;
- highpoly[i].pixel_array[pixel_id].dv_dx = dv_dx;
- highpoly[i].pixel_array[pixel_id].dv_dy = dv_dy;
- }
- else {
- highpoly[i].pixel_array[pixel_id].primitive_id = -1;
- }
+ if (hit_mesh != -1) {
+ calc_barycentric_from_point(triangles[hit_mesh], hits[hit_mesh].index, hits[hit_mesh].co, &primitive_id, uv);
+ pixel_array[pixel_id].primitive_id = primitive_id;
+ pixel_array[pixel_id].object_id = hit_mesh;
+ copy_v2_v2(pixel_array[pixel_id].uv, uv);
+
+ /* the differentials are relative to the UV/image space, so the highpoly differentials
+ * are the same as the low poly differentials */
+ pixel_array[pixel_id].du_dx = du_dx;
+ pixel_array[pixel_id].du_dy = du_dy;
+ pixel_array[pixel_id].dv_dx = dv_dx;
+ pixel_array[pixel_id].dv_dy = dv_dy;
+ }
+ else {
+ pixel_array[pixel_id].primitive_id = -1;
+ pixel_array[pixel_id].object_id = -1;
}
MEM_freeN(hits);
@@ -437,7 +442,7 @@ static void mesh_calc_tri_tessface(
}
bool RE_bake_pixels_populate_from_objects(
- struct Mesh *me_low, BakePixel pixel_array_from[],
+ struct Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[],
BakeHighPolyData highpoly[], const int tot_highpoly, const size_t num_pixels, const bool is_custom_cage,
const float cage_extrusion, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage)
{
@@ -508,10 +513,7 @@ bool RE_bake_pixels_populate_from_objects(
primitive_id = pixel_array_from[i].primitive_id;
if (primitive_id == -1) {
- int j;
- for (j = 0; j < tot_highpoly; j++) {
- highpoly[j].pixel_array[i].primitive_id = -1;
- }
+ pixel_array_to[i].primitive_id = -1;
continue;
}
@@ -530,7 +532,7 @@ bool RE_bake_pixels_populate_from_objects(
}
/* cast ray */
- if (!cast_ray_highpoly(treeData, tris_high, highpoly, co, dir, i, tot_highpoly,
+ if (!cast_ray_highpoly(treeData, tris_high, pixel_array_to, highpoly, co, dir, i, tot_highpoly,
pixel_array_from[i].du_dx, pixel_array_from[i].du_dy,
pixel_array_from[i].dv_dx, pixel_array_from[i].dv_dy)) {
/* if it fails mask out the original pixel array */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 343c4a9387a..653af7460f9 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -463,7 +463,8 @@ bool RE_bake_has_engine(Render *re)
}
bool RE_bake_engine(
- Render *re, Object *object, const BakePixel pixel_array[],
+ Render *re, Object *object,
+ const int object_id, const BakePixel pixel_array[],
const size_t num_pixels, const int depth,
const ScenePassType pass_type, float result[])
{
@@ -501,7 +502,7 @@ bool RE_bake_engine(
type->update(engine, re->main, re->scene);
if (type->bake)
- type->bake(engine, re->scene, object, pass_type, pixel_array, num_pixels, depth, result);
+ type->bake(engine, re->scene, object, pass_type, object_id, pixel_array, num_pixels, depth, result);
engine->tile_x = 0;
engine->tile_y = 0;