81 if (!em || !
backup.bmcopy) {
98 if (em &&
backup->bmcopy) {
102 else if (
backup->bmcopy) {
111 if (recalctess && em) {
194 printf(
"warning: em->emcopyusers was less than zero.\n");
233 const char *select_slot_out,
234 const bool select_extend,
263 if (select_extend ==
false) {
315 .use_toolflags =
true,
358 .calc_object_remap =
true,
359 .update_shapekey_indices = !free_data,
374 for (
Object *other_object = bmain->
objects.
first; other_object !=
NULL; other_object = other_object->id.next) {
375 if (other_object->data == ob->
data) {
471 "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b",
493 "region_extend geom=%hvef use_contract=%b use_faces=%b use_face_step=%b",
540 int totverts, i, totuv, totfaces;
542 bool *winding =
NULL;
569 winding =
MEM_callocN(
sizeof(*winding) * totfaces,
"winding");
572 if (!vmap->
vert || !vmap->
buf) {
610 const float *uv, *uv2;
635 (!use_winding || winding[iterv->
poly_index] == winding[
v->poly_index])) {
642 iterv->
next = newvlist;
655 vmap->
vert[
a] = newvlist;
669 return vmap->
vert[
v];
675 const bool face_selected,
676 const bool uv_selected,
677 const bool use_winding,
678 const bool do_islands)
687 bool *winding =
NULL;
691 int totverts, totfaces, i, totuv, j;
729 winding =
MEM_mallocN(
sizeof(*winding) * totfaces,
"winding");
776 const float *uv, *uv2;
777 bool uv_vert_sel, uv2_vert_sel;
803 const bool connected = (uv_vert_sel == uv2_vert_sel) &&
814 iterv->
next = newvlist;
827 element_map->
vert[i] = newvlist;
840 int *island_number =
NULL;
842 int nislands = 0, islandbufsize = 0;
845 map =
MEM_mallocN(
sizeof(*map) * totuv,
"uvelement_remap");
847 islandbuf =
MEM_callocN(
sizeof(*islandbuf) * totuv,
"uvelement_island_buffer");
848 island_number =
MEM_mallocN(
sizeof(*island_number) * totfaces,
"uv_island_number_face");
853 for (i = 0; i < totuv; i++) {
856 stack[0] = element_map->
buf[i].
l->
f;
860 while (stacksize > 0) {
861 efa = stack[--stacksize];
879 map[
element - element_map->
buf] = islandbufsize;
880 islandbuf[islandbufsize].
l =
element->l;
883 islandbuf[islandbufsize].
island = nislands;
892 stack[stacksize++] =
element->l->f;
911 if (element_map->
vert[i]) {
912 element_map->
vert[i] = &islandbuf[map[element_map->
vert[i] - element_map->
buf]];
917 "UvElementMap_island_indices");
919 for (i = 0; i < totuv; i++) {
925 islandbuf[map[i]].
next = &islandbuf[map[
element - element_map->
buf]];
928 if (islandbuf[i].island != j) {
936 element_map->
buf = islandbuf;
963 if (element_map->
vert) {
966 if (element_map->
buf) {
1035 intptr_t eve_i = index_lookup[index];
1036 return (eve_i == -1) ?
NULL : (
BMVert *)eve_i;
1057 #define BM_SEARCH_MAXDIST_MIRR 0.00002f
1058 #define BM_CD_LAYER_ID "__mirror_index"
1071 const bool use_self,
1072 const bool use_select,
1073 const bool respecthide,
1075 const bool use_topology,
1082 int cd_vmirr_offset = 0;
1084 const float maxdist_sq =
square_f(maxdist);
1092 if (r_index ==
NULL) {
1120 BLI_kdtree_3d_insert(
tree, i,
v->
co);
1122 BLI_kdtree_3d_balance(
tree);
1125 #define VERT_INTPTR(_v, _i) (r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset))
1142 if (v_mirr !=
NULL) {
1155 i_mirr = BLI_kdtree_3d_find_nearest(
tree, co,
NULL);
1164 if (v_mirr && (use_self || (v_mirr !=
v))) {
1181 BLI_kdtree_3d_free(
tree);
1187 const bool use_self,
1188 const bool use_select,
1189 const bool respecthide,
1190 const bool use_topology)
1209 if (mirr && *mirr >= 0 && *mirr < em->
bm->
totvert) {
1212 "err: should only be called between "
1213 "EDBM_verts_mirror_cache_begin and EDBM_verts_mirror_cache_end");
1240 BMLoop *l_iter, *l_first;
1248 }
while ((l_iter = l_iter->
next) != l_first);
1282 mirr->
co[0] *= -1.0f;
1302 bool changed =
true;
1340 const char iter_types[3] = {
1346 const bool sels[3] = {
1352 bool changed =
false;
1356 for (i = 0; i < 3; i++) {
1379 for (i = 0; i < 3; i++) {
1415 const char iter_types[3] = {
1432 for (i = 0; i < 3; i++) {
1434 for (; ele; ele = BM_iter_step(&iter)) {
1451 if (do_tessellation) {
1455 if (is_destructive) {
1551 if (index < bm->totvert) {
1555 if (index < bm->totedge) {
1559 if (index < bm->totface) {
1569 int *r_object_index)
1572 int elem_index = -1;
1573 *r_object_index = -1;
1575 for (
uint base_index = 0; base_index < bases_len; base_index++) {
1576 Base *base_iter = bases[base_index];
1578 *r_object_index = base_index;
1597 if (obedit !=
NULL) {
1641 float co1[3], co2[3], co3[3], dir1[3], dir2[3], dir3[3];
1642 float origin[3], invmat[4][4];
1645 const float mval_f[2] = {
1646 region->
winx / 2.0f,
1647 region->
winy / 2.0f,
1716 float mval[2], co_proj[3];
1724 .use_object_edit_cage =
false,
1725 .use_occlusion_test =
true,
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
struct Object * CTX_data_edit_object(const bContext *C)
struct View3D * CTX_wm_view3d(const bContext *C)
bool CustomData_has_layer(const struct CustomData *data, int type)
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name)
int CustomData_get_layer_index(const struct CustomData *data, int type)
void * CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n)
int CustomData_get_n_offset(const struct CustomData *data, int type, int n)
int CustomData_get_offset(const struct CustomData *data, int type)
void BKE_editmesh_free_derivedmesh(BMEditMesh *em)
void BKE_editmesh_looptri_calc(BMEditMesh *em)
BMEditMesh * BKE_editmesh_from_object(struct Object *ob)
Return the BMEditMesh for a given object.
void BKE_editmesh_free(BMEditMesh *em)
BMEditMesh * BKE_editmesh_copy(BMEditMesh *em)
BMEditMesh * BKE_editmesh_create(BMesh *bm, const bool do_tessellate)
struct BMFace * BKE_bmbvh_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], const float radius, float *r_dist, float r_hitout[3], float r_cagehit[3])
#define BKE_view_layer_array_from_bases_in_edit_mode(view_layer, v3d, r_len)
struct BMesh * BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob, const bool add_key_index, const struct BMeshCreateParams *params)
void BKE_mesh_uv_vert_map_free(UvVertMap *vmap)
#define STD_UV_CONNECT_LIMIT
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(struct Object *ob)
void BKE_report(ReportList *reports, ReportType type, const char *message)
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_array_alloca(arr, realsize)
#define BLI_buffer_reinit_data(buffer_, type_, new_count_)
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_)
#define BLI_buffer_free(name_)
A kd-tree for nearest neighbor search.
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
MINLINE float square_f(float a)
float cross_poly_v2(const float verts[][2], unsigned int nr)
bool invert_m4_m4(float R[4][4], const float A[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
void copy_vn_i(int *array_tar, const int size, const int val)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE bool compare_v2v2(const float a[2], const float b[2], const float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_length(float r[3], const float unit_scale)
MINLINE void add_v3_v3(float r[3], const float a[3])
struct Depsgraph Depsgraph
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Object is a sort of wrapper for general info.
#define SCE_SNAP_MODE_FACE
#define SCE_SELECT_VERTEX
void ED_mesh_mirror_topo_table_end(struct Object *ob)
void ED_mesh_mirrtopo_init(struct BMEditMesh *em, struct Mesh *me, MirrTopoStore_t *mesh_topo_store, const bool skip_em_vert_array_init)
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store)
void ED_mesh_mirror_spatial_table_end(struct Object *ob)
bool ED_operator_view3d_active(struct bContext *C)
bool ED_operator_editmesh(struct bContext *C)
SnapObjectContext * ED_transform_snap_object_context_create_view3d(struct Scene *scene, int flag, const struct ARegion *region, const struct View3D *v3d)
bool ED_transform_snap_object_project_view3d(struct SnapObjectContext *sctx, struct Depsgraph *depsgraph, const unsigned short snap_to, const struct SnapObjectParams *params, const float mval[2], const float prev_co[3], float *dist_px, float r_loc[3], float r_no[3])
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, const int cd_loop_uv_offset)
bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph, const struct ARegion *region, struct View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], const bool do_clip)
void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
Read Guarded memory(de)allocation.
#define BM_DEFAULT_NGON_STACK_SIZE
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
BMesh * BM_mesh_copy(BMesh *bm_old)
int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
void * BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar)
#define BM_iter_new(iter, bm, itype, data)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select)
void BM_mesh_select_flush(BMesh *bm)
void BM_mesh_select_mode_clean(BMesh *bm)
void BM_mesh_deselect_flush(BMesh *bm)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
BMFace * BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode)
Select Mode Flush.
#define BM_elem_hide_set(bm, ele, hide)
void BM_mesh_data_free(BMesh *bm)
BMesh Free Mesh Data.
void BM_mesh_clear(BMesh *bm)
BMesh Clear Mesh.
void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all)
BMEdge * BM_edge_at_index_find_or_table(BMesh *bm, const int index)
BMFace * BM_face_at_index_find_or_table(BMesh *bm, const int index)
BMVert * BM_vert_at_index_find_or_table(BMesh *bm, const int index)
void BM_mesh_normals_update(BMesh *bm)
BMesh Compute Normals.
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
bool BM_mesh_elem_table_check(BMesh *bm)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag, const bool do_flush)
BMO_FLAG_BUFFER.
void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag, const bool do_flush)
BMO_FLAG_BUFFER.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
bool BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt,...)
void BMO_op_finish(BMesh *bm, BMOperator *op)
BMESH OPSTACK FINISH OP.
BMOpSlot * BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
BMESH OPSTACK GET SLOT.
#define BMO_FLAG_DEFAULTS
bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, va_list vlist)
Format Strings for BMOperator Initialization.
ATTR_WARN_UNUSED_RESULT const void * element
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
bool BM_edge_in_face(const BMEdge *e, const BMFace *f)
BMFace * BM_face_exists(BMVert **varr, int len)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
const Depsgraph * depsgraph
bool EDBM_vert_color_check(BMEditMesh *em)
UvMapVert * BM_uv_vert_map_at_index(UvVertMap *vmap, uint v)
void EDBM_select_more(BMEditMesh *em, const bool use_face_step)
void EDBM_mesh_free(BMEditMesh *em)
bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt,...)
BMElem * EDBM_elem_from_selectmode(BMEditMesh *em, BMVert *eve, BMEdge *eed, BMFace *efa)
BMElem * EDBM_elem_from_index_any_multi(ViewLayer *view_layer, int object_index, int elem_index, Object **r_obedit)
BMVert * EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
bool BMBVH_EdgeVisible(struct BMBVHTree *tree, BMEdge *e, struct Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obedit)
void EDBM_flag_enable_all(BMEditMesh *em, const char hflag)
bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt,...)
bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const bool select_extend, const char *fmt,...)
BMFace * EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool selected)
void EDBM_mesh_normals_update(BMEditMesh *em)
bool EDBM_mesh_reveal(BMEditMesh *em, bool select)
void EDBM_deselect_flush(BMEditMesh *em)
void EDBM_redo_state_restore(BMBackup backup, BMEditMesh *em, int recalctess)
void EDBM_project_snap_verts(bContext *C, Depsgraph *depsgraph, ARegion *region, Object *obedit, BMEditMesh *em)
void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data)
UvVertMap * BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool use_winding)
static BMVert * cache_mirr_intptr_as_bmvert(const intptr_t *index_lookup, int index)
bool EDBM_op_finish(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const bool do_report)
bool EDBM_uv_check(BMEditMesh *em)
void BM_uv_element_map_free(UvElementMap *element_map)
void EDBM_stats_update(BMEditMesh *em)
bool EDBM_mesh_hide(BMEditMesh *em, bool swap)
void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool use_self, const bool use_select, const bool respecthide, const bool use_topology, float maxdist, int *r_index)
static void scale_point(float c1[3], const float p[3], const float s)
BMFace * EDBM_verts_mirror_get_face(BMEditMesh *em, BMFace *f)
void EDBM_selectmode_flush(BMEditMesh *em)
void EDBM_mesh_clear(BMEditMesh *em)
void EDBM_mesh_load(Main *bmain, Object *ob)
BMBackup EDBM_redo_state_store(BMEditMesh *em)
#define VERT_INTPTR(_v, _i)
void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const int axis, const bool use_self, const bool use_select, const bool respecthide, const bool use_topology)
bool EDBM_op_call_silentf(BMEditMesh *em, const char *fmt,...)
void EDBM_verts_mirror_cache_end(BMEditMesh *em)
void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v)
int EDBM_elem_to_index_any(BMEditMesh *em, BMElem *ele)
void EDBM_update_generic(Mesh *mesh, const bool do_tessellation, const bool is_destructive)
void EDBM_select_less(BMEditMesh *em, const bool use_face_step)
UvElementMap * BM_uv_element_map_create(BMesh *bm, const Scene *scene, const bool face_selected, const bool uv_selected, const bool use_winding, const bool do_islands)
static BMFace * edge_ray_cast(struct BMBVHTree *tree, const float co[3], const float dir[3], float *r_hitout, BMEdge *e)
bool EDBM_view3d_poll(bContext *C)
void EDBM_flag_disable_all(BMEditMesh *em, const char hflag)
#define BM_SEARCH_MAXDIST_MIRR
void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index)
void EDBM_select_flush(BMEditMesh *em)
void EDBM_selectmode_to_scene(bContext *C)
UvElement * BM_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l)
BMEdge * EDBM_verts_mirror_get_edge(BMEditMesh *em, BMEdge *e)
void EDBM_redo_state_free(BMBackup *backup, BMEditMesh *em, int recalctess)
void EDBM_verts_mirror_apply(BMEditMesh *em, const int sel_from, const int sel_to)
void BM_uv_vert_map_free(UvVertMap *vmap)
BMElem * EDBM_elem_from_index_any(BMEditMesh *em, int index)
void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode)
int EDBM_elem_to_index_any_multi(ViewLayer *view_layer, BMEditMesh *em, BMElem *ele, int *r_object_index)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
struct BMLoop *(* looptris)[3]
struct BMEditMesh * emcopy
struct BMEditSelection * next
eBMOpSlotSubType_Union slot_subtype
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMEditMesh * edit_mesh
struct ToolSettings * toolsettings
const struct ARegion * region
unsigned short loop_of_poly_index
unsigned short loop_of_poly_index
struct ReportList * reports
eBMOpSlotSubType_Elem elem
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)