| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bmesh | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Edge-Split. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bmesh.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bmesh_edgesplit.h"  /* own include */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-30 07:22:18 +10:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param use_verts: Use flagged verts instead of edges. | 
					
						
							|  |  |  |  * \param tag_only: Only split tagged edges. | 
					
						
							|  |  |  |  * \param copy_select: Copy selection history. | 
					
						
							| 
									
										
										
										
											2015-04-30 07:22:18 +10:00
										 |  |  |  */ | 
					
						
							|  |  |  | void BM_mesh_edgesplit( | 
					
						
							|  |  |  |         BMesh *bm, | 
					
						
							| 
									
										
										
										
											2015-05-02 16:05:32 +10:00
										 |  |  |         const bool use_verts, | 
					
						
							| 
									
										
										
										
											2015-04-30 07:22:18 +10:00
										 |  |  |         const bool tag_only, const bool copy_select) | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BMIter iter; | 
					
						
							|  |  |  | 	BMEdge *e; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 	bool use_ese = false; | 
					
						
							|  |  |  | 	GHash *ese_gh = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (copy_select && bm->selected.first) { | 
					
						
							|  |  |  | 		BMEditSelection *ese; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ese_gh = BLI_ghash_ptr_new(__func__); | 
					
						
							|  |  |  | 		for (ese = bm->selected.first; ese; ese = ese->next) { | 
					
						
							|  |  |  | 			if (ese->htype != BM_FACE) { | 
					
						
							|  |  |  | 				BLI_ghash_insert(ese_gh, ese->ele, ese); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		use_ese = true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-14 16:42:43 +00:00
										 |  |  | 	if (tag_only == false) { | 
					
						
							|  |  |  | 		BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, false); | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (use_verts) { | 
					
						
							|  |  |  | 		/* prevent one edge having both verts unflagged
 | 
					
						
							|  |  |  | 		 * we could alternately disable these edges, either way its a corner case. | 
					
						
							|  |  |  | 		 * | 
					
						
							|  |  |  | 		 * This is needed so we don't split off the edge but then none of its verts which | 
					
						
							|  |  |  | 		 * would leave a duplicate edge. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							|  |  |  | 			if (BM_elem_flag_test(e, BM_ELEM_TAG)) { | 
					
						
							| 
									
										
										
										
											2013-01-14 16:42:43 +00:00
										 |  |  | 				if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) && | 
					
						
							|  |  |  | 				              (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false)))) | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					BM_elem_flag_enable(e->v1, BM_ELEM_TAG); | 
					
						
							|  |  |  | 					BM_elem_flag_enable(e->v2, BM_ELEM_TAG); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							|  |  |  | 		if (BM_elem_flag_test(e, BM_ELEM_TAG)) { | 
					
						
							|  |  |  | 			BM_elem_flag_enable(e->v1, BM_ELEM_TAG); | 
					
						
							|  |  |  | 			BM_elem_flag_enable(e->v2, BM_ELEM_TAG); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							|  |  |  | 		if (BM_elem_flag_test(e, BM_ELEM_TAG)) { | 
					
						
							| 
									
										
										
										
											2017-05-06 14:18:31 +10:00
										 |  |  | 			uint i; | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 			for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  | 				BMVert *v = ((&e->v1)[i]); | 
					
						
							|  |  |  | 				if (BM_elem_flag_test(v, BM_ELEM_TAG)) { | 
					
						
							|  |  |  | 					BM_elem_flag_disable(v, BM_ELEM_TAG); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (use_ese) { | 
					
						
							|  |  |  | 						BMVert **vtar; | 
					
						
							|  |  |  | 						int vtar_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-02 16:05:32 +10:00
										 |  |  | 						BM_vert_separate_hflag(bm, v, BM_ELEM_TAG, copy_select, &vtar, &vtar_len); | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-19 10:00:17 +00:00
										 |  |  | 						/* first value is always in 'v' */ | 
					
						
							|  |  |  | 						if (vtar_len > 1) { | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 							BMEditSelection *ese = BLI_ghash_lookup(ese_gh, v); | 
					
						
							| 
									
										
										
										
											2013-08-19 10:00:17 +00:00
										 |  |  | 							BLI_assert(v == vtar[0]); | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 							if (UNLIKELY(ese)) { | 
					
						
							|  |  |  | 								int j; | 
					
						
							| 
									
										
										
										
											2013-08-19 10:00:17 +00:00
										 |  |  | 								for (j = 1; j < vtar_len; j++) { | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 									BLI_assert(v != vtar[j]); | 
					
						
							|  |  |  | 									BM_select_history_store_after_notest(bm, ese, vtar[j]); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						MEM_freeN(vtar); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							| 
									
										
										
										
											2015-05-02 16:05:32 +10:00
										 |  |  | 						BM_vert_separate_hflag(bm, v, BM_ELEM_TAG, copy_select, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-30 07:22:18 +10:00
										 |  |  | #ifndef NDEBUG
 | 
					
						
							| 
									
										
										
										
											2015-05-02 16:05:32 +10:00
										 |  |  | 	/* ensure we don't have any double edges! */ | 
					
						
							|  |  |  | 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							|  |  |  | 		if (BM_elem_flag_test(e, BM_ELEM_TAG)) { | 
					
						
							|  |  |  | 			BLI_assert(BM_edge_find_double(e) == NULL); | 
					
						
							| 
									
										
										
										
											2015-04-30 07:22:18 +10:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-05-02 16:05:32 +10:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-04-30 07:22:18 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-14 09:14:33 +00:00
										 |  |  | 	if (use_ese) { | 
					
						
							|  |  |  | 		BLI_ghash_free(ese_gh, NULL, NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-12-12 12:57:27 +00:00
										 |  |  | } |