50 static IMesh mesh_from_bm(
BMesh *
bm,
51 struct BMLoop *(*looptris)[3],
52 const int looptris_tot,
53 IMesh *r_triangulated,
60 const int estimate_num_outv = 3 *
bm->
totvert;
61 const int estimate_num_outf = 4 *
bm->
totface;
62 arena->reserve(estimate_num_outv, estimate_num_outf);
66 vert[
v] = arena->add_or_find_vert(mpq3(bmv->
co[0], bmv->
co[1], bmv->
co[2]),
v);
69 constexpr
int estimated_max_facelen = 100;
70 Vector<const Vert *, estimated_max_facelen> face_vert;
71 Vector<int, estimated_max_facelen> face_edge_orig;
76 face_edge_orig.clear();
78 for (
int i = 0; i < flen; ++i) {
82 face_edge_orig.append(e_index);
85 face[f] = arena->add_face(face_vert, f, face_edge_orig);
91 Array<Face *> tri_face(looptris_tot);
93 face_edge_orig.resize(3);
94 for (
int i = 0; i < looptris_tot; ++i) {
95 BMFace *bmf = looptris[i][0]->f;
97 for (
int j = 0; j < 3; ++j) {
101 if (
l->
next->
v == looptris[i][(j + 1) % 3]->v) {
107 face_vert[j] = vert[v_index];
108 face_edge_orig[j] = e_index;
110 tri_face[i] = arena->add_face(face_vert, f, face_edge_orig);
112 r_triangulated->set_faces(tri_face);
116 static bool bmvert_attached_to_wire(
const BMVert *bmv)
124 static bool bmvert_attached_to_hidden_face(
BMVert *bmv)
129 bmf =
static_cast<BMFace *
>(BM_iter_step(&iter))) {
141 while (
l !=
nullptr) {
145 l =
static_cast<BMLoop *
>(BM_iter_step(&liter));
151 constexpr
uint KEEP_FLAG = (1 << 6);
160 static bool apply_mesh_output_to_bmesh(
BMesh *
bm, IMesh &m_out,
bool keep_hidden)
162 bool any_change =
false;
164 m_out.populate_vert();
172 bmvert_attached_to_wire(bmv)) {
184 Array<BMVert *> new_bmvs(m_out.vert_size());
185 for (
int v : m_out.vert_index_range()) {
186 const Vert *vertp = m_out.vert(
v);
187 int orig = vertp->orig;
188 if (orig != NO_INDEX) {
198 for (
int v : m_out.vert_index_range()) {
199 const Vert *vertp = m_out.vert(
v);
200 if (new_bmvs[
v] ==
NULL) {
202 const double3 &d_co = vertp->co;
203 for (
int i = 0; i < 3; ++i) {
204 co[i] =
static_cast<float>(d_co[i]);
236 for (
const Face *f : m_out.faces()) {
237 maxflen =
max_ii(maxflen, f->size());
239 Array<BMVert *> face_bmverts(maxflen);
240 Array<BMEdge *> face_bmedges(maxflen);
241 for (
const Face *f : m_out.faces()) {
242 const Face &face = *f;
243 int flen = face.size();
244 for (
int i = 0; i < flen; ++i) {
245 const Vert *
v = face[i];
246 int v_index = m_out.lookup_vert(
v);
248 face_bmverts[i] = new_bmvs[v_index];
253 if (bmf !=
nullptr && face_has_verts_in_order(
bm, bmf, face_bmverts[0], face_bmverts[1])) {
257 int orig = face.orig;
260 if (orig != NO_INDEX) {
261 orig_face = old_bmfs[orig];
267 for (
int i = 0; i < flen; ++i) {
268 BMVert *bmv1 = face_bmverts[i];
269 BMVert *bmv2 = face_bmverts[(i + 1) % flen];
271 if (bme ==
nullptr) {
272 BMEdge *orig_edge =
nullptr;
273 if (face.edge_orig[i] != NO_INDEX) {
274 orig_edge = old_edges[face.edge_orig[i]];
277 if (orig_edge !=
nullptr) {
281 face_bmedges[i] = bme;
282 if (face.is_intersect[i]) {
290 bm, face_bmverts.data(), face_bmedges.data(), flen, orig_face,
BM_CREATE_NOP);
291 if (orig_face !=
nullptr) {
296 if (orig_face !=
nullptr) {
299 while (
l !=
nullptr) {
301 l =
static_cast<BMLoop *
>(BM_iter_step(&liter));
313 while (bmf !=
nullptr) {
317 BMFace *bmf_next =
static_cast<BMFace *
>(BM_iter_step(&iter));
331 while (bmv !=
nullptr) {
335 BMVert *bmv_next =
static_cast<BMVert *
>(BM_iter_step(&iter));
349 static bool bmesh_boolean(
BMesh *
bm,
350 struct BMLoop *(*looptris)[3],
351 const int looptris_tot,
356 const bool use_separate_all,
357 const bool keep_hidden,
358 const bool hole_tolerant,
359 const BoolOpType boolean_mode)
362 IMesh m_triangulated;
366 IMesh m_in = mesh_from_bm(
bm, looptris, looptris_tot, &m_triangulated, &arena);
369 std::cout <<
"bmesh_boolean, imesh_from_bm done, time = " << mesh_time - start_time <<
"\n";
371 std::function<int(
int)> shape_fn;
372 if (use_self && boolean_mode == BoolOpType::None) {
393 IMesh m_out = boolean_mesh(
394 m_in, boolean_mode, nshapes, shape_fn, use_self, hole_tolerant, &m_triangulated, &arena);
397 std::cout <<
"boolean done, time = " << boolean_time - mesh_time <<
"\n";
399 bool any_change = apply_mesh_output_to_bmesh(
bm, m_out, keep_hidden);
402 std::cout <<
"applied boolean output to bmesh, time = " << apply_mesh_time - boolean_time
405 if (use_separate_all) {
435 struct BMLoop *(*looptris)[3],
436 const int looptris_tot,
441 const bool keep_hidden,
442 const bool hole_tolerant,
443 const int boolean_mode)
445 return blender::meshintersect::bmesh_boolean(
456 static_cast<blender::meshintersect::BoolOpType
>(boolean_mode));
468 struct BMLoop *(*looptris)[3],
469 const int looptris_tot,
474 const bool use_separate_all,
475 const bool hole_tolerant,
476 const bool keep_hidden)
478 return blender::meshintersect::bmesh_boolean(
bm,
488 blender::meshintersect::BoolOpType::None);
492 struct BMLoop *(*looptris)[3],
493 const int UNUSED(looptris_tot),
494 int (*test_fn)(
BMFace *,
void *),
496 const int UNUSED(nshapes),
497 const bool UNUSED(use_self),
498 const bool UNUSED(keep_hidden),
499 const bool UNUSED(hole_tolerant),
500 const int UNUSED(boolean_mode))
515 struct BMLoop *(*looptris)[3],
516 const int UNUSED(looptris_tot),
517 int (*test_fn)(
BMFace *,
void *),
519 const int UNUSED(nshapes),
520 const bool UNUSED(use_self),
521 const bool UNUSED(use_separate_all),
522 const bool UNUSED(hole_tolerant),
523 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
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
double PIL_check_seconds_timer(void)