Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_bake_api.c
| Show First 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | typedef struct BakeAPIRender { | ||||
| ListBase selected_objects; | ListBase selected_objects; | ||||
| /* Baking settings. */ | /* Baking settings. */ | ||||
| eBakeTarget target; | eBakeTarget target; | ||||
| eScenePassType pass_type; | eScenePassType pass_type; | ||||
| int pass_filter; | int pass_filter; | ||||
| int margin; | int margin; | ||||
| eBakeMarginType margin_type; | |||||
| bool is_clear; | bool is_clear; | ||||
| bool is_selected_to_active; | bool is_selected_to_active; | ||||
| bool is_cage; | bool is_cage; | ||||
| float cage_extrusion; | float cage_extrusion; | ||||
| float max_ray_distance; | float max_ray_distance; | ||||
| int normal_space; | int normal_space; | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static bool write_internal_bake_pixels(Image *image, | static bool write_internal_bake_pixels(Image *image, | ||||
| BakePixel pixel_array[], | BakePixel pixel_array[], | ||||
| float *buffer, | float *buffer, | ||||
| const int width, | const int width, | ||||
| const int height, | const int height, | ||||
| const int margin, | const int margin, | ||||
| const char margin_type, | |||||
| const bool is_clear, | const bool is_clear, | ||||
| const bool is_noncolor) | const bool is_noncolor, | ||||
| Mesh const *mesh, | |||||
| MLoopUV const *mloopuv) | |||||
| { | { | ||||
| ImBuf *ibuf; | ImBuf *ibuf; | ||||
| void *lock; | void *lock; | ||||
| bool is_float; | bool is_float; | ||||
| char *mask_buffer = NULL; | char *mask_buffer = NULL; | ||||
| const size_t num_pixels = (size_t)width * (size_t)height; | const size_t num_pixels = (size_t)width * (size_t)height; | ||||
| ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); | ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | else { | ||||
| ibuf->x, | ibuf->x, | ||||
| ibuf->x, | ibuf->x, | ||||
| mask_buffer); | mask_buffer); | ||||
| } | } | ||||
| } | } | ||||
| /* margins */ | /* margins */ | ||||
| if (margin > 0) { | if (margin > 0) { | ||||
| RE_bake_margin(ibuf, mask_buffer, margin); | RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh, mloopuv); | ||||
| } | } | ||||
| ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; | ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; | ||||
| BKE_image_mark_dirty(image, ibuf); | BKE_image_mark_dirty(image, ibuf); | ||||
| if (ibuf->rect_float) { | if (ibuf->rect_float) { | ||||
| ibuf->userflags |= IB_RECT_INVALID; | ibuf->userflags |= IB_RECT_INVALID; | ||||
| } | } | ||||
| Show All 29 Lines | |||||
| } | } | ||||
| static bool write_external_bake_pixels(const char *filepath, | static bool write_external_bake_pixels(const char *filepath, | ||||
| BakePixel pixel_array[], | BakePixel pixel_array[], | ||||
| float *buffer, | float *buffer, | ||||
| const int width, | const int width, | ||||
| const int height, | const int height, | ||||
| const int margin, | const int margin, | ||||
| const int margin_type, | |||||
| ImageFormatData *im_format, | ImageFormatData *im_format, | ||||
| const bool is_noncolor) | const bool is_noncolor, | ||||
| Mesh const *mesh, | |||||
| MLoopUV const *mloopuv) | |||||
| { | { | ||||
| ImBuf *ibuf = NULL; | ImBuf *ibuf = NULL; | ||||
| bool ok = false; | bool ok = false; | ||||
| bool is_float; | bool is_float; | ||||
| is_float = im_format->depth > 8; | is_float = im_format->depth > 8; | ||||
| /* create a new ImBuf */ | /* create a new ImBuf */ | ||||
| Show All 40 Lines | static bool write_external_bake_pixels(const char *filepath, | ||||
| /* margins */ | /* margins */ | ||||
| if (margin > 0) { | if (margin > 0) { | ||||
| char *mask_buffer = NULL; | char *mask_buffer = NULL; | ||||
| const size_t num_pixels = (size_t)width * (size_t)height; | const size_t num_pixels = (size_t)width * (size_t)height; | ||||
| mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); | mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); | ||||
| RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); | RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); | ||||
| RE_bake_margin(ibuf, mask_buffer, margin); | RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh, mloopuv); | ||||
| if (mask_buffer) { | if (mask_buffer) { | ||||
| MEM_freeN(mask_buffer); | MEM_freeN(mask_buffer); | ||||
| } | } | ||||
| } | } | ||||
| if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) { | if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) { | ||||
| #ifndef WIN32 | #ifndef WIN32 | ||||
| ▲ Show 20 Lines • Show All 368 Lines • ▼ Show 20 Lines | |||||
| static bool bake_targets_output_internal(const BakeAPIRender *bkr, | static bool bake_targets_output_internal(const BakeAPIRender *bkr, | ||||
| BakeTargets *targets, | BakeTargets *targets, | ||||
| Object *ob, | Object *ob, | ||||
| BakePixel *pixel_array, | BakePixel *pixel_array, | ||||
| ReportList *reports) | ReportList *reports) | ||||
| { | { | ||||
| bool all_ok = true; | bool all_ok = true; | ||||
| const Mesh *me = (Mesh *)ob->data; | |||||
| const MLoopUV *mloopuv; | |||||
| char const *uv_layer = bkr->uv_layer; | |||||
| if ((uv_layer == NULL) || (uv_layer[0] == '\0')) { | |||||
| mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV); | |||||
| } | |||||
| else { | |||||
| int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); | |||||
| mloopuv = CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id); | |||||
| } | |||||
brecht: Can this code be moved into `generate_margin`, and also take into account the `uv_layer` name… | |||||
Done Inline ActionsI moved it there. That is slightly more logical. However I still need to pass the char const *uv_layer in, and the MultiRes baking doesn't have that, so it doesn't really simplify the code as much as I'd like. Still more clear this way I think. Baardaap: I moved it there. That is slightly more logical. However I still need to pass the char const… | |||||
| for (int i = 0; i < targets->num_images; i++) { | for (int i = 0; i < targets->num_images; i++) { | ||||
| BakeImage *bk_image = &targets->images[i]; | BakeImage *bk_image = &targets->images[i]; | ||||
| const bool ok = write_internal_bake_pixels(bk_image->image, | const bool ok = write_internal_bake_pixels(bk_image->image, | ||||
| pixel_array + bk_image->offset, | pixel_array + bk_image->offset, | ||||
| targets->result + | targets->result + | ||||
| bk_image->offset * targets->num_channels, | bk_image->offset * targets->num_channels, | ||||
| bk_image->width, | bk_image->width, | ||||
| bk_image->height, | bk_image->height, | ||||
| bkr->margin, | bkr->margin, | ||||
| bkr->margin_type, | |||||
| bkr->is_clear, | bkr->is_clear, | ||||
| targets->is_noncolor); | targets->is_noncolor, | ||||
| me, | |||||
| mloopuv); | |||||
| /* might be read by UI to set active image for display */ | /* might be read by UI to set active image for display */ | ||||
| bake_update_image(bkr->area, bk_image->image); | bake_update_image(bkr->area, bk_image->image); | ||||
| if (!ok) { | if (!ok) { | ||||
| BKE_reportf(reports, | BKE_reportf(reports, | ||||
| RPT_ERROR, | RPT_ERROR, | ||||
| "Problem saving the bake map internally for object \"%s\"", | "Problem saving the bake map internally for object \"%s\"", | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | static bool bake_targets_output_external(const BakeAPIRender *bkr, | ||||
| BakeTargets *targets, | BakeTargets *targets, | ||||
| Object *ob, | Object *ob, | ||||
| Object *ob_eval, | Object *ob_eval, | ||||
| Mesh *me, | Mesh *me, | ||||
| BakePixel *pixel_array, | BakePixel *pixel_array, | ||||
| ReportList *reports) | ReportList *reports) | ||||
| { | { | ||||
| bool all_ok = true; | bool all_ok = true; | ||||
| const MLoopUV *mloopuv; | |||||
| char const *uv_layer = bkr->uv_layer; | |||||
| if ((uv_layer == NULL) || (uv_layer[0] == '\0')) { | |||||
| mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV); | |||||
| } | |||||
| else { | |||||
| int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); | |||||
| mloopuv = CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id); | |||||
| } | |||||
| for (int i = 0; i < targets->num_images; i++) { | for (int i = 0; i < targets->num_images; i++) { | ||||
| BakeImage *bk_image = &targets->images[i]; | BakeImage *bk_image = &targets->images[i]; | ||||
| BakeData *bake = &bkr->scene->r.bake; | BakeData *bake = &bkr->scene->r.bake; | ||||
| char name[FILE_MAX]; | char name[FILE_MAX]; | ||||
| BKE_image_path_from_imtype(name, | BKE_image_path_from_imtype(name, | ||||
| Show All 33 Lines | for (int i = 0; i < targets->num_images; i++) { | ||||
| /* save it externally */ | /* save it externally */ | ||||
| const bool ok = write_external_bake_pixels(name, | const bool ok = write_external_bake_pixels(name, | ||||
| pixel_array + bk_image->offset, | pixel_array + bk_image->offset, | ||||
| targets->result + | targets->result + | ||||
| bk_image->offset * targets->num_channels, | bk_image->offset * targets->num_channels, | ||||
| bk_image->width, | bk_image->width, | ||||
| bk_image->height, | bk_image->height, | ||||
| bkr->margin, | bkr->margin, | ||||
| bkr->margin_type, | |||||
| &bake->im_format, | &bake->im_format, | ||||
| targets->is_noncolor); | targets->is_noncolor, | ||||
| me, | |||||
| mloopuv); | |||||
| if (!ok) { | if (!ok) { | ||||
| BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name); | BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name); | ||||
| all_ok = false; | all_ok = false; | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name); | BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 712 Lines • ▼ Show 20 Lines | static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) | ||||
| bkr->main = CTX_data_main(C); | bkr->main = CTX_data_main(C); | ||||
| bkr->view_layer = CTX_data_view_layer(C); | bkr->view_layer = CTX_data_view_layer(C); | ||||
| bkr->scene = CTX_data_scene(C); | bkr->scene = CTX_data_scene(C); | ||||
| bkr->area = screen ? BKE_screen_find_big_area(screen, SPACE_IMAGE, 10) : NULL; | bkr->area = screen ? BKE_screen_find_big_area(screen, SPACE_IMAGE, 10) : NULL; | ||||
| bkr->pass_type = RNA_enum_get(op->ptr, "type"); | bkr->pass_type = RNA_enum_get(op->ptr, "type"); | ||||
| bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter"); | bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter"); | ||||
| bkr->margin = RNA_int_get(op->ptr, "margin"); | bkr->margin = RNA_int_get(op->ptr, "margin"); | ||||
| bkr->margin_type = RNA_enum_get(op->ptr, "margin_type"); | |||||
| bkr->save_mode = (eBakeSaveMode)RNA_enum_get(op->ptr, "save_mode"); | bkr->save_mode = (eBakeSaveMode)RNA_enum_get(op->ptr, "save_mode"); | ||||
| bkr->target = (eBakeTarget)RNA_enum_get(op->ptr, "target"); | bkr->target = (eBakeTarget)RNA_enum_get(op->ptr, "target"); | ||||
| bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear"); | bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear"); | ||||
| bkr->is_split_materials = (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES && | bkr->is_split_materials = (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES && | ||||
| bkr->save_mode == R_BAKE_SAVE_EXTERNAL) && | bkr->save_mode == R_BAKE_SAVE_EXTERNAL) && | ||||
| RNA_boolean_get(op->ptr, "use_split_materials"); | RNA_boolean_get(op->ptr, "use_split_materials"); | ||||
| ▲ Show 20 Lines • Show All 177 Lines • ▼ Show 20 Lines | if (!RNA_property_is_set(op->ptr, prop)) { | ||||
| RNA_property_int_set(op->ptr, prop, bake->width); | RNA_property_int_set(op->ptr, prop, bake->width); | ||||
| } | } | ||||
| prop = RNA_struct_find_property(op->ptr, "margin"); | prop = RNA_struct_find_property(op->ptr, "margin"); | ||||
| if (!RNA_property_is_set(op->ptr, prop)) { | if (!RNA_property_is_set(op->ptr, prop)) { | ||||
| RNA_property_int_set(op->ptr, prop, bake->margin); | RNA_property_int_set(op->ptr, prop, bake->margin); | ||||
| } | } | ||||
| prop = RNA_struct_find_property(op->ptr, "margin_type"); | |||||
| if (!RNA_property_is_set(op->ptr, prop)) { | |||||
| RNA_property_enum_set(op->ptr, prop, bake->margin_type); | |||||
| } | |||||
| prop = RNA_struct_find_property(op->ptr, "use_selected_to_active"); | prop = RNA_struct_find_property(op->ptr, "use_selected_to_active"); | ||||
| if (!RNA_property_is_set(op->ptr, prop)) { | if (!RNA_property_is_set(op->ptr, prop)) { | ||||
| RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0); | RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0); | ||||
| } | } | ||||
| prop = RNA_struct_find_property(op->ptr, "max_ray_distance"); | prop = RNA_struct_find_property(op->ptr, "max_ray_distance"); | ||||
| if (!RNA_property_is_set(op->ptr, prop)) { | if (!RNA_property_is_set(op->ptr, prop)) { | ||||
| RNA_property_float_set(op->ptr, prop, bake->max_ray_distance); | RNA_property_float_set(op->ptr, prop, bake->max_ray_distance); | ||||
| ▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | RNA_def_int(ot->srna, | ||||
| "margin", | "margin", | ||||
| 16, | 16, | ||||
| 0, | 0, | ||||
| INT_MAX, | INT_MAX, | ||||
| "Margin", | "Margin", | ||||
| "Extends the baked result as a post process filter", | "Extends the baked result as a post process filter", | ||||
| 0, | 0, | ||||
| 64); | 64); | ||||
| RNA_def_enum(ot->srna, | |||||
| "margin_type", | |||||
| rna_enum_bake_margin_type_items, | |||||
| R_BAKE_EXTEND, | |||||
| "Margin Type", | |||||
| "What algorithm to use to generate the margin"); | |||||
Done Inline ActionsWhat -> Which HooglyBoogly: `What` -> `Which` | |||||
| RNA_def_boolean(ot->srna, | RNA_def_boolean(ot->srna, | ||||
| "use_selected_to_active", | "use_selected_to_active", | ||||
| false, | false, | ||||
| "Selected to Active", | "Selected to Active", | ||||
| "Bake shading on the surface of selected objects to the active object"); | "Bake shading on the surface of selected objects to the active object"); | ||||
| RNA_def_float(ot->srna, | RNA_def_float(ot->srna, | ||||
| "max_ray_distance", | "max_ray_distance", | ||||
| 0.0f, | 0.0f, | ||||
| ▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines | |||||
Can this code be moved into generate_margin, and also take into account the uv_layer name for the derivedmesh case there?