Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_wrapper.cc
| Show First 20 Lines • Show All 308 Lines • ▼ Show 20 Lines | |||||
| static Mesh *mesh_wrapper_ensure_subdivision(const Object *ob, Mesh *me) | static Mesh *mesh_wrapper_ensure_subdivision(const Object *ob, Mesh *me) | ||||
| { | { | ||||
| SubsurfModifierData *smd = BKE_object_get_last_subsurf_modifier(ob); | SubsurfModifierData *smd = BKE_object_get_last_subsurf_modifier(ob); | ||||
| if (!smd) { | if (!smd) { | ||||
| return me; | return me; | ||||
| } | } | ||||
| SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; | |||||
| if (runtime_data == nullptr || runtime_data->settings.level == 0) { | |||||
| return me; | |||||
| } | |||||
| /* Initialize the settings before ensuring the descriptor as this is checked to decide whether | /* Initialize the settings before ensuring the descriptor as this is checked to decide whether | ||||
| * subdivision is needed at all, and checking the descriptor status might involve checking if the | * subdivision is needed at all, and checking the descriptor status might involve checking if the | ||||
| * data is out-of-date, which is a very expensive operation. */ | * data is out-of-date, which is a very expensive operation. */ | ||||
| SubdivToMeshSettings mesh_settings; | SubdivToMeshSettings mesh_settings; | ||||
| mesh_settings.resolution = me->runtime.subsurf_resolution; | mesh_settings.resolution = runtime_data->resolution; | ||||
| mesh_settings.use_optimal_display = me->runtime.subsurf_use_optimal_display; | mesh_settings.use_optimal_display = runtime_data->use_optimal_display; | ||||
| if (mesh_settings.resolution < 3) { | if (mesh_settings.resolution < 3) { | ||||
| return me; | return me; | ||||
| } | } | ||||
| const bool apply_render = me->runtime.subsurf_apply_render; | Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, me, false); | ||||
| SubdivSettings subdiv_settings; | |||||
| BKE_subsurf_modifier_subdiv_settings_init(&subdiv_settings, smd, apply_render); | |||||
| if (subdiv_settings.level == 0) { | |||||
| return me; | |||||
| } | |||||
| SubsurfRuntimeData *runtime_data = BKE_subsurf_modifier_ensure_runtime(smd); | |||||
| Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(smd, &subdiv_settings, me, false); | |||||
| if (subdiv == nullptr) { | if (subdiv == nullptr) { | ||||
| /* Happens on bad topology, but also on empty input mesh. */ | /* Happens on bad topology, but also on empty input mesh. */ | ||||
| return me; | return me; | ||||
| } | } | ||||
| const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, me); | const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, me); | ||||
| if (use_clnors) { | if (use_clnors) { | ||||
| /* If custom normals are present and the option is turned on calculate the split | /* If custom normals are present and the option is turned on calculate the split | ||||
| * normals and clear flag so the normals get interpolated to the result mesh. */ | * normals and clear flag so the normals get interpolated to the result mesh. */ | ||||
| BKE_mesh_calc_normals_split(me); | BKE_mesh_calc_normals_split(me); | ||||
| CustomData_clear_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | CustomData_clear_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | ||||
| } | } | ||||
| Mesh *subdiv_mesh = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me); | Mesh *subdiv_mesh = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me); | ||||
| if (use_clnors) { | if (use_clnors) { | ||||
| float(*lnors)[3] = static_cast<float(*)[3]>( | float(*lnors)[3] = static_cast<float(*)[3]>( | ||||
| CustomData_get_layer(&subdiv_mesh->ldata, CD_NORMAL)); | CustomData_get_layer(&subdiv_mesh->ldata, CD_NORMAL)); | ||||
| BLI_assert(lnors != NULL); | BLI_assert(lnors != NULL); | ||||
| BKE_mesh_set_custom_normals(subdiv_mesh, lnors); | BKE_mesh_set_custom_normals(subdiv_mesh, lnors); | ||||
| CustomData_set_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | CustomData_set_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | ||||
| CustomData_set_layer_flag(&subdiv_mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | CustomData_set_layer_flag(&subdiv_mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); | ||||
| } | } | ||||
| else if (me->runtime.subsurf_do_loop_normals) { | else if (runtime_data->calc_loop_normals) { | ||||
| BKE_mesh_calc_normals_split(subdiv_mesh); | BKE_mesh_calc_normals_split(subdiv_mesh); | ||||
| } | } | ||||
| if (subdiv != runtime_data->subdiv) { | if (subdiv != runtime_data->subdiv) { | ||||
| BKE_subdiv_free(subdiv); | BKE_subdiv_free(subdiv); | ||||
| } | } | ||||
| if (subdiv_mesh != me) { | if (subdiv_mesh != me) { | ||||
| Show All 30 Lines | |||||