|
|
|
@@ -26,7 +26,6 @@
|
|
|
|
|
|
|
|
|
|
#define _USE_MATH_DEFINES
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
@@ -44,7 +43,6 @@
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
|
#include "BIF_glutil.h" /* for paint cursor */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "ED_screen.h"
|
|
|
|
|
#include "ED_space_api.h"
|
|
|
|
|
#include "ED_view3d.h"
|
|
|
|
@@ -185,7 +183,8 @@ static void knife_project_v3(knifetool_opdata *kcd, const float co[3], float sco
|
|
|
|
|
ED_view3d_project_float_v3(kcd->ar, co, sco, kcd->projmat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void knife_pos_data_clear(KnifePosData *kpd) {
|
|
|
|
|
static void knife_pos_data_clear(KnifePosData *kpd)
|
|
|
|
|
{
|
|
|
|
|
zero_v3(kpd->co);
|
|
|
|
|
zero_v3(kpd->cage);
|
|
|
|
|
kpd->vert = NULL;
|
|
|
|
@@ -495,8 +494,7 @@ static int verge_linehit(const void *vlh1, const void *vlh2)
|
|
|
|
|
else return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void knife_add_single_cut_through(knifetool_opdata *kcd,
|
|
|
|
|
KnifeVert *v1, KnifeVert *v2, BMFace *f)
|
|
|
|
|
static void knife_add_single_cut_through(knifetool_opdata *kcd, KnifeVert *v1, KnifeVert *v2, BMFace *f)
|
|
|
|
|
{
|
|
|
|
|
KnifeEdge *kfenew;
|
|
|
|
|
|
|
|
|
@@ -551,7 +549,7 @@ static void knife_cut_through(knifetool_opdata *kcd)
|
|
|
|
|
BMFace *f;
|
|
|
|
|
KnifeEdge *kfe, *kfe2, *kfe3;
|
|
|
|
|
KnifeVert *v1, *v2, *firstv = NULL, *lastv = NULL;
|
|
|
|
|
ListBase firstfaces = {NULL, NULL}, lastfaces = { NULL, NULL};
|
|
|
|
|
ListBase firstfaces = {NULL, NULL}, lastfaces = {NULL, NULL};
|
|
|
|
|
Ref *r, *r2;
|
|
|
|
|
KnifeEdge **splitkfe;
|
|
|
|
|
int i, j, found;
|
|
|
|
@@ -590,7 +588,7 @@ static void knife_cut_through(knifetool_opdata *kcd)
|
|
|
|
|
if (firstv) {
|
|
|
|
|
/* For each face incident to firstv,
|
|
|
|
|
* find the first following linehit (if any) sharing that face and connect */
|
|
|
|
|
for (r = firstfaces.first; r; r = r->next ) {
|
|
|
|
|
for (r = firstfaces.first; r; r = r->next) {
|
|
|
|
|
f = r->ref;
|
|
|
|
|
found = 0;
|
|
|
|
|
for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit; j++, lh2++) {
|
|
|
|
@@ -627,8 +625,8 @@ static void knife_cut_through(knifetool_opdata *kcd)
|
|
|
|
|
kfe2 = lh2->kfe;
|
|
|
|
|
for (r2 = kfe2->faces.first; r2; r2 = r2->next) {
|
|
|
|
|
if (r2->ref == f) {
|
|
|
|
|
v1 = splitkfe[i]? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]);
|
|
|
|
|
v2 = splitkfe[j]? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]);
|
|
|
|
|
v1 = splitkfe[i] ? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]);
|
|
|
|
|
v2 = splitkfe[j] ? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]);
|
|
|
|
|
knife_add_single_cut_through(kcd, v1, v2, f);
|
|
|
|
|
found = 1;
|
|
|
|
|
break;
|
|
|
|
@@ -638,7 +636,7 @@ static void knife_cut_through(knifetool_opdata *kcd)
|
|
|
|
|
if (!found && lastv) {
|
|
|
|
|
for (r2 = lastfaces.first; r2; r2 = r2->next) {
|
|
|
|
|
if (r2->ref == f) {
|
|
|
|
|
v1 = splitkfe[i]? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]);
|
|
|
|
|
v1 = splitkfe[i] ? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]);
|
|
|
|
|
knife_add_single_cut_through(kcd, v1, lastv, f);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
@@ -1080,7 +1078,7 @@ static BMEdgeHit *knife_edge_tri_isect(knifetool_opdata *kcd, BMBVHTree *bmtree,
|
|
|
|
|
if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
|
|
|
|
|
BMEdgeHit hit;
|
|
|
|
|
|
|
|
|
|
if ( len_squared_v3v3(p, kcd->cur.co) < depsilon_squared ||
|
|
|
|
|
if (len_squared_v3v3(p, kcd->cur.co) < depsilon_squared ||
|
|
|
|
|
len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
@@ -1238,7 +1236,6 @@ static void knife_input_ray_cast(knifetool_opdata *kcd, const int mval_i[2],
|
|
|
|
|
mul_m3_v3(imat, r_ray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static BMFace *knife_find_closest_face(knifetool_opdata *kcd, float co[3], float cageco[3], int *is_space)
|
|
|
|
|
{
|
|
|
|
|
BMFace *f;
|
|
|
|
@@ -1422,7 +1419,8 @@ static KnifeEdge *knife_find_closest_edge(knifetool_opdata *kcd, float p[3], flo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* find a vertex near the mouse cursor, if it exists */
|
|
|
|
|
static KnifeVert *knife_find_closest_vert(knifetool_opdata *kcd, float p[3], float cagep[3], BMFace **fptr, int *is_space)
|
|
|
|
|
static KnifeVert *knife_find_closest_vert(knifetool_opdata *kcd, float p[3], float cagep[3], BMFace **fptr,
|
|
|
|
|
int *is_space)
|
|
|
|
|
{
|
|
|
|
|
BMFace *f;
|
|
|
|
|
float co[3], cageco[3], sco[3], maxdist = knife_snap_size(kcd, kcd->vthresh);
|
|
|
|
@@ -1659,7 +1657,7 @@ static void remerge_faces(knifetool_opdata *kcd)
|
|
|
|
|
f2 = BM_faces_join(bm, faces, BLI_array_count(faces));
|
|
|
|
|
if (f2) {
|
|
|
|
|
BMO_elem_flag_enable(bm, f2, FACE_NEW);
|
|
|
|
|
BM_elem_index_set(f2, idx); /* set_dirty! */ /* BMESH_TODO, check if this is valid or not */
|
|
|
|
|
BM_elem_index_set(f2, idx); /* set_dirty! *//* BMESH_TODO, check if this is valid or not */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -1874,7 +1872,7 @@ static void knifenet_fill_faces(knifetool_opdata *kcd)
|
|
|
|
|
} while ((l_iter = l_iter->next) != BM_FACE_FIRST_LOOP(f2));
|
|
|
|
|
|
|
|
|
|
BMO_elem_flag_disable(bm, f2, DEL);
|
|
|
|
|
BM_elem_index_set(f2, i); /* set_dirty! */ /* note, not 100% sure this is dirty? need to check */
|
|
|
|
|
BM_elem_index_set(f2, i); /* set_dirty! *//* note, not 100% sure this is dirty? need to check */
|
|
|
|
|
|
|
|
|
|
BM_face_normal_update(bm, f2);
|
|
|
|
|
if (dot_v3v3(f->no, f2->no) < 0.0f) {
|
|
|
|
@@ -1931,7 +1929,8 @@ static void knifenet_fill_faces(knifetool_opdata *kcd)
|
|
|
|
|
#else /* use direct (non-scanfill) method for cuts */
|
|
|
|
|
|
|
|
|
|
/* assuming v is on line ab, what fraction of the way is v from a to b? */
|
|
|
|
|
static float frac_along(const float a[3], const float b[3], const float v[3]) {
|
|
|
|
|
static float frac_along(const float a[3], const float b[3], const float v[3])
|
|
|
|
|
{
|
|
|
|
|
float lab;
|
|
|
|
|
|
|
|
|
|
lab = len_v3v3(a, b);
|
|
|
|
@@ -1944,7 +1943,8 @@ static float frac_along(const float a[3], const float b[3], const float v[3]) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sort list of kverts by fraction along edge e */
|
|
|
|
|
static void sort_by_frac_along(ListBase *lst, BMEdge *e) {
|
|
|
|
|
static void sort_by_frac_along(ListBase *lst, BMEdge *e)
|
|
|
|
|
{
|
|
|
|
|
KnifeVert *vcur, *vprev;
|
|
|
|
|
float *v1co, *v2co;
|
|
|
|
|
Ref *cur = NULL, *prev = NULL, *next = NULL;
|
|
|
|
@@ -1976,8 +1976,9 @@ static void sort_by_frac_along(ListBase *lst, BMEdge *e) {
|
|
|
|
|
/* The chain so far goes from an instantiated vertex to kfv (some may be reversed).
|
|
|
|
|
* If possible, complete the chain to another instantiated vertex and return 1, else return 0.
|
|
|
|
|
* The visited hash says which KnifeVert's have already been tried, not including kfv. */
|
|
|
|
|
static int find_chain_search(knifetool_opdata *kcd, KnifeVert *kfv,
|
|
|
|
|
ListBase *fedges, SmallHash *visited, ListBase *chain) {
|
|
|
|
|
static int find_chain_search(knifetool_opdata *kcd, KnifeVert *kfv, ListBase *fedges, SmallHash *visited,
|
|
|
|
|
ListBase *chain)
|
|
|
|
|
{
|
|
|
|
|
Ref *r;
|
|
|
|
|
KnifeEdge *kfe;
|
|
|
|
|
KnifeVert *kfv_other;
|
|
|
|
@@ -2007,8 +2008,8 @@ static int find_chain_search(knifetool_opdata *kcd, KnifeVert *kfv,
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ListBase * find_chain_from_vertex(knifetool_opdata *kcd, KnifeEdge *kfe,
|
|
|
|
|
BMVert *v, ListBase *fedges) {
|
|
|
|
|
static ListBase * find_chain_from_vertex(knifetool_opdata *kcd, KnifeEdge *kfe, BMVert *v, ListBase *fedges)
|
|
|
|
|
{
|
|
|
|
|
SmallHash visited_, *visited = &visited_;
|
|
|
|
|
ListBase *ans;
|
|
|
|
|
int found;
|
|
|
|
@@ -2037,7 +2038,8 @@ static ListBase * find_chain_from_vertex(knifetool_opdata *kcd, KnifeEdge *kfe,
|
|
|
|
|
|
|
|
|
|
/* Find a chain in fedges from one instantiated vertex to another.
|
|
|
|
|
* Remove the edges in the chain from fedges and return a separate list of the chain. */
|
|
|
|
|
static ListBase * find_chain(knifetool_opdata *kcd, ListBase *fedges) {
|
|
|
|
|
static ListBase * find_chain(knifetool_opdata *kcd, ListBase *fedges)
|
|
|
|
|
{
|
|
|
|
|
Ref *r, *ref;
|
|
|
|
|
KnifeEdge *kfe;
|
|
|
|
|
BMVert *v1, *v2;
|
|
|
|
@@ -2075,8 +2077,9 @@ static ListBase * find_chain(knifetool_opdata *kcd, ListBase *fedges) {
|
|
|
|
|
/* The hole so far goes from kfvfirst to kfv (some may be reversed).
|
|
|
|
|
* If possible, complete the hole back to kfvfirst and return 1, else return 0.
|
|
|
|
|
* The visited hash says which KnifeVert's have already been tried, not including kfv or kfvfirst. */
|
|
|
|
|
static int find_hole_search(knifetool_opdata *kcd, KnifeVert *kfvfirst, KnifeVert *kfv,
|
|
|
|
|
ListBase *fedges, SmallHash *visited, ListBase *hole) {
|
|
|
|
|
static int find_hole_search(knifetool_opdata *kcd, KnifeVert *kfvfirst, KnifeVert *kfv, ListBase *fedges,
|
|
|
|
|
SmallHash *visited, ListBase *hole)
|
|
|
|
|
{
|
|
|
|
|
Ref *r;
|
|
|
|
|
KnifeEdge *kfe, *kfelast;
|
|
|
|
|
KnifeVert *kfv_other;
|
|
|
|
@@ -2109,7 +2112,8 @@ static int find_hole_search(knifetool_opdata *kcd, KnifeVert *kfvfirst, KnifeVer
|
|
|
|
|
|
|
|
|
|
/* Find a hole (simple cycle with no instantiated vertices).
|
|
|
|
|
* Remove the edges in the cycle from fedges and return a separate list of the cycle */
|
|
|
|
|
static ListBase *find_hole(knifetool_opdata *kcd, ListBase *fedges) {
|
|
|
|
|
static ListBase *find_hole(knifetool_opdata *kcd, ListBase *fedges)
|
|
|
|
|
{
|
|
|
|
|
ListBase *ans;
|
|
|
|
|
Ref *r, *ref;
|
|
|
|
|
KnifeEdge *kfe;
|
|
|
|
@@ -2151,8 +2155,9 @@ static ListBase *find_hole(knifetool_opdata *kcd, ListBase *fedges) {
|
|
|
|
|
* If found, return TRUE and make a 'main chain' going across f which uses
|
|
|
|
|
* the two diagonals and one part of the hole, and a 'side chain' that
|
|
|
|
|
* completes the hole. */
|
|
|
|
|
static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
ListBase **mainchain, ListBase **sidechain) {
|
|
|
|
|
static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f, ListBase **mainchain,
|
|
|
|
|
ListBase **sidechain)
|
|
|
|
|
{
|
|
|
|
|
float **fco, **hco;
|
|
|
|
|
BMVert **fv;
|
|
|
|
|
KnifeVert **hv;
|
|
|
|
@@ -2189,11 +2194,12 @@ static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
he[i] = kfe;
|
|
|
|
|
if (kfvother == NULL) {
|
|
|
|
|
kfv = kfe->v1;
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
kfv = kfvother;
|
|
|
|
|
BLI_assert(kfv == kfe->v1 || kfv == kfe->v2);
|
|
|
|
|
}
|
|
|
|
|
hco[i] = BLI_memarena_alloc(kcd->arena, 2*sizeof(float));
|
|
|
|
|
hco[i] = BLI_memarena_alloc(kcd->arena, 2 * sizeof(float));
|
|
|
|
|
hco[i][0] = kfv->co[ax];
|
|
|
|
|
hco[i][1] = kfv->co[ay];
|
|
|
|
|
hv[i] = kfv;
|
|
|
|
@@ -2203,7 +2209,7 @@ static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
|
|
|
|
|
j = 0;
|
|
|
|
|
BM_ITER(v, &iter, kcd->em->bm, BM_VERTS_OF_FACE, f) {
|
|
|
|
|
fco[j] = BLI_memarena_alloc(kcd->arena, 2*sizeof(float));
|
|
|
|
|
fco[j] = BLI_memarena_alloc(kcd->arena, 2 * sizeof(float));
|
|
|
|
|
fco[j][0] = v->co[ax];
|
|
|
|
|
fco[j][1] = v->co[ay];
|
|
|
|
|
fv[j] = v;
|
|
|
|
@@ -2238,17 +2244,17 @@ static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
|
|
|
|
|
ok = TRUE;
|
|
|
|
|
for (k = 0; k < nh && ok; k++) {
|
|
|
|
|
if (k == i || (k+1) % nh == i)
|
|
|
|
|
if (k == i || (k + 1) % nh == i)
|
|
|
|
|
continue;
|
|
|
|
|
if (isect_line_line_v2(hco[i], fco[j], hco[k], hco[(k+1) % nh]))
|
|
|
|
|
if (isect_line_line_v2(hco[i], fco[j], hco[k], hco[(k + 1) % nh]))
|
|
|
|
|
ok = FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (!ok)
|
|
|
|
|
continue;
|
|
|
|
|
for (k = 0; k < nf && ok; k++) {
|
|
|
|
|
if (k == j || (k+1) % nf == j)
|
|
|
|
|
if (k == j || (k + 1) % nf == j)
|
|
|
|
|
continue;
|
|
|
|
|
if (isect_line_line_v2(hco[i], fco[j], fco[k], fco[(k+1) % nf]))
|
|
|
|
|
if (isect_line_line_v2(hco[i], fco[j], fco[k], fco[(k + 1) % nf]))
|
|
|
|
|
ok = FALSE;
|
|
|
|
|
}
|
|
|
|
|
if (ok) {
|
|
|
|
@@ -2269,7 +2275,7 @@ static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
kfe->v2 = hv[besti[0]];
|
|
|
|
|
chain = knife_empty_list(kcd);
|
|
|
|
|
knife_append_list(kcd, chain, kfe);
|
|
|
|
|
for (i = besti[0]; i != besti[1]; i = (i+1) % nh) {
|
|
|
|
|
for (i = besti[0]; i != besti[1]; i = (i + 1) % nh) {
|
|
|
|
|
knife_append_list(kcd, chain, he[i]);
|
|
|
|
|
}
|
|
|
|
|
kfe = new_knife_edge(kcd);
|
|
|
|
@@ -2279,7 +2285,7 @@ static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
*mainchain = chain;
|
|
|
|
|
|
|
|
|
|
chain = knife_empty_list(kcd);
|
|
|
|
|
for (i = besti[1]; i != besti[0]; i = (i+1) % nh) {
|
|
|
|
|
for (i = besti[1]; i != besti[0]; i = (i + 1) % nh) {
|
|
|
|
|
knife_append_list(kcd, chain, he[i]);
|
|
|
|
|
}
|
|
|
|
|
*sidechain = chain;
|
|
|
|
@@ -2291,7 +2297,8 @@ static int find_hole_chains(knifetool_opdata *kcd, ListBase *hole, BMFace *f,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int knife_edge_in_face(knifetool_opdata *kcd, KnifeEdge *kfe, BMFace *f) {
|
|
|
|
|
static int knife_edge_in_face(knifetool_opdata *kcd, KnifeEdge *kfe, BMFace *f)
|
|
|
|
|
{
|
|
|
|
|
BMesh *bm = kcd->em->bm;
|
|
|
|
|
BMVert *v1, *v2;
|
|
|
|
|
BMLoop *l1, *l2, *l;
|
|
|
|
@@ -2333,7 +2340,8 @@ static int knife_edge_in_face(knifetool_opdata *kcd, KnifeEdge *kfe, BMFace *f)
|
|
|
|
|
|
|
|
|
|
/* Split face f with KnifeEdges on chain. f remains as one side, the face formed is put in *newface.
|
|
|
|
|
* The new face will be on the left side of the chain as viewed from the normal-out side of f. */
|
|
|
|
|
static void knife_make_chain_cut(knifetool_opdata *kcd, BMFace *f, ListBase *chain, BMFace **newface) {
|
|
|
|
|
static void knife_make_chain_cut(knifetool_opdata *kcd, BMFace *f, ListBase *chain, BMFace **newface)
|
|
|
|
|
{
|
|
|
|
|
BMesh *bm = kcd->em->bm;
|
|
|
|
|
KnifeEdge *kfe, *kfelast;
|
|
|
|
|
BMVert *v1, *v2;
|
|
|
|
@@ -2354,10 +2362,10 @@ static void knife_make_chain_cut(knifetool_opdata *kcd, BMFace *f, ListBase *cha
|
|
|
|
|
v2 = kfelast->v2->v ? kfelast->v2->v : kfelast->v1->v;
|
|
|
|
|
BLI_assert(v1 != NULL && v2 != NULL);
|
|
|
|
|
kfvprev = kfe->v1->v == v1 ? kfe->v1 : kfe->v2;
|
|
|
|
|
for (ref = chain->first, i=0; i < nco && ref != chain->last; ref = ref->next, i++) {
|
|
|
|
|
for (ref = chain->first, i = 0; i < nco && ref != chain->last; ref = ref->next, i++) {
|
|
|
|
|
kfe = ref->ref;
|
|
|
|
|
BLI_assert(kfvprev == kfe->v1 || kfvprev == kfe->v2);
|
|
|
|
|
kfv = kfe->v1 == kfvprev? kfe->v2 : kfe->v1;
|
|
|
|
|
kfv = kfe->v1 == kfvprev ? kfe->v2 : kfe->v1;
|
|
|
|
|
copy_v3_v3(cos[i], kfv->co);
|
|
|
|
|
kverts[i] = kfv;
|
|
|
|
|
kfvprev = kfv;
|
|
|
|
@@ -2366,7 +2374,8 @@ static void knife_make_chain_cut(knifetool_opdata *kcd, BMFace *f, ListBase *cha
|
|
|
|
|
lnew = NULL;
|
|
|
|
|
if (nco == 0) {
|
|
|
|
|
*newface = BM_face_split(bm, f, v1, v2, &lnew, NULL, TRUE);
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fnew = BM_face_split_n(bm, f, v1, v2, cos, nco, &lnew, NULL);
|
|
|
|
|
*newface = fnew;
|
|
|
|
|
|
|
|
|
@@ -2383,7 +2392,8 @@ static void knife_make_chain_cut(knifetool_opdata *kcd, BMFace *f, ListBase *cha
|
|
|
|
|
BLI_array_fixedstack_free(kverts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void knife_make_face_cuts(knifetool_opdata *kcd, BMFace *f, ListBase *kfedges) {
|
|
|
|
|
static void knife_make_face_cuts(knifetool_opdata *kcd, BMFace *f, ListBase *kfedges)
|
|
|
|
|
{
|
|
|
|
|
BMesh *bm = kcd->em->bm;
|
|
|
|
|
KnifeEdge *kfe;
|
|
|
|
|
BMFace *fnew, *fnew2, *fhole;
|
|
|
|
@@ -2575,7 +2585,7 @@ static void knifetool_finish(bContext *C, wmOperator *op)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
DAG_id_tag_update(kcd->ob->data, OB_RECALC_DATA);
|
|
|
|
|
WM_event_add_notifier(C, NC_GEOM|ND_DATA, kcd->ob->data);
|
|
|
|
|
WM_event_add_notifier(C, NC_GEOM | ND_DATA, kcd->ob->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* copied from paint_image.c */
|
|
|
|
@@ -2608,7 +2618,7 @@ static void knife_recalc_projmat(knifetool_opdata *kcd)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* called when modal loop selection is done... */
|
|
|
|
|
static void knifetool_exit (bContext *UNUSED(C), wmOperator *op)
|
|
|
|
|
static void knifetool_exit(bContext *UNUSED(C), wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
knifetool_opdata *kcd = op->customdata;
|
|
|
|
|
|
|
|
|
@@ -2641,8 +2651,7 @@ static void knifetool_exit (bContext *UNUSED(C), wmOperator *op)
|
|
|
|
|
op->customdata = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void cage_mapped_verts_callback(void *userData, int index, float *co,
|
|
|
|
|
float *UNUSED(no_f), short *UNUSED(no_s))
|
|
|
|
|
static void cage_mapped_verts_callback(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
|
|
|
|
|
{
|
|
|
|
|
void **data = userData;
|
|
|
|
|
BMEditMesh *em = data[0];
|
|
|
|
@@ -2689,7 +2698,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, scene, obedit);
|
|
|
|
|
kcd->arena = BLI_memarena_new(1 << 15, "knife");
|
|
|
|
|
kcd->vthresh = KMAXDIST - 1;
|
|
|
|
|
kcd->ethresh = KMAXDIST;
|
|
|
|
@@ -2717,14 +2726,14 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int knifetool_cancel (bContext *C, wmOperator *op)
|
|
|
|
|
static int knifetool_cancel(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
/* this is just a wrapper around exit() */
|
|
|
|
|
knifetool_exit(C, op);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int knifetool_invoke (bContext *C, wmOperator *op, wmEvent *evt)
|
|
|
|
|
static int knifetool_invoke(bContext *C, wmOperator *op, wmEvent *evt)
|
|
|
|
|
{
|
|
|
|
|
knifetool_opdata *kcd;
|
|
|
|
|
|
|
|
|
@@ -2773,7 +2782,8 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
|
wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Knife Tool Modal Map");
|
|
|
|
|
|
|
|
|
|
/* this function is called for each spacetype, only needs to add map once */
|
|
|
|
|
if (keymap) return NULL;
|
|
|
|
|
if (keymap)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
keymap = WM_modalkeymap_add(keyconf, "Knife Tool Modal Map", modal_items);
|
|
|
|
|
|
|
|
|
@@ -2802,7 +2812,7 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
|
|
|
|
|
return keymap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int knifetool_modal (bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
Object *obedit;
|
|
|
|
|
knifetool_opdata *kcd = op->customdata;
|
|
|
|
@@ -2925,7 +2935,7 @@ static int knifetool_modal (bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MESH_OT_knifetool (wmOperatorType *ot)
|
|
|
|
|
void MESH_OT_knifetool(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* description */
|
|
|
|
|
ot->name = "Knife Topology Tool";
|
|
|
|
@@ -2939,5 +2949,5 @@ void MESH_OT_knifetool (wmOperatorType *ot)
|
|
|
|
|
ot->poll = ED_operator_editmesh_view3d;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
}
|
|
|
|
|