bmesh knife tool:
- only cut selected geometry. - exclude hidden geometry from snapping.
This commit is contained in:
@@ -90,6 +90,7 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
|
||||
SmallHash shash;
|
||||
float cos[3][3], (*cagecos)[3] = NULL;
|
||||
int i;
|
||||
int tottri;
|
||||
|
||||
/* when initializing cage verts, we only want the first cage coordinate for each vertex,
|
||||
* so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
|
||||
@@ -104,7 +105,19 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
|
||||
tree->epsilon = FLT_EPSILON * 2.0f;
|
||||
tree->flag = flag;
|
||||
|
||||
tree->tree = BLI_bvhtree_new(em->tottri, tree->epsilon, 8, 8);
|
||||
if (flag & BMBVH_RESPECT_HIDDEN) {
|
||||
tottri = 0;
|
||||
for (i = 0; i < em->tottri; i++) {
|
||||
if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) {
|
||||
tottri++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tottri = em->tottri;
|
||||
}
|
||||
|
||||
tree->tree = BLI_bvhtree_new(tottri, tree->epsilon, 8, 8);
|
||||
|
||||
if (flag & BMBVH_USE_CAGE) {
|
||||
BMIter iter;
|
||||
@@ -132,6 +145,14 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit)
|
||||
tree->cagecos = cagecos;
|
||||
|
||||
for (i = 0; i < em->tottri; i++) {
|
||||
|
||||
if (flag & BMBVH_RESPECT_HIDDEN) {
|
||||
/* note, the arrays wont allign now! take care */
|
||||
if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag & BMBVH_USE_CAGE) {
|
||||
copy_v3_v3(cos[0], cagecos[BM_elem_index_get(em->looptris[i][0]->v)]);
|
||||
copy_v3_v3(cos[1], cagecos[BM_elem_index_get(em->looptris[i][1]->v)]);
|
||||
|
||||
@@ -60,8 +60,11 @@ int BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e,
|
||||
/*find a vert closest to co in a sphere of radius maxdist*/
|
||||
struct BMVert *BMBVH_FindClosestVert(struct BMBVHTree *tree, float *co, float maxdist);
|
||||
|
||||
/*BMBVH_NewBVH flag parameter*/
|
||||
#define BMBVH_USE_CAGE 1 /*project geometry onto modifier cage */
|
||||
#define BMBVH_RETURN_ORIG 2 /*use with BMBVH_USE_CAGE, returns hits in relation to original geometry*/
|
||||
/* BMBVH_NewBVH flag parameter */
|
||||
enum {
|
||||
BMBVH_USE_CAGE = 1, /* project geometry onto modifier cage */
|
||||
BMBVH_RETURN_ORIG = 2, /* use with BMBVH_USE_CAGE, returns hits in relation to original geometry */
|
||||
BMBVH_RESPECT_HIDDEN = 4
|
||||
};
|
||||
|
||||
#endif /* __EDITBMESH_BVH_H__ */
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
|
||||
#define KMAXDIST 10 /* max mouse distance from edge before not detecting it */
|
||||
|
||||
#define USE_SELECTED_ONLY
|
||||
|
||||
/* knifetool operator */
|
||||
typedef struct KnifeVert {
|
||||
BMVert *v; /* non-NULL if this is an original vert */
|
||||
@@ -713,6 +715,15 @@ static void knife_add_cut(knifetool_opdata *kcd)
|
||||
if (len_v3v3(kcd->cur.cage, lh->realhit) < FLT_EPSILON * 80)
|
||||
continue;
|
||||
|
||||
#if 0 /* not working perfect, ignore for now */
|
||||
#ifdef USE_SELECTED_ONLY
|
||||
/* don't mess up logic by skipping too early */
|
||||
if (lh->kfe->e && !BM_elem_flag_test(lh->kfe->e, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (kcd->prev.is_space) {
|
||||
kcd->prev.is_space = 0;
|
||||
copy_v3_v3(kcd->prev.co, lh->hit);
|
||||
@@ -923,6 +934,13 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
|
||||
lh = kcd->linehits;
|
||||
for (i = 0; i < kcd->totlinehit; i++, lh++) {
|
||||
float sv1[3], sv2[3];
|
||||
int do_draw = TRUE;
|
||||
|
||||
#ifdef USE_SELECTED_ONLY
|
||||
if (!BM_elem_flag_test(lh->f, BM_ELEM_SELECT)) {
|
||||
do_draw = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
knife_project_v3(kcd, lh->kfe->v1->cageco, sv1);
|
||||
knife_project_v3(kcd, lh->kfe->v2->cageco, sv2);
|
||||
@@ -930,12 +948,12 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
|
||||
|
||||
if (len_v2v2(lh->schit, sv1) < kcd->vthresh / 4.0f) {
|
||||
copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco);
|
||||
glVertex3fv(lh->cagehit);
|
||||
if (do_draw) glVertex3fv(lh->cagehit);
|
||||
lh->v = lh->kfe->v1;
|
||||
}
|
||||
else if (len_v2v2(lh->schit, sv2) < kcd->vthresh / 4.0f) {
|
||||
copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco);
|
||||
glVertex3fv(lh->cagehit);
|
||||
if (do_draw) glVertex3fv(lh->cagehit);
|
||||
lh->v = lh->kfe->v2;
|
||||
}
|
||||
}
|
||||
@@ -947,6 +965,13 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
|
||||
glBegin(GL_POINTS);
|
||||
lh = kcd->linehits;
|
||||
for (i = 0; i < kcd->totlinehit; i++, lh++) {
|
||||
|
||||
#ifdef USE_SELECTED_ONLY
|
||||
if (!BM_elem_flag_test(lh->f, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
glVertex3fv(lh->cagehit);
|
||||
}
|
||||
glEnd();
|
||||
@@ -2588,6 +2613,12 @@ static void knife_make_cuts(knifetool_opdata *kcd)
|
||||
for (lst = BLI_smallhash_iternew(ehash, &hiter, (uintptr_t *)&e); lst;
|
||||
lst = BLI_smallhash_iternext(&hiter, (uintptr_t *)&e))
|
||||
{
|
||||
#ifdef USE_SELECTED_ONLY
|
||||
if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
sort_by_frac_along(lst, e);
|
||||
for (ref = lst->first; ref; ref = ref->next) {
|
||||
kfv = ref->ref;
|
||||
@@ -2600,6 +2631,12 @@ static void knife_make_cuts(knifetool_opdata *kcd)
|
||||
for (lst = BLI_smallhash_iternew(fhash, &hiter, (uintptr_t *)&f); lst;
|
||||
lst = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f))
|
||||
{
|
||||
#ifdef USE_SELECTED_ONLY
|
||||
if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
knife_make_face_cuts(kcd, f, lst);
|
||||
}
|
||||
|
||||
@@ -2733,7 +2770,7 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
|
||||
cage->foreachMappedVert(cage, cage_mapped_verts_callback, data);
|
||||
BLI_smallhash_release(&shash);
|
||||
|
||||
kcd->bmbvh = BMBVH_NewBVH(kcd->em, BMBVH_USE_CAGE | BMBVH_RETURN_ORIG, scene, obedit);
|
||||
kcd->bmbvh = BMBVH_NewBVH(kcd->em, BMBVH_USE_CAGE | BMBVH_RETURN_ORIG | BMBVH_RESPECT_HIDDEN, scene, obedit);
|
||||
kcd->arena = BLI_memarena_new(1 << 15, "knife");
|
||||
kcd->vthresh = KMAXDIST - 1;
|
||||
kcd->ethresh = KMAXDIST;
|
||||
|
||||
Reference in New Issue
Block a user