}
}
- // Get # of selected verts
- for(ev=em->verts.first;ev;ev=ev->next) {
- if(ev->f & SELECT) vertsel++;
+ j = 0;
+ BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if (BM_TestHFlag(v, BM_SELECT)) {
+ BM_SetIndex(v, 1);
+ BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j));
+ j += 1;
+ } else BM_SetIndex(v, 0);
}
- // Test for multiple segments
- if(vertsel > numsel+1) {
- //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop");
- MEM_freeN(sld);
+ if (!j)
return 0;
- }
- // Get the edgeloop in order - mark f1 with SELECT once added
- for(eed=em->edges.first;eed;eed=eed->next) {
- if((eed->f & SELECT) && !(eed->f1 & SELECT)) {
- // If this is the first edge added, just put it in
- if(!edgelist) {
- BLI_linklist_prepend(&edgelist,eed);
- numadded++;
- first = eed;
- last = eed;
- eed->f1 = SELECT;
- } else {
- if(editedge_getSharedVert(eed, last)) {
- BLI_linklist_append(&edgelist,eed);
- eed->f1 = SELECT;
- numadded++;
- last = eed;
- } else if(editedge_getSharedVert(eed, first)) {
- BLI_linklist_prepend(&edgelist,eed);
- eed->f1 = SELECT;
- numadded++;
- first = eed;
- }
- }
- }
- if(eed->next == NULL && numadded != numsel) {
- eed=em->edges.first;
- timesthrough++;
- }
+ tempsv = MEM_callocN(sizeof(TransDataSlideVert)*j, "tempsv");
+
+ j = 0;
+ while (1) {
+ v = NULL;
+ BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ if (BM_GetIndex(v))
+ break;
- // It looks like there was an unexpected case - Hopefully should not happen
- if(timesthrough >= numsel*2) {
- BLI_linklist_free(edgelist,NULL);
- //BKE_report(op->reports, RPT_ERROR, "Could not order loop");
- MEM_freeN(sld);
- return 0;
}
- }
- // Put the verts in order in a linklist
- look = edgelist;
- while(look) {
- eed = look->link;
- if(!vertlist) {
- if(look->next) {
- temp = look->next->link;
+ if (!v)
+ break;
- //This is the first entry takes care of extra vert
- if(eed->v1 != temp->v1 && eed->v1 != temp->v2) {
- BLI_linklist_append(&vertlist,eed->v1);
- eed->v1->f1 = 1;
- } else {
- BLI_linklist_append(&vertlist,eed->v2);
- eed->v2->f1 = 1;
- }
- } else {
- //This is the case that we only have 1 edge
- BLI_linklist_append(&vertlist,eed->v1);
- eed->v1->f1 = 1;
- }
- }
- // for all the entries
- if(eed->v1->f1 != 1) {
- BLI_linklist_append(&vertlist,eed->v1);
- eed->v1->f1 = 1;
- } else if(eed->v2->f1 != 1) {
- BLI_linklist_append(&vertlist,eed->v2);
- eed->v2->f1 = 1;
- }
- look = look->next;
- }
-
- // populate the SlideVerts
-
- vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createSlideVerts gh");
- look = vertlist;
- while(look) {
- i=0;
- j=0;
- ev = look->link;
- tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert");
- tempsv->up = NULL;
- tempsv->down = NULL;
- tempsv->origvert.co[0] = ev->co[0];
- tempsv->origvert.co[1] = ev->co[1];
- tempsv->origvert.co[2] = ev->co[2];
- tempsv->origvert.no[0] = ev->no[0];
- tempsv->origvert.no[1] = ev->no[1];
- tempsv->origvert.no[2] = ev->no[2];
- // i is total edges that vert is on
- // j is total selected edges that vert is on
-
- for(eed=em->edges.first;eed;eed=eed->next) {
- if(eed->v1 == ev || eed->v2 == ev) {
- i++;
- if(eed->f & SELECT) {
- j++;
- }
- }
- }
- // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges
- if(i == 4 && j == 2) {
- for(eed=em->edges.first;eed;eed=eed->next) {
- if(editedge_containsVert(eed, ev)) {
- if(!(eed->f & SELECT)) {
- if(!tempsv->up) {
- tempsv->up = eed;
- } else if (!(tempsv->down)) {
- tempsv->down = eed;
- }
- }
- }
- }
- }
- // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected
- if(i >= 3 && j == 1) {
- for(eed=em->edges.first;eed;eed=eed->next) {
- if(editedge_containsVert(eed, ev) && eed->f & SELECT) {
- for(efa = em->faces.first;efa;efa=efa->next) {
- if(editface_containsEdge(efa, eed)) {
- if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) {
- if(!tempsv->up) {
- tempsv->up = efa->e1;
- } else if (!(tempsv->down)) {
- tempsv->down = efa->e1;
- }
- }
- if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) {
- if(!tempsv->up) {
- tempsv->up = efa->e2;
- } else if (!(tempsv->down)) {
- tempsv->down = efa->e2;
- }
- }
- if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) {
- if(!tempsv->up) {
- tempsv->up = efa->e3;
- } else if (!(tempsv->down)) {
- tempsv->down = efa->e3;
- }
- }
- if(efa->e4) {
- if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) {
- if(!tempsv->up) {
- tempsv->up = efa->e4;
- } else if (!(tempsv->down)) {
- tempsv->down = efa->e4;
- }
- }
- }
+ if (!v->e)
+ continue;
+
+ first = v;
- }
- }
- }
+ /*walk along the edge loop*/
+ e = v->e;
+
+ /*first, rewind*/
+ numsel = 0;
+ do {
+ e = get_other_edge(bm, v, e);
+ if (!e) {
+ e = v->e;
+ break;
}
- }
- if(i > 4 && j == 2) {
- BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
- BLI_linklist_free(vertlist,NULL);
- BLI_linklist_free(edgelist,NULL);
- return 0;
- }
- BLI_ghash_insert(vertgh,ev,tempsv);
- look = look->next;
- }
+ numsel += 1;
- // make sure the UPs and DOWNs are 'faceloops'
- // Also find the nearest slidevert to the cursor
+ if (!BM_GetIndex(BM_OtherEdgeVert(e, v)))
+ break;
- look = vertlist;
- nearest = NULL;
- vertdist = -1;
- while(look) {
- tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+ v = BM_OtherEdgeVert(e, v);
+ } while (e != first->e);
- if(!tempsv->up || !tempsv->down) {
- //BKE_report(op->reports, RPT_ERROR, "Missing rails");
- BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
- BLI_linklist_free(vertlist,NULL);
- BLI_linklist_free(edgelist,NULL);
- return 0;
- }
+ BM_SetIndex(v, 0);
- if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
- if(!(tempsv->up->f & SELECT)) {
- tempsv->up->f |= SELECT;
- tempsv->up->f2 |= 16;
- } else {
- tempsv->up->f2 |= ~16;
- }
- if(!(tempsv->down->f & SELECT)) {
- tempsv->down->f |= SELECT;
- tempsv->down->f2 |= 16;
- } else {
- tempsv->down->f2 |= ~16;
- }
- }
+ l1 = l2 = l = NULL;
+ l1 = e->l;
+ l2 = e->l->radial_next;
- if(look->next != NULL) {
- TransDataSlideVert *sv;
-
- ev = (EditVert*)look->next->link;
- sv = BLI_ghash_lookup(vertgh, ev);
+ l = BM_OtherFaceLoop(l1->e, l1->f, v);
+ sub_v3_v3v3(vec, BM_OtherEdgeVert(l->e, v)->co, v->co);
- if(sv) {
- float co[3], co2[3], tvec[3];
+ if (l2 != l1) {
+ l = BM_OtherFaceLoop(l2->e, l2->f, v);
+ sub_v3_v3v3(vec2, BM_OtherEdgeVert(l->e, v)->co, v->co);
+ } else {
+ l2 = NULL;
+ }
- ev = (EditVert*)look->link;
+ /*iterate over the loop*/
+ first = v;
+ j = 0;
+ do {
+ TransDataSlideVert *sv = tempsv + j;
- if(!sharesFace(em, tempsv->up,sv->up)) {
- EditEdge *swap;
- swap = sv->up;
- sv->up = sv->down;
- sv->down = swap;
- }
-
- if (v3d) {
- ED_view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat);
- ED_view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat);
- }
+ sv->v = v;
+ sv->origvert = *v;
+ VECCOPY(sv->upvec, vec);
+ if (l2)
+ VECCOPY(sv->downvec, vec2);
- if (ev == tempsv->up->v1) {
- sub_v3_v3v3(tvec, co, co2);
- } else {
- sub_v3_v3v3(tvec, co2, co);
- }
+ l = BM_OtherFaceLoop(l1->e, l1->f, v);
+ sv->up = BM_OtherEdgeVert(l->e, v);
- add_v3_v3(start, tvec);
+ if (l2) {
+ l = BM_OtherFaceLoop(l2->e, l2->f, v);
+ sv->down = BM_OtherEdgeVert(l->e, v);
+ }
- if (v3d) {
- ED_view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat);
- ED_view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat);
- }
+ v2=v, v = BM_OtherEdgeVert(e, v);
- if (ev == tempsv->down->v1) {
- sub_v3_v3v3(tvec, co2, co);
- } else {
- sub_v3_v3v3(tvec, co, co2);
- }
+ e1 = e;
+ e = get_other_edge(bm, v, e);
+ if (!e) {
+ //v2=v, v = BM_OtherEdgeVert(l1->e, v);
- add_v3_v3(end, tvec);
+ sv = tempsv + j + 1;
+ sv->v = v;
+ sv->origvert = *v;
+
+ l = BM_OtherFaceLoop(l1->e, l1->f, v);
+ sv->up = BM_OtherEdgeVert(l->e, v);
+ sub_v3_v3v3(sv->upvec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+
+ if (l2) {
+ l = BM_OtherFaceLoop(l2->e, l2->f, v);
+ sv->down = BM_OtherEdgeVert(l->e, v);
+ sub_v3_v3v3(sv->downvec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+ }
- totvec += 1.0f;
- nearest = (EditVert*)look->link;
+ BM_SetIndex(v, 0);
+ BM_SetIndex(v2, 0);
+
+ j += 2;
+ break;
}
- }
+ l1 = get_next_loop(bm, v, l1, e1, e, vec);
+ l2 = l2 ? get_next_loop(bm, v, l2, e1, e, vec2) : NULL;
+ j += 1;
- look = look->next;
+ BM_SetIndex(v, 0);
+ BM_SetIndex(v2, 0);
+ } while (e != first->e && l1);
}
- add_v3_v3(start, end);
- mul_v3_fl(start, 0.5f*(1.0f/totvec));
- VECCOPY(vec, start);
- start[0] = t->mval[0];
- start[1] = t->mval[1];
- add_v3_v3v3(end, start, vec);
+ //EDBM_clear_flag_all(em, BM_SELECT);
+ sld->sv = tempsv;
+ sld->totsv = j;
+
+ /*find mouse vector*/
+ dis = z = -1.0f;
+ size = 50.0;
+ zero_v3(lastvec); zero_v3(dir);
+ ee = le = NULL;
+ BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+ if (BM_TestHFlag(e, BM_SELECT)) {
+ BMIter iter2;
+ BMEdge *e2;
+ float vec1[3], dis2, mval[2] = {t->mval[0], t->mval[1]}, d;
+
+ /*search cross edges for visible edge to the mouse cursor,
+ then use the shared vertex to calculate screen vector*/
+ dis2 = -1.0f;
+ for (i=0; i<2; i++) {
+ v = i?e->v1:e->v2;
+ BM_ITER(e2, &iter2, em->bm, BM_EDGES_OF_VERT, v) {
+ if (BM_TestHFlag(e2, BM_SELECT))
+ continue;
+
+ if (!BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
+ continue;
+
+ j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
+
+ if (tempsv[j].down) {
+ ED_view3d_project_float_v3(ar, tempsv[j].down->co, vec1, projectMat);
+ } else {
+ add_v3_v3v3(vec1, v->co, tempsv[j].downvec);
+ ED_view3d_project_float_v3(ar, vec1, vec1, projectMat);
+ }
+
+ if (tempsv[j].up) {
+ ED_view3d_project_float_v3(ar, tempsv[j].up->co, vec2, projectMat);
+ } else {
+ add_v3_v3v3(vec1, v->co, tempsv[j].upvec);
+ ED_view3d_project_float_v3(ar, vec2, vec2, projectMat);
+ }
- /* Ensure minimum screen distance, when looking top down on edge loops */
-#define EDGE_SLIDE_MIN 30
- if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) {
- if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) {
- /* even more exceptional case, points are ontop of each other */
- end[0]= start[0];
- end[1]= start[1] + EDGE_SLIDE_MIN;
- }
- else {
- sub_v2_v2(end, start);
- normalize_v2(end);
- mul_v2_fl(end, EDGE_SLIDE_MIN);
- add_v2_v2(end, start);
+ d = dist_to_line_segment_v2(mval, vec1, vec2);
+ if (dis2 == -1.0f || d < dis2) {
+ dis2 = d;
+ ee = e2;
+ size = len_v3v3(vec1, vec2);
+ sub_v3_v3v3(dir, vec1, vec2);
+ }
+ }
+ }
}
}
-#undef EDGE_SLIDE_MIN
+
+ em->bm->ob = t->obedit;
+ bmesh_begin_edit(em->bm, BMOP_UNTAN_MULTIRES);
+ /*create copies of faces for customdata projection*/
+ tempsv = sld->sv;
+ for (i=0; i<sld->totsv; i++, tempsv++) {
+ BMIter fiter, liter;
+ BMFace *f;
+ BMLoop *l;
+
+ BM_ITER(f, &fiter, em->bm, BM_FACES_OF_VERT, tempsv->v) {
+
+ if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) {
+ BMFace *copyf = BM_Copy_Face(em->bm, f, 1, 1);
+
+ BM_Select(em->bm, copyf, 0);
+ BM_SetHFlag(copyf, BM_HIDDEN);
+ BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, copyf) {
+ BM_Select(em->bm, l->v, 0);
+ BM_SetHFlag(l->v, BM_HIDDEN);
+ BM_Select(em->bm, l->e, 0);
+ BM_SetHFlag(l->e, BM_HIDDEN);
+ }
- sld->start[0] = (int) start[0];
- sld->start[1] = (int) start[1];
- sld->end[0] = (int) end[0];
- sld->end[1] = (int) end[1];
+ BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf);
+ }
+ }
+
+ BLI_smallhash_insert(&sld->vhash, (uintptr_t)tempsv->v, tempsv);
+ }
+
+ sld->em = em;
+
+ /*zero out start*/
+ zero_v3(start);
- if (uvlay_tot) {
- int maxnum = 0;
+ /*dir holds a vector along edge loop*/
+ copy_v3_v3(end, dir);
+ mul_v3_fl(end, 0.5);
+
+ sld->start[0] = t->mval[0] + start[0];
+ sld->start[1] = t->mval[1] + start[1];
- uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
- sld->totuv = uvlay_tot;
- suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */
- suv = NULL;
+ sld->end[0] = t->mval[0] + end[0];
+ sld->end[1] = t->mval[1] + end[1];
+
+ sld->perc = 0.0f;
+
+ t->customData = sld;
+
+ BLI_smallhash_release(&table);
+ BMBVH_FreeBVH(btree);
+
+ return 1;
+}
- for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+void projectSVData(TransInfo *t, int final)
+{
+ SlideData *sld = t->customData;
+ TransDataSlideVert *tempsv;
+ BMEditMesh *em = sld->em;
+ SmallHash visit;
+ int i;
+
+ if (!em)
+ return;
+
++ /* BMESH_TODO, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)
++ * currently all vertex data is interpolated which is nice mostly
++ * except for shape keys where you dont want to modify UVs for eg.
++ * current BMesh code doesnt make it easy to pick which data we interpolate
++ * - campbell */
+
- uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createSlideVerts2 gh");
+ BLI_smallhash_init(&visit);
+
+ for (i=0, tempsv=sld->sv; i<sld->totsv; i++, tempsv++) {
+ BMIter fiter;
+ BMFace *f;
+
+ BM_ITER(f, &fiter, em->bm, BM_FACES_OF_VERT, tempsv->v) {
+ BMIter liter2;
+ BMFace *copyf, *copyf2;
+ BMLoop *l2;
+ int sel, do_vdata;
+
+ if (BLI_smallhash_haskey(&visit, (uintptr_t)f))
+ continue;
+
+ BLI_smallhash_insert(&visit, (uintptr_t)f, NULL);
+
+ /*the face attributes of the copied face will get
+ copied over, so its necessary to save the selection state*/
+ sel = BM_TestHFlag(f, BM_SELECT);
+
+ copyf2 = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)f);
+
+ /*project onto copied projection face*/
+ BM_ITER(l2, &liter2, em->bm, BM_LOOPS_OF_FACE, f) {
+ copyf = copyf2;
+ do_vdata = l2->v==tempsv->v;
+
+ if (BM_TestHFlag(l2->e, BM_SELECT) || BM_TestHFlag(l2->prev->e, BM_SELECT)) {
+ BMLoop *l3 = l2;
+
+ do_vdata = 1;
+
+ if (!BM_TestHFlag(l2->e, BM_SELECT))
+ l3 = l3->prev;
+
+ if (sld->perc < 0.0 && BM_Vert_In_Face(l3->radial_next->f, tempsv->down)) {
+ copyf = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l3->radial_next->f);
+ } else if (sld->perc > 0.0 && BM_Vert_In_Face(l3->radial_next->f, tempsv->up)) {
+ copyf = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l3->radial_next->f);
+ }
+ }
+
+ BM_loop_interp_from_face(em->bm, l2, copyf, do_vdata, 0);
- for(ev=em->verts.first;ev;ev=ev->next) {
- ev->tmp.l = 0;
- }
- look = vertlist;
- while(look) {
- float *uv_new;
- tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
-
- ev = look->link;
- suv = NULL;
- for(efa = em->faces.first;efa;efa=efa->next) {
- if (ev->tmp.l != -1) { /* test for self, in this case its invalid */
- int k=-1; /* face corner */
-
- /* Is this vert in the faces corner? */
- if (efa->v1==ev) k=0;
- else if (efa->v2==ev) k=1;
- else if (efa->v3==ev) k=2;
- else if (efa->v4 && efa->v4==ev) k=3;
-
- if (k != -1) {
- MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx);
- EditVert *ev_up, *ev_down;
-
- uv_new = tf->uv[k];
-
- if (ev->tmp.l) {
- if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001f || fabs(suv->origuv[1]-uv_new[1]) > 0.0001f) {
- ev->tmp.l = -1; /* Tag as invalid */
- BLI_linklist_free(suv->fuv_list,NULL);
- suv->fuv_list = NULL;
- BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
- suv = NULL;
- break;
- }
- } else {
- ev->tmp.l = 1;
- suv = suv_last;
-
- suv->fuv_list = NULL;
- suv->uv_up = suv->uv_down = NULL;
- suv->origuv[0] = uv_new[0];
- suv->origuv[1] = uv_new[1];
-
- BLI_linklist_prepend(&suv->fuv_list, uv_new);
- BLI_ghash_insert(uvarray[uvlay_idx],ev,suv);
-
- suv_last++; /* advance to next slide UV */
- maxnum++;
- }
-
- /* Now get the uvs along the up or down edge if we can */
- if (suv) {
- if (!suv->uv_up) {
- ev_up = editedge_getOtherVert(tempsv->up,ev);
- if (efa->v1==ev_up) suv->uv_up = tf->uv[0];
- else if (efa->v2==ev_up) suv->uv_up = tf->uv[1];
- else if (efa->v3==ev_up) suv->uv_up = tf->uv[2];
- else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3];
- }
- if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */
- ev_down = editedge_getOtherVert(tempsv->down,ev);
- if (efa->v1==ev_down) suv->uv_down = tf->uv[0];
- else if (efa->v2==ev_down) suv->uv_down = tf->uv[1];
- else if (efa->v3==ev_down) suv->uv_down = tf->uv[2];
- else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3];
- }
-
- /* Copy the pointers to the face UV's */
- BLI_linklist_prepend(&suv->fuv_list, uv_new);
- }
- }
+ if (final) {
+ BM_loop_interp_multires(em->bm, l2, copyf);
+ if (copyf2 != copyf) {
+ BM_loop_interp_multires(em->bm, l2, copyf2);
}
}
- look = look->next;
}
- } /* end uv layer loop */
- } /* end uvlay_tot */
-
- sld->uvhash = uvarray;
- sld->slideuv = slideuvs;
- sld->vhash = vertgh;
- sld->nearest = nearest;
- sld->vertlist = vertlist;
- sld->edgelist = edgelist;
- sld->suv_last = suv_last;
- sld->uvlay_tot = uvlay_tot;
-
- // we should have enough info now to slide
-
- t->customData = sld;
-
- return 1;
+
+ /*make sure face-attributes are correct (e.g. MTexPoly)*/
+ BM_Copy_Attributes(em->bm, em->bm, copyf2, f);
+
+ /*restore selection, and undo hidden flag*/
+ BM_ClearHFlag(f, BM_HIDDEN);
+ if (sel)
+ BM_Select(em->bm, f, sel);
+ }
+ }
+
+ BLI_smallhash_release(&visit);
}
void freeSlideVerts(TransInfo *t)