Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_impl_mesh.c
| Show First 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | typedef struct MeshRenderData { | ||||
| /* Data created on-demand (usually not for bmesh-based data). */ | /* Data created on-demand (usually not for bmesh-based data). */ | ||||
| EdgeAdjacentPolys *edges_adjacent_polys; | EdgeAdjacentPolys *edges_adjacent_polys; | ||||
| MLoopTri *mlooptri; | MLoopTri *mlooptri; | ||||
| int *loose_edges; | int *loose_edges; | ||||
| int *loose_verts; | int *loose_verts; | ||||
| float (*poly_normals)[3]; | float (*poly_normals)[3]; | ||||
| float (*vert_weight_color)[3]; | float (*vert_weight); | ||||
| char (*vert_color)[3]; | char (*vert_color)[3]; | ||||
| GPUPackedNormal *poly_normals_pack; | GPUPackedNormal *poly_normals_pack; | ||||
| GPUPackedNormal *vert_normals_pack; | GPUPackedNormal *vert_normals_pack; | ||||
| bool *edge_select_bool; | bool *edge_select_bool; | ||||
| } MeshRenderData; | } MeshRenderData; | ||||
| enum { | enum { | ||||
| MR_DATATYPE_VERT = 1 << 0, | MR_DATATYPE_VERT = 1 << 0, | ||||
| ▲ Show 20 Lines • Show All 627 Lines • ▼ Show 20 Lines | static void mesh_render_data_free(MeshRenderData *rdata) | ||||
| MEM_SAFE_FREE(rdata->loose_verts); | MEM_SAFE_FREE(rdata->loose_verts); | ||||
| MEM_SAFE_FREE(rdata->loose_edges); | MEM_SAFE_FREE(rdata->loose_edges); | ||||
| MEM_SAFE_FREE(rdata->edges_adjacent_polys); | MEM_SAFE_FREE(rdata->edges_adjacent_polys); | ||||
| MEM_SAFE_FREE(rdata->mlooptri); | MEM_SAFE_FREE(rdata->mlooptri); | ||||
| MEM_SAFE_FREE(rdata->loop_normals); | MEM_SAFE_FREE(rdata->loop_normals); | ||||
| MEM_SAFE_FREE(rdata->poly_normals); | MEM_SAFE_FREE(rdata->poly_normals); | ||||
| MEM_SAFE_FREE(rdata->poly_normals_pack); | MEM_SAFE_FREE(rdata->poly_normals_pack); | ||||
| MEM_SAFE_FREE(rdata->vert_normals_pack); | MEM_SAFE_FREE(rdata->vert_normals_pack); | ||||
| MEM_SAFE_FREE(rdata->vert_weight_color); | MEM_SAFE_FREE(rdata->vert_weight); | ||||
| MEM_SAFE_FREE(rdata->edge_select_bool); | MEM_SAFE_FREE(rdata->edge_select_bool); | ||||
| MEM_SAFE_FREE(rdata->vert_color); | MEM_SAFE_FREE(rdata->vert_color); | ||||
| CustomData_free(&rdata->cd.output.ldata, rdata->loop_len); | CustomData_free(&rdata->cd.output.ldata, rdata->loop_len); | ||||
| MEM_freeN(rdata); | MEM_freeN(rdata); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 206 Lines • ▼ Show 20 Lines | fallback: | ||||
| for (int i = 0; i < rdata->loop_len; i++) { | for (int i = 0; i < rdata->loop_len; i++) { | ||||
| vcol[i][0] = 255; | vcol[i][0] = 255; | ||||
| vcol[i][1] = 255; | vcol[i][1] = 255; | ||||
| vcol[i][2] = 255; | vcol[i][2] = 255; | ||||
| } | } | ||||
| } | } | ||||
| /* TODO, move into shader? */ | static float evaluate_vertex_weight(const MDeformVert *dvert, const VertexWeightSelection *vwsel) | ||||
| static void rgb_from_weight(float r_rgb[3], const float weight) | |||||
| { | |||||
| const float blend = ((weight / 2.0f) + 0.5f); | |||||
| if (weight <= 0.25f) { /* blue->cyan */ | |||||
| r_rgb[0] = 0.0f; | |||||
| r_rgb[1] = blend * weight * 4.0f; | |||||
| r_rgb[2] = blend; | |||||
| } | |||||
| else if (weight <= 0.50f) { /* cyan->green */ | |||||
| r_rgb[0] = 0.0f; | |||||
| r_rgb[1] = blend; | |||||
| r_rgb[2] = blend * (1.0f - ((weight - 0.25f) * 4.0f)); | |||||
| } | |||||
| else if (weight <= 0.75f) { /* green->yellow */ | |||||
| r_rgb[0] = blend * ((weight - 0.50f) * 4.0f); | |||||
| r_rgb[1] = blend; | |||||
| r_rgb[2] = 0.0f; | |||||
| } | |||||
| else if (weight <= 1.0f) { /* yellow->red */ | |||||
| r_rgb[0] = blend; | |||||
| r_rgb[1] = blend * (1.0f - ((weight - 0.75f) * 4.0f)); | |||||
| r_rgb[2] = 0.0f; | |||||
| } | |||||
| else { | |||||
| /* exceptional value, unclamped or nan, | |||||
| * avoid uninitialized memory use */ | |||||
| r_rgb[0] = 1.0f; | |||||
| r_rgb[1] = 0.0f; | |||||
| r_rgb[2] = 1.0f; | |||||
| } | |||||
| } | |||||
| static void vertex_weight_color(float vweight[3], float weight, bool show_alert_color) | |||||
| { | |||||
| CLAMP(weight, 0.0f, 1.0f); | |||||
| if (show_alert_color) { | |||||
| bTheme *theme = U.themes.first; | |||||
| rgb_uchar_to_float(vweight, (unsigned char*)theme->tv3d.vertex_unreferenced); | |||||
| } | |||||
| else if (U.flag & USER_CUSTOM_RANGE) { | |||||
| BKE_colorband_evaluate(&U.coba_weight, weight, vweight); | |||||
| } | |||||
| else { | |||||
| rgb_from_weight(vweight, weight); | |||||
| } | |||||
| } | |||||
| static void evaluate_vertex_weight(float vweight[3], const MDeformVert *dvert, const VertexWeightSelection *vwsel) | |||||
| { | { | ||||
| float input = 0.0f; | float input = 0.0f; | ||||
| bool show_alert_color = false; | bool show_alert_color = false; | ||||
| if (vwsel->flags & VWEIGHT_MULTIPAINT) { | if (vwsel->flags & VWEIGHT_MULTIPAINT) { | ||||
| /* Multi-Paint feature */ | /* Multi-Paint feature */ | ||||
| input = BKE_defvert_multipaint_collective_weight( | input = BKE_defvert_multipaint_collective_weight( | ||||
| dvert, vwsel->defgroup_tot, vwsel->defgroup_sel, vwsel->defgroup_sel_tot, (vwsel->flags & VWEIGHT_AUTO_NORMALIZE) != 0); | dvert, vwsel->defgroup_tot, vwsel->defgroup_sel, vwsel->defgroup_sel_tot, (vwsel->flags & VWEIGHT_AUTO_NORMALIZE) != 0); | ||||
| Show All 15 Lines | if (input == 0.0f) { | ||||
| case OB_DRAW_GROUPUSER_ALL: | case OB_DRAW_GROUPUSER_ALL: | ||||
| show_alert_color = defvert_is_weight_zero(dvert, vwsel->defgroup_tot); | show_alert_color = defvert_is_weight_zero(dvert, vwsel->defgroup_tot); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| vertex_weight_color(vweight, input, show_alert_color); | if (show_alert_color) { | ||||
| return -1.0f; | |||||
| } | |||||
| else { | |||||
| CLAMP(input, 0.0f, 1.0f); | |||||
| return input; | |||||
| } | |||||
| } | } | ||||
| /* color-code for missing data (full brightness isn't easy on the eye). */ | /** Ensure #MeshRenderData.vert_weight */ | ||||
| static const unsigned char missing_weight_color[3] = { 0xa0, 0x00, 0xa0 }; | static void mesh_render_data_ensure_vert_weight(MeshRenderData *rdata, const VertexWeightSelection *vwsel) | ||||
| /** Ensure #MeshRenderData.vert_weight_color */ | |||||
| static void mesh_render_data_ensure_vert_weight_color(MeshRenderData *rdata, const VertexWeightSelection *vwsel) | |||||
| { | { | ||||
| float (*vweight)[3] = rdata->vert_weight_color; | float (*vweight) = rdata->vert_weight; | ||||
| if (vweight == NULL) { | if (vweight == NULL) { | ||||
| if (vwsel->defgroup_active == -1) { | if (vwsel->defgroup_active == -1) { | ||||
| goto fallback; | goto fallback; | ||||
| } | } | ||||
| if (rdata->edit_bmesh) { | if (rdata->edit_bmesh) { | ||||
| BMesh *bm = rdata->edit_bmesh->bm; | BMesh *bm = rdata->edit_bmesh->bm; | ||||
| const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); | const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); | ||||
| if (cd_dvert_offset == -1) { | if (cd_dvert_offset == -1) { | ||||
| goto fallback; | goto fallback; | ||||
| } | } | ||||
| BMIter viter; | BMIter viter; | ||||
| BMVert *eve; | BMVert *eve; | ||||
| int i; | int i; | ||||
| vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__); | vweight = rdata->vert_weight = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__); | ||||
| BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) { | BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) { | ||||
| const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); | const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); | ||||
| evaluate_vertex_weight(vweight[i], dvert, vwsel); | vweight[i] = evaluate_vertex_weight(dvert, vwsel); | ||||
angavrilov: Why is the code using defvert_find_weight instead of properly reproducing… | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (rdata->dvert == NULL) { | if (rdata->dvert == NULL) { | ||||
| goto fallback; | goto fallback; | ||||
| } | } | ||||
| vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__); | vweight = rdata->vert_weight = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__); | ||||
| for (int i = 0; i < rdata->vert_len; i++) { | for (int i = 0; i < rdata->vert_len; i++) { | ||||
| evaluate_vertex_weight(vweight[i], &rdata->dvert[i], vwsel); | vweight[i] = evaluate_vertex_weight(&rdata->dvert[i], vwsel); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return; | return; | ||||
| fallback: | fallback: | ||||
| vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__); | vweight = rdata->vert_weight = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__); | ||||
| float error_color[3]; | |||||
| if ((vwsel->defgroup_active < 0) && (vwsel->defgroup_tot > 0)) { | if ((vwsel->defgroup_active < 0) && (vwsel->defgroup_tot > 0)) { | ||||
| rgb_uchar_to_float(error_color, missing_weight_color); | copy_vn_fl(vweight, rdata->vert_len, -2.0f); | ||||
| } | |||||
| else { | |||||
| vertex_weight_color(error_color, 0.0f, vwsel->alert_mode != OB_DRAW_GROUPUSER_NONE); | |||||
| } | } | ||||
| else if (vwsel->alert_mode != OB_DRAW_GROUPUSER_NONE) { | |||||
Done Inline ActionsWhy ? default weight is 0 and it's a calloc. fclem: Why ? default weight is 0 and it's a calloc. | |||||
| for (int i = 0; i < rdata->vert_len; i++) { | copy_vn_fl(vweight, rdata->vert_len, -1.0f); | ||||
| copy_v3_v3(vweight[i], error_color); | |||||
| } | } | ||||
| } | } | ||||
| /** Ensure #MeshRenderData.edge_select_bool */ | /** Ensure #MeshRenderData.edge_select_bool */ | ||||
| static void mesh_render_data_ensure_edge_select_bool(MeshRenderData *rdata, bool use_wire) | static void mesh_render_data_ensure_edge_select_bool(MeshRenderData *rdata, bool use_wire) | ||||
| { | { | ||||
| bool *edge_select_bool = rdata->edge_select_bool; | bool *edge_select_bool = rdata->edge_select_bool; | ||||
| if (edge_select_bool == NULL) { | if (edge_select_bool == NULL) { | ||||
| edge_select_bool = rdata->edge_select_bool = | edge_select_bool = rdata->edge_select_bool = | ||||
| MEM_callocN(sizeof(*edge_select_bool) * rdata->edge_len, __func__); | MEM_callocN(sizeof(*edge_select_bool) * rdata->edge_len, __func__); | ||||
| ▲ Show 20 Lines • Show All 1,552 Lines • ▼ Show 20 Lines | BLI_assert( | ||||
| rdata->types & | rdata->types & | ||||
| (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT)); | (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT)); | ||||
| GPUVertBuf *vbo; | GPUVertBuf *vbo; | ||||
| { | { | ||||
| uint cidx = 0; | uint cidx = 0; | ||||
| static GPUVertFormat format = { 0 }; | static GPUVertFormat format = { 0 }; | ||||
| static struct { uint col; } attr_id; | static struct { uint weight; } attr_id; | ||||
| if (format.attr_len == 0) { | if (format.attr_len == 0) { | ||||
| attr_id.col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | attr_id.weight = GPU_vertformat_attr_add(&format, "weight", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); | ||||
| } | } | ||||
| vbo = GPU_vertbuf_create_with_format(&format); | vbo = GPU_vertbuf_create_with_format(&format); | ||||
| const int tri_len = mesh_render_data_looptri_len_get(rdata); | const int tri_len = mesh_render_data_looptri_len_get(rdata); | ||||
| const int vbo_len_capacity = tri_len * 3; | const int vbo_len_capacity = tri_len * 3; | ||||
| int vbo_len_used = 0; | int vbo_len_used = 0; | ||||
| GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); | GPU_vertbuf_data_alloc(vbo, vbo_len_capacity); | ||||
| mesh_render_data_ensure_vert_weight_color(rdata, vwsel); | mesh_render_data_ensure_vert_weight(rdata, vwsel); | ||||
| const float (*vert_weight_color)[3] = rdata->vert_weight_color; | const float (*vert_weight) = rdata->vert_weight; | ||||
| if (rdata->edit_bmesh) { | if (rdata->edit_bmesh) { | ||||
| for (int i = 0; i < tri_len; i++) { | for (int i = 0; i < tri_len; i++) { | ||||
| const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; | const BMLoop **ltri = (const BMLoop **)rdata->edit_bmesh->looptris[i]; | ||||
| /* Assume 'use_hide' */ | /* Assume 'use_hide' */ | ||||
| if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { | if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) { | ||||
| for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { | for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { | ||||
| const int v_index = BM_elem_index_get(ltri[tri_corner]->v); | const int v_index = BM_elem_index_get(ltri[tri_corner]->v); | ||||
| GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]); | GPU_vertbuf_attr_set(vbo, attr_id.weight, cidx++, &vert_weight[v_index]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (int i = 0; i < tri_len; i++) { | for (int i = 0; i < tri_len; i++) { | ||||
| const MLoopTri *mlt = &rdata->mlooptri[i]; | const MLoopTri *mlt = &rdata->mlooptri[i]; | ||||
| if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) { | if (!(use_hide && (rdata->mpoly[mlt->poly].flag & ME_HIDE))) { | ||||
| for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { | for (uint tri_corner = 0; tri_corner < 3; tri_corner++) { | ||||
| const uint v_index = rdata->mloop[mlt->tri[tri_corner]].v; | const uint v_index = rdata->mloop[mlt->tri[tri_corner]].v; | ||||
| GPU_vertbuf_attr_set(vbo, attr_id.col, cidx++, vert_weight_color[v_index]); | GPU_vertbuf_attr_set(vbo, attr_id.weight, cidx++, &vert_weight[v_index]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| vbo_len_used = cidx; | vbo_len_used = cidx; | ||||
| if (vbo_len_capacity != vbo_len_used) { | if (vbo_len_capacity != vbo_len_used) { | ||||
| GPU_vertbuf_data_resize(vbo, vbo_len_used); | GPU_vertbuf_data_resize(vbo, vbo_len_used); | ||||
| ▲ Show 20 Lines • Show All 1,757 Lines • Show Last 20 Lines | |||||
Why is the code using defvert_find_weight instead of properly reproducing calc_weightpaint_vert_color? This is completely missing support for multipaint and alert color.