36 static IMesh mesh_from_bm(
BMesh *
bm,
37 struct BMLoop *(*looptris)[3],
38 const int looptris_tot,
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_tot);
79 face_edge_orig.resize(3);
80 for (
int i = 0; i < looptris_tot; ++i) {
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);
102 static bool bmvert_attached_to_wire(
const BMVert *bmv)
110 static bool bmvert_attached_to_hidden_face(
BMVert *bmv)
115 bmf =
static_cast<BMFace *
>(BM_iter_step(&iter))) {
127 while (
l !=
nullptr) {
131 l =
static_cast<BMLoop *
>(BM_iter_step(&liter));
137 constexpr
uint KEEP_FLAG = (1 << 6);
146 static bool apply_mesh_output_to_bmesh(
BMesh *
bm, IMesh &m_out,
bool keep_hidden)
148 bool any_change =
false;
150 m_out.populate_vert();
158 bmvert_attached_to_wire(bmv)) {
170 Array<BMVert *> new_bmvs(m_out.vert_size());
171 for (
int v : m_out.vert_index_range()) {
172 const Vert *vertp = m_out.vert(
v);
173 int orig = vertp->orig;
174 if (orig != NO_INDEX) {
181 new_bmvs[
v] =
nullptr;
184 for (
int v : m_out.vert_index_range()) {
185 const Vert *vertp = m_out.vert(
v);
186 if (new_bmvs[
v] ==
nullptr) {
188 const double3 &d_co = vertp->co;
189 for (
int i = 0; i < 3; ++i) {
190 co[i] =
static_cast<float>(d_co[i]);
222 for (
const Face *f : m_out.faces()) {
223 maxflen =
max_ii(maxflen, f->size());
225 Array<BMVert *> face_bmverts(maxflen);
226 Array<BMEdge *> face_bmedges(maxflen);
227 for (
const Face *f : m_out.faces()) {
228 const Face &face = *f;
229 int flen = face.size();
230 for (
int i = 0; i < flen; ++i) {
231 const Vert *
v = face[i];
232 int v_index = m_out.lookup_vert(
v);
234 face_bmverts[i] = new_bmvs[v_index];
239 if (bmf !=
nullptr && face_has_verts_in_order(
bm, bmf, face_bmverts[0], face_bmverts[1])) {
243 int orig = face.orig;
246 if (orig != NO_INDEX) {
247 orig_face = old_bmfs[orig];
253 for (
int i = 0; i < flen; ++i) {
254 BMVert *bmv1 = face_bmverts[i];
255 BMVert *bmv2 = face_bmverts[(i + 1) % flen];
257 if (bme ==
nullptr) {
258 BMEdge *orig_edge =
nullptr;
259 if (face.edge_orig[i] != NO_INDEX) {
260 orig_edge = old_edges[face.edge_orig[i]];
263 if (orig_edge !=
nullptr) {
267 face_bmedges[i] = bme;
268 if (face.is_intersect[i]) {
276 bm, face_bmverts.data(), face_bmedges.data(), flen, orig_face,
BM_CREATE_NOP);
277 if (orig_face !=
nullptr) {
282 if (orig_face !=
nullptr) {
285 while (
l !=
nullptr) {
287 l =
static_cast<BMLoop *
>(BM_iter_step(&liter));
299 while (bmf !=
nullptr) {
303 BMFace *bmf_next =
static_cast<BMFace *
>(BM_iter_step(&iter));
317 while (bmv !=
nullptr) {
321 BMVert *bmv_next =
static_cast<BMVert *
>(BM_iter_step(&iter));
335 static bool bmesh_boolean(
BMesh *
bm,
336 struct BMLoop *(*looptris)[3],
337 const int looptris_tot,
342 const bool use_separate_all,
343 const bool keep_hidden,
344 const bool hole_tolerant,
345 const BoolOpType boolean_mode)
348 IMesh m_triangulated;
352 IMesh m_in = mesh_from_bm(
bm, looptris, looptris_tot, &m_triangulated, &arena);
355 std::cout <<
"bmesh_boolean, imesh_from_bm done, time = " << mesh_time - start_time <<
"\n";
357 std::function<int(
int)> shape_fn;
358 if (use_self && boolean_mode == BoolOpType::None) {
379 IMesh m_out = boolean_mesh(
380 m_in, boolean_mode, nshapes, shape_fn, use_self, hole_tolerant, &m_triangulated, &arena);
383 std::cout <<
"boolean done, time = " << boolean_time - mesh_time <<
"\n";
385 bool any_change = apply_mesh_output_to_bmesh(
bm, m_out, keep_hidden);
388 std::cout <<
"applied boolean output to bmesh, time = " << apply_mesh_time - boolean_time
391 if (use_separate_all) {
421 struct BMLoop *(*looptris)[3],
422 const int looptris_tot,
427 const bool keep_hidden,
428 const bool hole_tolerant,
429 const int boolean_mode)
431 return blender::meshintersect::bmesh_boolean(
442 static_cast<blender::meshintersect::BoolOpType
>(boolean_mode));
446 struct BMLoop *(*looptris)[3],
447 const int looptris_tot,
452 const bool use_separate_all,
453 const bool hole_tolerant,
454 const bool keep_hidden)
456 return blender::meshintersect::bmesh_boolean(
bm,
466 blender::meshintersect::BoolOpType::None);
470 struct BMLoop *(*looptris)[3],
471 const int UNUSED(looptris_tot),
472 int (*test_fn)(
BMFace *,
void *),
474 const int UNUSED(nshapes),
475 const bool UNUSED(use_self),
476 const bool UNUSED(keep_hidden),
477 const bool UNUSED(hole_tolerant),
478 const int UNUSED(boolean_mode))
493 struct BMLoop *(*looptris)[3],
494 const int UNUSED(looptris_tot),
495 int (*test_fn)(
BMFace *,
void *),
497 const int UNUSED(nshapes),
498 const bool UNUSED(use_self),
499 const bool UNUSED(use_separate_all),
500 const bool UNUSED(hole_tolerant),
501 const bool UNUSED(keep_hidden))
MINLINE int max_ii(int a, int b)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Platform independent time functions.
bool BM_mesh_boolean(BMesh *UNUSED(bm), struct BMLoop *(*looptris)[3], const int UNUSED(looptris_tot), int(*test_fn)(BMFace *, void *), void *UNUSED(user_data), const int UNUSED(nshapes), const bool UNUSED(use_self), const bool UNUSED(keep_hidden), const bool UNUSED(hole_tolerant), const int UNUSED(boolean_mode))
bool BM_mesh_boolean_knife(BMesh *UNUSED(bm), struct BMLoop *(*looptris)[3], const int UNUSED(looptris_tot), int(*test_fn)(BMFace *, void *), void *UNUSED(user_data), const int UNUSED(nshapes), const bool UNUSED(use_self), const bool UNUSED(use_separate_all), const bool UNUSED(hole_tolerant), const bool UNUSED(keep_hidden))
void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v)
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.
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 **verts, BMEdge **edges, const int len, const BMFace *f_example, const eBMCreateFlag create_flag)
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 BMFace * BM_face_at_index(BMesh *bm, const int index)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
bool BM_vert_is_wire(const BMVert *v)
BMFace * BM_face_exists(BMVert **varr, int len)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
vec_base< double, 3 > double3
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
double PIL_check_seconds_timer(void)