Page Menu
Home
Search
Configure Global Search
Log In
Files
F20722
bmop_vertex_slide.patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Francisco De La Cruz (xercesblue)
Nov 13 2013, 4:27 PM
Size
22 KB
Subscribers
None
bmop_vertex_slide.patch
View Options
# HG changeset patch
# User xerces
# Date 1333430066 14400
# Node ID 314b6b0235098609bfef26eb3ee374c402fbcd5d
# Parent bac7e2ddad62168f019c74e03d4d5fb8906854cd
[mq]: bmesh_vertex_slide
diff -r bac7e2ddad62 -r 314b6b023509 release/scripts/startup/bl_ui/space_view3d.py
--- a/release/scripts/startup/bl_ui/space_view3d.py Mon Apr 02 23:24:25 2012 -0400
+++ b/release/scripts/startup/bl_ui/space_view3d.py Tue Apr 03 01:14:26 2012 -0400
@@ -1684,6 +1684,7 @@
layout.operator("mesh.split")
layout.operator("mesh.separate")
layout.operator("mesh.vert_connect")
+ layout.operator("mesh.vert_slide")
layout.separator()
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/bmesh/CMakeLists.txt
--- a/source/blender/bmesh/CMakeLists.txt Mon Apr 02 23:24:25 2012 -0400
+++ b/source/blender/bmesh/CMakeLists.txt Tue Apr 03 01:14:26 2012 -0400
@@ -36,6 +36,7 @@
set(SRC
operators/bmo_bevel.c
operators/bmo_connect.c
+ operators/bmo_slide.c
operators/bmo_create.c
operators/bmo_dissolve.c
operators/bmo_dupe.c
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/bmesh/intern/bmesh_opdefines.c
--- a/source/blender/bmesh/intern/bmesh_opdefines.c Mon Apr 02 23:24:25 2012 -0400
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c Tue Apr 03 01:14:26 2012 -0400
@@ -1103,6 +1103,23 @@
0
};
+/*
+ * Vertex Slide
+ *
+ * Translates vertes along an edge
+ */
+static BMOpDefine bmo_vert_slide_def = {
+"vertslide",
+ {{BMO_OP_SLOT_ELEMENT_BUF, "vert"},
+ {BMO_OP_SLOT_ELEMENT_BUF, "edge"},
+ {BMO_OP_SLOT_ELEMENT_BUF, "vertout"},
+ {BMO_OP_SLOT_FLT, "distance_t"},
+ {0} /* null-terminating sentinel */},
+ bmo_vert_slide_exec,
+ BMO_OP_FLAG_UNTAN_MULTIRES
+};
+
+
BMOpDefine *opdefines[] = {
&bmo_split_def,
&bmo_spin_def,
@@ -1170,6 +1187,7 @@
&bmo_bridge_loops_def,
&bmo_solidify_def,
&bmo_inset_def,
+ &bmo_vert_slide_def,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/bmesh/intern/bmesh_operators_private.h
--- a/source/blender/bmesh/intern/bmesh_operators_private.h Mon Apr 02 23:24:25 2012 -0400
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h Tue Apr 03 01:14:26 2012 -0400
@@ -43,6 +43,7 @@
void bmo_dissolve_verts_exec(BMesh *bmesh, BMOperator *op);
void bmo_dissolve_limit_exec(BMesh *bmesh, BMOperator *op);
void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op);
+void bmo_vert_slide_exec(BMesh *bm, BMOperator *op);
void bmo_connectverts_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op);
void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op);
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/bmesh/operators/bmo_slide.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/blender/bmesh/operators/bmo_slide.c Tue Apr 03 01:14:26 2012 -0400
@@ -0,0 +1,112 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Francisco De La Cruz
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#include "MEM_guardedalloc.h"
+
+#include "BKE_global.h"
+
+#include "BLI_math.h"
+#include "BLI_array.h"
+#include "BLI_utildefines.h"
+
+#include "bmesh.h"
+
+#define EDGE_MARK 1
+#define VERT_MARK 2
+
+/*
+ * Slides a vertex along a connected edge
+ *
+ */
+void bmo_vert_slide_exec(BMesh *bm, BMOperator *op) {
+ BMOIter oiter;
+ BMIter iter;
+ BMHeader *h;
+ BMVert *vertex;
+ BMEdge *edge;
+ int is_start_v1 = 0;
+
+ /* Selection counts */
+ int selected_verts = 0;
+ int selected_edges = 0;
+
+ /* Get slide amount */
+ const float distance_t = BMO_slot_float_get(op, "distance_t");
+
+ /* Get start vertex */
+ vertex = BMO_iter_new(&oiter, bm, op, "vert", BM_VERT);
+
+
+ if (!vertex) {
+ if (G.debug & G_DEBUG)
+ fprintf(stderr, "vertslide: No vertex selected...");
+ return;
+ }
+
+ /* Count selected edges */
+ BMO_ITER(h, &oiter, bm, op, "edge", BM_VERT|BM_EDGE) {
+ switch (h->htype) {
+ case BM_VERT:
+ selected_verts++;
+ break;
+ case BM_EDGE:
+ selected_edges++;
+ /* Mark all selected edges (cast BMHeader->BMEdge) */
+ BMO_elem_flag_enable(bm, (BMElemF *) h, EDGE_MARK);
+ break;
+ }
+ }
+
+ /* Only allow sliding between two verts */
+
+ if (selected_verts != 2 || selected_edges == 0) {
+ if (G.debug & G_DEBUG)
+ fprintf(stderr, "vertslide: select a single edge\n");
+ return;
+ }
+
+ /* Make sure we get the correct edge. */
+ BM_ITER(edge, &iter, bm, BM_EDGES_OF_VERT, vertex) {
+ if (BMO_elem_flag_test(bm, edge, EDGE_MARK)) {
+ is_start_v1 = edge->v1 == vertex;
+ break;
+ }
+ }
+
+ /* Found edge */
+ if (edge) {
+
+ BMVert* other = BM_edge_other_vert(edge, vertex);
+
+ /* mark */
+ BMO_elem_flag_enable(bm, vertex, VERT_MARK);
+
+ /* Interpolate */
+ interp_v3_v3v3(vertex->co, vertex->co, other->co, distance_t);
+ }
+
+ /* Deselect the edges */
+ BMO_slot_buffer_hflag_disable(bm, op, "edge", BM_ALL, BM_ELEM_SELECT, TRUE);
+
+ /* Return the new edge. The same previously marked with VERT_MARK */
+ BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+ return;
+}
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/editors/mesh/CMakeLists.txt
--- a/source/blender/editors/mesh/CMakeLists.txt Mon Apr 02 23:24:25 2012 -0400
+++ b/source/blender/editors/mesh/CMakeLists.txt Tue Apr 03 01:14:26 2012 -0400
@@ -46,6 +46,7 @@
editmesh_select.c
editmesh_tools.c
editmesh_utils.c
+ editmesh_slide.c
mesh_data.c
mesh_ops.c
meshtools.c
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/editors/mesh/editmesh_slide.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/blender/editors/mesh/editmesh_slide.c Tue Apr 03 01:14:26 2012 -0400
@@ -0,0 +1,609 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Francisco De La Cruz
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/* Takes heavily from editmesh_loopcut.c */
+
+#include <float.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_space_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_array.h"
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_mesh.h"
+#include "BKE_report.h"
+#include "BKE_tessmesh.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_mesh.h"
+#include "ED_space_api.h"
+
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "mesh_intern.h"
+
+#define VTX_SLIDE_SLIDE_SENS_F 15.0
+#define VTX_SLIDE_SLOW_SENS_F 0.3
+#define VTX_SLIDE_SNAP_THRSH 0.3
+
+static void vtx_slide_draw(const bContext *C, ARegion *ar, void *arg);
+static int edbm_vert_slide_exec(bContext *C, wmOperator *op);
+static void vtx_slide_exit(const bContext *C, wmOperator *op);
+
+/* Cusom VertexSlide Operator data */
+typedef struct VertexSlideOp {
+ /* Starting Vertex */
+ BMVert *start_vtx;
+ BMEdge *sel_edge;
+
+ ViewContext *view_context;
+ ARegion *active_region;
+
+ /* Draw callback handle */
+ void *draw_handle;
+
+ /* Active Object */
+ Object *obj;
+
+ /* Are we in slide mode */
+ int slide_mode;
+ int slow_mode;
+ int snap_to_end_vtx;
+ int snap_to_mid;
+
+ float distance;
+ float interp[3];
+
+ /* Edge Frame
+ Count */
+ int disk_edges;
+
+ /* Edges */
+ float (*edge_frame)[3];
+
+ /* Mouse Click 2d pos */
+ int m_co[2];
+
+} VertexSlideOp;
+
+
+static int vtx_slide_init(bContext *C, wmOperator *op) {
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMEditSelection *ese = em->bm->selected.first;
+
+ const char* header_str = "Vertex Slide: Hover over an edge and left-click to select slide edge. "
+ "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Slow Move";
+
+ /* Allocate custom data */
+ VertexSlideOp *vso;
+ EDBM_selectmode_flush(em);
+ ese = em->bm->selected.first;
+
+ /* Is there a starting vertex ? */
+ if (ese == NULL || ese->htype != BM_VERT) {
+ BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex");
+ return FALSE;
+ }
+
+ vso = MEM_callocN(sizeof(VertexSlideOp), "Vertex Slide Operator");
+ vso->view_context = MEM_callocN(sizeof(ViewContext), "Vertex Slide View Context");
+
+ op->customdata = vso;
+
+ /* Set the start vertex */
+ vso->start_vtx = (BMVert *)ese->ele;
+ vso->sel_edge = NULL;
+
+ /* Edges */
+ vso->edge_frame = NULL;
+
+ vso->disk_edges = 0;
+
+ vso->slide_mode = FALSE;
+
+ vso->slow_mode = FALSE;
+
+ vso->snap_to_end_vtx = FALSE;
+
+ vso->snap_to_mid = FALSE;
+
+ vso->distance = 0.0f;
+
+ /* Add handler for the vertex sliding */
+ WM_event_add_modal_handler(C, op);
+
+ /* Notify the viewport */
+ view3d_operator_needs_opengl(C);
+
+ /* Set the drawing region */
+ vso->active_region = CTX_wm_region(C);
+
+ /* Set the draw callback */
+ vso->draw_handle = ED_region_draw_cb_activate(vso->active_region->type, vtx_slide_draw, vso, REGION_DRAW_POST_VIEW);
+
+ ED_area_headerprint(CTX_wm_area(C), header_str);
+
+ em_setup_viewcontext(C, vso->view_context);
+
+ /* Tag for redraw */
+ ED_region_tag_redraw(vso->active_region);
+
+ /* Set the object */
+ vso->obj = obedit;
+
+ return TRUE;
+}
+
+static void vtx_slide_confirm(bContext *C, wmOperator *op) {
+ /* Invoke operator */
+ edbm_vert_slide_exec(C, op);
+}
+
+static void vtx_slide_exit(const bContext *C, wmOperator *op) {
+ /* Fetch custom data */
+ VertexSlideOp *vso = op->customdata;
+ BMEditMesh *em = BMEdit_FromObject(vso->obj);
+
+ /* Clean-up the custom data */
+ ED_region_draw_cb_exit(vso->active_region->type, vso->draw_handle);
+ ED_region_tag_redraw(vso->active_region);
+
+ /* Store edit selection of the active vertex, allows other
+ * ops to run without reselecting */
+ if (vso->start_vtx)
+ EDBM_editselection_store(em, &vso->start_vtx->head);
+
+ /* Free Custom Data
+ *
+ */
+ MEM_freeN(vso->view_context);
+
+ vso->view_context = NULL;
+
+ if (vso->edge_frame) {
+ MEM_freeN(vso->edge_frame);
+ }
+
+ vso->edge_frame = NULL;
+
+ vso->slide_mode = FALSE;
+
+
+ MEM_freeN(vso);
+ vso = NULL;
+
+ /* Clear the header */
+ ED_area_headerprint(CTX_wm_area(C), NULL);
+
+}
+
+static void vtx_slide_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) {
+ VertexSlideOp *vso = arg;
+
+ /* Have an edge to draw */
+ if (vso && vso->sel_edge) {
+ /* Get 3d view */
+ View3D *view3d = CTX_wm_view3d(C);
+ int outline_w = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 1;
+ int i = 0;
+ if (view3d && view3d->zbuf)
+ glDisable(GL_DEPTH_TEST);
+
+ glPushAttrib(GL_CURRENT_BIT|GL_LINE_BIT|GL_POINT_BIT);
+
+ glPushMatrix();
+ glMultMatrixf(vso->obj->obmat);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* Draw selected edge
+ * Add color offset and reduce alpha */
+ UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 50, -50);
+
+ glLineWidth(outline_w);
+
+ glBegin(GL_LINES);
+ bglVertex3fv(vso->sel_edge->v1->co);
+ bglVertex3fv(vso->sel_edge->v2->co);
+ glEnd();
+
+
+ if (vso->disk_edges > 0) {
+ /* Draw intermediate edge frame */
+ UI_ThemeColorShadeAlpha(TH_EDGE_SELECT, 50, -50);
+
+ for (i = 0; i < vso->disk_edges; i++) {
+ glBegin(GL_LINES);
+ glVertex3fv(vso->edge_frame[i]);
+ glVertex3fv(vso->interp);
+ glEnd();
+ }
+ }
+
+
+ if (vso->slide_mode) {
+ /* Draw interpolated vertex */
+ int pt_size = UI_GetThemeValuef(TH_FACEDOT_SIZE) + 2;
+ UI_ThemeColorShadeAlpha(TH_FACE_DOT, -90, -50);
+
+ glPointSize(pt_size);
+
+ bglBegin(GL_POINTS);
+ bglVertex3fv(vso->interp);
+ bglEnd();
+ }
+
+ glDisable(GL_BLEND);
+ glPopMatrix();
+ glPopAttrib();
+
+ if (view3d && view3d->zbuf)
+ glEnable(GL_DEPTH_TEST);
+ }
+}
+
+static void vtx_slide_find_edge(VertexSlideOp *vso, wmEvent *event) {
+ /* Nearest edge */
+ BMEdge *nst_edge = NULL;
+
+ /* Temp Vtx */
+ BMVert *start_vtx = vso->start_vtx;
+
+ /* dist {input = max dist to search }
+ * { output = dist found } */
+ int dist = 50;
+
+ /* Set mouse coords */
+ vso->view_context->mval[0] = event->mval[0];
+ vso->view_context->mval[1] = event->mval[1];
+
+ /* Find nearest edge */
+ nst_edge = EDBM_edge_find_nearest(vso->view_context, &dist);
+
+ if (nst_edge) {
+ /* Find a connected edge */
+ if (nst_edge->v1 == start_vtx || nst_edge->v2 == start_vtx) {
+ /* Save mouse coords */
+ vso->m_co[0] = event->mval[0];
+ vso->m_co[1] = event->mval[1];
+
+ /* Set edge */
+ vso->sel_edge = nst_edge;
+ }
+ }
+}
+
+/* Updates the status of the operator - Invoked on mouse movement */
+static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) {
+ BMEdge* edge;
+ float edge_other_proj[3];
+ float start_vtx_proj[3];
+ BMVert* other;
+ /* Find nearest edge */
+ edge = vso->sel_edge;
+
+ if (edge) {
+ float interp[3];
+
+ /* Calculate interpolation value for preview */
+ float t_val;
+
+ float mval_float[] = { (float)event->mval[0], (float)event->mval[1]};
+ float closest_2d[2];
+
+ other = BM_edge_other_vert(edge, vso->start_vtx);
+
+ /* Project points onto screen and do interpolation in 2D */
+ project_float_noclip(vso->active_region, vso->start_vtx->co, start_vtx_proj);
+
+ project_float_noclip(vso->active_region, other->co, edge_other_proj);
+
+ closest_to_line_v2(closest_2d, mval_float, start_vtx_proj, edge_other_proj);
+
+ t_val = line_point_factor_v2(closest_2d, start_vtx_proj, edge_other_proj);
+
+ if (vso->slow_mode)
+ t_val = t_val * VTX_SLIDE_SLOW_SENS_F;
+
+ /* Snap to mid */
+ if (vso->snap_to_mid) {
+ t_val = 0.5f;
+ }
+
+ /* Interpolate preview vertex 3D */
+ interp_v3_v3v3(interp, vso->start_vtx->co, other->co, t_val);
+ copy_v3_v3(vso->interp, interp);
+
+ vso->distance = t_val;
+
+ /* If snapping */
+ if (vso->snap_to_end_vtx) {
+ int start_at_v1 = edge->v1 == vso->start_vtx;
+ float v1_d = len_v3v3(vso->interp, edge->v1->co);
+ float v2_d = len_v3v3(vso->interp, edge->v2->co);
+
+ if (v1_d > v2_d && v2_d < VTX_SLIDE_SNAP_THRSH) {
+ copy_v3_v3(vso->interp, edge->v2->co);
+
+ if (start_at_v1)
+ vso->distance = 1.0f;
+ else
+ vso->distance = 0.0f;
+ }
+ if (v2_d > v1_d && v1_d < VTX_SLIDE_SNAP_THRSH) {
+ copy_v3_v3(vso->interp, edge->v1->co);
+ if (start_at_v1)
+ vso->distance = 0.0f;
+ else
+ vso->distance = 1.0f;
+ }
+ }
+ }
+}
+
+/* Sets the outline frame */
+static void vtx_slide_set_frame(VertexSlideOp *vso) {
+ BMEdge* edge;
+ float (*edge_frame)[3] = NULL;
+ BLI_array_declare(edge_frame);
+ BMIter iter;
+ BMEditMesh *em = BMEdit_FromObject(vso->obj);
+ BMesh* bm = em->bm;
+ BMVert* sel_vtx = vso->start_vtx;
+ int idx = 0;
+
+ vso->disk_edges = 0;
+
+ if (vso->edge_frame) {
+ MEM_freeN(vso->edge_frame);
+ vso->edge_frame = NULL;
+ }
+
+ /* Iterate over edges of vertex and copy them */
+ BM_ITER_INDEX(edge, &iter, bm, BM_EDGES_OF_VERT, sel_vtx, idx) {
+ /* TODO: Deallocate this array */
+ BLI_array_growone(edge_frame);
+
+ if (sel_vtx == edge->v1)
+ copy_v3_v3(edge_frame[idx], edge->v2->co);
+ else
+ copy_v3_v3(edge_frame[idx], edge->v1->co);
+
+ vso->disk_edges++;
+ }
+
+ vso->edge_frame = edge_frame;
+
+ /* Select new edge */
+ BM_edge_select_set(bm, vso->sel_edge, TRUE);
+
+ /* Set the interp at starting vtx */
+ copy_v3_v3(vso->interp, sel_vtx->co);
+
+}
+
+static int edbm_vert_slide_modal(bContext *C, wmOperator *op, wmEvent *event) {
+ VertexSlideOp *vso = op->customdata;
+
+ /* Notify the viewport */
+ view3d_operator_needs_opengl(C);
+
+ switch (event->type) {
+ case LEFTSHIFTKEY: {
+ switch (event->val) {
+ case KM_PRESS:
+ vso->snap_to_mid = TRUE;
+ break;
+ case KM_RELEASE:
+ vso->snap_to_mid = FALSE;
+ break;
+ }
+
+ break;
+ }
+ case LEFTCTRLKEY: {
+ switch (event->val) {
+ case KM_PRESS:
+ vso->slow_mode = TRUE;
+ break;
+ case KM_RELEASE:
+ vso->slow_mode = FALSE;
+ break;
+ }
+
+ break;
+ }
+ case LEFTALTKEY: {
+ switch (event->val) {
+ case KM_PRESS:
+ vso->snap_to_end_vtx = TRUE;
+ break;
+ case KM_RELEASE:
+ vso->snap_to_end_vtx = FALSE;
+ break;
+ }
+
+ break;
+ }
+ case RIGHTMOUSE: {
+ /* Enforce redraw */
+ ED_region_tag_redraw(vso->active_region);
+
+ /* Clean-up */
+ vtx_slide_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+ }
+ case LEFTMOUSE: {
+ if (event->val == KM_PRESS) {
+ /* Update mouse coords */
+ copy_v2_v2_int(vso->m_co, event->mval);
+
+ if (vso->slide_mode) {
+ vtx_slide_confirm(C, op);
+ /* Clean-up */
+ vtx_slide_exit(C, op);
+ return OPERATOR_FINISHED;
+ } else if (vso->sel_edge) {
+ vso->slide_mode = TRUE;
+
+ /* Sets the frame */
+ vtx_slide_set_frame(vso);
+ }
+ }
+
+ ED_region_tag_redraw(vso->active_region);
+ break;
+
+ }
+ case MOUSEMOVE: {
+ if (!vso->slide_mode) {
+ vtx_slide_find_edge(vso, event);
+ } else {
+ vtx_slide_update(vso, event);
+ }
+
+ ED_region_tag_redraw(vso->active_region);
+ break;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int edbm_vert_slide_cancel(bContext *C, wmOperator *op) {
+ /* Exit the modal */
+ vtx_slide_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
+static int edbm_vert_slide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) {
+
+ /* Initialize the operator */
+ if (vtx_slide_init(C, op))
+ return OPERATOR_RUNNING_MODAL;
+ else
+ return OPERATOR_CANCELLED;
+}
+
+/* Vertex Slide */
+static int edbm_vert_slide_exec(bContext *C, wmOperator *op) {
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMesh *bm = em->bm;
+ BMVert *start_vert;
+ BMOperator bmop;
+ BMEditSelection *ese = em->bm->selected.first;
+
+ float distance_t = 0.0f;
+
+ /* Invoked modally? */
+ if (op->type->modal == edbm_vert_slide_modal && op->customdata) {
+ VertexSlideOp *vso = op->customdata;
+ distance_t = vso->distance;
+ } else {
+ /* Get Properties */
+ distance_t = RNA_float_get(op->ptr, "distance_t");
+ }
+
+ /* Is there a starting vertex ? */
+ if (ese == NULL || ese->htype != BM_VERT) {
+ BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex");
+ return OPERATOR_CANCELLED;
+ }
+
+ start_vert = (BMVert *)ese->ele;
+
+ /* Prepare operator */
+ if (!EDBM_op_init(em, &bmop, op, "vertslide vert=%e edge=%hfev distance_t=%f", start_vert, BM_ELEM_SELECT, distance_t)) {
+ return OPERATOR_CANCELLED;
+ }
+ /* Execute operator */
+ BMO_op_exec(bm, &bmop);
+
+ /* Select the edge */
+ BMO_slot_buffer_hflag_enable(bm, &bmop, "vertout", BM_ALL, BM_ELEM_SELECT, TRUE);
+
+ /* Flush the select buffers */
+ EDBM_selectmode_flush(em);
+
+ if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Update Geometry */
+ EDBM_update_generic(C, em, TRUE);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vert_slide(wmOperatorType *ot) {
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Vertex Slide";
+ ot->idname = "MESH_OT_vert_slide";
+ ot->description = "Vertex slide";
+
+ /* api callback */
+ ot->invoke = edbm_vert_slide_invoke;
+ ot->modal = edbm_vert_slide_modal;
+ ot->cancel = edbm_vert_slide_cancel;
+ ot->poll = ED_operator_editmesh_region_view3d;
+
+ /* ot->exec = edbm_vert_slide_exec;
+ * ot->poll = ED_operator_editmesh; */
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* Properties for vertex slide */
+ prop = RNA_def_float(ot->srna, "distance_t", 0.0f, -FLT_MAX, FLT_MAX , "Distance", "Distance", -5.0f, 5.0f);
+ RNA_def_property_ui_range(prop, -5.0f, 5.0f, 0.1, 4);
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+}
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/editors/mesh/mesh_intern.h
--- a/source/blender/editors/mesh/mesh_intern.h Mon Apr 02 23:24:25 2012 -0400
+++ b/source/blender/editors/mesh/mesh_intern.h Tue Apr 03 01:14:26 2012 -0400
@@ -214,6 +214,7 @@
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
void MESH_OT_inset(struct wmOperatorType *ot);
+void MESH_OT_vert_slide(struct wmOperatorType *ot);
/* ******************* mesh_navmesh.c */
void MESH_OT_navmesh_make(struct wmOperatorType *ot);
diff -r bac7e2ddad62 -r 314b6b023509 source/blender/editors/mesh/mesh_ops.c
--- a/source/blender/editors/mesh/mesh_ops.c Mon Apr 02 23:24:25 2012 -0400
+++ b/source/blender/editors/mesh/mesh_ops.c Tue Apr 03 01:14:26 2012 -0400
@@ -155,6 +155,7 @@
WM_operatortype_append(MESH_OT_solidify);
WM_operatortype_append(MESH_OT_select_nth);
WM_operatortype_append(MESH_OT_vert_connect);
+ WM_operatortype_append(MESH_OT_vert_slide);
WM_operatortype_append(MESH_OT_knifetool);
WM_operatortype_append(MESH_OT_bevel);
@@ -335,6 +336,8 @@
WM_keymap_add_item(keymap, "MESH_OT_split", YKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_vert_connect", JKEY, KM_PRESS, 0, 0);
+ /* Vertex Slide */
+ WM_keymap_add_item(keymap, "MESH_OT_vert_slide", VKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
/* use KM_CLICK because same key is used for tweaks */
kmi = WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", ACTIONMOUSE, KM_CLICK, KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "rotate_source", TRUE);
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
14/90/bab9723bf7664cabad52e82c37af
Event Timeline
Log In to Comment