Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_subsurf.c
| Show First 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | if (ccg_settings.resolution < 3) { | ||||
| return result; | return result; | ||||
| } | } | ||||
| result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh); | result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh); | ||||
| return result; | return result; | ||||
| } | } | ||||
| /* Cache settings for lazy CPU evaluation. */ | /* Cache settings for lazy CPU evaluation. */ | ||||
| static void subdiv_cache_cpu_evaluation_settings(const ModifierEvalContext *ctx, | static void subdiv_cache_mesh_wrapper_settings(const ModifierEvalContext *ctx, | ||||
| Mesh *me, | Mesh *mesh, | ||||
| SubsurfModifierData *smd) | SubsurfModifierData *smd, | ||||
| SubsurfRuntimeData *runtime_data) | |||||
| { | { | ||||
| SubdivToMeshSettings mesh_settings; | SubdivToMeshSettings mesh_settings; | ||||
| subdiv_mesh_settings_init(&mesh_settings, smd, ctx); | subdiv_mesh_settings_init(&mesh_settings, smd, ctx); | ||||
| me->runtime.subsurf_apply_render = (ctx->flag & MOD_APPLY_RENDER) != 0; | |||||
| me->runtime.subsurf_resolution = mesh_settings.resolution; | runtime_data->has_gpu_subdiv = true; | ||||
| me->runtime.subsurf_use_optimal_display = mesh_settings.use_optimal_display; | runtime_data->resolution = mesh_settings.resolution; | ||||
| me->runtime.subsurf_session_uuid = smd->modifier.session_uuid; | runtime_data->use_optimal_display = mesh_settings.use_optimal_display; | ||||
| runtime_data->calc_loop_normals = false; /* Will be set during modifier evaluation. */ | |||||
| runtime_data->use_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals); | |||||
| mesh->runtime.subsurf_runtime_data = runtime_data; | |||||
| } | } | ||||
| /* Modifier itself. */ | /* Modifier itself. */ | ||||
| static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | ||||
| { | { | ||||
| Mesh *result = mesh; | Mesh *result = mesh; | ||||
| #if !defined(WITH_OPENSUBDIV) | #if !defined(WITH_OPENSUBDIV) | ||||
| BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); | BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); | ||||
| return result; | return result; | ||||
| #endif | #endif | ||||
| SubsurfModifierData *smd = (SubsurfModifierData *)md; | SubsurfModifierData *smd = (SubsurfModifierData *)md; | ||||
| SubdivSettings subdiv_settings; | if (!BKE_subsurf_modifier_runtime_init(smd, (ctx->flag & MOD_APPLY_RENDER) != 0)) { | ||||
| BKE_subsurf_modifier_subdiv_settings_init( | |||||
| &subdiv_settings, smd, (ctx->flag & MOD_APPLY_RENDER) != 0); | |||||
| if (subdiv_settings.level == 0) { | |||||
| return result; | return result; | ||||
| } | } | ||||
| SubsurfRuntimeData *runtime_data = BKE_subsurf_modifier_ensure_runtime(smd); | |||||
| SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; | |||||
| /* Delay evaluation to the draw code if possible, provided we do not have to apply the modifier. | /* Delay evaluation to the draw code if possible, provided we do not have to apply the modifier. | ||||
| */ | */ | ||||
| if ((ctx->flag & MOD_APPLY_TO_BASE_MESH) == 0) { | if ((ctx->flag & MOD_APPLY_TO_BASE_MESH) == 0) { | ||||
| Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); | Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); | ||||
| const bool is_render_mode = (ctx->flag & MOD_APPLY_RENDER) != 0; | const bool is_render_mode = (ctx->flag & MOD_APPLY_RENDER) != 0; | ||||
| /* Same check as in `DRW_mesh_batch_cache_create_requested` to keep both code coherent. The | /* Same check as in `DRW_mesh_batch_cache_create_requested` to keep both code coherent. The | ||||
| * difference is that here we do not check for the final edit mesh pointer as it is not yet | * difference is that here we do not check for the final edit mesh pointer as it is not yet | ||||
| * assigned at this stage of modifier stack evaluation. */ | * assigned at this stage of modifier stack evaluation. */ | ||||
| const bool is_editmode = (mesh->edit_mesh != NULL); | const bool is_editmode = (mesh->edit_mesh != NULL); | ||||
| const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode); | const int required_mode = BKE_subsurf_modifier_eval_required_mode(is_render_mode, is_editmode); | ||||
| if (BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ctx->object, mesh, smd, required_mode)) { | if (BKE_subsurf_modifier_can_do_gpu_subdiv(scene, ctx->object, mesh, smd, required_mode)) { | ||||
| subdiv_cache_cpu_evaluation_settings(ctx, mesh, smd); | subdiv_cache_mesh_wrapper_settings(ctx, mesh, smd, runtime_data); | ||||
| return result; | return result; | ||||
| } | } | ||||
| } | } | ||||
| Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure( | Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, mesh, false); | ||||
| smd, &subdiv_settings, mesh, false); | |||||
| if (subdiv == NULL) { | if (subdiv == NULL) { | ||||
| /* Happens on bad topology, but also on empty input mesh. */ | /* Happens on bad topology, but also on empty input mesh. */ | ||||
| return result; | return result; | ||||
| } | } | ||||
| const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh); | const bool use_clnors = BKE_subsurf_modifier_use_custom_loop_normals(smd, mesh); | ||||
| 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. */ | ||||
| Show All 34 Lines | #if !defined(WITH_OPENSUBDIV) | ||||
| BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); | BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); | ||||
| return; | return; | ||||
| #endif | #endif | ||||
| /* Subsurf does not require extra space mapping, keep matrices as is. */ | /* Subsurf does not require extra space mapping, keep matrices as is. */ | ||||
| (void)deform_matrices; | (void)deform_matrices; | ||||
| SubsurfModifierData *smd = (SubsurfModifierData *)md; | SubsurfModifierData *smd = (SubsurfModifierData *)md; | ||||
| SubdivSettings subdiv_settings; | if (!BKE_subsurf_modifier_runtime_init(smd, (ctx->flag & MOD_APPLY_RENDER) != 0)) { | ||||
| BKE_subsurf_modifier_subdiv_settings_init( | |||||
| &subdiv_settings, smd, (ctx->flag & MOD_APPLY_RENDER) != 0); | |||||
| if (subdiv_settings.level == 0) { | |||||
| return; | return; | ||||
| } | } | ||||
| SubsurfRuntimeData *runtime_data = BKE_subsurf_modifier_ensure_runtime(smd); | SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)smd->modifier.runtime; | ||||
| Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure( | Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, mesh, false); | ||||
| smd, &subdiv_settings, mesh, false); | |||||
| if (subdiv == NULL) { | if (subdiv == NULL) { | ||||
| /* Happens on bad topology, but also on empty input mesh. */ | /* Happens on bad topology, but also on empty input mesh. */ | ||||
| return; | return; | ||||
| } | } | ||||
| BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num); | BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num); | ||||
| if (subdiv != runtime_data->subdiv) { | if (subdiv != runtime_data->subdiv) { | ||||
| BKE_subdiv_free(subdiv); | BKE_subdiv_free(subdiv); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 196 Lines • Show Last 20 Lines | |||||