| 
									
										
										
										
											2012-02-19 18:31:04 +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, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Joseph Eagar. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  | /** \file blender/bmesh/operators/bmo_connect.c
 | 
					
						
							|  |  |  |  *  \ingroup bmesh | 
					
						
							| 
									
										
										
										
											2013-03-30 08:54:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-06-22 17:25:02 +00:00
										 |  |  |  * Connect verts across faces (splits faces). | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 01:24:58 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2013-07-28 10:38:25 +00:00
										 |  |  | #include "BLI_alloca.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-17 05:33:55 +00:00
										 |  |  | #include "BLI_linklist_stack.h"
 | 
					
						
							| 
									
										
										
										
											2012-03-24 01:24:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "bmesh.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  | #include "intern/bmesh_operators_private.h" /* own include */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | #define VERT_INPUT	1
 | 
					
						
							|  |  |  | #define EDGE_OUT	1
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | #define FACE_TAG	2
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 12:52:34 +11:00
										 |  |  | static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenerate) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	BMLoop *(*loops_split)[2] = BLI_array_alloca(loops_split, f->len); | 
					
						
							|  |  |  | 	STACK_DECLARE(loops_split); | 
					
						
							|  |  |  | 	BMVert *(*verts_pair)[2] = BLI_array_alloca(verts_pair, f->len); | 
					
						
							|  |  |  | 	STACK_DECLARE(verts_pair); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	BMIter liter; | 
					
						
							|  |  |  | 	BMFace *f_new; | 
					
						
							| 
									
										
										
										
											2014-03-13 18:40:16 +11:00
										 |  |  | 	BMLoop *l; | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	BMLoop *l_last; | 
					
						
							|  |  |  | 	unsigned int i; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	STACK_INIT(loops_split); | 
					
						
							|  |  |  | 	STACK_INIT(verts_pair); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	l_last = NULL; | 
					
						
							|  |  |  | 	BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { | 
					
						
							|  |  |  | 		if (BMO_elem_flag_test(bm, l->v, VERT_INPUT)) { | 
					
						
							|  |  |  | 			if (!l_last) { | 
					
						
							| 
									
										
										
										
											2013-03-09 16:19:07 +00:00
										 |  |  | 				l_last = l; | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-24 11:04:03 +11:00
										 |  |  | 			if (!BM_loop_is_adjacent(l_last, l)) { | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 				BMLoop **l_pair = STACK_PUSH_RET(loops_split); | 
					
						
							|  |  |  | 				l_pair[0] = l_last; | 
					
						
							|  |  |  | 				l_pair[1] = l; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			l_last = l; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (STACK_SIZE(loops_split) == 0) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	if (STACK_SIZE(loops_split) > 1) { | 
					
						
							|  |  |  | 		BMLoop **l_pair = STACK_PUSH_RET(loops_split); | 
					
						
							|  |  |  | 		l_pair[0] = loops_split[STACK_SIZE(loops_split) - 2][1]; | 
					
						
							|  |  |  | 		l_pair[1] = loops_split[0][0]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 12:52:34 +11:00
										 |  |  | 	if (check_degenerate) { | 
					
						
							|  |  |  | 		BM_face_legal_splits(f, loops_split, STACK_SIZE(loops_split)); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < STACK_SIZE(loops_split); i++) { | 
					
						
							|  |  |  | 		BMVert **v_pair; | 
					
						
							|  |  |  | 		if (loops_split[i][0] == NULL) { | 
					
						
							| 
									
										
										
										
											2012-03-01 13:13:08 +00:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 		v_pair = STACK_PUSH_RET(verts_pair); | 
					
						
							|  |  |  | 		v_pair[0] = loops_split[i][0]->v; | 
					
						
							|  |  |  | 		v_pair[1] = loops_split[i][1]->v; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < STACK_SIZE(verts_pair); i++) { | 
					
						
							| 
									
										
										
										
											2014-03-13 18:40:16 +11:00
										 |  |  | 		BMLoop *l_new; | 
					
						
							| 
									
										
										
										
											2013-12-24 11:04:03 +11:00
										 |  |  | 		BMLoop *l_a, *l_b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ((l_a = BM_face_vert_share_loop(f, verts_pair[i][0])) && | 
					
						
							|  |  |  | 		    (l_b = BM_face_vert_share_loop(f, verts_pair[i][1]))) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			f_new = NULL; | 
					
						
							| 
									
										
										
										
											2014-03-19 07:07:59 +11:00
										 |  |  | 			l_new = NULL; | 
					
						
							| 
									
										
										
										
											2013-12-24 11:04:03 +11:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 		f = f_new; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 		if (!l_new || !f_new) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 		// BMO_elem_flag_enable(bm, f_new, FACE_NEW);
 | 
					
						
							|  |  |  | 		BMO_elem_flag_enable(bm, l_new->e, EDGE_OUT); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BMOIter siter; | 
					
						
							|  |  |  | 	BMIter iter; | 
					
						
							|  |  |  | 	BMVert *v; | 
					
						
							|  |  |  | 	BMFace *f; | 
					
						
							| 
									
										
										
										
											2014-03-27 12:52:34 +11:00
										 |  |  | 	const bool check_degenerate = BMO_slot_bool_get(op->slots_in,  "check_degenerate"); | 
					
						
							| 
									
										
										
										
											2013-08-17 05:33:55 +00:00
										 |  |  | 	BLI_LINKSTACK_DECLARE(faces, BMFace *); | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-17 05:33:55 +00:00
										 |  |  | 	BLI_LINKSTACK_INIT(faces); | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* add all faces connected to verts */ | 
					
						
							|  |  |  | 	BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) { | 
					
						
							|  |  |  | 		BMO_elem_flag_enable(bm, v, VERT_INPUT); | 
					
						
							|  |  |  | 		BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) { | 
					
						
							|  |  |  | 			if (!BMO_elem_flag_test(bm, f, FACE_TAG)) { | 
					
						
							|  |  |  | 				BMO_elem_flag_enable(bm, f, FACE_TAG); | 
					
						
							|  |  |  | 				if (f->len > 3) { | 
					
						
							| 
									
										
										
										
											2013-08-17 05:33:55 +00:00
										 |  |  | 					BLI_LINKSTACK_PUSH(faces, f); | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 	/* connect faces */ | 
					
						
							| 
									
										
										
										
											2013-08-17 05:33:55 +00:00
										 |  |  | 	while ((f = BLI_LINKSTACK_POP(faces))) { | 
					
						
							| 
									
										
										
										
											2014-03-27 12:52:34 +11:00
										 |  |  | 		if (bm_face_connect_verts(bm, f, check_degenerate) == -1) { | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 			BMO_error_raise(bm, op, BMERR_CONNECTVERT_FAILED, NULL); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-17 05:33:55 +00:00
										 |  |  | 	BLI_LINKSTACK_FREE(faces); | 
					
						
							| 
									
										
										
										
											2013-05-25 23:34:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, EDGE_OUT); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } |