static BVHTree *bvhtree_from_mesh_verts_create_tree( float epsilon, int tree_type, int axis, MVert *vert, const int numVerts, BLI_bitmap *mask, int numVerts_active) { BVHTree *tree = NULL; int i; if (vert) { if (mask && numVerts_active < 0) { numVerts_active = 0; for (i = 0; i < numVerts; i++) { if (BLI_BITMAP_TEST_BOOL(mask, i)) { numVerts_active++; } } } else if (!mask) { numVerts_active = numVerts; } tree = BLI_bvhtree_new(numVerts_active, epsilon, tree_type, axis); if (tree) { for (i = 0; i < numVerts; i++) { if (mask && !BLI_BITMAP_TEST_BOOL(mask, i)) { continue; } BLI_bvhtree_insert(tree, i, vert[i].co, 1); } BLI_bvhtree_balance(tree); } } return tree; }
static bool id_check_type(const ID *id, const BLI_bitmap *types_bitmap) { return BLI_BITMAP_TEST_BOOL(types_bitmap, id_code_as_index(GS(id->name))); }
static BVHTree *bvhtree_from_mesh_looptri_create_tree( float epsilon, int tree_type, int axis, BMEditMesh *em, const MVert *vert, const MLoop *mloop, const MLoopTri *looptri, const int looptri_num, BLI_bitmap *mask, int looptri_num_active) { BVHTree *tree = NULL; int i; if (looptri_num) { if (mask && looptri_num_active < 0) { looptri_num_active = 0; for (i = 0; i < looptri_num; i++) { if (BLI_BITMAP_TEST_BOOL(mask, i)) { looptri_num_active++; } } } else if (!mask) { looptri_num_active = looptri_num; } /* Create a bvh-tree of the given target */ /* printf("%s: building BVH, total=%d\n", __func__, numFaces); */ tree = BLI_bvhtree_new(looptri_num_active, epsilon, tree_type, axis); if (tree) { if (em) { const struct BMLoop *(*looptris)[3] = (void *)em->looptris; /* avoid double-up on face searches for quads-ngons */ bool insert_prev = false; BMFace *f_prev = NULL; /* data->em_evil is only set for snapping, and only for the mesh of the object * which is currently open in edit mode. When set, the bvhtree should not contain * faces that will interfere with snapping (e.g. faces that are hidden/selected * or faces that have selected verts). */ /* Insert BMesh-tessellation triangles into the bvh tree, unless they are hidden * and/or selected. Even if the faces themselves are not selected for the snapped * transform, having a vertex selected means the face (and thus it's tessellated * triangles) will be moving and will not be a good snap targets. */ for (i = 0; i < looptri_num; i++) { const BMLoop **ltri = looptris[i]; BMFace *f = ltri[0]->f; bool insert = mask ? BLI_BITMAP_TEST_BOOL(mask, i) : true; /* Start with the assumption the triangle should be included for snapping. */ if (f == f_prev) { insert = insert_prev; } else if (insert) { if (BM_elem_flag_test(f, BM_ELEM_SELECT) || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { /* Don't insert triangles tessellated from faces that are hidden or selected */ insert = false; } else { BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { if (BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) { /* Don't insert triangles tessellated from faces that have any selected verts */ insert = false; break; } } while ((l_iter = l_iter->next) != l_first); } /* skip if face doesn't change */ f_prev = f; insert_prev = insert; } if (insert) { /* No reason found to block hit-testing the triangle for snap, so insert it now.*/ float co[3][3]; copy_v3_v3(co[0], ltri[0]->v->co); copy_v3_v3(co[1], ltri[1]->v->co); copy_v3_v3(co[2], ltri[2]->v->co); BLI_bvhtree_insert(tree, i, co[0], 3); } } } else { if (vert && looptri) { for (i = 0; i < looptri_num; i++) { float co[4][3]; if (mask && !BLI_BITMAP_TEST_BOOL(mask, i)) { continue; } copy_v3_v3(co[0], vert[mloop[looptri[i].tri[0]].v].co); copy_v3_v3(co[1], vert[mloop[looptri[i].tri[1]].v].co); copy_v3_v3(co[2], vert[mloop[looptri[i].tri[2]].v].co); BLI_bvhtree_insert(tree, i, co[0], 3); } } } BLI_bvhtree_balance(tree); } } return tree; }