Commit: 11adf6e99899687778046542f1d6680c8ade6fac Author: Bastien Montagne Date: Thu Feb 22 16:03:58 2018 +0100 Branches: soc-2017-normal-tools https://developer.blender.org/rB11adf6e99899687778046542f1d6680c8ade6fac
Merge branch 'master' into soc-2017-normal-tools Conflicts: source/blender/blenkernel/intern/mesh_evaluate.c source/blender/bmesh/intern/bmesh_mesh.c =================================================================== =================================================================== diff --cc source/blender/blenkernel/BKE_mesh.h index ec538d08ccd,31d889863b2..6fdec0ee422 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@@ -195,11 -195,14 +195,18 @@@ void BKE_mesh_loop_tangents_ex struct ReportList *reports); void BKE_mesh_loop_tangents( struct Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], struct ReportList *reports); +void BKE_mesh_loop_manifold_fan_around_vert_next( + const struct MLoop *mloops, const struct MPoly *mpolys, + const int *loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index, + const struct MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index); + void BKE_edges_sharp_from_angle_set( + const struct MVert *mverts, const int numVerts, + struct MEdge *medges, const int numEdges, + struct MLoop *mloops, const int numLoops, + struct MPoly *mpolys, const float (*polynors)[3], const int numPolys, + const float split_angle); + /** * References a contiguous loop-fan with normal offset vars. */ diff --cc source/blender/blenkernel/intern/mesh_evaluate.c index 97684f333b9,788ebe4119f..69a55256e5e --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@@ -715,7 -694,154 +716,154 @@@ typedef struct LoopSplitTaskDataCommon /* See comment about edge_to_loops below. */ #define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID)) + static void mesh_edges_sharp_tag( + LoopSplitTaskDataCommon *data, + const bool check_angle, const float split_angle, const bool do_sharp_edges_tag) + { + const MVert *mverts = data->mverts; + const MEdge *medges = data->medges; + const MLoop *mloops = data->mloops; + + const MPoly *mpolys = data->mpolys; + + const int numEdges = data->numEdges; + const int numPolys = data->numPolys; + + float (*loopnors)[3] = data->loopnors; /* Note: loopnors may be NULL here. */ + const float (*polynors)[3] = data->polynors; + + int (*edge_to_loops)[2] = data->edge_to_loops; + int *loop_to_poly = data->loop_to_poly; + + BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : NULL; + + const MPoly *mp; + int mp_index; + + const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f; + + for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) { + const MLoop *ml_curr; + int *e2l; + int ml_curr_index = mp->loopstart; + const int ml_last_index = (ml_curr_index + mp->totloop) - 1; + + ml_curr = &mloops[ml_curr_index]; + + for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) { + e2l = edge_to_loops[ml_curr->e]; + + loop_to_poly[ml_curr_index] = mp_index; + + /* Pre-populate all loop normals as if their verts were all-smooth, this way we don't have to compute + * those later! + */ + if (loopnors) { + normal_short_to_float_v3(loopnors[ml_curr_index], mverts[ml_curr->v].no); + } + + /* Check whether current edge might be smooth or sharp */ + if ((e2l[0] | e2l[1]) == 0) { + /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */ + e2l[0] = ml_curr_index; + /* We have to check this here too, else we might miss some flat faces!!! */ + e2l[1] = (mp->flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID; + } + else if (e2l[1] == INDEX_UNSET) { + const bool is_angle_sharp = (check_angle && + dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) < split_angle_cos); + + /* Second loop using this edge, time to test its sharpness. + * An edge is sharp if it is tagged as such, or its face is not smooth, + * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the same vertex, + * or angle between both its polys' normals is above split_angle value. + */ + if (!(mp->flag & ME_SMOOTH) || (medges[ml_curr->e].flag & ME_SHARP) || + ml_curr->v == mloops[e2l[0]].v || + is_angle_sharp) + { + /* Note: we are sure that loop != 0 here ;) */ + e2l[1] = INDEX_INVALID; + + /* We want to avoid tagging edges as sharp when it is already defined as such by + * other causes than angle threshold... */ + if (do_sharp_edges_tag && is_angle_sharp) { + BLI_BITMAP_SET(sharp_edges, ml_curr->e, true); + } + } + else { + e2l[1] = ml_curr_index; + } + } + else if (!IS_EDGE_SHARP(e2l)) { + /* More than two loops using this edge, tag as sharp if not yet done. */ + e2l[1] = INDEX_INVALID; + + /* We want to avoid tagging edges as sharp when it is already defined as such by + * other causes than angle threshold... */ + if (do_sharp_edges_tag) { + BLI_BITMAP_SET(sharp_edges, ml_curr->e, false); + } + } + /* Else, edge is already 'disqualified' (i.e. sharp)! */ + } + } + + /* If requested, do actual tagging of edges as sharp in another loop. */ + if (do_sharp_edges_tag) { + MEdge *me; + int me_index; + for (me = (MEdge *)medges, me_index = 0; me_index < numEdges; me++, me_index++) { + if (BLI_BITMAP_TEST(sharp_edges, me_index)) { + me->flag |= ME_SHARP; + } + } + + MEM_freeN(sharp_edges); + } + } + + /** Define sharp edges as needed to mimic 'autosmooth' from angle threshold. + * + * Used when defining an empty custom loop normals data layer, to keep same shading as with autosmooth! + */ + void BKE_edges_sharp_from_angle_set( + const struct MVert *mverts, const int UNUSED(numVerts), + struct MEdge *medges, const int numEdges, + struct MLoop *mloops, const int numLoops, + struct MPoly *mpolys, const float (*polynors)[3], const int numPolys, + const float split_angle) + { + if (split_angle >= (float)M_PI) { + /* Nothing to do! */ + return; + } + + /* Mapping edge -> loops. See BKE_mesh_normals_loop_split() for details. */ + int (*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__); + + /* Simple mapping from a loop to its polygon index. */ + int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + + LoopSplitTaskDataCommon common_data = { + .mverts = mverts, + .medges = medges, + .mloops = mloops, + .mpolys = mpolys, + .edge_to_loops = edge_to_loops, + .loop_to_poly = loop_to_poly, + .polynors = polynors, + .numEdges = numEdges, + .numPolys = numPolys, + }; + + mesh_edges_sharp_tag(&common_data, true, split_angle, true); + + MEM_freeN(edge_to_loops); + MEM_freeN(loop_to_poly); + } + -static void loop_manifold_fan_around_vert_next( +void BKE_mesh_loop_manifold_fan_around_vert_next( const MLoop *mloops, const MPoly *mpolys, const int *loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index, const MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index) @@@ -1354,60 -1475,9 +1497,9 @@@ void BKE_mesh_normals_loop_split r_lnors_spacearr = &_lnors_spacearr; } if (r_lnors_spacearr) { - BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops); + BKE_lnor_spacearr_init(r_lnors_spacearr, numLoops, MLNOR_SPACEARR_LOOP_INDEX); } - /* This first loop check which edges are actually smooth, and compute edge vectors. */ - for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) { - MLoop *ml_curr; - int *e2l; - int ml_curr_index = mp->loopstart; - const int ml_last_index = (ml_curr_index + mp->totloop) - 1; - - ml_curr = &mloops[ml_curr_index]; - - for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) { - e2l = edge_to_loops[ml_curr->e]; - - loop_to_poly[ml_curr_index] = mp_index; - - /* Pre-populate all loop normals as if their verts were all-smooth, this way we don't have to compute - * those later! - */ - normal_short_to_float_v3(r_loopnors[ml_curr_index], mverts[ml_curr->v].no); - - /* Check whether current edge might be smooth or sharp */ - if ((e2l[0] | e2l[1]) == 0) { - /* 'Empty' edge until now, set e2l[0] (and e2l[1] to INDEX_UNSET to tag it as unset). */ - e2l[0] = ml_curr_index; - /* We have to check this here too, else we might miss some flat faces!!! */ - e2l[1] = (mp->flag & ME_SMOOTH) ? INDEX_UNSET : INDEX_INVALID; - } - else if (e2l[1] == INDEX_UNSET) { - /* Second loop using this edge, time to test its sharpness. - * An edge is sharp if it is tagged as such, or its face is not smooth, - * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the same vertex, - * or angle between both its polys' normals is above split_angle value. - */ - if (!(mp->flag & ME_SMOOTH) || (medges[ml_curr->e].flag & ME_SHARP) || - ml_curr->v == mloops[e2l[0]].v || - (check_angle && dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) < split_angle_cos)) - { - /* Note: we are sure that loop != 0 here ;) */ - e2l[1] = INDEX_INVALID; - } - else { - e2l[1] = ml_curr_index; - } - } - else if (!IS_EDGE_SHARP(e2l)) { - /* More than two loops using this edge, tag as sharp if not yet done. */ - e2l[1] = INDEX_INVALID; - } - /* Else, edge is already 'disqualified' (i.e. sharp)! */ - } - } - /* Init data common to all tasks. */ LoopSplitTaskDataCommon common_data = { .lnors_spacearr = r_lnors_spacearr, diff --cc source/blender/bmesh/intern/bmesh_mesh.c index 18d857d5687,8d6e7ae5b29..52708977434 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@@ -1030,11 -1014,10 +1036,11 @@@ void BM_loops_calc_normal_vcos if (use_split_normals) { /* Tag smooth edges and set lnos from vnos when they might be completely smooth... * When using custom loop normals, disable the angle feature! */ - bm_mesh_edges_sharp_tag(bm, vnos, fnos, has_clnors ? (float)M_PI : split_angle, r_lnos); + bm_mesh_edges_sharp_tag(bm, vnos, fnos, r_lnos @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs