37static IMesh mesh_from_bm(
BMesh *
bm,
38 const Span<std::array<BMLoop *, 3>> looptris,
39 IMesh *r_triangulated,
46 const int estimate_num_outv = 3 *
bm->
totvert;
47 const int estimate_num_outf = 4 *
bm->
totface;
48 arena->reserve(estimate_num_outv, estimate_num_outf);
52 vert[
v] = arena->add_or_find_vert(mpq3(bmv->
co[0], bmv->
co[1], bmv->
co[2]),
v);
55 constexpr int estimated_max_facelen = 100;
56 Vector<const Vert *, estimated_max_facelen> face_vert;
57 Vector<int, estimated_max_facelen> face_edge_orig;
62 face_edge_orig.clear();
64 for (
int i = 0; i < flen; ++i) {
68 face_edge_orig.append(e_index);
71 face[f] = arena->add_face(face_vert, f, face_edge_orig);
77 Array<Face *> tri_face(looptris.size());
79 face_edge_orig.resize(3);
80 for (
const int i : looptris.index_range()) {
81 BMFace *bmf = looptris[i][0]->f;
83 for (
int j = 0; j < 3; ++j) {
87 if (
l->
next->
v == looptris[i][(j + 1) % 3]->v) {
93 face_vert[j] = vert[v_index];
94 face_edge_orig[j] = e_index;
96 tri_face[i] = arena->add_face(face_vert, f, face_edge_orig);
98 r_triangulated->set_faces(tri_face);
102static bool bmvert_attached_to_wire(
const BMVert *bmv)
110static bool bmvert_attached_to_hidden_face(
BMVert *bmv)
115 bmf =
static_cast<BMFace *
>(BM_iter_step(&iter)))
128 while (
l !=
nullptr) {
132 l =
static_cast<BMLoop *
>(BM_iter_step(&liter));
138constexpr uint KEEP_FLAG = (1 << 6);
147static bool apply_mesh_output_to_bmesh(
BMesh *
bm, IMesh &m_out,
bool keep_hidden)
149 bool any_change =
false;
151 m_out.populate_vert();
159 bmvert_attached_to_wire(bmv))
172 Array<BMVert *> new_bmvs(m_out.vert_size());
173 for (
int v : m_out.vert_index_range()) {
174 const Vert *vertp = m_out.vert(
v);
175 int orig = vertp->orig;
176 if (orig != NO_INDEX) {
183 new_bmvs[
v] =
nullptr;
186 for (
int v : m_out.vert_index_range()) {
187 const Vert *vertp = m_out.vert(
v);
188 if (new_bmvs[
v] ==
nullptr) {
190 const double3 &d_co = vertp->co;
191 for (
int i = 0; i < 3; ++i) {
192 co[i] =
float(d_co[i]);
224 for (
const Face *f : m_out.faces()) {
225 maxflen =
max_ii(maxflen, f->size());
227 Array<BMVert *> face_bmverts(maxflen);
228 Array<BMEdge *> face_bmedges(maxflen);
229 for (
const Face *f : m_out.faces()) {
230 const Face &face = *f;
231 int flen = face.size();
232 for (
int i = 0; i < flen; ++i) {
233 const Vert *
v = face[i];
234 int v_index = m_out.lookup_vert(
v);
236 face_bmverts[i] = new_bmvs[v_index];
241 if (bmf !=
nullptr && face_has_verts_in_order(
bm, bmf, face_bmverts[0], face_bmverts[1])) {
245 int orig = face.orig;
248 if (orig != NO_INDEX) {
249 orig_face = old_bmfs[orig];
255 for (
int i = 0; i < flen; ++i) {
256 BMVert *bmv1 = face_bmverts[i];
257 BMVert *bmv2 = face_bmverts[(i + 1) % flen];
259 if (bme ==
nullptr) {
260 BMEdge *orig_edge =
nullptr;
261 if (face.edge_orig[i] != NO_INDEX) {
262 orig_edge = old_edges[face.edge_orig[i]];
265 if (orig_edge !=
nullptr) {
269 face_bmedges[i] = bme;
270 if (face.is_intersect[i]) {
278 bm, face_bmverts.data(), face_bmedges.data(), flen, orig_face,
BM_CREATE_NOP);
279 if (orig_face !=
nullptr) {
284 if (orig_face !=
nullptr) {
287 while (
l !=
nullptr) {
289 l =
static_cast<BMLoop *
>(BM_iter_step(&liter));
301 while (bmf !=
nullptr) {
305 BMFace *bmf_next =
static_cast<BMFace *
>(BM_iter_step(&iter));
319 while (bmv !=
nullptr) {
323 BMVert *bmv_next =
static_cast<BMVert *
>(BM_iter_step(&iter));
337static bool bmesh_boolean(
BMesh *
bm,
338 const Span<std::array<BMLoop *, 3>> looptris,
339 int (*test_fn)(
BMFace *f,
void *user_data),
343 const bool use_separate_all,
344 const bool keep_hidden,
345 const bool hole_tolerant,
346 const BoolOpType boolean_mode)
349 IMesh m_triangulated;
353 IMesh m_in = mesh_from_bm(
bm, looptris, &m_triangulated, &arena);
356 std::cout <<
"bmesh_boolean, imesh_from_bm done, time = " << mesh_time - start_time <<
"\n";
358 std::function<
int(
int)> shape_fn;
359 if (use_self && boolean_mode == BoolOpType::None) {
362 shape_fn = [
bm, test_fn, user_data](
int f) {
364 if (test_fn(bmf, user_data) != -1) {
371 shape_fn = [
bm, test_fn, user_data](
int f) {
373 int test_val = test_fn(bmf, user_data);
380 IMesh m_out = boolean_mesh(
381 m_in, boolean_mode, nshapes, shape_fn, use_self, hole_tolerant, &m_triangulated, &arena);
384 std::cout <<
"boolean done, time = " << boolean_time - mesh_time <<
"\n";
386 bool any_change = apply_mesh_output_to_bmesh(
bm, m_out, keep_hidden);
389 std::cout <<
"applied boolean output to bmesh, time = " << apply_mesh_time - boolean_time
392 if (use_separate_all) {
422 int (*test_fn)(
BMFace *f,
void *user_data),
426 const bool keep_hidden,
427 const bool hole_tolerant,
428 const int boolean_mode)
430 return blender::meshintersect::bmesh_boolean(
440 static_cast<blender::meshintersect::BoolOpType
>(boolean_mode));
445 int (*test_fn)(
BMFace *f,
void *user_data),
449 const bool use_separate_all,
450 const bool hole_tolerant,
451 const bool keep_hidden)
453 return blender::meshintersect::bmesh_boolean(
bm,
462 blender::meshintersect::BoolOpType::None);
467 int (*test_fn)(
BMFace *,
void *),
489 int (*test_fn)(
BMFace *,
void *),
MINLINE int max_ii(int a, int b)
double BLI_time_now_seconds(void)
bool BM_mesh_boolean_knife(BMesh *, blender::Span< std::array< BMLoop *, 3 > > looptris, int(*test_fn)(BMFace *, void *), void *, const int, const bool, const bool, const bool, const bool)
bool BM_mesh_boolean(BMesh *, blender::Span< std::array< BMLoop *, 3 > > looptris, int(*test_fn)(BMFace *, void *), void *, const int, const bool, const bool, const bool, const int)
void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v)
void BM_vert_kill(BMesh *bm, BMVert *v)
void BM_face_kill(BMesh *bm, BMFace *f)
void BM_face_kill_loose(BMesh *bm, BMFace *f)
BMFace * BM_face_create(BMesh *bm, BMVert *const *verts, BMEdge *const *edges, const int len, const BMFace *f_example, const eBMCreateFlag create_flag)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select)
#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_loop_interp_from_face(BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
int BM_iter_mesh_count(const char itype, BMesh *bm)
#define BM_iter_new(iter, bm, itype, data)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
bool BM_vert_is_wire(const BMVert *v)
BMFace * BM_face_exists(BMVert *const *varr, int len)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
VecBase< double, 3 > double3