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:
authorGermano <germano.costa@ig.com.br>2017-11-06 19:14:07 +0300
committerGermano <germano.costa@ig.com.br>2017-11-06 19:14:07 +0300
commit5d70e847dd6f5182fa67c3b08260fbb5366009b5 (patch)
tree1456cfbc4cb11214f5ecff1e65a1719c08b44bd0 /source/blender/draw/intern
parent7082bd1f4ca4516109dba72506d33d1c65bc2e35 (diff)
Fix T51604: Support Auto-Smooth in Edit-Mesh
and allocate loop_normals in MeshRenderData instead of CustomData Differential Revision: D2907
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c91
1 files changed, 65 insertions, 26 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 615b79328b6..8cd0c13faec 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -339,6 +339,33 @@ static void mesh_cd_calc_used_gpu_layers(
}
}
+
+static void mesh_render_calc_normals_loop_and_poly(const Mesh *me, const float split_angle, MeshRenderData *rdata)
+{
+ BLI_assert((me->flag & ME_AUTOSMOOTH) != 0);
+
+ int totloop = me->totloop;
+ int totpoly = me->totpoly;
+ float (*loop_normals)[3] = MEM_mallocN(sizeof(*loop_normals) * totloop, __func__);
+ float (*poly_normals)[3] = MEM_mallocN(sizeof(*poly_normals) * totpoly, __func__);
+ short (*clnors)[2] = CustomData_get_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BKE_mesh_calc_normals_poly(
+ me->mvert, NULL, me->totvert,
+ me->mloop, me->mpoly, totloop, totpoly, poly_normals, false);
+
+ BKE_mesh_normals_loop_split(
+ me->mvert, me->totvert, me->medge, me->totedge,
+ me->mloop, loop_normals, totloop, me->mpoly, poly_normals, totpoly,
+ true, split_angle, NULL, clnors, NULL);
+
+ rdata->loop_len = totloop;
+ rdata->poly_len = totpoly;
+ rdata->loop_normals = loop_normals;
+ rdata->poly_normals = poly_normals;
+}
+
+
/**
* TODO(campbell): 'gpumat_array' may include materials linked to the object.
* While not default, object materials should be supported.
@@ -354,6 +381,9 @@ static MeshRenderData *mesh_render_data_create_ex(
CustomData_reset(&rdata->cd.output.ldata);
+ const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
+ const float split_angle = is_auto_smooth ? me->smoothresh : (float)M_PI;
+
if (me->edit_btmesh) {
BMEditMesh *embm = me->edit_btmesh;
BMesh *bm = embm->bm;
@@ -374,7 +404,12 @@ static MeshRenderData *mesh_render_data_create_ex(
rdata->tri_len = embm->tottri;
}
if (types & MR_DATATYPE_LOOP) {
- rdata->loop_len = bm->totloop;
+ int totloop = bm->totloop;
+ if (is_auto_smooth) {
+ rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * totloop, __func__);
+ BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1);
+ }
+ rdata->loop_len = totloop;
bm_ensure_types |= BM_LOOP;
}
if (types & MR_DATATYPE_POLY) {
@@ -447,12 +482,12 @@ static MeshRenderData *mesh_render_data_create_ex(
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, rdata->mlooptri);
}
if (types & MR_DATATYPE_LOOP) {
- if (me->flag & ME_AUTOSMOOTH) {
- BKE_mesh_calc_normals_split(me);
- rdata->loop_normals = CustomData_get_layer(&me->ldata, CD_NORMAL);
- }
rdata->loop_len = me->totloop;
rdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
+
+ if (is_auto_smooth) {
+ mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
+ }
}
if (types & MR_DATATYPE_POLY) {
rdata->poly_len = me->totpoly;
@@ -538,8 +573,6 @@ static MeshRenderData *mesh_render_data_create_ex(
rdata->orco = NULL;
}
- const bool is_auto_smooth = (me->flag & ME_AUTOSMOOTH) != 0;
-
/* don't access mesh directly, instead use vars taken from BMesh or Mesh */
#define me DONT_USE_THIS
#ifdef me /* quiet warning */
@@ -665,8 +698,10 @@ static MeshRenderData *mesh_render_data_create_ex(
BMesh *bm = em->bm;
if (is_auto_smooth && rdata->loop_normals == NULL) {
- /* TODO: split normals, see below */
- rdata->loop_normals = CustomData_get_layer(cd_ldata, CD_NORMAL);
+ /* Should we store the previous array of `loop_normals` in somewhere? */
+ rdata->loop_len = bm->totloop;
+ rdata->loop_normals = MEM_mallocN(sizeof(*rdata->loop_normals) * rdata->loop_len, __func__);
+ BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, split_angle, rdata->loop_normals, NULL, NULL, -1);
}
bool calc_active_tangent = false;
@@ -683,10 +718,8 @@ static MeshRenderData *mesh_render_data_create_ex(
#undef me
if (is_auto_smooth && rdata->loop_normals == NULL) {
- if (!CustomData_has_layer(cd_ldata, CD_NORMAL)) {
- BKE_mesh_calc_normals_split(me);
- }
- rdata->loop_normals = CustomData_get_layer(cd_ldata, CD_NORMAL);
+ /* Should we store the previous array of `loop_normals` in CustomData? */
+ mesh_render_calc_normals_loop_and_poly(me, split_angle, rdata);
}
bool calc_active_tangent = false;
@@ -777,6 +810,7 @@ static void mesh_render_data_free(MeshRenderData *rdata)
MEM_SAFE_FREE(rdata->loose_edges);
MEM_SAFE_FREE(rdata->edges_adjacent_polys);
MEM_SAFE_FREE(rdata->mlooptri);
+ MEM_SAFE_FREE(rdata->loop_normals);
MEM_SAFE_FREE(rdata->poly_normals);
MEM_SAFE_FREE(rdata->poly_normals_pack);
MEM_SAFE_FREE(rdata->vert_normals_pack);
@@ -1981,12 +2015,18 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
GWN_vertbuf_attr_get_raw_data(vbo, attr_id.pos, &pos_step);
GWN_vertbuf_attr_get_raw_data(vbo, attr_id.nor, &nor_step);
+ float (*lnors)[3] = rdata->loop_normals;
+
if (rdata->edit_bmesh) {
- mesh_render_data_ensure_poly_normals_pack(rdata);
- mesh_render_data_ensure_vert_normals_pack(rdata);
+ Gwn_PackedNormal *pnors_pack, *vnors_pack;
- Gwn_PackedNormal *pnors_pack = rdata->poly_normals_pack;
- Gwn_PackedNormal *vnors_pack = rdata->vert_normals_pack;
+ if (lnors == NULL) {
+ mesh_render_data_ensure_poly_normals_pack(rdata);
+ mesh_render_data_ensure_vert_normals_pack(rdata);
+
+ pnors_pack = rdata->poly_normals_pack;
+ vnors_pack = rdata->vert_normals_pack;
+ }
for (int i = 0; i < tri_len; i++) {
const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
@@ -1997,15 +2037,15 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
continue;
}
- const uint vtri[3] = {
- BM_elem_index_get(bm_looptri[0]->v),
- BM_elem_index_get(bm_looptri[1]->v),
- BM_elem_index_get(bm_looptri[2]->v),
- };
-
- if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) {
+ if (lnors) {
+ for (uint t = 0; t < 3; t++) {
+ const float *nor = lnors[BM_elem_index_get(bm_looptri[t])];
+ *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = GWN_normal_convert_i10_v3(nor);
+ }
+ }
+ else if (BM_elem_flag_test(bm_face, BM_ELEM_SMOOTH)) {
for (uint t = 0; t < 3; t++) {
- *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = vnors_pack[vtri[t]];
+ *((Gwn_PackedNormal *)GWN_vertbuf_raw_step(&nor_step)) = vnors_pack[BM_elem_index_get(bm_looptri[t]->v)];
}
}
else {
@@ -2021,7 +2061,6 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_ex(
}
}
else {
- float (*lnors)[3] = rdata->loop_normals;
if (lnors == NULL) {
/* Use normals from vertex. */
mesh_render_data_ensure_poly_normals_pack(rdata);