Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/object/object_bake_api.c
| Show First 20 Lines • Show All 489 Lines • ▼ Show 20 Lines | typedef struct BakeAPIRender { | ||||
| bool is_automatic_name; | bool is_automatic_name; | ||||
| bool is_selected_to_active; | bool is_selected_to_active; | ||||
| bool is_cage; | bool is_cage; | ||||
| float cage_extrusion; | float cage_extrusion; | ||||
| int normal_space; | int normal_space; | ||||
| BakeNormalSwizzle normal_swizzle[3]; | BakeNormalSwizzle normal_swizzle[3]; | ||||
| char uv_layer[MAX_NAME]; | |||||
| char custom_cage[MAX_NAME]; | char custom_cage[MAX_NAME]; | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| int width; | int width; | ||||
| int height; | int height; | ||||
| const char *identifier; | const char *identifier; | ||||
| int result; | int result; | ||||
| bool ready; | bool ready; | ||||
| /* for redrawing */ | /* for redrawing */ | ||||
| ScrArea *sa; | ScrArea *sa; | ||||
| } BakeAPIRender; | } BakeAPIRender; | ||||
| static int bake( | static int bake( | ||||
| Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, | Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, | ||||
| const ScenePassType pass_type, const int margin, | const ScenePassType pass_type, const int margin, | ||||
| const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials, | const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials, | ||||
| const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage, | const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage, | ||||
| const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[], | const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[], | ||||
| const char *custom_cage, const char *filepath, const int width, const int height, | const char *custom_cage, const char *filepath, const int width, const int height, | ||||
| const char *identifier, ScrArea *sa) | const char *identifier, ScrArea *sa, const char *uv_layer) | ||||
| { | { | ||||
| int op_result = OPERATOR_CANCELLED; | int op_result = OPERATOR_CANCELLED; | ||||
| bool ok = false; | bool ok = false; | ||||
| Object *ob_cage = NULL; | Object *ob_cage = NULL; | ||||
| BakeHighPolyData *highpoly = NULL; | BakeHighPolyData *highpoly = NULL; | ||||
| int tot_highpoly; | int tot_highpoly; | ||||
| Show All 19 Lines | static int bake( | ||||
| int tot_materials; | int tot_materials; | ||||
| int i; | int i; | ||||
| re = RE_NewRender(scene->id.name); | re = RE_NewRender(scene->id.name); | ||||
| RE_SetReports(re, NULL); | RE_SetReports(re, NULL); | ||||
| tot_materials = ob_low->totcol; | tot_materials = ob_low->totcol; | ||||
| if (uv_layer && uv_layer[0] != '\0') { | |||||
| Mesh *me = (Mesh *)ob_low->data; | |||||
| if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer) == -1) { | |||||
| BKE_reportf(reports, RPT_ERROR, | |||||
campbellbarton: I think only this check is needed?
- Source mesh needs CD_MLOOPUV
- Tessellated mesh needs… | |||||
| "No UV layer named \"%s\" found in the active object", uv_layer); | |||||
| goto cleanup; | |||||
| } | |||||
| } | |||||
| if (tot_materials == 0) { | if (tot_materials == 0) { | ||||
| if (is_save_internal) { | if (is_save_internal) { | ||||
| BKE_report(reports, RPT_ERROR, | BKE_report(reports, RPT_ERROR, | ||||
| "No active image found, add a material or bake to an external file"); | "No active image found, add a material or bake to an external file"); | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| else if (is_split_materials) { | else if (is_split_materials) { | ||||
| ▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | static int bake( | ||||
| pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); | pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly"); | ||||
| result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels"); | result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels"); | ||||
| /* get the mesh as it arrives in the renderer */ | /* get the mesh as it arrives in the renderer */ | ||||
| me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); | me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); | ||||
| /* populate the pixel array with the face data */ | /* populate the pixel array with the face data */ | ||||
| if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false) | if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false) | ||||
| RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images); | RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images, uv_layer); | ||||
| /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh) */ | /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh) */ | ||||
| if (is_selected_to_active) { | if (is_selected_to_active) { | ||||
| CollectionPointerLink *link; | CollectionPointerLink *link; | ||||
| ModifierData *md, *nmd; | ModifierData *md, *nmd; | ||||
| ListBase modifiers_tmp, modifiers_original; | ListBase modifiers_tmp, modifiers_original; | ||||
| int i = 0; | int i = 0; | ||||
| Show All 27 Lines | else if (is_cage) { | ||||
| BLI_addtail(&modifiers_tmp, nmd); | BLI_addtail(&modifiers_tmp, nmd); | ||||
| } | } | ||||
| /* temporarily replace the modifiers */ | /* temporarily replace the modifiers */ | ||||
| ob_low->modifiers = modifiers_tmp; | ob_low->modifiers = modifiers_tmp; | ||||
| /* get the cage mesh as it arrives in the renderer */ | /* get the cage mesh as it arrives in the renderer */ | ||||
| me_cage = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); | me_cage = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); | ||||
| RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images); | RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer); | ||||
| } | } | ||||
| highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects"); | highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects"); | ||||
| /* populate highpoly array */ | /* populate highpoly array */ | ||||
| for (link = selected_objects->first; link; link = link->next) { | for (link = selected_objects->first; link; link = link->next) { | ||||
| TriangulateModifierData *tmd; | TriangulateModifierData *tmd; | ||||
| Object *ob_iter = link->ptr.data; | Object *ob_iter = link->ptr.data; | ||||
| ▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | switch (normal_space) { | ||||
| md = modifiers_findByType(ob_low, eModifierType_Multires); | md = modifiers_findByType(ob_low, eModifierType_Multires); | ||||
| if (md) { | if (md) { | ||||
| mode = md->mode; | mode = md->mode; | ||||
| md->mode &= ~eModifierMode_Render; | md->mode &= ~eModifierMode_Render; | ||||
| } | } | ||||
| me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); | me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); | ||||
| RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images); | RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer); | ||||
| RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat); | RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat); | ||||
| BKE_libblock_free(bmain, me_nores); | BKE_libblock_free(bmain, me_nores); | ||||
| if (md) | if (md) | ||||
| md->mode = mode; | md->mode = mode; | ||||
| } | } | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) | ||||
| bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r"); | bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r"); | ||||
| bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g"); | bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g"); | ||||
| bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b"); | bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b"); | ||||
| bkr->width = RNA_int_get(op->ptr, "width"); | bkr->width = RNA_int_get(op->ptr, "width"); | ||||
| bkr->height = RNA_int_get(op->ptr, "height"); | bkr->height = RNA_int_get(op->ptr, "height"); | ||||
| bkr->identifier = ""; | bkr->identifier = ""; | ||||
| RNA_string_get(op->ptr, "uv_layer", bkr->uv_layer); | |||||
| RNA_string_get(op->ptr, "cage", bkr->custom_cage); | RNA_string_get(op->ptr, "cage", bkr->custom_cage); | ||||
| if ((!is_save_internal) && bkr->is_automatic_name) { | if ((!is_save_internal) && bkr->is_automatic_name) { | ||||
| PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type"); | PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type"); | ||||
| RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier); | RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier); | ||||
| } | } | ||||
| CTX_data_selected_objects(C, &bkr->selected_objects); | CTX_data_selected_objects(C, &bkr->selected_objects); | ||||
| Show All 23 Lines | static int bake_exec(bContext *C, wmOperator *op) | ||||
| } | } | ||||
| if (bkr.is_selected_to_active) { | if (bkr.is_selected_to_active) { | ||||
| result = bake( | result = bake( | ||||
| bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, | bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, | ||||
| bkr.pass_type, bkr.margin, bkr.save_mode, | bkr.pass_type, bkr.margin, bkr.save_mode, | ||||
| bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage, | bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage, | ||||
| bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle, | bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle, | ||||
| bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa); | bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa, | ||||
| bkr.uv_layer); | |||||
| } | } | ||||
| else { | else { | ||||
| CollectionPointerLink *link; | CollectionPointerLink *link; | ||||
| const bool is_clear = bkr.is_clear && BLI_listbase_is_single(&bkr.selected_objects); | const bool is_clear = bkr.is_clear && BLI_listbase_is_single(&bkr.selected_objects); | ||||
| for (link = bkr.selected_objects.first; link; link = link->next) { | for (link = bkr.selected_objects.first; link; link = link->next) { | ||||
| Object *ob_iter = link->ptr.data; | Object *ob_iter = link->ptr.data; | ||||
| result = bake( | result = bake( | ||||
| bkr.main, bkr.scene, ob_iter, NULL, bkr.reports, | bkr.main, bkr.scene, ob_iter, NULL, bkr.reports, | ||||
| bkr.pass_type, bkr.margin, bkr.save_mode, | bkr.pass_type, bkr.margin, bkr.save_mode, | ||||
| is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage, | is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage, | ||||
| bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle, | bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle, | ||||
| bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa); | bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa, | ||||
| bkr.uv_layer); | |||||
| } | } | ||||
| } | } | ||||
| BLI_freelistN(&bkr.selected_objects); | BLI_freelistN(&bkr.selected_objects); | ||||
| return result; | return result; | ||||
| } | } | ||||
| static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress)) | static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress)) | ||||
| Show All 11 Lines | static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_update), float *UNUSED(progress)) | ||||
| } | } | ||||
| if (bkr->is_selected_to_active) { | if (bkr->is_selected_to_active) { | ||||
| bkr->result = bake( | bkr->result = bake( | ||||
| bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, | bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, | ||||
| bkr->pass_type, bkr->margin, bkr->save_mode, | bkr->pass_type, bkr->margin, bkr->save_mode, | ||||
| bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage, | bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage, | ||||
| bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle, | bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle, | ||||
| bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa); | bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa, | ||||
| bkr->uv_layer); | |||||
| } | } | ||||
| else { | else { | ||||
| CollectionPointerLink *link; | CollectionPointerLink *link; | ||||
| const bool is_clear = bkr->is_clear && BLI_listbase_is_single(&bkr->selected_objects); | const bool is_clear = bkr->is_clear && BLI_listbase_is_single(&bkr->selected_objects); | ||||
| for (link = bkr->selected_objects.first; link; link = link->next) { | for (link = bkr->selected_objects.first; link; link = link->next) { | ||||
| Object *ob_iter = link->ptr.data; | Object *ob_iter = link->ptr.data; | ||||
| bkr->result = bake( | bkr->result = bake( | ||||
| bkr->main, bkr->scene, ob_iter, NULL, bkr->reports, | bkr->main, bkr->scene, ob_iter, NULL, bkr->reports, | ||||
| bkr->pass_type, bkr->margin, bkr->save_mode, | bkr->pass_type, bkr->margin, bkr->save_mode, | ||||
| is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage, | is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage, | ||||
| bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle, | bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle, | ||||
| bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa); | bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa, | ||||
| bkr->uv_layer); | |||||
| if (bkr->result == OPERATOR_CANCELLED) | if (bkr->result == OPERATOR_CANCELLED) | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void bake_freejob(void *bkv) | static void bake_freejob(void *bkv) | ||||
| ▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | void OBJECT_OT_bake(wmOperatorType *ot) | ||||
| RNA_def_boolean(ot->srna, "use_clear", false, "Clear", | RNA_def_boolean(ot->srna, "use_clear", false, "Clear", | ||||
| "Clear Images before baking (only for internal saving)"); | "Clear Images before baking (only for internal saving)"); | ||||
| RNA_def_boolean(ot->srna, "use_cage", false, "Cage", | RNA_def_boolean(ot->srna, "use_cage", false, "Cage", | ||||
| "Cast rays to active object from a cage"); | "Cast rays to active object from a cage"); | ||||
| RNA_def_boolean(ot->srna, "use_split_materials", false, "Split Materials", | RNA_def_boolean(ot->srna, "use_split_materials", false, "Split Materials", | ||||
| "Split baked maps per material, using material name in output file (external only)"); | "Split baked maps per material, using material name in output file (external only)"); | ||||
| RNA_def_boolean(ot->srna, "use_automatic_name", false, "Automatic Name", | RNA_def_boolean(ot->srna, "use_automatic_name", false, "Automatic Name", | ||||
| "Automatically name the output file with the pass type"); | "Automatically name the output file with the pass type"); | ||||
| RNA_def_string(ot->srna, "uv_layer", NULL, MAX_NAME, "UV Layer", "UV layer to override active"); | |||||
Not Done Inline Actionsthink this is more clear? "UV layer to override active" campbellbarton: think this is more clear?
"UV layer to override active" | |||||
| } | } | ||||
I think only this check is needed?