diff options
Diffstat (limited to 'source/blender/editors/object/object_bake_api.c')
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 5746f9efd56..2c4f7a8e107 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -379,7 +379,10 @@ static bool bake_object_check(Object *ob, ReportList *reports) if (node) { if (BKE_node_is_connected_to_output(ntree, node)) { - BKE_reportf(reports, RPT_ERROR, + /* we don't return false since this may be a false positive + * this can't be RPT_ERROR though, otherwise it prevents + * multiple highpoly objects to be baked at once */ + BKE_reportf(reports, RPT_INFO, "Circular dependency for image \"%s\" from object \"%s\"", image->id.name + 2, ob->id.name + 2); } @@ -560,7 +563,7 @@ static int bake( Object *ob_cage = NULL; BakeHighPolyData *highpoly = NULL; - int tot_highpoly; + int tot_highpoly = 0; char restrict_flag_low = ob_low->restrictflag; char restrict_flag_cage = 0; @@ -571,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); @@ -679,10 +683,13 @@ 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 */ - 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, 0, 0); + BKE_mesh_split_faces(me_low); + BKE_mesh_tessface_ensure(me_low); /* populate the pixel array with the face data */ if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false) @@ -697,7 +704,9 @@ static int bake( /* prepare cage mesh */ if (ob_cage) { - me_cage = BKE_mesh_new_from_object(bmain, scene, ob_cage, 1, 2, 1, 0); + me_cage = BKE_mesh_new_from_object(bmain, scene, ob_cage, 1, 2, 0, 0); + BKE_mesh_split_faces(me_cage); + BKE_mesh_tessface_ensure(me_cage); if (me_low->totface != me_cage->totface) { BKE_report(reports, RPT_ERROR, "Invalid cage object, the cage mesh must have the same number " @@ -729,7 +738,9 @@ static int bake( ob_low->modifiers = modifiers_tmp; /* 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, 0, 0); + BKE_mesh_split_faces(me_cage); + BKE_mesh_tessface_ensure(me_cage); RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer); } @@ -746,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( @@ -757,18 +766,16 @@ static int bake( tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED; tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP; - highpoly[i].me = BKE_mesh_new_from_object(bmain, scene, highpoly[i].ob, 1, 2, 1, 0); + highpoly[i].me = BKE_mesh_new_from_object(bmain, scene, highpoly[i].ob, 1, 2, 0, 0); highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER; + BKE_mesh_split_faces(highpoly[i].me); + BKE_mesh_tessface_ensure(highpoly[i].me); /* lowpoly to highpoly transformation matrix */ copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat); invert_m4_m4(highpoly[i].imat, highpoly[i].obmat); - /* rotation */ - normalize_m4_m4(highpoly[i].rotmat, highpoly[i].imat); - zero_v3(highpoly[i].rotmat[3]); - if (is_negative_m4(highpoly[i].rotmat)) - negate_m3(highpoly[i].rotmat); + highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat); i++; } @@ -779,7 +786,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"); @@ -788,8 +795,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; @@ -815,7 +822,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"); @@ -864,7 +871,9 @@ cage_cleanup: 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, 0, 0); + BKE_mesh_split_faces(me_nores); + BKE_mesh_tessface_ensure(me_nores); 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); @@ -916,7 +925,7 @@ cage_cleanup: BakeData *bake = &scene->r.bake; char name[FILE_MAX]; - BKE_makepicstring_from_type(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false); + BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL); if (is_automatic_name) { BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_"); @@ -977,9 +986,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); @@ -997,6 +1003,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); @@ -1081,8 +1090,9 @@ static int bake_exec(bContext *C, wmOperator *op) /* setup new render */ RE_test_break_cb(re, NULL, bake_break); - if (!bake_objects_check(bkr.main, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) - return OPERATOR_CANCELLED; + if (!bake_objects_check(bkr.main, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) { + goto finally; + } if (bkr.is_clear) { const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) && (bkr.normal_space == R_BAKE_SPACE_TANGENT)); @@ -1117,6 +1127,8 @@ static int bake_exec(bContext *C, wmOperator *op) RE_SetReports(re, NULL); + +finally: BLI_freelistN(&bkr.selected_objects); return result; } @@ -1208,7 +1220,7 @@ static void bake_set_props(wmOperator *op, Scene *scene) prop = RNA_struct_find_property(op->ptr, "use_selected_to_active"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE)); + RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0); } prop = RNA_struct_find_property(op->ptr, "cage_extrusion"); @@ -1248,22 +1260,22 @@ static void bake_set_props(wmOperator *op, Scene *scene) prop = RNA_struct_find_property(op->ptr, "use_clear"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR)); + RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0); } prop = RNA_struct_find_property(op->ptr, "use_cage"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE)); + RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0); } prop = RNA_struct_find_property(op->ptr, "use_split_materials"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT)); + RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0); } prop = RNA_struct_find_property(op->ptr, "use_automatic_name"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME)); + RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0); } } |