diff options
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_callback_generic.c | 6 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_callback_generic.h | 6 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_log.c | 60 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.c | 48 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.h | 28 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_conv.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 5 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 45 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_query.c | 44 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_query.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_walkers.c | 8 |
14 files changed, 178 insertions, 84 deletions
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.c b/source/blender/bmesh/intern/bmesh_callback_generic.c index e9304e8536f..90b2497aa80 100644 --- a/source/blender/bmesh/intern/bmesh_callback_generic.c +++ b/source/blender/bmesh/intern/bmesh_callback_generic.c @@ -32,7 +32,7 @@ bool BM_elem_cb_check_hflag_ex(BMElem *ele, void *user_data) { - const uint hflag_pair = GET_INT_FROM_POINTER(user_data); + const uint hflag_pair = POINTER_AS_INT(user_data); const char hflag_p = (hflag_pair & 0xff); const char hflag_n = (hflag_pair >> 8); @@ -42,14 +42,14 @@ bool BM_elem_cb_check_hflag_ex(BMElem *ele, void *user_data) bool BM_elem_cb_check_hflag_enabled(BMElem *ele, void *user_data) { - const char hflag = GET_INT_FROM_POINTER(user_data); + const char hflag = POINTER_AS_INT(user_data); return (BM_elem_flag_test(ele, hflag) != 0); } bool BM_elem_cb_check_hflag_disabled(BMElem *ele, void *user_data) { - const char hflag = GET_INT_FROM_POINTER(user_data); + const char hflag = POINTER_AS_INT(user_data); return (BM_elem_flag_test(ele, hflag) == 0); } diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.h b/source/blender/bmesh/intern/bmesh_callback_generic.h index 3cae01d417f..44495d54edd 100644 --- a/source/blender/bmesh/intern/bmesh_callback_generic.h +++ b/source/blender/bmesh/intern/bmesh_callback_generic.h @@ -32,14 +32,14 @@ bool BM_elem_cb_check_elem_not_equal(BMElem *ele, void *user_data); #define BM_elem_cb_check_hflag_ex_simple(type, hflag_p, hflag_n) \ (bool (*)(type, void *))BM_elem_cb_check_hflag_ex, \ - SET_UINT_IN_POINTER(((hflag_p) | (hflag_n << 8))) + POINTER_FROM_UINT(((hflag_p) | (hflag_n << 8))) #define BM_elem_cb_check_hflag_enabled_simple(type, hflag_p) \ (bool (*)(type, void *))BM_elem_cb_check_hflag_enabled, \ - SET_UINT_IN_POINTER((hflag_p)) + POINTER_FROM_UINT((hflag_p)) #define BM_elem_cb_check_hflag_disabled_simple(type, hflag_n) \ (bool (*)(type, void *))BM_elem_cb_check_hflag_disabled, \ - SET_UINT_IN_POINTER(hflag_n) + POINTER_FROM_UINT(hflag_n) #endif /* __BMESH_CALLBACK_GENERIC_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 30ab0dd9459..732647f83a7 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -134,13 +134,13 @@ typedef struct { static uint bm_log_vert_id_get(BMLog *log, BMVert *v) { BLI_assert(BLI_ghash_haskey(log->elem_to_id, v)); - return GET_UINT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, v)); + return POINTER_AS_UINT(BLI_ghash_lookup(log->elem_to_id, v)); } /* Set the vertex's unique ID in the log */ static void bm_log_vert_id_set(BMLog *log, BMVert *v, uint id) { - void *vid = SET_UINT_IN_POINTER(id); + void *vid = POINTER_FROM_UINT(id); BLI_ghash_reinsert(log->id_to_elem, vid, v, NULL, NULL); BLI_ghash_reinsert(log->elem_to_id, v, vid, NULL, NULL); @@ -149,7 +149,7 @@ static void bm_log_vert_id_set(BMLog *log, BMVert *v, uint id) /* Get a vertex from its unique ID */ static BMVert *bm_log_vert_from_id(BMLog *log, uint id) { - void *key = SET_UINT_IN_POINTER(id); + void *key = POINTER_FROM_UINT(id); BLI_assert(BLI_ghash_haskey(log->id_to_elem, key)); return BLI_ghash_lookup(log->id_to_elem, key); } @@ -158,13 +158,13 @@ static BMVert *bm_log_vert_from_id(BMLog *log, uint id) static uint bm_log_face_id_get(BMLog *log, BMFace *f) { BLI_assert(BLI_ghash_haskey(log->elem_to_id, f)); - return GET_UINT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, f)); + return POINTER_AS_UINT(BLI_ghash_lookup(log->elem_to_id, f)); } /* Set the face's unique ID in the log */ static void bm_log_face_id_set(BMLog *log, BMFace *f, uint id) { - void *fid = SET_UINT_IN_POINTER(id); + void *fid = POINTER_FROM_UINT(id); BLI_ghash_reinsert(log->id_to_elem, fid, f, NULL, NULL); BLI_ghash_reinsert(log->elem_to_id, f, fid, NULL, NULL); @@ -173,7 +173,7 @@ static void bm_log_face_id_set(BMLog *log, BMFace *f, uint id) /* Get a face from its unique ID */ static BMFace *bm_log_face_from_id(BMLog *log, uint id) { - void *key = SET_UINT_IN_POINTER(id); + void *key = POINTER_FROM_UINT(id); BLI_assert(BLI_ghash_haskey(log->id_to_elem, key)); return BLI_ghash_lookup(log->id_to_elem, key); } @@ -255,7 +255,7 @@ static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts) GHASH_ITER (gh_iter, verts) { void *key = BLI_ghashIterator_getKey(&gh_iter); BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter); - uint id = GET_UINT_FROM_POINTER(key); + uint id = POINTER_AS_UINT(key); BMVert *v = bm_log_vert_from_id(log, id); /* Ensure the log has the final values of the vertex before @@ -271,7 +271,7 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces) GHashIterator gh_iter; GHASH_ITER (gh_iter, faces) { void *key = BLI_ghashIterator_getKey(&gh_iter); - uint id = GET_UINT_FROM_POINTER(key); + uint id = POINTER_AS_UINT(key); BMFace *f = bm_log_face_from_id(log, id); BMEdge *e_tri[3]; BMLoop *l_iter; @@ -304,7 +304,7 @@ static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts) vert_mask_set(v, lv->mask, cd_vert_mask_offset); v->head.hflag = lv->hflag; normal_short_to_float_v3(v->no, lv->no); - bm_log_vert_id_set(log, v, GET_UINT_FROM_POINTER(key)); + bm_log_vert_id_set(log, v, POINTER_AS_UINT(key)); } } @@ -321,7 +321,7 @@ static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces) f = BM_face_create_verts(bm, v, 3, NULL, BM_CREATE_NOP, true); f->head.hflag = lf->hflag; - bm_log_face_id_set(log, f, GET_UINT_FROM_POINTER(key)); + bm_log_face_id_set(log, f, POINTER_AS_UINT(key)); } } @@ -333,7 +333,7 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts) GHASH_ITER (gh_iter, verts) { void *key = BLI_ghashIterator_getKey(&gh_iter); BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter); - uint id = GET_UINT_FROM_POINTER(key); + uint id = POINTER_AS_UINT(key); BMVert *v = bm_log_vert_from_id(log, id); float mask; short normal[3]; @@ -355,7 +355,7 @@ static void bm_log_face_values_swap(BMLog *log, GHash *faces) GHASH_ITER (gh_iter, faces) { void *key = BLI_ghashIterator_getKey(&gh_iter); BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter); - uint id = GET_UINT_FROM_POINTER(key); + uint id = POINTER_AS_UINT(key); BMFace *f = bm_log_face_from_id(log, id); SWAP(char, f->head.hflag, lf->hflag); @@ -425,7 +425,7 @@ static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash) GHASH_ITER (gh_iter, id_ghash) { void *key = BLI_ghashIterator_getKey(&gh_iter); - uint id = GET_UINT_FROM_POINTER(key); + uint id = POINTER_AS_UINT(key); range_tree_uint_retake(unused_ids, id); } @@ -454,8 +454,8 @@ static GHash *bm_log_compress_ids_to_indices(uint *ids, uint totid) qsort(ids, totid, sizeof(*ids), uint_compare); for (i = 0; i < totid; i++) { - void *key = SET_UINT_IN_POINTER(ids[i]); - void *val = SET_UINT_IN_POINTER(i); + void *key = POINTER_FROM_UINT(ids[i]); + void *val = POINTER_FROM_UINT(i); BLI_ghash_insert(map, key, val); } @@ -469,7 +469,7 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash) GHASH_ITER (gh_iter, id_ghash) { void *key = BLI_ghashIterator_getKey(&gh_iter); - uint id = GET_UINT_FROM_POINTER(key); + uint id = POINTER_AS_UINT(key); range_tree_uint_release(log->unused_ids, id); } } @@ -620,9 +620,9 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log) id_to_idx = bm_log_compress_ids_to_indices(varr, (uint)bm->totvert); BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) { const unsigned id = bm_log_vert_id_get(log, v); - const void *key = SET_UINT_IN_POINTER(id); + const void *key = POINTER_FROM_UINT(id); const void *val = BLI_ghash_lookup(id_to_idx, key); - varr[i] = GET_UINT_FROM_POINTER(val); + varr[i] = POINTER_AS_UINT(val); } BLI_ghash_free(id_to_idx, NULL, NULL); @@ -630,9 +630,9 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log) id_to_idx = bm_log_compress_ids_to_indices(farr, (uint)bm->totface); BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) { const unsigned id = bm_log_face_id_get(log, f); - const void *key = SET_UINT_IN_POINTER(id); + const void *key = POINTER_FROM_UINT(id); const void *val = BLI_ghash_lookup(id_to_idx, key); - farr[i] = GET_UINT_FROM_POINTER(val); + farr[i] = POINTER_AS_UINT(val); } BLI_ghash_free(id_to_idx, NULL, NULL); @@ -840,7 +840,7 @@ void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_o BMLogEntry *entry = log->current_entry; BMLogVert *lv; uint v_id = bm_log_vert_id_get(log, v); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); void **val_p; /* Find or create the BMLogVert entry */ @@ -864,7 +864,7 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset) { BMLogVert *lv; uint v_id = range_tree_uint_take_any(log->unused_ids); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); bm_log_vert_id_set(log, v, v_id); lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset); @@ -881,7 +881,7 @@ void BM_log_face_modified(BMLog *log, BMFace *f) { BMLogFace *lf; uint f_id = bm_log_face_id_get(log, f); - void *key = SET_UINT_IN_POINTER(f_id); + void *key = POINTER_FROM_UINT(f_id); lf = bm_log_face_alloc(log, f); BLI_ghash_insert(log->current_entry->modified_faces, key, lf); @@ -897,7 +897,7 @@ void BM_log_face_added(BMLog *log, BMFace *f) { BMLogFace *lf; uint f_id = range_tree_uint_take_any(log->unused_ids); - void *key = SET_UINT_IN_POINTER(f_id); + void *key = POINTER_FROM_UINT(f_id); /* Only triangles are supported for now */ BLI_assert(f->len == 3); @@ -927,7 +927,7 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset) { BMLogEntry *entry = log->current_entry; uint v_id = bm_log_vert_id_get(log, v); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); /* if it has a key, it shouldn't be NULL */ BLI_assert(!!BLI_ghash_lookup(entry->added_verts, key) == @@ -968,7 +968,7 @@ void BM_log_face_removed(BMLog *log, BMFace *f) { BMLogEntry *entry = log->current_entry; uint f_id = bm_log_face_id_get(log, f); - void *key = SET_UINT_IN_POINTER(f_id); + void *key = POINTER_FROM_UINT(f_id); /* if it has a key, it shouldn't be NULL */ BLI_assert(!!BLI_ghash_lookup(entry->added_faces, key) == @@ -1040,7 +1040,7 @@ const float *BM_log_original_vert_co(BMLog *log, BMVert *v) BMLogEntry *entry = log->current_entry; const BMLogVert *lv; unsigned v_id = bm_log_vert_id_get(log, v); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); @@ -1058,7 +1058,7 @@ const short *BM_log_original_vert_no(BMLog *log, BMVert *v) BMLogEntry *entry = log->current_entry; const BMLogVert *lv; unsigned v_id = bm_log_vert_id_get(log, v); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); @@ -1076,7 +1076,7 @@ float BM_log_original_mask(BMLog *log, BMVert *v) BMLogEntry *entry = log->current_entry; const BMLogVert *lv; unsigned v_id = bm_log_vert_id_get(log, v); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); @@ -1093,7 +1093,7 @@ void BM_log_original_vert_data( BMLogEntry *entry = log->current_entry; const BMLogVert *lv; unsigned v_id = bm_log_vert_id_get(log, v); - void *key = SET_UINT_IN_POINTER(v_id); + void *key = POINTER_FROM_UINT(v_id); BLI_assert(entry); diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 10a03050d4b..1e53180396e 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -863,7 +863,7 @@ void BM_editselection_normal(BMEditSelection *ese, float r_normal[3]) /* Calculate a plane that is rightangles to the edge/vert/faces normal * also make the plane run along an axis that is related to the geometry, - * because this is used for the manipulators Y axis. */ + * because this is used for the gizmos Y axis. */ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]) { if (ese->htype == BM_VERT) { @@ -895,7 +895,7 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]) else { /* the plane is simple, it runs along the edge * however selecting different edges can swap the direction of the y axis. - * this makes it less likely for the y axis of the manipulator + * this makes it less likely for the y axis of the gizmo * (running along the edge).. to flip less often. * at least its more predictable */ if (eed->v2->co[1] > eed->v1->co[1]) { /* check which to do first */ diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 185e5412b3d..3fe54b7229a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -188,7 +188,7 @@ BMesh *BM_mesh_create( /** * \brief BMesh Free Mesh Data * - * Frees a BMesh structure. + * Frees a BMesh structure. * * \note frees mesh, but not actual BMesh struct */ @@ -292,7 +292,7 @@ void BM_mesh_clear(BMesh *bm) /** * \brief BMesh Free Mesh * - * Frees a BMesh data and its structure. + * Frees a BMesh data and its structure. */ void BM_mesh_free(BMesh *bm) { @@ -363,6 +363,8 @@ typedef struct BMVertsCalcNormalsData { static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp_f) { +#define FLT_EQ_NONAN(_fa, _fb) (*((const uint32_t *)&_fa) == *((const uint32_t *)&_fb)) + BMVertsCalcNormalsData *data = userdata; BMFace *f = (BMFace *)mp_f; @@ -390,6 +392,11 @@ static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp fac = saacos(-dotprod); + if (fac != fac) { /* NAN detection. */ + /* Degenerated case, nothing to do here, just ignore that vertex. */ + continue; + } + /* accumulate weighted face normal into the vertex's normal */ float *v_no = data->vnos ? data->vnos[BM_elem_index_get(l_iter->v)] : l_iter->v->no; @@ -405,7 +412,7 @@ static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp * - v_no[0] was not FLT_MAX, i.e. it was not locked by another thread. */ const float vl = atomic_cas_float(&v_no[0], virtual_lock, FLT_MAX); - if (vl == virtual_lock && vl != FLT_MAX) { + if (FLT_EQ_NONAN(vl, virtual_lock) && vl != FLT_MAX) { break; } virtual_lock = vl; @@ -423,6 +430,8 @@ static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp BLI_assert(virtual_lock == FLT_MAX); } while ((l_iter = l_iter->next) != l_first); + +#undef FLT_EQ_NONAN } static void mesh_verts_calc_normals_normalize_cb(void *userdata, MempoolIterData *mp_v) @@ -894,7 +903,10 @@ static void bm_mesh_loops_calc_normals( clnors_avg[0] /= clnors_nbr; clnors_avg[1] /= clnors_nbr; /* Fix/update all clnors of this fan with computed average value. */ - printf("Invalid clnors in this fan!\n"); + + /* Prints continuously when merge custom normals, so commenting. */ + /* printf("Invalid clnors in this fan!\n"); */ + while ((clnor = BLI_SMALLSTACK_POP(clnors))) { //print_v2("org clnor", clnor); clnor[0] = (short)clnors_avg[0]; @@ -1009,7 +1021,8 @@ void BM_mesh_loop_normals_update( void BM_loops_calc_normal_vcos( BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3], const bool use_split_normals, const float split_angle, float (*r_lnos)[3], - MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset) + MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], + const int cd_loop_clnors_offset) { const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1); @@ -1019,7 +1032,8 @@ void BM_loops_calc_normal_vcos( bm_mesh_edges_sharp_tag(bm, vnos, fnos, r_lnos, has_clnors ? (float)M_PI : split_angle, false); /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */ - bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset); + bm_mesh_loops_calc_normals( + bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset); } else { BLI_assert(!r_lnors_spacearr); @@ -1455,28 +1469,6 @@ void BM_mesh_elem_table_free(BMesh *bm, const char htype) } } -BMVert *BM_vert_at_index(BMesh *bm, const int index) -{ - BLI_assert((index >= 0) && (index < bm->totvert)); - BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); - return bm->vtable[index]; -} - -BMEdge *BM_edge_at_index(BMesh *bm, const int index) -{ - BLI_assert((index >= 0) && (index < bm->totedge)); - BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0); - return bm->etable[index]; -} - -BMFace *BM_face_at_index(BMesh *bm, const int index) -{ - BLI_assert((index >= 0) && (index < bm->totface)); - BLI_assert((bm->elem_table_dirty & BM_FACE) == 0); - return bm->ftable[index]; -} - - BMVert *BM_vert_at_index_find(BMesh *bm, const int index) { return BLI_mempool_findelem(bm->vpool, index); diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index d449aac04f5..cc056e1fa19 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -48,9 +48,10 @@ void BM_mesh_clear(BMesh *bm); void BM_mesh_normals_update(BMesh *bm); void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3]); void BM_loops_calc_normal_vcos( - BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*pnos)[3], - const bool use_split_normals, const float split_angle, float (*r_lnos)[3], - struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset); + BMesh *bm, const float(*vcos)[3], const float(*vnos)[3], const float(*pnos)[3], + const bool use_split_normals, const float split_angle, float(*r_lnos)[3], + struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], + const int cd_loop_clnors_offset); bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr); @@ -75,9 +76,24 @@ void BM_mesh_elem_table_ensure(BMesh *bm, const char htype); void BM_mesh_elem_table_init(BMesh *bm, const char htype); void BM_mesh_elem_table_free(BMesh *bm, const char htype); -BMVert *BM_vert_at_index(BMesh *bm, const int index); -BMEdge *BM_edge_at_index(BMesh *bm, const int index); -BMFace *BM_face_at_index(BMesh *bm, const int index); +BLI_INLINE BMVert *BM_vert_at_index(BMesh *bm, const int index) +{ + BLI_assert((index >= 0) && (index < bm->totvert)); + BLI_assert((bm->elem_table_dirty & BM_VERT) == 0); + return bm->vtable[index]; +} +BLI_INLINE BMEdge *BM_edge_at_index(BMesh *bm, const int index) +{ + BLI_assert((index >= 0) && (index < bm->totedge)); + BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0); + return bm->etable[index]; +} +BLI_INLINE BMFace *BM_face_at_index(BMesh *bm, const int index) +{ + BLI_assert((index >= 0) && (index < bm->totface)); + BLI_assert((bm->elem_table_dirty & BM_FACE) == 0); + return bm->ftable[index]; +} BMVert *BM_vert_at_index_find(BMesh *bm, const int index); BMEdge *BM_edge_at_index_find(BMesh *bm, const int index); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 340b0b70772..2259a7dfe09 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -592,7 +592,7 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e) /** * - * \param bmain May be NULL in case \a calc_object_remap parameter option is set. + * \param bmain May be NULL in case \a calc_object_remap parameter option is not set. */ void BM_mesh_bm_to_me( Main *bmain, BMesh *bm, Mesh *me, diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 450d49211ec..7abf05044dd 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -881,6 +881,7 @@ static BMOpDefine bmo_extrude_discrete_faces_def = { "extrude_discrete_faces", /* slots_in */ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */ + {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */ {{'\0'}}, }, @@ -902,6 +903,7 @@ static BMOpDefine bmo_extrude_edge_only_def = { "extrude_edge_only", /* slots_in */ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */ + {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */ {{'\0'}}, }, @@ -1037,6 +1039,7 @@ static BMOpDefine bmo_extrude_face_region_def = { {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */ {"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}}, {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */ + {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */ {{'\0'}}, }, @@ -1386,6 +1389,8 @@ static BMOpDefine bmo_spin_def = { {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */ {"steps", BMO_OP_SLOT_INT}, /* number of steps */ + {"use_merge", BMO_OP_SLOT_BOOL}, /* Merge first/last when the angle is a full revolution. */ + {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */ {{'\0'}}, }, diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 3137725d6e7..5e3f5958a32 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -240,6 +240,28 @@ float BM_face_calc_area(const BMFace *f) } /** + * Get the area of the face in world space. + */ +float BM_face_calc_area_with_mat3(const BMFace *f, float mat3[3][3]) +{ + /* inline 'area_poly_v3' logic, avoid creating a temp array */ + const BMLoop *l_iter, *l_first; + float co[3]; + float n[3]; + + zero_v3(n); + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + mul_v3_m3v3(co, mat3, l_iter->v->co); + do { + float co_next[3]; + mul_v3_m3v3(co_next, mat3, l_iter->next->v->co); + add_newell_cross_v3_v3v3(n, co, co_next); + copy_v3_v3(co, co_next); + } while ((l_iter = l_iter->next) != l_first); + return len_v3(n) * 0.5f; +} + +/** * compute the perimeter of an ngon */ float BM_face_calc_perimeter(const BMFace *f) @@ -256,6 +278,27 @@ float BM_face_calc_perimeter(const BMFace *f) } /** + * Calculate the perimeter of a ngon in world space. + */ +float BM_face_calc_perimeter_with_mat3(const BMFace *f, float mat3[3][3]) +{ + const BMLoop *l_iter, *l_first; + float co[3]; + float perimeter = 0.0f; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + mul_v3_m3v3(co, mat3, l_iter->v->co); + do { + float co_next[3]; + mul_v3_m3v3(co_next, mat3, l_iter->next->v->co); + perimeter += len_v3v3(co, co_next); + copy_v3_v3(co, co_next); + } while ((l_iter = l_iter->next) != l_first); + + return perimeter; +} + +/** * Utility function to calculate the edge which is most different from the other two. * * \return The first edge index, where the second vertex is ``(index + 1) % 3``. @@ -487,7 +530,7 @@ void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_tangent[3]) } /** - * Compute a meaningful direction along the face (use for manipulator axis). + * Compute a meaningful direction along the face (use for gizmo axis). * * \note Callers shouldn't depend on the *exact* method used here. */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index a40da2bfbfa..1d5fb2cc620 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -44,7 +44,9 @@ float BM_face_calc_normal_vcos( float const (*vertexCos)[3]) ATTR_NONNULL(); float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3]) ATTR_NONNULL(); float BM_face_calc_area(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_face_calc_area_with_mat3(const BMFace *f, float mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_face_calc_perimeter(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_face_calc_perimeter_with_mat3(const BMFace *f, float mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BM_face_calc_tangent_edge(const BMFace *f, float r_plane[3]) ATTR_NONNULL(); void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_plane[3]) ATTR_NONNULL(); void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_plane[3]) ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c index 540888ac0b9..e1f16508b8b 100644 --- a/source/blender/bmesh/intern/bmesh_query.c +++ b/source/blender/bmesh/intern/bmesh_query.c @@ -792,7 +792,7 @@ bool BM_vert_edge_pair(BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b) } /** - * Returns the number of edges around this vertex. + * Returns the number of edges around this vertex. */ int BM_vert_edge_count(const BMVert *v) { @@ -817,7 +817,7 @@ int BM_vert_edge_count_nonwire(const BMVert *v) return count; } /** - * Returns the number of faces around this edge + * Returns the number of faces around this edge */ int BM_edge_face_count(const BMEdge *e) { @@ -1311,7 +1311,7 @@ bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2) } /** - * Test if e1 shares any quad faces with e2 + * Test if e1 shares any quad faces with e2 */ bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2) { @@ -1334,7 +1334,7 @@ bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2) } /** - * Tests to see if e1 shares a vertex with e2 + * Tests to see if e1 shares a vertex with e2 */ bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2) { @@ -1345,7 +1345,7 @@ bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2) } /** - * Return the shared vertex between the two edges or NULL + * Return the shared vertex between the two edges or NULL */ BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2) { @@ -1678,6 +1678,40 @@ float BM_edge_calc_face_angle(const BMEdge *e) } /** +* \brief BMESH EDGE/FACE ANGLE +* +* Calculates the angle between two faces in world space. +* Assumes the face normals are correct. +* +* \return angle in radians +*/ +float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e, float imat3[3][3], const float fallback) +{ + if (BM_edge_is_manifold(e)) { + const BMLoop *l1 = e->l; + const BMLoop *l2 = e->l->radial_next; + float no1[3], no2[3]; + copy_v3_v3(no1, l1->f->no); + copy_v3_v3(no2, l2->f->no); + + mul_transposed_m3_v3(imat3, no1); + mul_transposed_m3_v3(imat3, no2); + + normalize_v3(no1); + normalize_v3(no2); + + return angle_normalized_v3v3(no1, no2); + } + else { + return fallback; + } +} +float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, float imat3[3][3]) +{ + return BM_edge_calc_face_angle_with_imat3_ex(e, imat3, DEG2RADF(90.0f)); +} + +/** * \brief BMESH EDGE/FACE ANGLE * * Calculates the angle between two faces. diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h index 51956761d8f..fb625c9acc8 100644 --- a/source/blender/bmesh/intern/bmesh_query.h +++ b/source/blender/bmesh/intern/bmesh_query.h @@ -123,6 +123,8 @@ void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3]); float BM_edge_calc_face_angle_ex(const BMEdge *e, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_edge_calc_face_angle(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_edge_calc_face_angle_signed_ex(const BMEdge *e, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e, float imat3[3][3], const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, float imat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_edge_calc_face_angle_signed(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3]) ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index ff744ae1a42..8f9b4274336 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -37,7 +37,7 @@ #include "intern/bmesh_private.h" /** - * MISC utility functions. + * MISC utility functions. */ void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c index 77e9d441bbb..44692b760b6 100644 --- a/source/blender/bmesh/intern/bmesh_walkers.c +++ b/source/blender/bmesh/intern/bmesh_walkers.c @@ -190,10 +190,10 @@ void *BMW_current_state(BMWalker *walker) if (currentstate) { /* Automatic update of depth. For most walkers that * follow the standard "Step" pattern of: - * - read current state - * - remove current state - * - push new states - * - return walk result from just-removed current state + * - read current state + * - remove current state + * - push new states + * - return walk result from just-removed current state * this simple automatic update should keep track of depth * just fine. Walkers that deviate from that pattern may * need to manually update the depth if they care about |