diff options
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_mesh.c')
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 177 |
1 files changed, 140 insertions, 37 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 79a080cfccd..e6f34d3dd0d 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -454,29 +454,24 @@ static void mesh_cd_calc_active_mask_uv_layer(const Object *object, } } -static void mesh_cd_calc_active_vcol_layer(const Object *object, - const Mesh *me, - DRW_MeshAttributes *attrs_used) -{ - const Mesh *me_final = editmesh_final_or_this(object, me); - const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); - - int layer = CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR); - if (layer != -1) { - drw_mesh_attributes_add_request(attrs_used, CD_PROP_COLOR, layer, ATTR_DOMAIN_POINT); - } -} - static void mesh_cd_calc_active_mloopcol_layer(const Object *object, const Mesh *me, DRW_MeshCDMask *cd_used) { const Mesh *me_final = editmesh_final_or_this(object, me); + Mesh me_query = {0}; + + const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); - int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL); - if (layer != -1) { - cd_used->vcol |= (1 << layer); + BKE_id_attribute_copy_domains_temp(ID_ME, cd_vdata, NULL, cd_ldata, NULL, NULL, &me_query.id); + + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me_query.id); + int layer_i = BKE_id_attribute_to_index( + &me_query.id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + + if (layer_i != -1) { + cd_used->vcol |= (1UL << (uint)layer_i); } } @@ -510,6 +505,51 @@ static bool custom_data_match_attribute(const CustomData *custom_data, return false; } +static uint mesh_cd_calc_gpu_layers_vcol_used(const Mesh *me_query, + const CustomData *cd_vdata, + const CustomData *cd_ldata, + const char name[]) +{ + CustomDataLayer *layer = NULL; + AttributeDomain domain; + + if (name[0]) { + int layer_i = 0; + + domain = ATTR_DOMAIN_POINT; + layer_i = CustomData_get_named_layer_index(cd_vdata, CD_PROP_COLOR, name); + layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_vdata, CD_MLOOPCOL, name) : + layer_i; + + if (layer_i == -1) { + domain = ATTR_DOMAIN_CORNER; + layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_ldata, CD_PROP_COLOR, name) : + layer_i; + layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_ldata, CD_MLOOPCOL, name) : + layer_i; + } + + /* Note: this is not the same as the layer_i below. */ + if (layer_i != -1) { + layer = (domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata)->layers + layer_i; + } + } + else { + layer = BKE_id_attributes_render_color_get(&me_query->id); + } + + if (!layer) { + return -1; + } + + /* Note: this is the logical index into the color attribute list, + * not the customdata index. */ + int vcol_i = BKE_id_attribute_to_index( + (ID *)me_query, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + + return vcol_i; +} + static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, const Mesh *me, struct GPUMaterial **gpumat_array, @@ -522,6 +562,13 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); const CustomData *cd_edata = mesh_cd_edata_get_from_mesh(me_final); + /* Create a mesh with final customdata domains + * we can query with attribute API. */ + Mesh me_query = {0}; + + BKE_id_attribute_copy_domains_temp( + ID_ME, cd_vdata, cd_edata, cd_ldata, cd_pdata, NULL, &me_query.id); + /* See: DM_vertex_attributes_from_gpu for similar logic */ DRW_MeshCDMask cd_used; mesh_cd_layers_type_clear(&cd_used); @@ -547,8 +594,35 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, type = CD_MTFACE; if (layer == -1) { + layer = CustomData_get_named_layer(cd_vdata, CD_PROP_COLOR, name); + if (layer != -1) { + type = CD_PROP_COLOR; + domain = ATTR_DOMAIN_POINT; + } + } + + if (layer == -1) { + layer = CustomData_get_named_layer(cd_ldata, CD_PROP_COLOR, name); + if (layer != -1) { + type = CD_PROP_COLOR; + domain = ATTR_DOMAIN_CORNER; + } + } + + if (layer == -1) { + layer = CustomData_get_named_layer(cd_vdata, CD_MLOOPCOL, name); + if (layer != -1) { + type = CD_MLOOPCOL; + domain = ATTR_DOMAIN_POINT; + } + } + + if (layer == -1) { layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name); - type = CD_MCOL; + if (layer != -1) { + type = CD_MLOOPCOL; + domain = ATTR_DOMAIN_CORNER; + } } #if 0 /* Tangents are always from UV's - this will never happen. */ @@ -619,29 +693,33 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, } break; } - case CD_MCOL: { - /* Vertex Color Data */ - if (layer == -1) { - layer = (name[0] != '\0') ? CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name) : - CustomData_get_render_layer(cd_ldata, CD_MLOOPCOL); - } - if (layer != -1) { - cd_used.vcol |= (1 << layer); - } - break; - } case CD_ORCO: { cd_used.orco = 1; break; } + + /* Note: attr->type will always be CD_PROP_COLOR even for + * CD_MLOOPCOL layers, see node_shader_gpu_vertex_color in + * node_shader_vertex_color.cc. + */ + case CD_MCOL: + case CD_MLOOPCOL: + case CD_PROP_COLOR: { + int vcol_bit = mesh_cd_calc_gpu_layers_vcol_used(&me_query, cd_vdata, cd_ldata, name); + + if (vcol_bit != -1) { + cd_used.vcol |= 1UL << (uint)vcol_bit; + } + + break; + } + case CD_PROP_FLOAT3: case CD_PROP_BOOL: case CD_PROP_INT8: case CD_PROP_INT32: case CD_PROP_FLOAT: - case CD_PROP_FLOAT2: - case CD_PROP_FLOAT3: - case CD_PROP_COLOR: { + case CD_PROP_FLOAT2: { if (layer != -1 && domain != ATTR_DOMAIN_NUM) { drw_mesh_attributes_add_request(attributes, type, layer, domain); } @@ -799,6 +877,12 @@ static bool mesh_batch_cache_valid(Object *object, Mesh *me) return false; } + if (object->sculpt && object->sculpt->pbvh) { + if (cache->pbvh_is_drawing != BKE_pbvh_is_drawing(object->sculpt->pbvh)) { + return false; + } + } + if (cache->is_editmode != (me->edit_mesh != NULL)) { return false; } @@ -827,6 +911,10 @@ static void mesh_batch_cache_init(Object *object, Mesh *me) cache->is_editmode = me->edit_mesh != NULL; + if (object->sculpt && object->sculpt->pbvh) { + cache->pbvh_is_drawing = BKE_pbvh_is_drawing(object->sculpt->pbvh); + } + if (cache->is_editmode == false) { // cache->edge_len = mesh_render_edges_len_get(me); // cache->tri_len = mesh_render_looptri_len_get(me); @@ -1120,14 +1208,28 @@ static void texpaint_request_active_vcol(MeshBatchCache *cache, Object *object, static void sculpt_request_active_vcol(MeshBatchCache *cache, Object *object, Mesh *me) { - DRW_MeshAttributes attrs_needed; - drw_mesh_attributes_clear(&attrs_needed); - mesh_cd_calc_active_vcol_layer(object, me, &attrs_needed); + const Mesh *me_final = editmesh_final_or_this(object, me); + const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); + const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); + + Mesh me_query = {0}; + BKE_id_attribute_copy_domains_temp(ID_ME, cd_vdata, NULL, cd_ldata, NULL, NULL, &me_query.id); - BLI_assert(attrs_needed.num_requests != 0 && - "No MPropCol layer available in Sculpt, but batches requested anyway!"); + CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id); + CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id); - drw_mesh_attributes_merge(&cache->attr_needed, &attrs_needed, me->runtime.render_mutex); + int active_i = BKE_id_attribute_to_index( + &me_query.id, active, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + int render_i = BKE_id_attribute_to_index( + &me_query.id, render, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + + if (active_i >= 0) { + cache->cd_used.vcol |= 1UL << (uint)active_i; + } + + if (render_i >= 0) { + cache->cd_used.vcol |= 1UL << (uint)render_i; + } } GPUBatch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) @@ -1148,6 +1250,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); mesh_batch_cache_request_surface_batches(cache); + return cache->batch.surface; } |