| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  |  * ***** 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, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2007 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Contributor(s): Joseph Eagar, Joshua Leung | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 00:20:36 +00:00
										 |  |  | /** \file blender/editors/mesh/editmesh_loopcut.c
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:29:51 +00:00
										 |  |  |  *  \ingroup edmesh | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | #include <float.h>
 | 
					
						
							|  |  |  | #define _USE_MATH_DEFINES
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_ID.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-21 15:10:09 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-19 22:17:30 +00:00
										 |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | #include "DNA_screen_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | #include "DNA_userdef_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "PIL_time.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-17 16:03:49 +00:00
										 |  |  | #include "BLI_array.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | #include "BLI_blenlib.h"
 | 
					
						
							| 
									
										
										
										
											2012-01-17 18:11:17 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | #include "BLI_dynstr.h" /*for WM_operator_pystring */
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_blender.h"
 | 
					
						
							|  |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | #include "BKE_depsgraph.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | #include "BKE_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2010-12-21 15:10:09 +00:00
										 |  |  | #include "BKE_modifier.h"
 | 
					
						
							|  |  |  | #include "BKE_report.h"
 | 
					
						
							|  |  |  | #include "BKE_scene.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | #include "BKE_tessmesh.h"
 | 
					
						
							|  |  |  | #include "BKE_depsgraph.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BIF_gl.h"
 | 
					
						
							|  |  |  | #include "BIF_glutil.h" /* for paint cursor */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "IMB_imbuf_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ED_screen.h"
 | 
					
						
							|  |  |  | #include "ED_space_api.h"
 | 
					
						
							|  |  |  | #include "ED_view3d.h"
 | 
					
						
							|  |  |  | #include "ED_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | #include "ED_numinput.h"
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | #include "RNA_define.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "UI_interface.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mesh_intern.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ringsel operator */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* struct for properties used while drawing */ | 
					
						
							|  |  |  | typedef struct tringselOpData { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	ARegion *ar;        /* region that ringsel was activated in */ | 
					
						
							|  |  |  | 	void *draw_handle;  /* for drawing preview loop */ | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	float (*edges)[2][3]; | 
					
						
							|  |  |  | 	int totedge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ViewContext vc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Object *ob; | 
					
						
							|  |  |  | 	BMEditMesh *em; | 
					
						
							|  |  |  | 	BMEdge *eed; | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 	NumInput num; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int extend; | 
					
						
							|  |  |  | 	int do_cut; | 
					
						
							|  |  |  | } tringselOpData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* modal loop selection drawing callback */ | 
					
						
							| 
									
										
										
										
											2010-11-10 15:10:54 +00:00
										 |  |  | static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-11-10 15:10:54 +00:00
										 |  |  | 	View3D *v3d = CTX_wm_view3d(C); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	tringselOpData *lcd = arg; | 
					
						
							| 
									
										
										
										
											2010-11-10 15:10:54 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 	if (lcd->totedge > 0) { | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 		if (v3d && v3d->zbuf) | 
					
						
							| 
									
										
										
										
											2010-11-10 15:10:54 +00:00
										 |  |  | 			glDisable(GL_DEPTH_TEST); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 		glPushMatrix(); | 
					
						
							|  |  |  | 		glMultMatrixf(lcd->ob->obmat); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 		glColor3ub(255, 0, 255); | 
					
						
							|  |  |  | 		glBegin(GL_LINES); | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 		for (i = 0; i < lcd->totedge; i++) { | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 			glVertex3fv(lcd->edges[i][0]); | 
					
						
							|  |  |  | 			glVertex3fv(lcd->edges[i][1]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		glEnd(); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 		glPopMatrix(); | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 		if (v3d && v3d->zbuf) | 
					
						
							| 
									
										
										
										
											2010-11-10 15:10:54 +00:00
										 |  |  | 			glEnable(GL_DEPTH_TEST); | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | /* given two opposite edges in a face, finds the ordering of their vertices so
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  |  * that cut preview lines won't cross each other */ | 
					
						
							| 
									
										
										
										
											2012-04-19 14:38:09 +00:00
										 |  |  | static void edgering_find_order(BMEdge *lasteed, BMEdge *eed, | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  |                                 BMVert *lastv1, BMVert *v[2][2]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 	BMIter liter; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 	BMLoop *l, *l2; | 
					
						
							|  |  |  | 	int rev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 22:06:10 +00:00
										 |  |  | 	l = eed->l; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	/* find correct order for v[1] */ | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 	if (!(BM_edge_in_face(l->f, eed) && BM_edge_in_face(l->f, lasteed))) { | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 		BM_ITER_ELEM (l, &liter, l, BM_LOOPS_OF_LOOP) { | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 			if (BM_edge_in_face(l->f, eed) && BM_edge_in_face(l->f, lasteed)) | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	/* this should never happen */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 	if (!l) { | 
					
						
							|  |  |  | 		v[0][0] = eed->v1; | 
					
						
							|  |  |  | 		v[0][1] = eed->v2; | 
					
						
							|  |  |  | 		v[1][0] = lasteed->v1; | 
					
						
							|  |  |  | 		v[1][1] = lasteed->v2; | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-04 16:36:31 +00:00
										 |  |  | 	l2 = BM_face_other_edge_loop(l->f, l->e, eed->v1); | 
					
						
							| 
									
										
										
										
											2011-09-12 15:10:59 +00:00
										 |  |  | 	rev = (l2 == l->prev); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 	while (l2->v != lasteed->v1 && l2->v != lasteed->v2) { | 
					
						
							| 
									
										
										
										
											2011-09-12 15:10:59 +00:00
										 |  |  | 		l2 = rev ? l2->prev : l2->next; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (l2->v == lastv1) { | 
					
						
							|  |  |  | 		v[0][0] = eed->v1; | 
					
						
							|  |  |  | 		v[0][1] = eed->v2; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 		v[0][0] = eed->v2; | 
					
						
							|  |  |  | 		v[0][1] = eed->v1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | static void edgering_sel(tringselOpData *lcd, int previewlines, int select) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BMEditMesh *em = lcd->em; | 
					
						
							|  |  |  | 	BMEdge *startedge = lcd->eed; | 
					
						
							|  |  |  | 	BMEdge *eed, *lasteed; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 	BMVert *v[2][2], *lastv1; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	BMWalker walker; | 
					
						
							|  |  |  | 	float (*edges)[2][3] = NULL; | 
					
						
							| 
									
										
										
										
											2009-09-17 23:05:33 +00:00
										 |  |  | 	BLI_array_declare(edges); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	float co[2][3]; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	int i, tot = 0; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-05-03 03:05:15 +00:00
										 |  |  | 	memset(v, 0, sizeof(v)); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	if (!startedge) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (lcd->edges) { | 
					
						
							|  |  |  | 		MEM_freeN(lcd->edges); | 
					
						
							|  |  |  | 		lcd->edges = NULL; | 
					
						
							|  |  |  | 		lcd->totedge = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!lcd->extend) { | 
					
						
							| 
									
										
										
										
											2012-02-12 18:43:59 +00:00
										 |  |  | 		EDBM_flag_disable_all(lcd->em, BM_ELEM_SELECT); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (select) { | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 		BMW_init(&walker, em->bm, BMW_EDGERING, | 
					
						
							| 
									
										
										
										
											2012-03-29 13:09:07 +00:00
										 |  |  | 		         BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP, | 
					
						
							| 
									
										
										
										
											2012-04-03 06:12:04 +00:00
										 |  |  | 		         BMW_FLAG_TEST_HIDDEN, | 
					
						
							| 
									
										
										
										
											2012-02-06 05:18:08 +00:00
										 |  |  | 		         BMW_NIL_LAY); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 		eed = BMW_begin(&walker, startedge); | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 		for ( ; eed; eed = BMW_step(&walker)) { | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 			BM_elem_select_set(em->bm, eed, TRUE); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 		BMW_end(&walker); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 	BMW_init(&walker, em->bm, BMW_EDGERING, | 
					
						
							| 
									
										
										
										
											2012-03-29 13:09:07 +00:00
										 |  |  | 	         BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP, | 
					
						
							| 
									
										
										
										
											2012-04-03 06:12:04 +00:00
										 |  |  | 	         BMW_FLAG_TEST_HIDDEN, | 
					
						
							| 
									
										
										
										
											2012-02-06 05:18:08 +00:00
										 |  |  | 	         BMW_NIL_LAY); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 	eed = startedge = BMW_begin(&walker, startedge); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 	lastv1 = NULL; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	for (lasteed = NULL; eed; eed = BMW_step(&walker)) { | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 		if (lasteed) { | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 			if (lastv1) { | 
					
						
							|  |  |  | 				v[1][0] = v[0][0]; | 
					
						
							|  |  |  | 				v[1][1] = v[0][1]; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 				v[1][0] = lasteed->v1; | 
					
						
							|  |  |  | 				v[1][1] = lasteed->v2; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 				lastv1 = lasteed->v1; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 14:38:09 +00:00
										 |  |  | 			edgering_find_order(lasteed, eed, lastv1, v); | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 			lastv1 = v[0][0]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 06:12:04 +00:00
										 |  |  | 			BLI_array_growitems(edges, previewlines); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			for (i = 1; i <= previewlines; i++) { | 
					
						
							|  |  |  | 				co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0]) * (i / ((float)previewlines + 1)) + v[0][0]->co[0]; | 
					
						
							|  |  |  | 				co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1]) * (i / ((float)previewlines + 1)) + v[0][0]->co[1]; | 
					
						
							|  |  |  | 				co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2]) * (i / ((float)previewlines + 1)) + v[0][0]->co[2]; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 				co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0]) * (i / ((float)previewlines + 1)) + v[1][0]->co[0]; | 
					
						
							|  |  |  | 				co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1]) * (i / ((float)previewlines + 1)) + v[1][0]->co[1]; | 
					
						
							|  |  |  | 				co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2]) * (i / ((float)previewlines + 1)) + v[1][0]->co[2]; | 
					
						
							| 
									
										
										
										
											2012-01-23 13:51:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				copy_v3_v3(edges[tot][0], co[0]); | 
					
						
							|  |  |  | 				copy_v3_v3(edges[tot][1], co[1]); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 				tot++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		lasteed = eed; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-02-26 19:46:12 +00:00
										 |  |  | 	if (lasteed != startedge && BM_edge_share_face_count(lasteed, startedge)) { | 
					
						
							| 
									
										
										
										
											2011-05-01 00:23:08 +00:00
										 |  |  | 		v[1][0] = v[0][0]; | 
					
						
							|  |  |  | 		v[1][1] = v[0][1]; | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 14:38:09 +00:00
										 |  |  | 		edgering_find_order(lasteed, startedge, lastv1, v); | 
					
						
							| 
									
										
										
										
											2011-05-01 00:23:08 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-04-03 06:12:04 +00:00
										 |  |  | 		BLI_array_growitems(edges, previewlines); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 		for (i = 1; i <= previewlines; i++) { | 
					
						
							| 
									
										
										
										
											2011-03-17 22:59:54 +00:00
										 |  |  | 			if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1]) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0]) * (i / ((float)previewlines + 1)) + v[0][0]->co[0]; | 
					
						
							|  |  |  | 			co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1]) * (i / ((float)previewlines + 1)) + v[0][0]->co[1]; | 
					
						
							|  |  |  | 			co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2]) * (i / ((float)previewlines + 1)) + v[0][0]->co[2]; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0]) * (i / ((float)previewlines + 1)) + v[1][0]->co[0]; | 
					
						
							|  |  |  | 			co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1]) * (i / ((float)previewlines + 1)) + v[1][0]->co[1]; | 
					
						
							|  |  |  | 			co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2]) * (i / ((float)previewlines + 1)) + v[1][0]->co[2]; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-01-17 17:08:32 +00:00
										 |  |  | 			copy_v3_v3(edges[tot][0], co[0]); | 
					
						
							|  |  |  | 			copy_v3_v3(edges[tot][1], co[1]); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 			tot++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 	BMW_end(&walker); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	lcd->edges = edges; | 
					
						
							|  |  |  | 	lcd->totedge = tot; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | static void ringsel_find_edge(tringselOpData *lcd, int cuts) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 	if (lcd->eed) { | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		edgering_sel(lcd, cuts, 0); | 
					
						
							| 
									
										
										
										
											2012-03-08 04:38:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else if (lcd->edges) { | 
					
						
							|  |  |  | 		MEM_freeN(lcd->edges); | 
					
						
							| 
									
										
										
										
											2010-01-10 19:56:22 +00:00
										 |  |  | 		lcd->edges = NULL; | 
					
						
							|  |  |  | 		lcd->totedge = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void ringsel_finish(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	tringselOpData *lcd = op->customdata; | 
					
						
							|  |  |  | 	int cuts = RNA_int_get(op->ptr, "number_cuts"); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (lcd->eed) { | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 		BMEditMesh *em = lcd->em; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		edgering_sel(lcd, cuts, 1); | 
					
						
							| 
									
										
										
										
											2011-01-15 14:07:11 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 		if (lcd->do_cut) { | 
					
						
							| 
									
										
										
										
											2012-02-27 14:07:19 +00:00
										 |  |  | 			BM_mesh_esubdivideflag(lcd->ob, em->bm, BM_ELEM_SELECT, 0.0f, | 
					
						
							|  |  |  | 			                       0.0f, 0, cuts, SUBDIV_SELECT_LOOPCUT, | 
					
						
							|  |  |  | 			                       SUBD_PATH, 0, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2011-04-13 22:30:25 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2010-04-16 08:14:20 +00:00
										 |  |  | 			/* force edge slide to edge select mode in in face select mode */ | 
					
						
							|  |  |  | 			if (em->selectmode & SCE_SELECT_FACE) { | 
					
						
							|  |  |  | 				if (em->selectmode == SCE_SELECT_FACE) | 
					
						
							|  |  |  | 					em->selectmode = SCE_SELECT_EDGE; | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					em->selectmode &= ~SCE_SELECT_FACE; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 				CTX_data_tool_settings(C)->selectmode = em->selectmode; | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 				EDBM_selectmode_set(em); | 
					
						
							| 
									
										
										
										
											2010-09-07 05:47:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 				WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, CTX_data_scene(C)); | 
					
						
							| 
									
										
										
										
											2010-04-16 08:14:20 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			WM_event_add_notifier(C, NC_GEOM | ND_SELECT | ND_DATA, lcd->ob->data); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 			DAG_id_tag_update(lcd->ob->data, 0); | 
					
						
							| 
									
										
										
										
											2010-02-07 01:01:32 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2011-01-15 14:07:11 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			/* sets as active, useful for other tools */ | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			if (em->selectmode & SCE_SELECT_VERTEX) | 
					
						
							| 
									
										
										
										
											2012-03-27 04:46:52 +00:00
										 |  |  | 				EDBM_editselection_store(em, &lcd->eed->v1->head);  /* low priority TODO, get vertrex close to mouse */ | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			if (em->selectmode & SCE_SELECT_EDGE) | 
					
						
							| 
									
										
										
										
											2012-03-27 04:46:52 +00:00
										 |  |  | 				EDBM_editselection_store(em, &lcd->eed->head); | 
					
						
							| 
									
										
										
										
											2011-01-15 14:07:11 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-02-10 06:16:21 +00:00
										 |  |  | 			EDBM_selectmode_flush(lcd->em); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			WM_event_add_notifier(C, NC_GEOM | ND_SELECT, lcd->ob->data); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* called when modal loop selection is done... */ | 
					
						
							| 
									
										
										
										
											2011-05-10 23:48:09 +00:00
										 |  |  | static void ringsel_exit(bContext *UNUSED(C), wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	tringselOpData *lcd = op->customdata; | 
					
						
							| 
									
										
										
										
											2009-09-13 16:15:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	/* deactivate the extra drawing stuff in 3D-View */ | 
					
						
							|  |  |  | 	ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (lcd->edges) | 
					
						
							|  |  |  | 		MEM_freeN(lcd->edges); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* free the custom data */ | 
					
						
							|  |  |  | 	MEM_freeN(lcd); | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	op->customdata = NULL; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* called when modal loop selection gets set up... */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | static int ringsel_init(bContext *C, wmOperator *op, int do_cut) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	tringselOpData *lcd; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* alloc new customdata */ | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	lcd = op->customdata = MEM_callocN(sizeof(tringselOpData), "ringsel Modal Op Data"); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* assign the drawing handle for drawing preview line... */ | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	lcd->ar = CTX_wm_region(C); | 
					
						
							|  |  |  | 	lcd->draw_handle = ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST_VIEW); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	lcd->ob = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2012-03-02 12:09:49 +00:00
										 |  |  | 	lcd->em = BMEdit_FromObject(lcd->ob); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	lcd->extend = do_cut ? 0 : RNA_boolean_get(op->ptr, "extend"); | 
					
						
							|  |  |  | 	lcd->do_cut = do_cut; | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	initNumInput(&lcd->num); | 
					
						
							|  |  |  | 	lcd->num.idx_max = 0; | 
					
						
							|  |  |  | 	lcd->num.flag |= NUM_NO_NEGATIVE | NUM_NO_FRACTION; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	em_setup_viewcontext(C, &lcd->vc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | static int ringcut_cancel(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* this is just a wrapper around exit() */ | 
					
						
							|  |  |  | 	ringsel_exit(C, op); | 
					
						
							|  |  |  | 	return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	tringselOpData *lcd; | 
					
						
							|  |  |  | 	BMEdge *edge; | 
					
						
							|  |  |  | 	int dist = 75; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	if (modifiers_isDeformedByLattice(obedit) || modifiers_isDeformedByArmature(obedit)) | 
					
						
							| 
									
										
										
										
											2010-12-22 18:46:54 +00:00
										 |  |  | 		BKE_report(op->reports, RPT_WARNING, "Loop cut doesn't work well on deformed edit mesh display"); | 
					
						
							| 
									
										
										
										
											2010-12-21 15:10:09 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	view3d_operator_needs_opengl(C); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!ringsel_init(C, op, 1)) | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* add a modal handler for this operator - handles loop selection */ | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 	WM_event_add_modal_handler(C, op); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	lcd = op->customdata; | 
					
						
							|  |  |  | 	lcd->vc.mval[0] = evt->mval[0]; | 
					
						
							|  |  |  | 	lcd->vc.mval[1] = evt->mval[1]; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-27 04:46:52 +00:00
										 |  |  | 	edge = EDBM_edge_find_nearest(&lcd->vc, &dist); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	if (edge != lcd->eed) { | 
					
						
							|  |  |  | 		lcd->eed = edge; | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | 		ringsel_find_edge(lcd, 1); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-01-01 17:52:06 +00:00
										 |  |  | 	ED_area_headerprint(CTX_wm_area(C), "Select a ring to be cut, use mouse-wheel or page-up/down for number of cuts"); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	return OPERATOR_RUNNING_MODAL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	int cuts = RNA_int_get(op->ptr, "number_cuts"); | 
					
						
							|  |  |  | 	tringselOpData *lcd = op->customdata; | 
					
						
							| 
									
										
										
										
											2012-03-08 13:20:06 +00:00
										 |  |  | 	int show_cuts = 0; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	view3d_operator_needs_opengl(C); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 09:37:08 +00:00
										 |  |  | 	switch (event->type) { | 
					
						
							| 
									
										
										
										
											2011-03-17 22:59:54 +00:00
										 |  |  | 		case RETKEY: | 
					
						
							| 
									
										
										
										
											2011-05-03 03:05:15 +00:00
										 |  |  | 		case LEFTMOUSE: /* confirm */ // XXX hardcoded
 | 
					
						
							| 
									
										
										
										
											2011-05-09 20:43:05 +00:00
										 |  |  | 			if (event->val == KM_PRESS) { | 
					
						
							| 
									
										
										
										
											2009-11-04 09:37:08 +00:00
										 |  |  | 				/* finish */ | 
					
						
							|  |  |  | 				ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				ringsel_finish(C, op); | 
					
						
							|  |  |  | 				ringsel_exit(C, op); | 
					
						
							|  |  |  | 				 | 
					
						
							| 
									
										
										
										
											2011-01-01 17:52:06 +00:00
										 |  |  | 				ED_area_headerprint(CTX_wm_area(C), NULL); | 
					
						
							| 
									
										
										
										
											2009-11-04 09:37:08 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2011-05-09 20:43:05 +00:00
										 |  |  | 				return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-11-04 09:37:08 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		case RIGHTMOUSE: /* abort */ // XXX hardcoded
 | 
					
						
							| 
									
										
										
										
											2009-11-04 09:37:08 +00:00
										 |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 			ringsel_exit(C, op); | 
					
						
							| 
									
										
										
										
											2011-05-03 03:05:15 +00:00
										 |  |  | 			ED_area_headerprint(CTX_wm_area(C), NULL); | 
					
						
							| 
									
										
										
										
											2009-11-04 09:37:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		case ESCKEY: | 
					
						
							|  |  |  | 			if (event->val == KM_RELEASE) { | 
					
						
							|  |  |  | 				/* cancel */ | 
					
						
							|  |  |  | 				ED_region_tag_redraw(lcd->ar); | 
					
						
							| 
									
										
										
										
											2011-05-03 03:05:15 +00:00
										 |  |  | 				ED_area_headerprint(CTX_wm_area(C), NULL); | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 				return ringcut_cancel(C, op); | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 		case PADPLUSKEY: | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 		case PAGEUPKEY: | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		case WHEELUPMOUSE:  /* change number of cuts */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 			if (event->val == KM_RELEASE) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 			cuts++; | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			RNA_int_set(op->ptr, "number_cuts", cuts); | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 			ringsel_find_edge(lcd, cuts); | 
					
						
							| 
									
										
										
										
											2012-03-08 13:20:06 +00:00
										 |  |  | 			show_cuts = TRUE; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 		case PADMINUS: | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 		case PAGEDOWNKEY: | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		case WHEELDOWNMOUSE:  /* change number of cuts */ | 
					
						
							| 
									
										
										
										
											2009-11-09 22:47:55 +00:00
										 |  |  | 			if (event->val == KM_RELEASE) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			cuts = MAX2(cuts - 1, 1); | 
					
						
							|  |  |  | 			RNA_int_set(op->ptr, "number_cuts", cuts); | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 			ringsel_find_edge(lcd, cuts); | 
					
						
							| 
									
										
										
										
											2012-03-08 13:20:06 +00:00
										 |  |  | 			show_cuts = TRUE; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ | 
					
						
							|  |  |  | 			int dist = 75; | 
					
						
							|  |  |  | 			BMEdge *edge; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			lcd->vc.mval[0] = event->mval[0]; | 
					
						
							|  |  |  | 			lcd->vc.mval[1] = event->mval[1]; | 
					
						
							| 
									
										
										
										
											2012-03-27 04:46:52 +00:00
										 |  |  | 			edge = EDBM_edge_find_nearest(&lcd->vc, &dist); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (edge != lcd->eed) { | 
					
						
							|  |  |  | 				lcd->eed = edge; | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | 				ringsel_find_edge(lcd, cuts); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		}			 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 	/* using the keyboard to input the number of cuts */ | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 	if (event->val == KM_PRESS) { | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 		float value; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-03-06 18:40:15 +00:00
										 |  |  | 		if (handleNumInput(&lcd->num, event)) { | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 			applyNumInput(&lcd->num, &value); | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			cuts = CLAMPIS(value, 1, 130); | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-03-24 02:51:46 +00:00
										 |  |  | 			RNA_int_set(op->ptr, "number_cuts", cuts); | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 			ringsel_find_edge(lcd, cuts); | 
					
						
							| 
									
										
										
										
											2012-03-08 13:20:06 +00:00
										 |  |  | 			show_cuts = TRUE; | 
					
						
							| 
									
										
										
										
											2011-11-21 17:14:44 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			ED_region_tag_redraw(lcd->ar); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-08 13:20:06 +00:00
										 |  |  | 	if (show_cuts) { | 
					
						
							|  |  |  | 		char buf[64]; | 
					
						
							|  |  |  | 		BLI_snprintf(buf, sizeof(buf), "Number of Cuts: %d", cuts); | 
					
						
							|  |  |  | 		ED_area_headerprint(CTX_wm_area(C), buf); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	/* keep going until the user confirms */ | 
					
						
							|  |  |  | 	return OPERATOR_RUNNING_MODAL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-08 05:45:16 +00:00
										 |  |  | /* for bmesh this tool is in bmesh_select.c */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | void MESH_OT_edgering_select(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-09-13 16:15:26 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* description */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Edge Ring Select"; | 
					
						
							|  |  |  | 	ot->idname = "MESH_OT_edgering_select"; | 
					
						
							|  |  |  | 	ot->description = "Select an edge ring"; | 
					
						
							| 
									
										
										
										
											2009-09-13 16:15:26 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->invoke = ringsel_invoke; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmesh_region_view3d;  | 
					
						
							| 
									
										
										
										
											2009-09-13 16:15:26 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-09-13 16:15:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-16 09:55:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-08 05:45:16 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | void MESH_OT_loopcut(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-20 22:27:08 +00:00
										 |  |  | 	PropertyRNA *prop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	/* description */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Loop Cut"; | 
					
						
							|  |  |  | 	ot->idname = "MESH_OT_loopcut"; | 
					
						
							|  |  |  | 	ot->description = "Add a new loop between existing loops"; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* callbacks */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->invoke = ringcut_invoke; | 
					
						
							|  |  |  | 	ot->modal = loopcut_modal; | 
					
						
							|  |  |  | 	ot->cancel = ringcut_cancel; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmesh_region_view3d; | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2012-03-20 22:27:08 +00:00
										 |  |  | 	prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10); | 
					
						
							|  |  |  | 	/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */ | 
					
						
							|  |  |  | 	RNA_def_property_flag(prop, PROP_SKIP_SAVE); | 
					
						
							| 
									
										
										
										
											2009-09-16 22:27:22 +00:00
										 |  |  | } |