Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/subdiv_modifier.c
| /* SPDX-License-Identifier: GPL-2.0-or-later | /* SPDX-License-Identifier: GPL-2.0-or-later | ||||
| * Copyright 2021 Blender Foundation. All rights reserved. */ | * Copyright 2021 Blender Foundation. All rights reserved. */ | ||||
| #include "BKE_subdiv_modifier.h" | #include "BKE_subdiv_modifier.h" | ||||
| #include "BLI_session_uuid.h" | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_modifier_types.h" | #include "DNA_modifier_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_userdef_types.h" | #include "DNA_userdef_types.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_subdiv.h" | #include "BKE_subdiv.h" | ||||
| #include "GPU_capabilities.h" | #include "GPU_capabilities.h" | ||||
| #include "GPU_context.h" | #include "GPU_context.h" | ||||
| #include "opensubdiv_capi.h" | #include "opensubdiv_capi.h" | ||||
| void BKE_subsurf_modifier_subdiv_settings_init(SubdivSettings *settings, | bool BKE_subsurf_modifier_runtime_init(SubsurfModifierData *smd, const bool use_render_params) | ||||
| const SubsurfModifierData *smd, | |||||
| const bool use_render_params) | |||||
| { | { | ||||
| const int requested_levels = (use_render_params) ? smd->renderLevels : smd->levels; | const int requested_levels = (use_render_params) ? smd->renderLevels : smd->levels; | ||||
| settings->is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); | SubdivSettings settings; | ||||
| settings->is_adaptive = !(smd->flags & eSubsurfModifierFlag_UseRecursiveSubdivision); | settings.is_simple = (smd->subdivType == SUBSURF_TYPE_SIMPLE); | ||||
| settings->level = settings->is_simple ? | settings.is_adaptive = !(smd->flags & eSubsurfModifierFlag_UseRecursiveSubdivision); | ||||
| 1 : | settings.level = settings.is_simple ? 1 : | ||||
| (settings->is_adaptive ? smd->quality : requested_levels); | (settings.is_adaptive ? smd->quality : requested_levels); | ||||
| settings->use_creases = (smd->flags & eSubsurfModifierFlag_UseCrease); | settings.use_creases = (smd->flags & eSubsurfModifierFlag_UseCrease); | ||||
| settings->vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf( | settings.vtx_boundary_interpolation = BKE_subdiv_vtx_boundary_interpolation_from_subsurf( | ||||
| smd->boundary_smooth); | smd->boundary_smooth); | ||||
| settings->fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth( | settings.fvar_linear_interpolation = BKE_subdiv_fvar_interpolation_from_uv_smooth( | ||||
| smd->uv_smooth); | smd->uv_smooth); | ||||
| SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; | |||||
| if (settings.level == 0) { | |||||
| /* Modifier is effectively disabled, but still update settings if runtime data | |||||
| * was already allocated. */ | |||||
| if (runtime_data) { | |||||
| runtime_data->settings = settings; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| else { | |||||
| /* Allocate runtime data if it did not exist yet. */ | |||||
| if (runtime_data == NULL) { | |||||
| runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime"); | |||||
| smd->modifier.runtime = runtime_data; | |||||
| } | |||||
| runtime_data->settings = settings; | |||||
| return true; | |||||
| } | |||||
| } | } | ||||
| static ModifierData *modifier_get_last_enabled_for_mode(const Scene *scene, | static ModifierData *modifier_get_last_enabled_for_mode(const Scene *scene, | ||||
| const Object *ob, | const Object *ob, | ||||
| int required_mode) | int required_mode) | ||||
| { | { | ||||
| ModifierData *md = ob->modifiers.last; | ModifierData *md = ob->modifiers.last; | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | if (md != (const ModifierData *)smd) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return is_subdivision_evaluation_possible_on_gpu(); | return is_subdivision_evaluation_possible_on_gpu(); | ||||
| } | } | ||||
| bool BKE_subsurf_modifier_has_gpu_subdiv(const Mesh *mesh) | bool BKE_subsurf_modifier_has_gpu_subdiv(const Mesh *mesh) | ||||
| { | { | ||||
| return BLI_session_uuid_is_generated(&mesh->runtime.subsurf_session_uuid); | SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data; | ||||
| return runtime_data && runtime_data->has_gpu_subdiv; | |||||
| } | } | ||||
| void (*BKE_subsurf_modifier_free_gpu_cache_cb)(Subdiv *subdiv) = NULL; | void (*BKE_subsurf_modifier_free_gpu_cache_cb)(Subdiv *subdiv) = NULL; | ||||
| Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(const SubsurfModifierData *smd, | Subdiv *BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtime_data, | ||||
| const SubdivSettings *subdiv_settings, | |||||
| const Mesh *mesh, | const Mesh *mesh, | ||||
| const bool for_draw_code) | const bool for_draw_code) | ||||
| { | { | ||||
| SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; | |||||
| if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) { | if (runtime_data->subdiv && runtime_data->set_by_draw_code != for_draw_code) { | ||||
| BKE_subdiv_free(runtime_data->subdiv); | BKE_subdiv_free(runtime_data->subdiv); | ||||
| runtime_data->subdiv = NULL; | runtime_data->subdiv = NULL; | ||||
| } | } | ||||
| Subdiv *subdiv = BKE_subdiv_update_from_mesh(runtime_data->subdiv, subdiv_settings, mesh); | Subdiv *subdiv = BKE_subdiv_update_from_mesh( | ||||
| runtime_data->subdiv, &runtime_data->settings, mesh); | |||||
| runtime_data->subdiv = subdiv; | runtime_data->subdiv = subdiv; | ||||
| runtime_data->set_by_draw_code = for_draw_code; | runtime_data->set_by_draw_code = for_draw_code; | ||||
| return subdiv; | return subdiv; | ||||
| } | } | ||||
| SubsurfRuntimeData *BKE_subsurf_modifier_ensure_runtime(SubsurfModifierData *smd) | |||||
| { | |||||
| SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; | |||||
| if (runtime_data == NULL) { | |||||
| runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime"); | |||||
| smd->modifier.runtime = runtime_data; | |||||
| } | |||||
| return runtime_data; | |||||
| } | |||||
| int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode) | int BKE_subsurf_modifier_eval_required_mode(bool is_final_render, bool is_edit_mode) | ||||
| { | { | ||||
| if (is_final_render) { | if (is_final_render) { | ||||
| return eModifierMode_Render; | return eModifierMode_Render; | ||||
| } | } | ||||
| return eModifierMode_Realtime | (is_edit_mode ? eModifierMode_Editmode : 0); | return eModifierMode_Realtime | (is_edit_mode ? eModifierMode_Editmode : 0); | ||||
| } | } | ||||