Blender V5.0
editmesh_automerge.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2019 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13
14#include "BKE_editmesh.hh"
15
16#include "DNA_object_types.h"
17
18#include "ED_mesh.hh"
19
21
22// #define DEBUG_TIME
23#ifdef DEBUG_TIME
24# include "BLI_time.h"
25#endif
26
27/* use bmesh operator flags for a few operators */
28#define BMO_ELE_TAG 1
29
30/* -------------------------------------------------------------------- */
35
37 Object *obedit, bool update, const char hflag, const float dist, const bool use_connected)
38{
40 BMesh *bm = em->bm;
41 int totvert_prev = bm->totvert;
42
43 BMOperator findop, weldop;
44
45 /* Search for doubles among all vertices, but only merge non-VERT_KEEP
46 * vertices into VERT_KEEP vertices. */
48 &findop,
50 "find_doubles verts=%av keep_verts=%Hv dist=%f use_connected=%b",
51 hflag,
52 dist,
53 use_connected);
54
55 BMO_op_exec(bm, &findop);
56
57 /* weld the vertices */
58 BMO_op_init(bm, &weldop, BMO_FLAG_DEFAULTS, "weld_verts");
59 BMO_slot_copy(&findop, slots_out, "targetmap.out", &weldop, slots_in, "targetmap");
60 BMO_op_exec(bm, &weldop);
61
62 BMO_op_finish(bm, &findop);
63 BMO_op_finish(bm, &weldop);
64
65 bool changed = totvert_prev != bm->totvert;
66 if (changed && update) {
68 params.calc_looptris = true;
69 params.calc_normals = false;
70 params.is_destructive = true;
71 EDBM_update(static_cast<Mesh *>(obedit->data), &params);
72 }
73 return changed;
74}
75
76bool EDBM_automerge(Object *obedit, bool update, const char hflag, const float dist)
77{
78 return edbm_automerge_impl(obedit, update, hflag, dist, false);
79}
80
81bool EDBM_automerge_connected(Object *obedit, bool update, const char hflag, const float dist)
82{
83 return edbm_automerge_impl(obedit, update, hflag, dist, true);
84}
85
87
88/* -------------------------------------------------------------------- */
93
95 const bool /*split_edges*/,
96 const bool split_faces,
97 const bool update,
98 const char hflag,
99 const float dist)
100{
101 bool ok = false;
102
104 BMesh *bm = em->bm;
105
106#ifdef DEBUG_TIME
107 em->bm = BM_mesh_copy(bm);
108
109 double t1 = BLI_time_now_seconds();
110 EDBM_automerge(obedit, false, hflag, dist);
111 t1 = BLI_time_now_seconds() - t1;
112
113 BM_mesh_free(em->bm);
114 em->bm = bm;
115 double t2 = BLI_time_now_seconds();
116#endif
117
118 BMOperator weldop;
119 BMOpSlot *slot_targetmap;
120
121 BMO_op_init(bm, &weldop, BMO_FLAG_DEFAULTS, "weld_verts");
122 slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
123
124 GHash *ghash_targetmap = BMO_SLOT_AS_GHASH(slot_targetmap);
125
126 ok = BM_mesh_intersect_edges(bm, hflag, dist, split_faces, ghash_targetmap);
127
128 if (ok) {
129 BMO_op_exec(bm, &weldop);
130 }
131
132 BMO_op_finish(bm, &weldop);
133
134#ifdef DEBUG_TIME
135 t2 = BLI_time_now_seconds() - t2;
136 printf("t1: %lf; t2: %lf; fac: %lf\n", t1, t2, t1 / t2);
137#endif
138
139 if (LIKELY(ok) && update) {
141 params.calc_looptris = true;
142 params.calc_normals = false;
143 params.is_destructive = true;
144 EDBM_update(static_cast<Mesh *>(obedit->data), &params);
145 }
146
147 return ok;
148}
149
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:61
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.cc:113
#define LIKELY(x)
Object is a sort of wrapper for general info.
void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params)
BMesh * BM_mesh_copy(BMesh *bm_old)
bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, const bool split_faces, GHash *r_targetmap)
BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
BMOpSlot * BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
BMESH OPSTACK GET SLOT.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
#define BMO_slot_copy(op_src, slots_src, slot_name_src, op_dst, slots_dst, slot_name_dst)
#define BMO_SLOT_AS_GHASH(slot)
void BMO_op_init(BMesh *bm, BMOperator *op, int flag, const char *opname)
BMESH OPSTACK INIT OP.
bool BMO_op_initf(BMesh *bm, BMOperator *op, int flag, const char *fmt,...)
void BMO_op_finish(BMesh *bm, BMOperator *op)
BMESH OPSTACK FINISH OP.
#define BMO_FLAG_DEFAULTS
bool EDBM_automerge_connected(Object *obedit, bool update, const char hflag, const float dist)
bool EDBM_automerge_and_split(Object *obedit, const bool, const bool split_faces, const bool update, const char hflag, const float dist)
bool EDBM_automerge(Object *obedit, bool update, const char hflag, const float dist)
static bool edbm_automerge_impl(Object *obedit, bool update, const char hflag, const float dist, const bool use_connected)
#define printf(...)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static void update(bNodeTree *ntree)
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]