| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +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, | 
					
						
							| 
									
										
										
										
											2012-02-11 04:16:17 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Blender Foundation, Campbell Barton | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:29:51 +00:00
										 |  |  | /** \file blender/editors/mesh/editface.c
 | 
					
						
							|  |  |  |  *  \ingroup edmesh | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_blenlib.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | #include "BLI_edgehash.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-19 15:45:56 +00:00
										 |  |  | #include "BLF_translation.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | #include "IMB_imbuf_types.h"
 | 
					
						
							|  |  |  | #include "IMB_imbuf.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 22:17:30 +00:00
										 |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_DerivedMesh.h"
 | 
					
						
							|  |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | #include "BKE_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | #include "BKE_tessmesh.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BIF_gl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "ED_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | #include "ED_screen.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-05 15:19:31 +00:00
										 |  |  | #include "ED_view3d.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* own include */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | /* copy the face flags, most importantly selection from the mesh to the final derived mesh,
 | 
					
						
							|  |  |  |  * use in object mode when selecting faces (while painting) */ | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | void paintface_flush_flags(Object *ob) | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	Mesh *me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 	DerivedMesh *dm = ob->derivedFinal; | 
					
						
							|  |  |  | 	MPoly *polys, *mp_orig; | 
					
						
							| 
									
										
										
										
											2011-10-25 16:17:26 +00:00
										 |  |  | 	MFace *faces; | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 	int *index_array = NULL; | 
					
						
							|  |  |  | 	int totface, totpoly; | 
					
						
							| 
									
										
										
										
											2011-07-25 10:51:24 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-01-01 13:08:07 +00:00
										 |  |  | 	if (me == NULL) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* we could call this directly in all areas that change selection,
 | 
					
						
							|  |  |  | 	 * since this could become slow for realtime updates (circle-select for eg) */ | 
					
						
							|  |  |  | 	BKE_mesh_flush_select_from_polys(me); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (dm == NULL) | 
					
						
							| 
									
										
										
										
											2009-11-25 13:11:44 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 	 * Try to push updated mesh poly flags to three other data sets: | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 	 *  - Mesh polys => Mesh tess faces | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 	 *  - Mesh polys => Final derived polys | 
					
						
							|  |  |  | 	 *  - Final derived polys => Final derived tessfaces | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 19:20:17 +00:00
										 |  |  | 	if ((index_array = CustomData_get_layer(&me->fdata, CD_ORIGINDEX))) { | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 		faces = me->mface; | 
					
						
							|  |  |  | 		totface = me->totface; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* loop over tessfaces */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (i = 0; i < totface; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 			/* Copy flags onto the original tessface from its original poly */ | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 			mp_orig = me->mpoly + index_array[i]; | 
					
						
							|  |  |  | 			faces[i].flag = mp_orig->flag; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-25 13:11:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-17 03:06:20 +00:00
										 |  |  | 	if ((index_array = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX))) { | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 		polys = dm->getPolyArray(dm); | 
					
						
							| 
									
										
										
										
											2011-11-29 13:01:51 +00:00
										 |  |  | 		totpoly = dm->getNumPolys(dm); | 
					
						
							| 
									
										
										
										
											2009-11-25 13:11:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 		/* loop over final derived polys */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (i = 0; i < totpoly; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 			/* Copy flags onto the final derived poly from the original mesh poly */ | 
					
						
							| 
									
										
										
										
											2011-10-14 09:05:20 +00:00
										 |  |  | 			mp_orig = me->mpoly + index_array[i]; | 
					
						
							|  |  |  | 			polys[i].flag = mp_orig->flag; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-30 19:20:17 +00:00
										 |  |  | 	if ((index_array = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))) { | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 		polys = dm->getPolyArray(dm); | 
					
						
							| 
									
										
										
										
											2012-02-25 16:04:03 +00:00
										 |  |  | 		faces = dm->getTessFaceArray(dm); | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 		totface = dm->getNumTessFaces(dm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* loop over tessfaces */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (i = 0; i < totface; i++) { | 
					
						
							| 
									
										
										
										
											2011-11-13 15:13:59 +00:00
										 |  |  | 			/* Copy flags onto the final tessface from its final poly */ | 
					
						
							|  |  |  | 			mp_orig = polys + index_array[i]; | 
					
						
							|  |  |  | 			faces[i].flag = mp_orig->flag; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | void paintface_hide(Object *ob, const int unselected) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mpoly; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	int a; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == NULL || me->totpoly == 0) return; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	mpoly = me->mpoly; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	a = me->totpoly; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (a--) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		if ((mpoly->flag & ME_HIDE) == 0) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (unselected) { | 
					
						
							| 
									
										
										
										
											2012-09-09 00:00:21 +00:00
										 |  |  | 				if ((mpoly->flag & ME_FACE_SEL) == 0) mpoly->flag |= ME_HIDE; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-09-09 00:00:21 +00:00
										 |  |  | 				if ((mpoly->flag & ME_FACE_SEL)) mpoly->flag |= ME_HIDE; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		if (mpoly->flag & ME_HIDE) mpoly->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mpoly++; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	paintface_flush_flags(ob); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void paintface_reveal(Object *ob) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mpoly; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == NULL || me->totpoly == 0) return; | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	mpoly = me->mpoly; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	a = me->totpoly; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (a--) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		if (mpoly->flag & ME_HIDE) { | 
					
						
							|  |  |  | 			mpoly->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | 			mpoly->flag -= ME_HIDE; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mpoly++; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	paintface_flush_flags(ob); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | /* Set tface seams based on edge data, uses hash table to find seam edges. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-28 07:10:27 +00:00
										 |  |  | static void hash_add_face(EdgeHash *ehash, MPoly *mp, MLoop *mloop) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-28 04:18:01 +00:00
										 |  |  | 	MLoop *ml, *ml_next; | 
					
						
							| 
									
										
										
										
											2013-02-28 03:39:41 +00:00
										 |  |  | 	int i = mp->totloop; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 04:18:01 +00:00
										 |  |  | 	ml_next = mloop;       /* first loop */ | 
					
						
							|  |  |  | 	ml = &ml_next[i - 1];  /* last loop */ | 
					
						
							| 
									
										
										
										
											2013-02-28 03:39:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (i-- != 0) { | 
					
						
							|  |  |  | 		BLI_edgehash_insert(ehash, ml->v, ml_next->v, NULL); | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-28 03:39:41 +00:00
										 |  |  | 		ml = ml_next; | 
					
						
							|  |  |  | 		ml_next++; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	EdgeHash *ehash, *seamhash; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mp; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	MLoop *ml; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	MEdge *med; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	char *linkflag; | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 	int a, b, do_it = TRUE, mark = 0; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	ehash = BLI_edgehash_new(); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	seamhash = BLI_edgehash_new(); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	linkflag = MEM_callocN(sizeof(char) * me->totpoly, "linkflaguv"); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	for (med = me->medge, a = 0; a < me->totedge; a++, med++) | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (med->flag & ME_SEAM) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 			BLI_edgehash_insert(seamhash, med->v1, med->v2, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (mode == 0 || mode == 1) { | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 		/* only put face under cursor in array */ | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mp = ((MPoly *)me->mpoly) + index; | 
					
						
							|  |  |  | 		hash_add_face(ehash, mp, me->mloop + mp->loopstart); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		linkflag[index] = 1; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* fill array by selection */ | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mp = me->mpoly; | 
					
						
							|  |  |  | 		for (a = 0; a < me->totpoly; a++, mp++) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 			if (mp->flag & ME_HIDE) { | 
					
						
							|  |  |  | 				/* pass */ | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			else if (mp->flag & ME_FACE_SEL) { | 
					
						
							|  |  |  | 				hash_add_face(ehash, mp, me->mloop + mp->loopstart); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 				linkflag[a] = 1; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 	while (do_it) { | 
					
						
							|  |  |  | 		do_it = FALSE; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* expand selection */ | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mp = me->mpoly; | 
					
						
							|  |  |  | 		for (a = 0; a < me->totpoly; a++, mp++) { | 
					
						
							|  |  |  | 			if (mp->flag & ME_HIDE) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (!linkflag[a]) { | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 				MLoop *mnextl; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 				mark = 0; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				ml = me->mloop + mp->loopstart; | 
					
						
							|  |  |  | 				for (b = 0; b < mp->totloop; b++, ml++) { | 
					
						
							|  |  |  | 					mnextl = b < mp->totloop - 1 ? ml - 1 : me->mloop + mp->loopstart; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 					if (!BLI_edgehash_haskey(seamhash, ml->v, mnextl->v)) | 
					
						
							|  |  |  | 						if (!BLI_edgehash_haskey(ehash, ml->v, mnextl->v)) | 
					
						
							|  |  |  | 							mark = 1; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (mark) { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 					linkflag[a] = 1; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 					hash_add_face(ehash, mp, me->mloop + mp->loopstart); | 
					
						
							| 
									
										
										
										
											2012-05-19 13:28:19 +00:00
										 |  |  | 					do_it = TRUE; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_edgehash_free(ehash, NULL); | 
					
						
							|  |  |  | 	BLI_edgehash_free(seamhash, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (mode == 0 || mode == 2) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (linkflag[a]) | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				mp->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				mp->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	else if (mode == 1) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) | 
					
						
							|  |  |  | 			if (linkflag[a] && (mp->flag & ME_FACE_SEL)) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		if (a < me->totpoly) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (linkflag[a]) | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 					mp->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (linkflag[a]) | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 					mp->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	MEM_freeN(linkflag); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 09:03:46 +00:00
										 |  |  | void paintface_select_linked(bContext *UNUSED(C), Object *ob, const int UNUSED(mval[2]), int mode) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	unsigned int index = 0; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == NULL || me->totpoly == 0) return; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (mode == 0 || mode == 1) { | 
					
						
							| 
									
										
										
										
											2012-07-06 23:56:59 +00:00
										 |  |  | 		/* XXX - Causes glitches, not sure why */ | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2012-09-07 00:58:00 +00:00
										 |  |  | 		if (!ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2012-03-03 16:31:46 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	select_linked_tfaces_with_seams(mode, me, index); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 	paintface_flush_flags(ob); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | void paintface_deselect_all_visible(Object *ob, int action, short flush_flags) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mpoly; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 	int a; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == NULL) return; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (action == SEL_INVERT) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mpoly = me->mpoly; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		a = me->totpoly; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (a--) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			if ((mpoly->flag & ME_HIDE) == 0) { | 
					
						
							|  |  |  | 				mpoly->flag ^= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			mpoly++; | 
					
						
							| 
									
										
										
										
											2009-10-22 23:22:05 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 		if (action == SEL_TOGGLE) { | 
					
						
							|  |  |  | 			action = SEL_SELECT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			mpoly = me->mpoly; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			a = me->totpoly; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				if ((mpoly->flag & ME_HIDE) == 0 && mpoly->flag & ME_FACE_SEL) { | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 					action = SEL_DESELECT; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				mpoly++; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mpoly = me->mpoly; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		a = me->totpoly; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (a--) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			if ((mpoly->flag & ME_HIDE) == 0) { | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | 				switch (action) { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 					case SEL_SELECT: | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 						mpoly->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					case SEL_DESELECT: | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 						mpoly->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					case SEL_INVERT: | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 						mpoly->flag ^= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			mpoly++; | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (flush_flags) { | 
					
						
							| 
									
										
										
										
											2011-10-31 03:55:01 +00:00
										 |  |  | 		paintface_flush_flags(ob); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 08:29:20 +00:00
										 |  |  | int paintface_minmax(Object *ob, float r_min[3], float r_max[3]) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mp; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	MTexPoly *tf; | 
					
						
							|  |  |  | 	MLoop *ml; | 
					
						
							| 
									
										
										
										
											2011-11-07 09:02:10 +00:00
										 |  |  | 	MVert *mvert; | 
					
						
							| 
									
										
										
										
											2012-04-28 08:29:20 +00:00
										 |  |  | 	int a, b, ok = FALSE; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	float vec[3], bmat[3][3]; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (!me || !me->mtpoly) return ok; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 	copy_m3_m4(bmat, ob->obmat); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	mvert = me->mvert; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	mp = me->mpoly; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	tf = me->mtpoly; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	for (a = me->totpoly; a > 0; a--, mp++, tf++) { | 
					
						
							|  |  |  | 		if (mp->flag & ME_HIDE || !(mp->flag & ME_FACE_SEL)) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		ml = me->mloop + mp->totloop; | 
					
						
							|  |  |  | 		for (b = 0; b < mp->totloop; b++, ml++) { | 
					
						
							| 
									
										
										
										
											2011-11-07 09:02:10 +00:00
										 |  |  | 			copy_v3_v3(vec, (mvert[ml->v].co)); | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | 			mul_m3_v3(bmat, vec); | 
					
						
							|  |  |  | 			add_v3_v3v3(vec, vec, ob->obmat[3]); | 
					
						
							| 
									
										
										
										
											2012-05-13 11:05:52 +00:00
										 |  |  | 			minmax_v3v3_v3(r_min, r_max, vec); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 08:29:20 +00:00
										 |  |  | 		ok = TRUE; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	return ok; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-31 13:30:56 +00:00
										 |  |  | /* *************************************** */ | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | static void seam_edgehash_insert_face(EdgeHash *ehash, MPoly *mp, MLoop *loopstart) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	MLoop *ml1, *ml2; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	for (a = 0; a < mp->totloop; a++) { | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 		ml1 = loopstart + a; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		ml2 = loopstart + (a + 1) % mp->totloop; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		BLI_edgehash_insert(ehash, ml1->v, ml2->v, NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void seam_mark_clear_tface(Scene *scene, short mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mp; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	MLoop *ml1, *ml2; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	MEdge *med; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	int a, b; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(OBACT); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == 0 ||  me->totpoly == 0) return; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (mode == 0) | 
					
						
							| 
									
										
										
										
											2013-02-19 15:45:56 +00:00
										 |  |  | 		mode = pupmenu(IFACE_("Seams %t|Mark Border Seam %x1|Clear Seam %x2")); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (mode != 1 && mode != 2) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mode == 2) { | 
					
						
							|  |  |  | 		EdgeHash *ehash = BLI_edgehash_new(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) | 
					
						
							|  |  |  | 			if (!(mp->flag & ME_HIDE) && (mp->flag & ME_FACE_SEL)) | 
					
						
							|  |  |  | 				seam_edgehash_insert_face(ehash, mp, me->mloop + mp->loopstart); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (a = 0, med = me->medge; a < me->totedge; a++, med++) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 			if (BLI_edgehash_haskey(ehash, med->v1, med->v2)) | 
					
						
							|  |  |  | 				med->flag &= ~ME_SEAM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BLI_edgehash_free(ehash, NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* mark edges that are on both selected and deselected faces */ | 
					
						
							|  |  |  | 		EdgeHash *ehash1 = BLI_edgehash_new(); | 
					
						
							|  |  |  | 		EdgeHash *ehash2 = BLI_edgehash_new(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		for (a = 0, mp = me->mpoly; a < me->totpoly; a++, mp++) { | 
					
						
							|  |  |  | 			if ((mp->flag & ME_HIDE) || !(mp->flag & ME_FACE_SEL)) | 
					
						
							|  |  |  | 				seam_edgehash_insert_face(ehash1, mp, me->mloop + mp->loopstart); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				seam_edgehash_insert_face(ehash2, mp, me->mloop + mp->loopstart); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (a = 0, med = me->medge; a < me->totedge; a++, med++) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 			if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) && | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			    BLI_edgehash_haskey(ehash2, med->v1, med->v2)) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 				med->flag |= ME_SEAM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BLI_edgehash_free(ehash1, NULL); | 
					
						
							|  |  |  | 		BLI_edgehash_free(ehash2, NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-08 18:21:54 +00:00
										 |  |  | // XXX	if (G.debug_value == 8)
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | //		unwrap_lscm(1);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-31 13:30:56 +00:00
										 |  |  | 	me->drawflag |= ME_DRAWSEAMS; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], int extend, int deselect, int toggle) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mpoly, *mpoly_sel; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	unsigned int a, index; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Get the face under the cursor */ | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-23 01:54:11 +00:00
										 |  |  | 	if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-08-11 21:35:24 +00:00
										 |  |  | 	if (index >= me->totpoly) | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	mpoly_sel = me->mpoly + index; | 
					
						
							|  |  |  | 	if (mpoly_sel->flag & ME_HIDE) return 0; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* clear flags */ | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	mpoly = me->mpoly; | 
					
						
							| 
									
										
										
										
											2010-01-28 00:45:30 +00:00
										 |  |  | 	a = me->totpoly; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 	if (!extend && !deselect && !toggle) { | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		while (a--) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			mpoly->flag &= ~ME_FACE_SEL; | 
					
						
							|  |  |  | 			mpoly++; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	me->act_face = (int)index; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	if (extend) { | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 		mpoly_sel->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (deselect) { | 
					
						
							|  |  |  | 		mpoly_sel->flag &= ~ME_FACE_SEL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else if (toggle) { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		if (mpoly_sel->flag & ME_FACE_SEL) | 
					
						
							|  |  |  | 			mpoly_sel->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 			mpoly_sel->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-03-09 03:46:30 +00:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		mpoly_sel->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* image window redraw */ | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 	paintface_flush_flags(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend) | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 	Object *ob = vc->obact; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	Mesh *me; | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	MPoly *mpoly; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	struct ImBuf *ibuf; | 
					
						
							|  |  |  | 	unsigned int *rt; | 
					
						
							|  |  |  | 	char *selar; | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 	int a, index; | 
					
						
							| 
									
										
										
										
											2012-09-15 11:48:20 +00:00
										 |  |  | 	int sx = BLI_rcti_size_x(rect) + 1; | 
					
						
							|  |  |  | 	int sy = BLI_rcti_size_y(rect) + 1; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == NULL || me->totpoly == 0 || sx * sy <= 0) | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	selar = MEM_callocN(me->totpoly + 1, "selar"); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-08 04:38:35 +00:00
										 |  |  | 	if (extend == 0 && select) { | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 		paintface_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 		mpoly = me->mpoly; | 
					
						
							|  |  |  | 		for (a = 1; a <= me->totpoly; a++, mpoly++) { | 
					
						
							|  |  |  | 			if ((mpoly->flag & ME_HIDE) == 0) | 
					
						
							|  |  |  | 				mpoly->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 	view3d_validate_backbuf(vc); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	rt = ibuf->rect; | 
					
						
							| 
									
										
										
										
											2013-03-15 19:56:33 +00:00
										 |  |  | 	view3d_opengl_read_pixels(vc->ar, rect->xmin, rect->ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	a = sx * sy; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (a--) { | 
					
						
							|  |  |  | 		if (*rt) { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			index = WM_framebuffer_to_index(*rt); | 
					
						
							|  |  |  | 			if (index <= me->totpoly) selar[index] = 1; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 		rt++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 	mpoly = me->mpoly; | 
					
						
							|  |  |  | 	for (a = 1; a <= me->totpoly; a++, mpoly++) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (selar[a]) { | 
					
						
							| 
									
										
										
										
											2012-10-07 09:48:59 +00:00
										 |  |  | 			if (mpoly->flag & ME_HIDE) { | 
					
						
							|  |  |  | 				/* pass */ | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-04-03 23:40:24 +00:00
										 |  |  | 				if (select) mpoly->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | 				else mpoly->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-01 00:06:53 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	IMB_freeImBuf(ibuf); | 
					
						
							|  |  |  | 	MEM_freeN(selar); | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __APPLE__	
 | 
					
						
							|  |  |  | 	glReadBuffer(GL_BACK); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-11-03 01:56:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	paintface_flush_flags(vc->obact); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							| 
									
										
										
										
											2008-12-30 13:16:14 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*  (similar to void paintface_flush_flags(Object *ob))
 | 
					
						
							|  |  |  |  * copy the vertex flags, most importantly selection from the mesh to the final derived mesh, | 
					
						
							|  |  |  |  * use in object mode when selecting vertices (while painting) */ | 
					
						
							|  |  |  | void paintvert_flush_flags(Object *ob) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	Mesh *me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	DerivedMesh *dm = ob->derivedFinal; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 	MVert *dm_mvert, *dm_mv; | 
					
						
							|  |  |  | 	int *index_array = NULL; | 
					
						
							|  |  |  | 	int totvert; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-01 13:08:07 +00:00
										 |  |  | 	if (me == NULL) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* we could call this directly in all areas that change selection,
 | 
					
						
							|  |  |  | 	 * since this could become slow for realtime updates (circle-select for eg) */ | 
					
						
							|  |  |  | 	BKE_mesh_flush_select_from_verts(me); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (dm == NULL) | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dm_mvert = dm->getVertArray(dm); | 
					
						
							|  |  |  | 	totvert = dm->getNumVerts(dm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	dm_mv = dm_mvert; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (index_array) { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 		int orig_index; | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (i = 0; i < totvert; i++, dm_mv++) { | 
					
						
							|  |  |  | 			orig_index = index_array[i]; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (orig_index != ORIGINDEX_NONE) { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 				dm_mv->flag = me->mvert[index_array[i]].flag; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (i = 0; i < totvert; i++, dm_mv++) { | 
					
						
							|  |  |  | 			dm_mv->flag = me->mvert[i].flag; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /*  note: if the caller passes FALSE to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */ | 
					
						
							|  |  |  | void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Mesh *me; | 
					
						
							|  |  |  | 	MVert *mvert; | 
					
						
							|  |  |  | 	int a; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  | 	me = BKE_mesh_from_object(ob); | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if (me == NULL) return; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (action == SEL_INVERT) { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		mvert = me->mvert; | 
					
						
							|  |  |  | 		a = me->totvert; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (a--) { | 
					
						
							|  |  |  | 			if ((mvert->flag & ME_HIDE) == 0) { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 				mvert->flag ^= SELECT; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			mvert++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if (action == SEL_TOGGLE) { | 
					
						
							|  |  |  | 			action = SEL_SELECT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			mvert = me->mvert; | 
					
						
							|  |  |  | 			a = me->totvert; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			while (a--) { | 
					
						
							|  |  |  | 				if ((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 					action = SEL_DESELECT; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				mvert++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		mvert = me->mvert; | 
					
						
							|  |  |  | 		a = me->totvert; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (a--) { | 
					
						
							|  |  |  | 			if ((mvert->flag & ME_HIDE) == 0) { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 				switch (action) { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 					case SEL_SELECT: | 
					
						
							|  |  |  | 						mvert->flag |= SELECT; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case SEL_DESELECT: | 
					
						
							|  |  |  | 						mvert->flag &= ~SELECT; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case SEL_INVERT: | 
					
						
							|  |  |  | 						mvert->flag ^= SELECT; | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			mvert++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (flush_flags) { | 
					
						
							| 
									
										
										
										
											2011-09-22 16:09:27 +00:00
										 |  |  | 		paintvert_flush_flags(ob); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-12-20 21:28:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | /* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ | 
					
						
							|  |  |  | /* note, this is not the best place for the function to be but moved
 | 
					
						
							|  |  |  |  * here to for the purpose of syncing with bmesh */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef int MirrTopoHash_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | typedef struct MirrTopoVert_t { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	MirrTopoHash_t hash; | 
					
						
							|  |  |  | 	int v_index; | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | } MirrTopoVert_t; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | static int mirrtopo_hash_sort(const void *l1, const void *l2) | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-04-21 12:51:47 +00:00
										 |  |  | 	if      ((MirrTopoHash_t)(intptr_t)l1 > (MirrTopoHash_t)(intptr_t)l2) return 1; | 
					
						
							|  |  |  | 	else if ((MirrTopoHash_t)(intptr_t)l1 < (MirrTopoHash_t)(intptr_t)l2) return -1; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | static int mirrtopo_vert_sort(const void *v1, const void *v2) | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if      (((MirrTopoVert_t *)v1)->hash > ((MirrTopoVert_t *)v2)->hash) return 1; | 
					
						
							|  |  |  | 	else if (((MirrTopoVert_t *)v1)->hash < ((MirrTopoVert_t *)v2)->hash) return -1; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ED_mesh_mirrtopo_recalc_check(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int totvert; | 
					
						
							|  |  |  | 	int totedge; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 21:28:57 +00:00
										 |  |  | 	if (me->edit_btmesh) { | 
					
						
							| 
									
										
										
										
											2011-12-20 23:17:24 +00:00
										 |  |  | 		totvert = me->edit_btmesh->bm->totvert; | 
					
						
							|  |  |  | 		totedge = me->edit_btmesh->bm->totedge; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		totvert = me->totvert; | 
					
						
							|  |  |  | 		totedge = me->totedge; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	if ((mesh_topo_store->index_lookup == NULL) || | 
					
						
							|  |  |  | 	    (mesh_topo_store->prev_ob_mode != ob_mode) || | 
					
						
							|  |  |  | 	    (totvert != mesh_topo_store->prev_vert_tot) || | 
					
						
							|  |  |  | 	    (totedge != mesh_topo_store->prev_edge_tot)) | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		return TRUE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 22:01:11 +00:00
										 |  |  | void ED_mesh_mirrtopo_init(Mesh *me, const int ob_mode, MirrTopoStore_t *mesh_topo_store, | 
					
						
							|  |  |  |                            const short skip_em_vert_array_init) | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	MEdge *medge; | 
					
						
							| 
									
										
										
										
											2011-12-20 23:17:24 +00:00
										 |  |  | 	BMEditMesh *em = me->edit_btmesh; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* editmode*/ | 
					
						
							| 
									
										
										
										
											2011-12-20 21:28:57 +00:00
										 |  |  | 	BMEdge *eed; | 
					
						
							|  |  |  | 	BMIter iter; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int a, last; | 
					
						
							|  |  |  | 	int totvert, totedge; | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	int tot_unique = -1, tot_unique_prev = -1; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	MirrTopoHash_t *topo_hash = NULL; | 
					
						
							|  |  |  | 	MirrTopoHash_t *topo_hash_prev = NULL; | 
					
						
							|  |  |  | 	MirrTopoVert_t *topo_pairs; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	intptr_t *index_lookup; /* direct access to mesh_topo_store->index_lookup */ | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* reallocate if needed */ | 
					
						
							|  |  |  | 	ED_mesh_mirrtopo_free(mesh_topo_store); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	mesh_topo_store->prev_ob_mode = ob_mode; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (em) { | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 		BM_mesh_elem_index_ensure(em->bm, BM_VERT); | 
					
						
							| 
									
										
										
										
											2011-12-20 21:28:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:17:24 +00:00
										 |  |  | 		totvert = em->bm->totvert; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		totvert = me->totvert; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	topo_hash = MEM_callocN(totvert * sizeof(MirrTopoHash_t), "TopoMirr"); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Initialize the vert-edge-user counts used to detect unique topology */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (em) { | 
					
						
							| 
									
										
										
										
											2011-12-20 23:17:24 +00:00
										 |  |  | 		totedge = me->edit_btmesh->bm->totedge; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 		BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 			topo_hash[BM_elem_index_get(eed->v1)]++; | 
					
						
							|  |  |  | 			topo_hash[BM_elem_index_get(eed->v2)]++; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		totedge = me->totedge; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (a = 0, medge = me->medge; a < me->totedge; a++, medge++) { | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 			topo_hash[medge->v1]++; | 
					
						
							|  |  |  | 			topo_hash[medge->v2]++; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	topo_hash_prev = MEM_dupallocN(topo_hash); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	tot_unique_prev = -1; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (1) { | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 		/* use the number of edges per vert to give verts unique topology IDs */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		if (em) { | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 			BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2012-02-12 10:51:45 +00:00
										 |  |  | 				topo_hash[BM_elem_index_get(eed->v1)] += topo_hash_prev[BM_elem_index_get(eed->v2)]; | 
					
						
							|  |  |  | 				topo_hash[BM_elem_index_get(eed->v2)] += topo_hash_prev[BM_elem_index_get(eed->v1)]; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 			for (a = 0, medge = me->medge; a < me->totedge; a++, medge++) { | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 				/* This can make really big numbers, wrapping around here is fine */ | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 				topo_hash[medge->v1] += topo_hash_prev[medge->v2]; | 
					
						
							|  |  |  | 				topo_hash[medge->v2] += topo_hash_prev[medge->v1]; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* sort so we can count unique values */ | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		qsort(topo_hash_prev, totvert, sizeof(MirrTopoHash_t), mirrtopo_hash_sort); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		tot_unique = 1; /* account for skiping the first value */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		for (a = 1; a < totvert; a++) { | 
					
						
							|  |  |  | 			if (topo_hash_prev[a - 1] != topo_hash_prev[a]) { | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 				tot_unique++; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		if (tot_unique <= tot_unique_prev) { | 
					
						
							| 
									
										
										
										
											2012-05-20 21:23:26 +00:00
										 |  |  | 			/* Finish searching for unique values when 1 loop dosnt give a
 | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 			 * higher number of unique values compared to the previous loop */ | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			tot_unique_prev = tot_unique; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		/* Copy the hash calculated this iter, so we can use them next time */ | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		memcpy(topo_hash_prev, topo_hash, sizeof(MirrTopoHash_t) * totvert); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Hash/Index pairs are needed for sorting to find index pairs */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	topo_pairs = MEM_callocN(sizeof(MirrTopoVert_t) * totvert, "MirrTopoPairs"); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* since we are looping through verts, initialize these values here too */ | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	index_lookup = MEM_mallocN(totvert * sizeof(*index_lookup), "mesh_topo_lookup"); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (em) { | 
					
						
							| 
									
										
										
										
											2011-12-20 22:01:11 +00:00
										 |  |  | 		if (skip_em_vert_array_init == FALSE) { | 
					
						
							| 
									
										
										
										
											2012-12-12 06:53:39 +00:00
										 |  |  | 			EDBM_index_arrays_ensure(em, BM_VERT); | 
					
						
							| 
									
										
										
										
											2011-12-20 22:01:11 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	for (a = 0; a < totvert; a++) { | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		topo_pairs[a].hash    = topo_hash[a]; | 
					
						
							|  |  |  | 		topo_pairs[a].v_index = a; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* initialize lookup */ | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 		index_lookup[a] = -1; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-21 00:47:59 +00:00
										 |  |  | 	qsort(topo_pairs, totvert, sizeof(MirrTopoVert_t), mirrtopo_vert_sort); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Since the loop starts at 2, we must define the last index where the hash's differ */ | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	last = ((totvert >= 2) && (topo_pairs[0].hash == topo_pairs[1].hash)) ? 0 : 1; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2,
 | 
					
						
							|  |  |  | 	 * but you cant ever access the last 'a' index of MirrTopoPairs */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 	for (a = 2; a <= totvert; a++) { | 
					
						
							| 
									
										
										
										
											2011-12-20 21:28:57 +00:00
										 |  |  | 		/* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a  ].hash, MirrTopoPairs[a  ].v_index ); */ | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 		if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) { | 
					
						
							|  |  |  | 			if (a - last == 2) { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 				if (em) { | 
					
						
							| 
									
										
										
										
											2012-03-27 04:46:52 +00:00
										 |  |  | 					index_lookup[topo_pairs[a - 1].v_index] = (intptr_t)EDBM_vert_at_index(em, topo_pairs[a - 2].v_index); | 
					
						
							|  |  |  | 					index_lookup[topo_pairs[a - 2].v_index] = (intptr_t)EDBM_vert_at_index(em, topo_pairs[a - 1].v_index); | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2012-03-26 02:56:48 +00:00
										 |  |  | 					index_lookup[topo_pairs[a - 1].v_index] = topo_pairs[a - 2].v_index; | 
					
						
							|  |  |  | 					index_lookup[topo_pairs[a - 2].v_index] = topo_pairs[a - 1].v_index; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 			last = a; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	MEM_freeN(topo_pairs); | 
					
						
							|  |  |  | 	topo_pairs = NULL; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	MEM_freeN(topo_hash); | 
					
						
							|  |  |  | 	MEM_freeN(topo_hash_prev); | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-20 23:14:29 +00:00
										 |  |  | 	mesh_topo_store->index_lookup  = index_lookup; | 
					
						
							| 
									
										
										
										
											2011-12-20 10:05:58 +00:00
										 |  |  | 	mesh_topo_store->prev_vert_tot = totvert; | 
					
						
							|  |  |  | 	mesh_topo_store->prev_edge_tot = totedge; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (mesh_topo_store->index_lookup) { | 
					
						
							|  |  |  | 		MEM_freeN(mesh_topo_store->index_lookup); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mesh_topo_store->index_lookup  = NULL; | 
					
						
							|  |  |  | 	mesh_topo_store->prev_vert_tot = -1; | 
					
						
							|  |  |  | 	mesh_topo_store->prev_edge_tot = -1; | 
					
						
							|  |  |  | } |