62static const GPUVertFormat &get_patch_handle_format()
64 static const GPUVertFormat
format = [&]() {
75static const GPUVertFormat &get_quadtree_format()
77 static const GPUVertFormat
format = [&]() {
85struct CompressedPatchCoord {
91MINLINE CompressedPatchCoord make_patch_coord(
int ptex_face_index,
float u,
float v)
93 CompressedPatchCoord patch_coord = {
95 (
uint(u * 65535.0f) << 16) |
uint(
v * 65535.0f),
101static const GPUVertFormat &get_blender_patch_coords_format()
103 static const GPUVertFormat
format = [&]() {
131 const uint32_t number_of_quads = number_of_loops / 4;
132 return number_of_quads * 2;
147 buffer->data<
int32_t>().take_front(num_loops).copy_from({vert_origindex, num_loops});
162 buffer->data<
int32_t>().take_front(vert_origindex.
size()).copy_from(vert_origindex);
177#ifdef WITH_OPENSUBDIV
187 int min_patch_face = 0;
188 int max_patch_face = 0;
190 int patches_are_triangular = 0;
198 &patches_are_triangular);
200 gpu_patch_map->patch_map_handles = patch_map_handles;
201 gpu_patch_map->patch_map_quadtree = patch_map_quadtree;
202 gpu_patch_map->min_patch_face = min_patch_face;
203 gpu_patch_map->max_patch_face = max_patch_face;
204 gpu_patch_map->max_depth = max_depth;
205 gpu_patch_map->patches_are_triangular = patches_are_triangular;
280#define SUBDIV_COARSE_FACE_FLAG_SMOOTH 1u
281#define SUBDIV_COARSE_FACE_FLAG_SELECT 2u
282#define SUBDIV_COARSE_FACE_FLAG_ACTIVE 4u
283#define SUBDIV_COARSE_FACE_FLAG_HIDDEN 8u
285#define SUBDIV_COARSE_FACE_FLAG_OFFSET 28u
287#define SUBDIV_COARSE_FACE_FLAG_SMOOTH_MASK \
288 (SUBDIV_COARSE_FACE_FLAG_SMOOTH << SUBDIV_COARSE_FACE_FLAG_OFFSET)
289#define SUBDIV_COARSE_FACE_FLAG_SELECT_MASK \
290 (SUBDIV_COARSE_FACE_FLAG_SELECT << SUBDIV_COARSE_FACE_FLAG_OFFSET)
291#define SUBDIV_COARSE_FACE_FLAG_ACTIVE_MASK \
292 (SUBDIV_COARSE_FACE_FLAG_ACTIVE << SUBDIV_COARSE_FACE_FLAG_OFFSET)
293#define SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK \
294 (SUBDIV_COARSE_FACE_FLAG_HIDDEN << SUBDIV_COARSE_FACE_FLAG_OFFSET)
296#define SUBDIV_COARSE_FACE_LOOP_START_MASK \
297 ~((SUBDIV_COARSE_FACE_FLAG_SMOOTH | SUBDIV_COARSE_FACE_FLAG_SELECT | \
298 SUBDIV_COARSE_FACE_FLAG_ACTIVE | SUBDIV_COARSE_FACE_FLAG_HIDDEN) \
299 << SUBDIV_COARSE_FACE_FLAG_OFFSET)
339 for (
const int i :
faces.index_range()) {
367 for (
const int i :
faces.index_range()) {
417 if (subdiv_cache ==
nullptr) {
418 subdiv_cache = MEM_new<DRWSubdivCache>(__func__);
421 return *subdiv_cache;
424#ifdef WITH_OPENSUBDIV
459struct DRWCacheBuildingContext {
460 const Mesh *coarse_mesh;
461 const bke::subdiv::Subdiv *subdiv;
462 const bke::subdiv::ToMeshSettings *settings;
464 DRWSubdivCache *cache;
467 CompressedPatchCoord *patch_coords;
468 int *subdiv_loop_vert_index;
469 int *subdiv_loop_subdiv_vert_index;
470 int *subdiv_loop_edge_index;
471 int *subdiv_loop_edge_draw_flag;
472 int *subdiv_loop_subdiv_edge_index;
473 int *subdiv_loop_face_index;
476 int *vert_origindex_map;
477 int *edge_draw_flag_map;
478 int *edge_origindex_map;
483 const int *orig_index_vert;
484 const int *orig_index_edge;
487static bool draw_subdiv_topology_info_cb(
const bke::subdiv::ForeachContext *foreach_context,
492 const int *subdiv_face_offset)
496 if (num_verts == 0 && num_loops == 0) {
500 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
504 if (num_loops != 0) {
505 cache->num_subdiv_edges =
uint(num_edges);
506 cache->num_subdiv_loops =
uint(num_loops);
507 cache->num_subdiv_verts =
uint(num_verts);
508 cache->num_subdiv_quads =
uint(num_faces);
509 cache->subdiv_face_offset =
static_cast<int *
>(
MEM_dupallocN(subdiv_face_offset));
512 cache->may_have_loose_geom = num_verts != 0 || num_edges != 0;
527 *cache->corner_patch_coords, get_blender_patch_coords_format(),
GPU_USAGE_DYNAMIC);
546 "subdiv_loop_subdiv_vert_index");
549 "subdiv_loop_subdiv_edge_index");
552 "subdiv_loop_face_index");
555 ctx->patch_coords = cache->patch_coords->data<CompressedPatchCoord>().
data();
556 ctx->subdiv_loop_vert_index = cache->verts_orig_index->data<
int>().
data();
557 ctx->subdiv_loop_edge_index = cache->edges_orig_index->data<
int>().
data();
558 ctx->subdiv_loop_edge_draw_flag = cache->edges_draw_flag->data<
int>().
data();
559 ctx->subdiv_loop_subdiv_vert_index = cache->subdiv_loop_subdiv_vert_index;
560 ctx->subdiv_loop_subdiv_edge_index = cache->subdiv_loop_subdiv_edge_index;
561 ctx->subdiv_loop_face_index = cache->subdiv_loop_face_index;
563 ctx->orig_index_vert =
static_cast<const int *
>(
566 ctx->orig_index_edge =
static_cast<const int *
>(
569 if (cache->num_subdiv_verts) {
571 "subdiv_vert_origindex_map");
572 for (
int i = 0;
i < num_verts;
i++) {
573 ctx->vert_origindex_map[
i] = -1;
577 if (cache->num_subdiv_edges) {
579 "subdiv_edge_origindex_map");
580 for (
int i = 0;
i < num_edges;
i++) {
581 ctx->edge_origindex_map[
i] = -1;
584 "subdiv_edge_draw_flag_map");
590static void draw_subdiv_vertex_corner_cb(
const bke::subdiv::ForeachContext *foreach_context,
595 const int coarse_vertex_index,
598 const int subdiv_vertex_index)
601 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
602 ctx->vert_origindex_map[subdiv_vertex_index] = coarse_vertex_index;
605static void draw_subdiv_vertex_edge_cb(
const bke::subdiv::ForeachContext * ,
618static void draw_subdiv_edge_cb(
const bke::subdiv::ForeachContext *foreach_context,
620 const int coarse_edge_index,
621 const int subdiv_edge_index,
626 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
628 if (!ctx->edge_origindex_map) {
635 if (!ctx->cache->optimal_display) {
636 ctx->edge_draw_flag_map[subdiv_edge_index] = 1;
640 if (ctx->orig_index_edge) {
641 const int origindex = ctx->orig_index_edge[coarse_edge_index];
642 ctx->edge_origindex_map[subdiv_edge_index] = origindex;
643 if (!(origindex ==
ORIGINDEX_NONE && ctx->cache->hide_unmapped_edges)) {
645 ctx->edge_draw_flag_map[subdiv_edge_index] = 1;
649 ctx->edge_origindex_map[subdiv_edge_index] = coarse_edge_index;
650 ctx->edge_draw_flag_map[subdiv_edge_index] = 1;
655static void draw_subdiv_loop_cb(
const bke::subdiv::ForeachContext *foreach_context,
657 const int ptex_face_index,
661 const int coarse_face_index,
663 const int subdiv_loop_index,
664 const int subdiv_vertex_index,
665 const int subdiv_edge_index)
667 DRWCacheBuildingContext *ctx = (DRWCacheBuildingContext *)(foreach_context->user_data);
668 ctx->patch_coords[subdiv_loop_index] = make_patch_coord(ptex_face_index, u,
v);
670 int coarse_vertex_index = ctx->vert_origindex_map[subdiv_vertex_index];
672 ctx->subdiv_loop_subdiv_vert_index[subdiv_loop_index] = subdiv_vertex_index;
673 ctx->subdiv_loop_subdiv_edge_index[subdiv_loop_index] = subdiv_edge_index;
674 ctx->subdiv_loop_face_index[subdiv_loop_index] = coarse_face_index;
675 ctx->subdiv_loop_vert_index[subdiv_loop_index] = coarse_vertex_index;
678static void draw_subdiv_foreach_callbacks(bke::subdiv::ForeachContext *foreach_context)
680 *foreach_context = {};
681 foreach_context->topology_info = draw_subdiv_topology_info_cb;
682 foreach_context->loop = draw_subdiv_loop_cb;
683 foreach_context->edge = draw_subdiv_edge_cb;
684 foreach_context->vertex_corner = draw_subdiv_vertex_corner_cb;
685 foreach_context->vertex_edge = draw_subdiv_vertex_edge_cb;
688static void do_subdiv_traversal(DRWCacheBuildingContext *cache_building_context,
689 bke::subdiv::Subdiv *subdiv)
691 bke::subdiv::ForeachContext foreach_context;
692 draw_subdiv_foreach_callbacks(&foreach_context);
693 foreach_context.user_data = cache_building_context;
697 cache_building_context->settings,
698 cache_building_context->coarse_mesh);
703 for (
int i = 0;
i < cache_building_context->cache->num_subdiv_loops;
i++) {
704 const int edge_index = cache_building_context->subdiv_loop_subdiv_edge_index[
i];
705 cache_building_context->subdiv_loop_edge_index[
i] =
706 cache_building_context->edge_origindex_map[edge_index];
707 cache_building_context->subdiv_loop_edge_draw_flag[
i] =
708 cache_building_context->edge_draw_flag_map[edge_index];
712static gpu::VertBuf *gpu_vertbuf_create_from_format(
const GPUVertFormat &
format,
uint len)
722static void build_vertex_face_adjacency_maps(
DRWSubdivCache &cache)
726 cache.subdiv_vertex_face_adjacency_offsets = gpu_vertbuf_create_from_format(
729 MutableSpan<int> vertex_offsets = cache.subdiv_vertex_face_adjacency_offsets->data<
int>();
730 vertex_offsets.
fill(0);
733 {cache.subdiv_loop_subdiv_vert_index, cache.num_subdiv_loops}, vertex_offsets);
736 cache.num_subdiv_loops);
737 MutableSpan<int> adjacent_faces = cache.subdiv_vertex_face_adjacency->data<
int>();
740 for (
int i = 0;
i < cache.num_subdiv_loops / 4;
i++) {
741 for (
int j = 0; j < 4; j++) {
742 const int subdiv_vertex = cache.subdiv_loop_subdiv_vert_index[
i * 4 + j];
743 int first_face_offset = vertex_offsets[subdiv_vertex] + tmp_set_faces[subdiv_vertex];
744 adjacent_faces[first_face_offset] =
i;
745 tmp_set_faces[subdiv_vertex] += 1;
753 bke::subdiv::Subdiv *subdiv,
754 const Mesh *mesh_eval,
755 const SubsurfRuntimeData *runtime_data)
757 bke::subdiv::ToMeshSettings to_mesh_settings;
758 to_mesh_settings.resolution = runtime_data->
resolution;
759 to_mesh_settings.use_optimal_display =
false;
761 if (cache.resolution != to_mesh_settings.resolution) {
771 if (cache.patch_coords !=
nullptr) {
775 DRWCacheBuildingContext cache_building_context;
776 memset(&cache_building_context, 0,
sizeof(DRWCacheBuildingContext));
777 cache_building_context.coarse_mesh = mesh_eval;
778 cache_building_context.settings = &to_mesh_settings;
779 cache_building_context.cache = &cache;
781 do_subdiv_traversal(&cache_building_context, subdiv);
782 if (cache.num_subdiv_loops == 0 && cache.num_subdiv_verts == 0 && !cache.may_have_loose_geom) {
791 const OffsetIndices
faces = mesh_eval->faces();
792 if (cache.num_subdiv_loops != 0) {
794 draw_patch_map_build(&cache.gpu_patch_map, subdiv);
799 cache.fdots_patch_coords = gpu_vertbuf_create_from_format(get_blender_patch_coords_format(),
801 CompressedPatchCoord *blender_fdots_patch_coords =
802 cache.fdots_patch_coords->data<CompressedPatchCoord>().
data();
804 const int ptex_face_index = cache.face_ptex_offset[
i];
807 blender_fdots_patch_coords[
i] = make_patch_coord(ptex_face_index, 0.5f, 0.5f);
813 blender_fdots_patch_coords[
i] = make_patch_coord(ptex_face_index, 1.0f, 1.0f);
822 build_vertex_face_adjacency_maps(cache);
825 cache.resolution = to_mesh_settings.resolution;
826 cache.num_coarse_faces =
faces.size();
831 Vector<int> first_loop_index(cache.num_subdiv_verts, -1);
835 if (cache.num_subdiv_loops > 0) {
836 memcpy(cache.corner_patch_coords->data<CompressedPatchCoord>().data(),
837 cache_building_context.patch_coords,
838 sizeof(CompressedPatchCoord) * cache.num_subdiv_loops);
840 for (
int i = 0;
i < cache.num_subdiv_loops;
i++) {
841 const int vertex = cache_building_context.subdiv_loop_subdiv_vert_index[
i];
842 if (first_loop_index[vertex] != -1) {
845 first_loop_index[vertex] =
i;
848 for (
int i = 0;
i < cache.num_subdiv_loops;
i++) {
849 const int vertex = cache_building_context.subdiv_loop_subdiv_vert_index[
i];
850 cache_building_context.patch_coords[
i] =
851 cache_building_context.patch_coords[first_loop_index[vertex]];
875 const int src_offset,
876 const int dst_offset,
877 const uint total_dispatch_size,
878 const bool has_sculpt_mask,
879 const uint edge_loose_offset)
902 const int src_offset,
903 const int dst_offset,
904 const uint total_dispatch_size,
905 const bool has_sculpt_mask =
false,
906 const uint edge_loose_offset = 0)
930#define SUBDIV_LOCAL_WORK_GROUP_SIZE 64
943 const int src_offset,
944 const int dst_offset,
945 uint total_dispatch_size,
946 const bool has_sculpt_mask =
false,
947 const uint edge_loose_offset = 0)
952 uint dispatch_rx = dispatch_size;
953 uint dispatch_ry = 1u;
954 if (dispatch_rx > max_res_x) {
962 dispatch_rx = dispatch_ry =
ceilf(
sqrtf(dispatch_size));
964 if ((dispatch_rx * (dispatch_ry - 1)) >= dispatch_size) {
975 cache, src_offset, dst_offset, total_dispatch_size, has_sculpt_mask, edge_loose_offset);
982#ifdef WITH_OPENSUBDIV
1039 const int face_varying_channel,
1040 const int dst_offset)
1042#ifdef WITH_OPENSUBDIV
1052 face_varying_channel);
1054 face_varying_channel);
1059 face_varying_channel);
1061 face_varying_channel);
1092 UNUSED_VARS(cache, uvs, face_varying_channel, dst_offset);
1215 const int material_count)
1222 const bool do_single_material = material_count <= 1;
1232 if (!do_single_material) {
1253#ifdef WITH_OPENSUBDIV
1303 UNUSED_VARS(cache, fdots_pos, fdots_nor, fdots_indices);
1329 uint edge_loose_offset,
1330 uint num_loose_edges)
1515 const Mesh *mesh_eval,
1526 cache.
mat_end[0] = number_of_quads;
1540 const int next_offset = (
i == mesh_eval->
faces_num - 1) ? number_of_quads :
1541 subdiv_face_offset[
i + 1];
1542 const int quad_count = next_offset - subdiv_face_offset[
i];
1543 const uint mat_index =
uint(material_indices[
i]) < mat_len ?
uint(material_indices[
i]) : 0;
1544 mat_start[mat_index] += quad_count;
1548 int ofs = mat_start[0];
1550 for (
uint i = 1;
i < mat_len;
i++) {
1551 int tmp = mat_start[
i];
1557 int *mat_end =
static_cast<int *
>(
MEM_dupallocN(mat_start));
1561 const uint mat_index =
uint(material_indices[
i]) < mat_len ?
uint(material_indices[
i]) : 0;
1562 const int single_material_index = subdiv_face_offset[
i];
1563 const int material_offset = mat_end[mat_index];
1564 const int next_offset = (
i == mesh_eval->
faces_num - 1) ? number_of_quads :
1565 subdiv_face_offset[
i + 1];
1566 const int quad_count = next_offset - subdiv_face_offset[
i];
1567 mat_end[mat_index] += quad_count;
1569 per_face_mat_offset[
i] = material_offset - single_material_index;
1596 const bool is_editmode,
1597 const bool is_paint_mode,
1598 const bool do_final,
1599 const bool do_uvedit,
1602 const bool use_hide)
1611 const Mesh *mesh_eval = &mesh;
1613 if (mesh.
runtime->edit_mesh) {
1618#ifdef WITH_OPENSUBDIV
1619 draw_subdiv_invalidate_evaluator_for_orco(runtime_data->
subdiv_gpu, mesh_eval);
1623 runtime_data, mesh_eval,
true);
1636 bool evaluator_might_be_assigned = subdiv->
evaluator ==
nullptr;
1637 auto maybe_increment_cache_ref = [evaluator_might_be_assigned](
bke::subdiv::Subdiv *subdiv) {
1638 if (evaluator_might_be_assigned && subdiv->
evaluator !=
nullptr) {
1653 maybe_increment_cache_ref(subdiv);
1664 draw_cache.
mesh = mesh_eval;
1665 draw_cache.
subdiv = subdiv;
1667#ifdef WITH_OPENSUBDIV
1668 if (!draw_subdiv_build_cache(draw_cache, subdiv, mesh_eval, runtime_data)) {
1669 maybe_increment_cache_ref(subdiv);
1683 mesh_eval->
attributes().contains(
"custom_normal");
1690 ob, mesh, is_editmode, is_paint_mode, do_final, do_uvedit, use_hide, ts);
1701 batch_cache, mbc, ibo_requests, vbo_requests, draw_cache, mr);
1703 maybe_increment_cache_ref(subdiv);
1719 const Mesh *coarse_mesh = subdiv_cache.
mesh;
1721 const int resolution = subdiv_cache.
resolution;
1722 const int resolution_1 = resolution - 1;
1723 const float inv_resolution_1 = 1.0f /
float(resolution_1);
1725 const Span<float3> coarse_positions = coarse_mesh->vert_positions();
1726 const Span<int2> coarse_edges = coarse_mesh->edges();
1731 coarse_edges, coarse_mesh->
verts_num, vert_to_edge_offsets, vert_to_edge_indices);
1738 for (const int i : range) {
1739 const int coarse_edge = loose_edges[i];
1740 MutableSpan positions = edge_positions.slice(i * resolution, resolution);
1741 for (const int j : positions.index_range()) {
1742 positions[j] = bke::subdiv::mesh_interpolate_position_on_edge(coarse_positions,
1747 j * inv_resolution_1);
1769 const bool is_editmode,
1770 const bool is_paint_mode,
1771 const bool do_final,
1772 const bool do_uvedit,
1775 const bool use_hide)
1804 fprintf(stderr,
"Time to update subdivision: %f\n", end_time - begin_time);
1805 fprintf(stderr,
"Maximum FPS: %f\n", 1.0 / (end_time - begin_time));
1830#ifdef WITH_OPENSUBDIV
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_final(const Object *object)
blender::bke::subdiv::Subdiv * BKE_subsurf_modifier_subdiv_descriptor_ensure(SubsurfRuntimeData *runtime_data, const Mesh *mesh, bool for_draw_code)
void void void * BLI_linklist_pop(LinkNode **listp) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
MINLINE uint divide_ceil_u(uint a, uint b)
double BLI_time_now_seconds(void)
Object is a sort of wrapper for general info.
int GPU_max_work_group_count(int index)
void GPU_compute_dispatch(blender::gpu::Shader *shader, uint groups_x_len, uint groups_y_len, uint groups_z_len, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_indexbuf_bind_as_ssbo(blender::gpu::IndexBuf *elem, int binding)
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
@ GPU_BARRIER_SHADER_STORAGE
@ GPU_BARRIER_ELEMENT_ARRAY
@ GPU_BARRIER_VERTEX_ATTRIB_ARRAY
void GPU_memory_barrier(GPUBarrier barrier)
void GPU_storagebuf_free(blender::gpu::StorageBuf *ssbo)
void GPU_storagebuf_bind(blender::gpu::StorageBuf *ssbo, int slot)
blender::gpu::VertBuf * GPU_vertbuf_create_with_format_ex(const GPUVertFormat &format, GPUUsageType usage)
void GPU_vertbuf_tag_dirty(blender::gpu::VertBuf *verts)
#define GPU_vertbuf_init_with_format(verts, format)
#define GPU_VERTBUF_DISCARD_SAFE(verts)
blender::gpu::VertBuf * GPU_vertbuf_calloc()
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
void GPU_vertbuf_bind_as_ssbo(blender::gpu::VertBuf *verts, int binding)
void GPU_vertbuf_init_with_format_ex(blender::gpu::VertBuf &verts, const GPUVertFormat &format, GPUUsageType)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr void fill(const T &value) const
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr bool contains(const T &value) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
gpu::VertBuf * get_face_varying_source_buf(const int face_varying_channel)
gpu::StorageBuf * get_face_varying_patch_index_buf(const int face_varying_channel)
gpu::StorageBuf * create_patch_arrays_buf()
gpu::StorageBuf * get_patch_param_buf()
gpu::StorageBuf * create_face_varying_patch_array_buf(const int face_varying_channel)
gpu::StorageBuf * get_patch_index_buf()
int get_face_varying_source_offset(const int face_varying_channel) const
gpu::VertBuf * get_source_data_buf()
gpu::VertBuf * get_source_buf()
bool hasVertexData() const
gpu::StorageBuf * get_face_varying_patch_param_buf(const int face_varying_channel)
void getPatchMap(blender::gpu::VertBuf *patch_map_handles, blender::gpu::VertBuf *patch_map_quadtree, int *min_patch_face, int *max_patch_face, int *max_depth, int *patches_are_triangular)
#define SUBDIV_COARSE_FACE_FLAG_HIDDEN
#define SUBDIV_COARSE_FACE_FLAG_HIDDEN_MASK
#define SUBDIV_COARSE_FACE_FLAG_ACTIVE_MASK
#define SUBDIV_COARSE_FACE_FLAG_OFFSET
#define SUBDIV_COARSE_FACE_FLAG_SMOOTH_MASK
#define SUBDIV_COARSE_FACE_FLAG_SMOOTH
#define SUBDIV_COARSE_FACE_FLAG_ACTIVE
#define SUBDIV_COARSE_FACE_FLAG_SELECT_MASK
#define SUBDIV_LOCAL_WORK_GROUP_SIZE
#define SUBDIV_COARSE_FACE_FLAG_SELECT
#define SUBDIV_COARSE_FACE_LOOP_START_MASK
blender::gpu::Shader * DRW_shader_subdiv_get(SubdivShaderType shader_type)
blender::gpu::Shader * DRW_shader_subdiv_interp_corner_normals_get()
blender::gpu::Shader * DRW_shader_subdiv_custom_data_get(GPUVertCompType comp_type, int dimensions)
@ PATCH_EVALUATION_FACE_DOTS
@ BUFFER_PAINT_OVERLAY_FLAG
@ BUFFER_UV_STRETCH_ANGLE
@ BUFFER_NORMALS_ACCUMULATE
@ PATCH_EVALUATION_FACE_DOTS_WITH_NORMALS
@ BUFFER_TRIS_MULTIPLE_MATERIALS
#define LOOP_NORMALS_POS_SLOT
#define LOOP_NORMALS_VERT_NORMALS_BUF_SLOT
#define EDGE_FAC_EDGE_FAC_BUF_SLOT
#define LINES_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define TRIS_OUTPUT_TRIS_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_NORMALS_BUF_SLOT
#define NORMALS_ACCUMULATE_POS_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_POS_BUF_SLOT
#define PAINT_OVERLAY_EXTRA_INPUT_VERT_ORIG_INDEX_SLOT
#define PATCH_EVALUATION_PATCH_ARRAY_BUFFER_BUF_SLOT
#define CUSTOM_DATA_SOURCE_DATA_BUF_SLOT
#define CUSTOM_DATA_FACE_PTEX_OFFSET_BUF_SLOT
#define LOOP_NORMALS_OUTPUT_LNOR_BUF_SLOT
#define LINES_OUTPUT_LINES_BUF_SLOT
#define PATCH_EVALUATION_INPUT_VERTEX_ORIG_INDEX_BUF_SLOT
#define SCULPT_DATA_SCULPT_DATA_BUF_SLOT
#define SHADER_DATA_BUF_SLOT
#define PATCH_EVALUATION_QUAD_NODES_BUF_SLOT
#define PATCH_EVALUATION_INPUT_PATCH_HANDLES_BUF_SLOT
#define PATCH_EVALUATION_SOURCE_EXTRA_VERTEX_BUFFER_BUF_SLOT
#define STRETCH_ANGLE_UV_STRETCHES_BUF_SLOT
#define NORMALS_ACCUMULATE_FACE_ADJACENCY_LISTS_BUF_SLOT
#define PATCH_EVALUATION_PATCH_PARAM_BUFFER_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_FDOTS_VERTEX_BUFFER_BUF_SLOT
#define LINES_LINES_LOOSE_FLAGS
#define EDGE_FAC_POS_BUF_SLOT
#define EDGE_FAC_POLY_OTHER_MAP_BUF_SLOT
#define LINES_INPUT_EDGE_DRAW_FLAG_BUF_SLOT
#define TRIS_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define PATCH_EVALUATION_PATCH_COORDS_BUF_SLOT
#define PATCH_EVALUATION_PATCH_INDEX_BUFFER_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_INDICES_BUF_SLOT
#define NORMALS_ACCUMULATE_NORMALS_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_ORCOS_BUF_SLOT
#define SCULPT_DATA_SCULPT_FACE_SET_COLOR_BUF_SLOT
#define LOOP_NORMALS_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define SCULPT_DATA_SCULPT_MASK_BUF_SLOT
#define PAINT_OVERLAY_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define EDGE_FAC_EDGE_DRAW_FLAG_BUF_SLOT
#define STRETCH_ANGLE_POS_BUF_SLOT
#define PATCH_EVALUATION_SOURCE_VERTEX_BUFFER_BUF_SLOT
#define TRIS_FACE_MAT_OFFSET
#define STRETCH_AREA_COARSE_STRETCH_AREA_BUF_SLOT
#define CUSTOM_DATA_DESTINATION_DATA_BUF_SLOT
#define PATCH_EVALUATION_OUTPUT_FVAR_BUF_SLOT
#define SUBDIV_FACE_OFFSET_BUF_SLOT
#define CUSTOM_DATA_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define NORMALS_ACCUMULATE_VERTEX_LOOP_MAP_BUF_SLOT
#define STRETCH_AREA_SUBDIV_STRETCH_AREA_BUF_SLOT
#define PATCH_EVALUATION_EXTRA_COARSE_FACE_DATA_BUF_SLOT
#define NORMALS_ACCUMULATE_FACE_ADJACENCY_OFFSETS_BUF_SLOT
#define LOOP_NORMALS_VERTEX_LOOP_MAP_BUF_SLOT
#define PAINT_OVERLAY_OUTPUT_FLAG_SLOT
#define STRETCH_ANGLE_UVS_BUF_SLOT
#define CUSTOM_DATA_PATCH_COORDS_BUF_SLOT
void openSubdiv_deleteEvaluatorCache(OpenSubdiv_EvaluatorCache *evaluator_cache)
OpenSubdiv_EvaluatorCache * openSubdiv_createEvaluatorCache(eOpenSubdivEvaluator evaluator_type)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
GroupedSpan< int > build_vert_to_edge_map(Span< int2 > edges, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
void free(Subdiv *subdiv)
bool eval_begin_from_mesh(Subdiv *subdiv, const Mesh *mesh, eSubdivEvaluatorType evaluator_type, Span< float3 > coarse_vert_positions={}, OpenSubdiv_EvaluatorCache *evaluator_cache=nullptr)
bool foreach_subdiv_geometry(Subdiv *subdiv, const ForeachContext *context, const ToMeshSettings *mesh_settings, const Mesh *coarse_mesh)
@ SUBDIV_EVALUATOR_TYPE_GPU
Span< int > face_ptex_offset_get(Subdiv *subdiv)
BLI_INLINE BMFace * bm_original_face_get(const MeshRenderData &mr, int idx)
static void draw_subdiv_init_ubo_storage(const DRWSubdivCache &cache, DRWSubdivUboStorage *ubo, const int src_offset, const int dst_offset, const uint total_dispatch_size, const bool has_sculpt_mask, const uint edge_loose_offset)
static void draw_subdiv_cache_free_material_data(DRWSubdivCache &cache)
void draw_subdiv_build_edge_fac_buffer(const DRWSubdivCache &cache, gpu::VertBuf *pos, gpu::VertBuf *edge_draw_flag, gpu::VertBuf *poly_other_map, gpu::VertBuf *edge_fac)
static void draw_subdiv_free_edit_mode_cache(DRWSubdivCache &cache)
static bool draw_subdiv_cache_need_face_data(const DRWSubdivCache &cache)
void draw_subdiv_extract_uvs(const DRWSubdivCache &cache, gpu::VertBuf *uvs, const int face_varying_channel, const int dst_offset)
gpu::VertBufPtr draw_subdiv_init_origindex_buffer(int32_t *vert_origindex, uint num_loops, uint loose_len)
void draw_subdiv_build_edituv_stretch_area_buffer(const DRWSubdivCache &cache, gpu::VertBuf *coarse_data, gpu::VertBuf *subdiv_data)
static void draw_patch_map_free(DRWPatchMap *gpu_patch_map)
void draw_subdiv_build_lnor_buffer(const DRWSubdivCache &cache, gpu::VertBuf *pos, gpu::VertBuf *vert_normals, gpu::VertBuf *subdiv_corner_verts, gpu::VertBuf *lnor)
static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache &cache, const Mesh *mesh_eval, uint mat_len)
void draw_subdiv_build_fdots_buffers(const DRWSubdivCache &cache, gpu::VertBuf *fdots_pos, gpu::VertBuf *fdots_nor, gpu::IndexBuf *fdots_indices)
void draw_subdiv_interp_corner_normals(const DRWSubdivCache &cache, gpu::VertBuf &src_data, gpu::VertBuf &dst_data)
void DRW_subdivide_loose_geom(DRWSubdivCache &subdiv_cache, const MeshBufferCache &cache)
void draw_subdiv_interp_custom_data(const DRWSubdivCache &cache, gpu::VertBuf &src_data, gpu::VertBuf &dst_data, GPUVertCompType comp_type, int dimensions, int dst_offset)
static blender::Mutex gpu_subdiv_queue_mutex
void draw_subdiv_cache_free(DRWSubdivCache &cache)
void draw_subdiv_build_paint_overlay_flag_buffer(const DRWSubdivCache &cache, gpu::VertBuf &flags)
void draw_subdiv_build_tris_buffer(const DRWSubdivCache &cache, gpu::IndexBuf *subdiv_tris, const int material_count)
static LinkNode * gpu_subdiv_free_queue
void DRW_subdiv_cache_free(bke::subdiv::Subdiv *subdiv)
void draw_subdiv_build_lines_buffer(const DRWSubdivCache &cache, gpu::IndexBuf *lines_indices)
static void drw_subdiv_compute_dispatch(const DRWSubdivCache &cache, gpu::Shader *shader, const int src_offset, const int dst_offset, uint total_dispatch_size, const bool has_sculpt_mask=false, const uint edge_loose_offset=0)
static uint get_dispatch_size(uint elements)
void draw_subdiv_extract_pos(const DRWSubdivCache &cache, gpu::VertBuf *pos, gpu::VertBuf *orco)
static bool draw_subdiv_create_requested_buffers(Object &ob, Mesh &mesh, MeshBatchCache &batch_cache, MeshBufferCache &mbc, const Span< IBOType > ibo_requests, const Span< VBOType > vbo_requests, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool do_cage, const ToolSettings *ts, const bool use_hide)
void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache &cache, MeshBufferCache &mbc, Span< IBOType > ibo_requests, Span< VBOType > vbo_requests, DRWSubdivCache &subdiv_cache, MeshRenderData &mr)
static DRWSubdivCache & mesh_batch_cache_ensure_subdiv_cache(MeshBatchCache &mbc)
void draw_subdiv_build_lines_loose_buffer(const DRWSubdivCache &cache, gpu::IndexBuf *lines_indices, gpu::VertBuf *lines_flags, uint edge_loose_offset, uint num_loose_edges)
void draw_subdiv_build_edituv_stretch_angle_buffer(const DRWSubdivCache &cache, gpu::VertBuf *pos, gpu::VertBuf *uvs, int uvs_offset, gpu::VertBuf *stretch_angles)
static uint32_t compute_coarse_face_flag_bm(BMFace *f, BMFace *efa_act)
static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData &mr, const Mesh *mesh, MutableSpan< uint32_t > flags_data)
static void draw_subdiv_ubo_update_and_bind(const DRWSubdivCache &cache, const int src_offset, const int dst_offset, const uint total_dispatch_size, const bool has_sculpt_mask=false, const uint edge_loose_offset=0)
static uint tris_count_from_number_of_loops(const uint number_of_loops)
void draw_subdiv_build_sculpt_data_buffer(const DRWSubdivCache &cache, gpu::VertBuf *mask_vbo, gpu::VertBuf *face_set_vbo, gpu::VertBuf *sculpt_data)
void DRW_create_subdivision(Object &ob, Mesh &mesh, MeshBatchCache &batch_cache, MeshBufferCache &mbc, const Span< IBOType > ibo_requests, const Span< VBOType > vbo_requests, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool do_cage, const ToolSettings *ts, const bool use_hide)
void DRW_cache_free_old_subdiv()
gpu::VertBuf * draw_subdiv_build_origindex_buffer(int *vert_origindex, uint num_loops)
static void draw_subdiv_cache_extra_coarse_face_data_mapped(const Mesh *mesh, BMesh *bm, MeshRenderData &mr, MutableSpan< uint32_t > flags_data)
static void draw_subdiv_cache_update_extra_coarse_face_data(DRWSubdivCache &cache, const Mesh *mesh, MeshRenderData &mr)
MeshRenderData mesh_render_data_create(Object &object, Mesh &mesh, const bool is_editmode, const bool is_paint_mode, const bool do_final, const bool do_uvedit, const bool use_hide, const ToolSettings *ts)
static const GPUVertFormat & get_origindex_format()
static Mutex g_subdiv_eval_mutex
void draw_subdiv_accumulate_normals(const DRWSubdivCache &cache, gpu::VertBuf *pos, gpu::VertBuf *face_adjacency_offsets, gpu::VertBuf *face_adjacency_lists, gpu::VertBuf *vertex_loop_map, gpu::VertBuf *vert_normals)
static OpenSubdiv_EvaluatorCache * g_subdiv_evaluator_cache
static uint64_t g_subdiv_evaluator_users
static void draw_subdiv_cache_extra_coarse_face_data_bm(BMesh *bm, BMFace *efa_act, MutableSpan< uint32_t > flags_data)
std::unique_ptr< gpu::VertBuf, gpu::VertBufDeleter > VertBufPtr
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
@ OPENSUBDIV_EVALUATOR_GPU
@ OPENSUBDIV_EVALUATOR_CPU
uint coarse_face_active_mask
uint coarse_face_loopstart_mask
bool32_t patches_are_triangular
uint coarse_face_select_mask
uint coarse_face_smooth_mask
uint coarse_face_hidden_mask
MeshRuntimeHandle * runtime
blender::opensubdiv::EvalOutputAPI * eval_output
eOpenSubdivEvaluator type
blender::bke::subdiv::Settings settings
blender::bke::subdiv::Subdiv * subdiv_gpu
OpenSubdiv_Evaluator * evaluator
blender::opensubdiv::TopologyRefinerImpl * topology_refiner
gpu::VertBuf * patch_map_quadtree
bool patches_are_triangular
gpu::VertBuf * patch_map_handles
gpu::VertBuf * face_mat_offset
DRWPatchMap gpu_patch_map
int * subdiv_loop_subdiv_vert_index
gpu::VertBuf * verts_orig_index
gpu::VertBuf * subdiv_vertex_face_adjacency_offsets
gpu::VertBuf * edges_orig_index
gpu::VertBuf * subdiv_vertex_face_adjacency
bool use_custom_loop_normals
gpu::VertBuf * fdots_patch_coords
gpu::VertBuf * extra_coarse_face_data
gpu::VertBuf * face_ptex_offset_buffer
int * subdiv_loop_face_index
gpu::VertBuf * subdiv_face_offset_buffer
int * subdiv_loop_subdiv_edge_index
gpu::VertBuf * edges_draw_flag
Array< float3 > loose_edge_positions
uint num_subdiv_triangles
gpu::VertBuf * corner_patch_coords
bke::subdiv::Subdiv * subdiv
gpu::VertBuf * patch_coords
DRWSubdivCache * subdiv_cache
MeshExtractLooseGeom loose_geom
MeshExtractType extract_type
const int * orig_index_face
VArraySpan< bool > sharp_faces
VArraySpan< bool > select_poly
VArraySpan< bool > hide_poly
bke::MeshNormalDomain normals_domain