Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_subdivision.cc')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_subdivision.cc202
1 files changed, 120 insertions, 82 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
index cde2b59ea23..6a9e6c126e9 100644
--- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc
+++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc
@@ -7,8 +7,10 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BKE_attribute.hh"
#include "BKE_editmesh.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_scene.h"
@@ -19,8 +21,8 @@
#include "BKE_subdiv_modifier.h"
#include "BLI_linklist.h"
-
#include "BLI_string.h"
+#include "BLI_virtual_array.hh"
#include "PIL_time.h"
@@ -44,6 +46,8 @@
#include "draw_cache_inline.h"
#include "mesh_extractors/extract_mesh.hh"
+using blender::Span;
+
extern "C" char datatoc_common_subdiv_custom_data_interp_comp_glsl[];
extern "C" char datatoc_common_subdiv_ibo_lines_comp_glsl[];
extern "C" char datatoc_common_subdiv_ibo_tris_comp_glsl[];
@@ -357,14 +361,14 @@ static GPUVertFormat *get_subdiv_vertex_format()
struct CompressedPatchCoord {
int ptex_face_index;
/* UV coordinate encoded as u << 16 | v, where u and v are quantized on 16-bits. */
- unsigned int encoded_uv;
+ uint encoded_uv;
};
MINLINE CompressedPatchCoord make_patch_coord(int ptex_face_index, float u, float v)
{
CompressedPatchCoord patch_coord = {
ptex_face_index,
- (static_cast<unsigned int>(u * 65535.0f) << 16) | static_cast<unsigned int>(v * 65535.0f),
+ (uint(u * 65535.0f) << 16) | uint(v * 65535.0f),
};
return patch_coord;
}
@@ -631,17 +635,9 @@ void draw_subdiv_cache_free(DRWSubdivCache *cache)
SUBDIV_COARSE_FACE_FLAG_ACTIVE | SUBDIV_COARSE_FACE_FLAG_HIDDEN) \
<< SUBDIV_COARSE_FACE_FLAG_OFFSET)
-static uint32_t compute_coarse_face_flag(BMFace *f, BMFace *efa_act)
+static uint32_t compute_coarse_face_flag_bm(BMFace *f, BMFace *efa_act)
{
- if (f == nullptr) {
- /* May happen during mapped extraction. */
- return 0;
- }
-
uint32_t flag = 0;
- if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
- flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
- }
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
@@ -651,8 +647,7 @@ static uint32_t compute_coarse_face_flag(BMFace *f, BMFace *efa_act)
if (f == efa_act) {
flag |= SUBDIV_COARSE_FACE_FLAG_ACTIVE;
}
- const int loopstart = BM_elem_index_get(f->l_first);
- return (uint)(loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
+ return flag;
}
static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm,
@@ -664,24 +659,32 @@ static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm,
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
const int index = BM_elem_index_get(f);
- flags_data[index] = compute_coarse_face_flag(f, efa_act);
+ uint32_t flag = compute_coarse_face_flag_bm(f, efa_act);
+ if (BM_elem_flag_test(f, BM_ELEM_SMOOTH)) {
+ flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
+ }
+ const int loopstart = BM_elem_index_get(f->l_first);
+ flags_data[index] = uint(loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
-static void draw_subdiv_cache_extra_coarse_face_data_mesh(Mesh *mesh, uint32_t *flags_data)
+static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData *mr,
+ Mesh *mesh,
+ uint32_t *flags_data)
{
- for (int i = 0; i < mesh->totpoly; i++) {
+ const Span<MPoly> polys = mesh->polys();
+ for (const int i : polys.index_range()) {
uint32_t flag = 0;
- if ((mesh->mpoly[i].flag & ME_SMOOTH) != 0) {
+ if ((polys[i].flag & ME_SMOOTH) != 0) {
flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
}
- if ((mesh->mpoly[i].flag & ME_FACE_SEL) != 0) {
+ if (mr->select_poly && mr->select_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_SELECT;
}
- if ((mesh->mpoly[i].flag & ME_HIDE) != 0) {
+ if (mr->hide_poly && mr->hide_poly[i]) {
flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN;
}
- flags_data[i] = (uint)(mesh->mpoly[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
+ flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -691,13 +694,20 @@ static void draw_subdiv_cache_extra_coarse_face_data_mapped(Mesh *mesh,
uint32_t *flags_data)
{
if (bm == nullptr) {
- draw_subdiv_cache_extra_coarse_face_data_mesh(mesh, flags_data);
+ draw_subdiv_cache_extra_coarse_face_data_mesh(mr, mesh, flags_data);
return;
}
- for (int i = 0; i < mesh->totpoly; i++) {
+ const Span<MPoly> polys = mesh->polys();
+ for (const int i : polys.index_range()) {
BMFace *f = bm_original_face_get(mr, i);
- flags_data[i] = compute_coarse_face_flag(f, mr->efa_act);
+ /* Selection and hiding from bmesh. */
+ uint32_t flag = (f) ? compute_coarse_face_flag_bm(f, mr->efa_act) : 0;
+ /* Smooth from mesh. */
+ if ((polys[i].flag & ME_SMOOTH) != 0) {
+ flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH;
+ }
+ flags_data[i] = uint(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET);
}
}
@@ -717,16 +727,16 @@ static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache *cach
mesh->totpoly);
}
- uint32_t *flags_data = (uint32_t *)(GPU_vertbuf_get_data(cache->extra_coarse_face_data));
+ uint32_t *flags_data = (uint32_t *)GPU_vertbuf_get_data(cache->extra_coarse_face_data);
if (mr->extract_type == MR_EXTRACT_BMESH) {
draw_subdiv_cache_extra_coarse_face_data_bm(cache->bm, mr->efa_act, flags_data);
}
- else if (mr->extract_type == MR_EXTRACT_MAPPED) {
+ else if (mr->p_origindex != nullptr) {
draw_subdiv_cache_extra_coarse_face_data_mapped(mesh, cache->bm, mr, flags_data);
}
else {
- draw_subdiv_cache_extra_coarse_face_data_mesh(mesh, flags_data);
+ draw_subdiv_cache_extra_coarse_face_data_mesh(mr, mesh, flags_data);
}
/* Make sure updated data is re-uploaded. */
@@ -801,15 +811,15 @@ struct DRWCacheBuildingContext {
};
static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_context,
- const int num_vertices,
+ const int num_verts,
const int num_edges,
const int num_loops,
- const int num_polygons,
+ const int num_polys,
const int *subdiv_polygon_offset)
{
/* num_loops does not take into account meshes with only loose geometry, which might be meshes
- * used as custom bone shapes, so let's check the num_vertices also. */
- if (num_vertices == 0 && num_loops == 0) {
+ * used as custom bone shapes, so let's check the num_verts also. */
+ if (num_verts == 0 && num_loops == 0) {
return false;
}
@@ -818,14 +828,14 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
/* Set topology information only if we have loops. */
if (num_loops != 0) {
- cache->num_subdiv_edges = (uint)num_edges;
- cache->num_subdiv_loops = (uint)num_loops;
- cache->num_subdiv_verts = (uint)num_vertices;
- cache->num_subdiv_quads = (uint)num_polygons;
+ cache->num_subdiv_edges = uint(num_edges);
+ cache->num_subdiv_loops = uint(num_loops);
+ cache->num_subdiv_verts = uint(num_verts);
+ cache->num_subdiv_quads = uint(num_polys);
cache->subdiv_polygon_offset = static_cast<int *>(MEM_dupallocN(subdiv_polygon_offset));
}
- cache->may_have_loose_geom = num_vertices != 0 || num_edges != 0;
+ cache->may_have_loose_geom = num_verts != 0 || num_edges != 0;
/* Initialize cache buffers, prefer dynamic usage so we can reuse memory on the host even after
* it was sent to the device, since we may use the data while building other buffers on the CPU
@@ -876,7 +886,7 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
if (cache->num_subdiv_verts) {
ctx->vert_origindex_map = static_cast<int *>(
MEM_mallocN(cache->num_subdiv_verts * sizeof(int), "subdiv_vert_origindex_map"));
- for (int i = 0; i < num_vertices; i++) {
+ for (int i = 0; i < num_verts; i++) {
ctx->vert_origindex_map[i] = -1;
}
}
@@ -893,13 +903,13 @@ static bool draw_subdiv_topology_info_cb(const SubdivForeachContext *foreach_con
}
static void draw_subdiv_vertex_corner_cb(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
- const int UNUSED(ptex_face_index),
- const float UNUSED(u),
- const float UNUSED(v),
+ void * /*tls*/,
+ const int /*ptex_face_index*/,
+ const float /*u*/,
+ const float /*v*/,
const int coarse_vertex_index,
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
const int subdiv_vertex_index)
{
BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
@@ -907,26 +917,26 @@ static void draw_subdiv_vertex_corner_cb(const SubdivForeachContext *foreach_con
ctx->vert_origindex_map[subdiv_vertex_index] = coarse_vertex_index;
}
-static void draw_subdiv_vertex_edge_cb(const SubdivForeachContext *UNUSED(foreach_context),
- void *UNUSED(tls_v),
- const int UNUSED(ptex_face_index),
- const float UNUSED(u),
- const float UNUSED(v),
- const int UNUSED(coarse_edge_index),
- const int UNUSED(coarse_poly_index),
- const int UNUSED(coarse_corner),
- const int UNUSED(subdiv_vertex_index))
+static void draw_subdiv_vertex_edge_cb(const SubdivForeachContext * /*foreach_context*/,
+ void * /*tls_v*/,
+ const int /*ptex_face_index*/,
+ const float /*u*/,
+ const float /*v*/,
+ const int /*coarse_edge_index*/,
+ const int /*coarse_poly_index*/,
+ const int /*coarse_corner*/,
+ const int /*subdiv_vertex_index*/)
{
/* Required if SubdivForeachContext.vertex_corner is also set. */
}
static void draw_subdiv_edge_cb(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls),
+ void * /*tls*/,
const int coarse_edge_index,
const int subdiv_edge_index,
- const bool UNUSED(is_loose),
- const int UNUSED(subdiv_v1),
- const int UNUSED(subdiv_v2))
+ const bool /*is_loose*/,
+ const int /*subdiv_v1*/,
+ const int /*subdiv_v2*/)
{
DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
@@ -946,13 +956,13 @@ static void draw_subdiv_edge_cb(const SubdivForeachContext *foreach_context,
}
static void draw_subdiv_loop_cb(const SubdivForeachContext *foreach_context,
- void *UNUSED(tls_v),
+ void * /*tls_v*/,
const int ptex_face_index,
const float u,
const float v,
- const int UNUSED(coarse_loop_index),
+ const int /*coarse_loop_index*/,
const int coarse_poly_index,
- const int UNUSED(coarse_corner),
+ const int /*coarse_corner*/,
const int subdiv_loop_index,
const int subdiv_vertex_index,
const int subdiv_edge_index)
@@ -1089,6 +1099,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
}
/* Only build polygon related data if we have polygons. */
+ const Span<MPoly> polys = mesh_eval->polys();
if (cache->num_subdiv_loops != 0) {
/* Build buffers for the PatchMap. */
draw_patch_map_build(&cache->gpu_patch_map, subdiv);
@@ -1102,7 +1113,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
GPU_vertbuf_get_data(cache->fdots_patch_coords);
for (int i = 0; i < mesh_eval->totpoly; i++) {
const int ptex_face_index = cache->face_ptex_offset[i];
- if (mesh_eval->mpoly[i].totloop == 4) {
+ if (polys[i].totloop == 4) {
/* For quads, the center coordinate of the coarse face has `u = v = 0.5`. */
blender_fdots_patch_coords[i] = make_patch_coord(ptex_face_index, 0.5f, 0.5f);
}
@@ -1115,16 +1126,16 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache,
}
cache->subdiv_polygon_offset_buffer = draw_subdiv_build_origindex_buffer(
- cache->subdiv_polygon_offset, mesh_eval->totpoly);
+ cache->subdiv_polygon_offset, polys.size());
cache->face_ptex_offset_buffer = draw_subdiv_build_origindex_buffer(cache->face_ptex_offset,
- mesh_eval->totpoly + 1);
+ polys.size() + 1);
build_vertex_face_adjacency_maps(cache);
}
cache->resolution = to_mesh_settings.resolution;
- cache->num_coarse_poly = mesh_eval->totpoly;
+ cache->num_coarse_poly = polys.size();
/* To avoid floating point precision issues when evaluating patches at patch boundaries,
* ensure that all loops sharing a vertex use the same patch coordinate. This could cause
@@ -1284,7 +1295,7 @@ static void drw_subdiv_compute_dispatch(const DRWSubdivCache *cache,
uint total_dispatch_size,
const bool has_sculpt_mask = false)
{
- const uint max_res_x = static_cast<uint>(GPU_max_work_group_count(0));
+ const uint max_res_x = uint(GPU_max_work_group_count(0));
const uint dispatch_size = get_dispatch_size(total_dispatch_size);
uint dispatch_rx = dispatch_size;
@@ -1307,7 +1318,7 @@ static void drw_subdiv_compute_dispatch(const DRWSubdivCache *cache,
/* X and Y dimensions may have different limits so the above computation may not be right, but
* even with the standard 64k minimum on all dimensions we still have a lot of room. Therefore,
* we presume it all fits. */
- BLI_assert(dispatch_ry < static_cast<uint>(GPU_max_work_group_count(1)));
+ BLI_assert(dispatch_ry < uint(GPU_max_work_group_count(1)));
draw_subdiv_ubo_update_and_bind(
cache, shader, src_offset, dst_offset, total_dispatch_size, has_sculpt_mask);
@@ -1960,17 +1971,19 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache,
return;
}
+ const blender::VArraySpan<int> material_indices = mesh_eval->attributes().lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
+
/* Count number of subdivided polygons for each material. */
int *mat_start = static_cast<int *>(MEM_callocN(sizeof(int) * mat_len, "subdiv mat_start"));
int *subdiv_polygon_offset = cache->subdiv_polygon_offset;
/* TODO: parallel_reduce? */
for (int i = 0; i < mesh_eval->totpoly; i++) {
- const MPoly *mpoly = &mesh_eval->mpoly[i];
const int next_offset = (i == mesh_eval->totpoly - 1) ? number_of_quads :
subdiv_polygon_offset[i + 1];
const int quad_count = next_offset - subdiv_polygon_offset[i];
- const int mat_index = mpoly->mat_nr;
+ const int mat_index = material_indices[i];
mat_start[mat_index] += quad_count;
}
@@ -1989,8 +2002,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache,
MEM_mallocN(sizeof(int) * mesh_eval->totpoly, "per_polygon_mat_offset"));
for (int i = 0; i < mesh_eval->totpoly; i++) {
- const MPoly *mpoly = &mesh_eval->mpoly[i];
- const int mat_index = mpoly->mat_nr;
+ const int mat_index = material_indices[i];
const int single_material_index = subdiv_polygon_offset[i];
const int material_offset = mat_end[mat_index];
const int next_offset = (i == mesh_eval->totpoly - 1) ? number_of_quads :
@@ -2019,11 +2031,12 @@ static bool draw_subdiv_create_requested_buffers(Object *ob,
const float obmat[4][4],
const bool do_final,
const bool do_uvedit,
+ const bool do_cage,
const ToolSettings *ts,
const bool use_hide,
OpenSubdiv_EvaluatorCache *evaluator_cache)
{
- SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data;
+ SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data;
BLI_assert(runtime_data && runtime_data->has_gpu_subdiv);
if (runtime_data->settings.level == 0) {
@@ -2062,9 +2075,8 @@ static bool draw_subdiv_create_requested_buffers(Object *ob,
return false;
}
- /* 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. */
- const bool optimal_display = runtime_data->use_optimal_display || is_editmode;
+ /* Edges which do not come from coarse edges should not be drawn in edit cage mode. */
+ const bool optimal_display = runtime_data->use_optimal_display || (is_editmode && !do_cage);
draw_cache->bm = bm;
draw_cache->mesh = mesh_eval;
@@ -2125,7 +2137,7 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
const bool is_simple = subdiv_cache->subdiv->settings.is_simple;
const int resolution = subdiv_cache->resolution;
const int resolution_1 = resolution - 1;
- const float inv_resolution_1 = 1.0f / (float)resolution_1;
+ const float inv_resolution_1 = 1.0f / float(resolution_1);
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const int num_subdivided_edge = coarse_loose_edge_len *
@@ -2147,9 +2159,20 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
int subd_vert_offset = 0;
/* Subdivide each loose coarse edge. */
+ const Span<MVert> coarse_verts = coarse_mesh->verts();
+ const Span<MEdge> coarse_edges = coarse_mesh->edges();
+
+ int *vert_to_edge_buffer;
+ MeshElemMap *vert_to_edge_map;
+ BKE_mesh_vert_edge_map_create(&vert_to_edge_map,
+ &vert_to_edge_buffer,
+ coarse_edges.data(),
+ coarse_mesh->totvert,
+ coarse_edges.size());
+
for (int i = 0; i < coarse_loose_edge_len; i++) {
const int coarse_edge_index = cache->loose_geom.edges[i];
- const MEdge *coarse_edge = &coarse_mesh->medge[cache->loose_geom.edges[i]];
+ const MEdge *coarse_edge = &coarse_edges[cache->loose_geom.edges[i]];
/* Perform interpolation of each vertex. */
for (int i = 0; i < resolution - 1; i++, subd_edge_offset++) {
@@ -2160,8 +2183,13 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
DRWSubdivLooseVertex &subd_v1 = loose_subd_verts[subd_vert_offset];
subd_v1.coarse_vertex_index = (i == 0) ? coarse_edge->v1 : -1u;
const float u1 = i * inv_resolution_1;
- BKE_subdiv_mesh_interpolate_position_on_edge(
- coarse_mesh, coarse_edge, is_simple, u1, subd_v1.co);
+ BKE_subdiv_mesh_interpolate_position_on_edge(coarse_verts.data(),
+ coarse_edges.data(),
+ vert_to_edge_map,
+ coarse_edge_index,
+ is_simple,
+ u1,
+ subd_v1.co);
subd_edge.loose_subdiv_v1_index = subd_vert_offset++;
@@ -2169,17 +2197,25 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
DRWSubdivLooseVertex &subd_v2 = loose_subd_verts[subd_vert_offset];
subd_v2.coarse_vertex_index = ((i + 1) == resolution - 1) ? coarse_edge->v2 : -1u;
const float u2 = (i + 1) * inv_resolution_1;
- BKE_subdiv_mesh_interpolate_position_on_edge(
- coarse_mesh, coarse_edge, is_simple, u2, subd_v2.co);
+ BKE_subdiv_mesh_interpolate_position_on_edge(coarse_verts.data(),
+ coarse_edges.data(),
+ vert_to_edge_map,
+ coarse_edge_index,
+ is_simple,
+ u2,
+ subd_v2.co);
subd_edge.loose_subdiv_v2_index = subd_vert_offset++;
}
}
+ MEM_freeN(vert_to_edge_buffer);
+ MEM_freeN(vert_to_edge_map);
+
/* Copy the remaining loose_verts. */
for (int i = 0; i < coarse_loose_vert_len; i++) {
const int coarse_vertex_index = cache->loose_geom.verts[i];
- const MVert &coarse_vertex = coarse_mesh->mvert[coarse_vertex_index];
+ const MVert &coarse_vertex = coarse_verts[coarse_vertex_index];
DRWSubdivLooseVertex &subd_v = loose_subd_verts[subd_vert_offset++];
subd_v.coarse_vertex_index = cache->loose_geom.verts[i];
@@ -2195,13 +2231,13 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac
blender::Span<DRWSubdivLooseEdge> draw_subdiv_cache_get_loose_edges(const DRWSubdivCache *cache)
{
- return {cache->loose_geom.edges, static_cast<int64_t>(cache->loose_geom.edge_len)};
+ return {cache->loose_geom.edges, int64_t(cache->loose_geom.edge_len)};
}
blender::Span<DRWSubdivLooseVertex> draw_subdiv_cache_get_loose_verts(const DRWSubdivCache *cache)
{
return {cache->loose_geom.verts + cache->loose_geom.edge_len * 2,
- static_cast<int64_t>(cache->loose_geom.vert_len)};
+ int64_t(cache->loose_geom.vert_len)};
}
static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr;
@@ -2216,6 +2252,7 @@ void DRW_create_subdivision(Object *ob,
const float obmat[4][4],
const bool do_final,
const bool do_uvedit,
+ const bool do_cage,
const ToolSettings *ts,
const bool use_hide)
{
@@ -2239,6 +2276,7 @@ void DRW_create_subdivision(Object *ob,
obmat,
do_final,
do_uvedit,
+ do_cage,
ts,
use_hide,
g_evaluator_cache)) {