Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_impl_subdivision.cc
| Show First 20 Lines • Show All 1,017 Lines • ▼ Show 20 Lines | static void build_vertex_face_adjacency_maps(DRWSubdivCache *cache) | ||||
| } | } | ||||
| MEM_freeN(tmp_set_faces); | MEM_freeN(tmp_set_faces); | ||||
| } | } | ||||
| static bool draw_subdiv_build_cache(DRWSubdivCache *cache, | static bool draw_subdiv_build_cache(DRWSubdivCache *cache, | ||||
| Subdiv *subdiv, | Subdiv *subdiv, | ||||
| Mesh *mesh_eval, | Mesh *mesh_eval, | ||||
| const Scene *scene, | const SubsurfRuntimeData *runtime_data) | ||||
| const SubsurfModifierData *smd, | |||||
| const bool is_final_render) | |||||
| { | { | ||||
| const int requested_levels = (is_final_render) ? smd->renderLevels : smd->levels; | |||||
| const int level = get_render_subsurf_level(&scene->r, requested_levels, is_final_render); | |||||
| SubdivToMeshSettings to_mesh_settings; | SubdivToMeshSettings to_mesh_settings; | ||||
| to_mesh_settings.resolution = (1 << level) + 1; | to_mesh_settings.resolution = runtime_data->resolution; | ||||
| to_mesh_settings.use_optimal_display = false; | to_mesh_settings.use_optimal_display = false; | ||||
| if (cache->resolution != to_mesh_settings.resolution) { | if (cache->resolution != to_mesh_settings.resolution) { | ||||
| /* Resolution changed, we need to rebuild, free any existing cached data. */ | /* Resolution changed, we need to rebuild, free any existing cached data. */ | ||||
| draw_subdiv_cache_free(cache); | draw_subdiv_cache_free(cache); | ||||
| } | } | ||||
| /* If the resolution between the cache and the settings match for some reason, check if the patch | /* If the resolution between the cache and the settings match for some reason, check if the patch | ||||
| ▲ Show 20 Lines • Show All 913 Lines • ▼ Show 20 Lines | static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache, | ||||
| cache->polygon_mat_offset = draw_subdiv_build_origindex_buffer(per_polygon_mat_offset, | cache->polygon_mat_offset = draw_subdiv_build_origindex_buffer(per_polygon_mat_offset, | ||||
| mesh_eval->totpoly); | mesh_eval->totpoly); | ||||
| cache->mat_start = mat_start; | cache->mat_start = mat_start; | ||||
| cache->mat_end = mat_end; | cache->mat_end = mat_end; | ||||
| MEM_freeN(per_polygon_mat_offset); | MEM_freeN(per_polygon_mat_offset); | ||||
| } | } | ||||
| static bool draw_subdiv_create_requested_buffers(const Scene *scene, | static bool draw_subdiv_create_requested_buffers(Object *ob, | ||||
| Object *ob, | |||||
| Mesh *mesh, | Mesh *mesh, | ||||
| struct MeshBatchCache *batch_cache, | struct MeshBatchCache *batch_cache, | ||||
| MeshBufferCache *mbc, | MeshBufferCache *mbc, | ||||
| const bool is_editmode, | const bool is_editmode, | ||||
| const bool is_paint_mode, | const bool is_paint_mode, | ||||
| const bool is_mode_active, | const bool is_mode_active, | ||||
| const float obmat[4][4], | const float obmat[4][4], | ||||
| const bool do_final, | const bool do_final, | ||||
| const bool do_uvedit, | const bool do_uvedit, | ||||
| const ToolSettings *ts, | const ToolSettings *ts, | ||||
| const bool use_hide, | const bool use_hide, | ||||
| OpenSubdiv_EvaluatorCache *evaluator_cache) | OpenSubdiv_EvaluatorCache *evaluator_cache) | ||||
| { | { | ||||
| SubsurfModifierData *smd = reinterpret_cast<SubsurfModifierData *>( | SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data; | ||||
| BKE_modifiers_findby_session_uuid(ob, &mesh->runtime.subsurf_session_uuid)); | BLI_assert(runtime_data && runtime_data->has_gpu_subdiv); | ||||
| BLI_assert(smd); | |||||
| const bool is_final_render = DRW_state_is_scene_render(); | if (runtime_data->settings.level == 0) { | ||||
| SubdivSettings settings; | |||||
| BKE_subsurf_modifier_subdiv_settings_init(&settings, smd, is_final_render); | |||||
| if (settings.level == 0) { | |||||
| return false; | return false; | ||||
| } | } | ||||
| Mesh *mesh_eval = mesh; | Mesh *mesh_eval = mesh; | ||||
| BMesh *bm = nullptr; | BMesh *bm = nullptr; | ||||
| if (mesh->edit_mesh) { | if (mesh->edit_mesh) { | ||||
| mesh_eval = BKE_object_get_editmesh_eval_final(ob); | mesh_eval = BKE_object_get_editmesh_eval_final(ob); | ||||
| bm = mesh->edit_mesh->bm; | bm = mesh->edit_mesh->bm; | ||||
| } | } | ||||
| BKE_subsurf_modifier_ensure_runtime(smd); | Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(runtime_data, mesh_eval, true); | ||||
| Subdiv *subdiv = BKE_subsurf_modifier_subdiv_descriptor_ensure(smd, &settings, mesh_eval, true); | |||||
| if (!subdiv) { | if (!subdiv) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (!BKE_subdiv_eval_begin_from_mesh( | if (!BKE_subdiv_eval_begin_from_mesh( | ||||
| subdiv, mesh_eval, nullptr, SUBDIV_EVALUATOR_TYPE_GLSL_COMPUTE, evaluator_cache)) { | subdiv, mesh_eval, nullptr, SUBDIV_EVALUATOR_TYPE_GLSL_COMPUTE, evaluator_cache)) { | ||||
| /* This could happen in two situations: | /* This could happen in two situations: | ||||
| * - OpenSubdiv is disabled. | * - OpenSubdiv is disabled. | ||||
| * - Something totally bad happened, and OpenSubdiv rejected our | * - Something totally bad happened, and OpenSubdiv rejected our | ||||
| * topology. | * topology. | ||||
| * In either way, we can't safely continue. However, we still have to handle potential loose | * In either way, we can't safely continue. However, we still have to handle potential loose | ||||
| * geometry, which is done separately. */ | * geometry, which is done separately. */ | ||||
| if (mesh_eval->totpoly) { | if (mesh_eval->totpoly) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| DRWSubdivCache *draw_cache = mesh_batch_cache_ensure_subdiv_cache(batch_cache); | DRWSubdivCache *draw_cache = mesh_batch_cache_ensure_subdiv_cache(batch_cache); | ||||
| if (!draw_subdiv_build_cache(draw_cache, subdiv, mesh_eval, scene, smd, is_final_render)) { | if (!draw_subdiv_build_cache(draw_cache, subdiv, mesh_eval, runtime_data)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Edges which do not come from coarse edges should not be drawn in edit mode, only in object | /* Edges which do not come from coarse edges should not be drawn in edit mode, only in object | ||||
| * mode when optimal display in turned off. */ | * mode when optimal display in turned off. */ | ||||
| const bool optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges) || is_editmode; | const bool optimal_display = runtime_data->use_optimal_display || is_editmode; | ||||
| draw_cache->bm = bm; | draw_cache->bm = bm; | ||||
| draw_cache->mesh = mesh_eval; | draw_cache->mesh = mesh_eval; | ||||
| draw_cache->subdiv = subdiv; | draw_cache->subdiv = subdiv; | ||||
| draw_cache->optimal_display = optimal_display; | draw_cache->optimal_display = optimal_display; | ||||
| draw_cache->num_subdiv_triangles = tris_count_from_number_of_loops(draw_cache->num_subdiv_loops); | draw_cache->num_subdiv_triangles = tris_count_from_number_of_loops(draw_cache->num_subdiv_loops); | ||||
| /* Copy topology information for stats display. Use `mesh` directly, as `mesh_eval` could be the | /* Copy topology information for stats display. Use `mesh` directly, as `mesh_eval` could be the | ||||
| * edit mesh. */ | * edit mesh. */ | ||||
kevindietrich: The last sentence about `mesh` can be removed. | |||||
| mesh->runtime.subsurf_totvert = draw_cache->num_subdiv_verts; | runtime_data->stats_totvert = draw_cache->num_subdiv_verts; | ||||
| mesh->runtime.subsurf_totedge = draw_cache->num_subdiv_edges; | runtime_data->stats_totedge = draw_cache->num_subdiv_edges; | ||||
| mesh->runtime.subsurf_totpoly = draw_cache->num_subdiv_quads; | runtime_data->stats_totpoly = draw_cache->num_subdiv_quads; | ||||
| mesh->runtime.subsurf_totloop = draw_cache->num_subdiv_loops; | runtime_data->stats_totloop = draw_cache->num_subdiv_loops; | ||||
| draw_cache->use_custom_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals) && | draw_cache->use_custom_loop_normals = (runtime_data->use_loop_normals) && | ||||
| (mesh_eval->flag & ME_AUTOSMOOTH) && | (mesh_eval->flag & ME_AUTOSMOOTH) && | ||||
| CustomData_has_layer(&mesh_eval->ldata, | CustomData_has_layer(&mesh_eval->ldata, | ||||
| CD_CUSTOMLOOPNORMAL); | CD_CUSTOMLOOPNORMAL); | ||||
| if (DRW_ibo_requested(mbc->buff.ibo.tris)) { | if (DRW_ibo_requested(mbc->buff.ibo.tris)) { | ||||
| draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache->mat_len); | draw_subdiv_cache_ensure_mat_offsets(draw_cache, mesh_eval, batch_cache->mat_len); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | |||||
| blender::Span<DRWSubdivLooseVertex> draw_subdiv_cache_get_loose_verts(const DRWSubdivCache *cache) | blender::Span<DRWSubdivLooseVertex> draw_subdiv_cache_get_loose_verts(const DRWSubdivCache *cache) | ||||
| { | { | ||||
| return {cache->loose_geom.verts + cache->loose_geom.edge_len * 2, | return {cache->loose_geom.verts + cache->loose_geom.edge_len * 2, | ||||
| static_cast<int64_t>(cache->loose_geom.vert_len)}; | static_cast<int64_t>(cache->loose_geom.vert_len)}; | ||||
| } | } | ||||
| static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr; | static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr; | ||||
| void DRW_create_subdivision(const Scene *scene, | void DRW_create_subdivision(Object *ob, | ||||
| Object *ob, | |||||
| Mesh *mesh, | Mesh *mesh, | ||||
| struct MeshBatchCache *batch_cache, | struct MeshBatchCache *batch_cache, | ||||
| MeshBufferCache *mbc, | MeshBufferCache *mbc, | ||||
| const bool is_editmode, | const bool is_editmode, | ||||
| const bool is_paint_mode, | const bool is_paint_mode, | ||||
| const bool is_mode_active, | const bool is_mode_active, | ||||
| const float obmat[4][4], | const float obmat[4][4], | ||||
| const bool do_final, | const bool do_final, | ||||
| const bool do_uvedit, | const bool do_uvedit, | ||||
| const ToolSettings *ts, | const ToolSettings *ts, | ||||
| const bool use_hide) | const bool use_hide) | ||||
| { | { | ||||
| if (g_evaluator_cache == nullptr) { | if (g_evaluator_cache == nullptr) { | ||||
| g_evaluator_cache = openSubdiv_createEvaluatorCache(OPENSUBDIV_EVALUATOR_GLSL_COMPUTE); | g_evaluator_cache = openSubdiv_createEvaluatorCache(OPENSUBDIV_EVALUATOR_GLSL_COMPUTE); | ||||
| } | } | ||||
| #undef TIME_SUBDIV | #undef TIME_SUBDIV | ||||
| #ifdef TIME_SUBDIV | #ifdef TIME_SUBDIV | ||||
| const double begin_time = PIL_check_seconds_timer(); | const double begin_time = PIL_check_seconds_timer(); | ||||
| #endif | #endif | ||||
| if (!draw_subdiv_create_requested_buffers(scene, | if (!draw_subdiv_create_requested_buffers(ob, | ||||
| ob, | |||||
| mesh, | mesh, | ||||
| batch_cache, | batch_cache, | ||||
| mbc, | mbc, | ||||
| is_editmode, | is_editmode, | ||||
| is_paint_mode, | is_paint_mode, | ||||
| is_mode_active, | is_mode_active, | ||||
| obmat, | obmat, | ||||
| do_final, | do_final, | ||||
| ▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines | |||||
The last sentence about mesh can be removed.