| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |  * Contributor(s): none yet. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 20:29:51 +00:00
										 |  |  | /** \file blender/editors/metaball/mball_edit.c
 | 
					
						
							|  |  |  |  *  \ingroup edmeta | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_blenlib.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-10 20:43:45 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | #include "BLI_rand.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-04 06:05:48 +00:00
										 |  |  | #include "DNA_defs.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | #include "DNA_meta_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "RNA_define.h"
 | 
					
						
							|  |  |  | #include "RNA_access.h"
 | 
					
						
							| 
									
										
										
										
											2011-04-01 08:51:12 +00:00
										 |  |  | #include "RNA_enum_types.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_depsgraph.h"
 | 
					
						
							|  |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2010-09-07 05:47:34 +00:00
										 |  |  | #include "BKE_mball.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 17:55:27 +00:00
										 |  |  | #include "ED_mball.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | #include "ED_screen.h"
 | 
					
						
							|  |  |  | #include "ED_view3d.h"
 | 
					
						
							|  |  |  | #include "ED_transform.h"
 | 
					
						
							|  |  |  | #include "ED_util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "WM_api.h"
 | 
					
						
							|  |  |  | #include "WM_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 17:55:27 +00:00
										 |  |  | #include "mball_intern.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | /* This function is used to free all MetaElems from MetaBall */ | 
					
						
							|  |  |  | void free_editMball(Object *obedit) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2010-07-05 12:52:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	mb->editelems = NULL; | 
					
						
							|  |  |  | 	mb->lastelem = NULL; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This function is called, when MetaBall Object is
 | 
					
						
							|  |  |  |  * switched from object mode to edit mode */ | 
					
						
							|  |  |  | void make_editMball(Object *obedit) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							|  |  |  | 	MetaElem *ml; /*, *newml;*/ | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->elems.first; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							|  |  |  | 		if (ml->flag & SELECT) mb->lastelem = ml; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mb->editelems = &mb->elems; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This function is called, when MetaBall Object switched from
 | 
					
						
							|  |  |  |  * edit mode to object mode. List od MetaElements is copied | 
					
						
							| 
									
										
										
										
											2010-04-25 15:24:18 +00:00
										 |  |  |  * from object->data->edit_elems to object->data->elems. */ | 
					
						
							| 
									
										
										
										
											2010-10-16 14:32:17 +00:00
										 |  |  | void load_editMball(Object *UNUSED(obedit)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Add metaelem primitive to metaball object (which is in edit mode) */ | 
					
						
							| 
									
										
										
										
											2012-10-19 12:53:03 +00:00
										 |  |  | MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type, int UNUSED(newname)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	MetaBall *mball = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Deselect all existing metaelems */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mball->editelems->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		ml->flag &= ~SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = BKE_mball_element_add(mball, type); | 
					
						
							| 
									
										
										
										
											2012-10-19 12:53:03 +00:00
										 |  |  | 	ml->rad *= dia; | 
					
						
							| 
									
										
										
										
											2010-09-07 05:47:34 +00:00
										 |  |  | 	copy_v3_v3(&ml->x, mat[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ml->flag |= SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	mball->lastelem = ml; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	return ml; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************************** Select/Deselect operator *****************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Select or deselect all MetaElements */ | 
					
						
							| 
									
										
										
										
											2011-10-28 03:02:09 +00:00
										 |  |  | static int mball_select_all_exec(bContext *C, wmOperator *op) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 	int action = RNA_enum_get(op->ptr, "action"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 	if (mb->editelems->first == NULL) | 
					
						
							|  |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 	if (action == SEL_TOGGLE) { | 
					
						
							|  |  |  | 		action = SEL_SELECT; | 
					
						
							|  |  |  | 		for (ml = mb->editelems->first; ml; ml = ml->next) { | 
					
						
							|  |  |  | 			if (ml->flag & SELECT) { | 
					
						
							|  |  |  | 				action = SEL_DESELECT; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 	switch (action) { | 
					
						
							|  |  |  | 		case SEL_SELECT: | 
					
						
							|  |  |  | 			BKE_mball_select_all(mb); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SEL_DESELECT: | 
					
						
							|  |  |  | 			BKE_mball_deselect_all(mb); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case SEL_INVERT: | 
					
						
							|  |  |  | 			BKE_mball_select_swap(mb); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | void MBALL_OT_select_all(wmOperatorType *ot) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "(De)select All"; | 
					
						
							|  |  |  | 	ot->description = "Change selection of all meta elements"; | 
					
						
							|  |  |  | 	ot->idname = "MBALL_OT_select_all"; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* callback functions */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = mball_select_all_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmball; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-11-29 22:16:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	WM_operator_properties_select_all(ot); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************************** Select random operator *****************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Random metaball selection */ | 
					
						
							|  |  |  | static int select_random_metaelems_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	float percent = RNA_float_get(op->ptr, "percent"); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (percent == 0.0f) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		return OPERATOR_CANCELLED; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->editelems->first; | 
					
						
							|  |  |  | 	BLI_srand(BLI_rand());  /* Random seed */ | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* Stupid version of random selection. Should be improved. */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							|  |  |  | 		if (BLI_frand() < percent) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 			ml->flag |= SELECT; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			ml->flag &= ~SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Random..."; | 
					
						
							|  |  |  | 	ot->description = "Randomly select metaelements"; | 
					
						
							|  |  |  | 	ot->idname = "MBALL_OT_select_random_metaelems"; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* callback functions */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = select_random_metaelems_exec; | 
					
						
							|  |  |  | 	ot->invoke = WM_operator_props_popup; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmball; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* properties */ | 
					
						
							| 
									
										
										
										
											2012-07-04 15:52:07 +00:00
										 |  |  | 	RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", | 
					
						
							|  |  |  | 	                         "Percentage of metaelements to select randomly", 0.0001f, 1.0f); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************************** Duplicate operator *****************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Duplicate selected MetaElements */ | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml, *newml; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->editelems->last; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ml) { | 
					
						
							|  |  |  | 		while (ml) { | 
					
						
							|  |  |  | 			if (ml->flag & SELECT) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 				newml = MEM_dupallocN(ml); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				BLI_addtail(mb->editelems, newml); | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 				mb->lastelem = newml; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				ml->flag &= ~SELECT; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			ml = ml->prev; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	int retv = duplicate_metaelems_exec(C, op); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (retv == OPERATOR_FINISHED) { | 
					
						
							| 
									
										
										
										
											2011-03-22 12:53:36 +00:00
										 |  |  | 		RNA_enum_set(op->ptr, "mode", TFM_TRANSLATION); | 
					
						
							| 
									
										
										
										
											2009-12-10 10:36:32 +00:00
										 |  |  | 		WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return retv; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Duplicate Metaelements"; | 
					
						
							| 
									
										
										
										
											2012-05-12 20:50:46 +00:00
										 |  |  | 	ot->description = "Duplicate selected metaelement(s)"; | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->idname = "MBALL_OT_duplicate_metaelems"; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* callback functions */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = duplicate_metaelems_exec; | 
					
						
							|  |  |  | 	ot->invoke = duplicate_metaelems_invoke; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmball; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* to give to transform */ | 
					
						
							| 
									
										
										
										
											2011-04-01 08:51:12 +00:00
										 |  |  | 	RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", ""); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************************** Delete operator *****************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Delete all selected MetaElems (not MetaBall) */ | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int delete_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml, *next; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->editelems->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ml) { | 
					
						
							|  |  |  | 		while (ml) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			next = ml->next; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 			if (ml->flag & SELECT) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 				if (mb->lastelem == ml) mb->lastelem = NULL; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				BLI_remlink(mb->editelems, ml); | 
					
						
							|  |  |  | 				MEM_freeN(ml); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			ml = next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MBALL_OT_delete_metaelems(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Delete"; | 
					
						
							|  |  |  | 	ot->description = "Delete selected metaelement(s)"; | 
					
						
							|  |  |  | 	ot->idname = "MBALL_OT_delete_metaelems"; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* callback functions */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = delete_metaelems_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmball; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************************** Hide operator *****************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Hide selected MetaElems */ | 
					
						
							|  |  |  | static int hide_metaelems_exec(bContext *C, wmOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	const int invert = RNA_boolean_get(op->ptr, "unselected") ? SELECT : 0; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->editelems->first; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ml) { | 
					
						
							|  |  |  | 		while (ml) { | 
					
						
							|  |  |  | 			if ((ml->flag & SELECT) != invert) | 
					
						
							| 
									
										
										
										
											2011-02-24 16:04:36 +00:00
										 |  |  | 				ml->flag |= MB_HIDE; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MBALL_OT_hide_metaelems(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Hide"; | 
					
						
							|  |  |  | 	ot->description = "Hide (un)selected metaelement(s)"; | 
					
						
							|  |  |  | 	ot->idname = "MBALL_OT_hide_metaelems"; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* callback functions */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = hide_metaelems_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmball; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* props */ | 
					
						
							| 
									
										
										
										
											2011-09-19 12:26:20 +00:00
										 |  |  | 	RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected"); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /***************************** Unhide operator *****************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Unhide all edited MetaElems */ | 
					
						
							| 
									
										
										
										
											2010-10-15 01:36:14 +00:00
										 |  |  | static int reveal_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							|  |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->editelems->first; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	if (ml) { | 
					
						
							|  |  |  | 		while (ml) { | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 			ml->flag &= ~MB_HIDE; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); | 
					
						
							| 
									
										
										
										
											2011-01-03 12:41:16 +00:00
										 |  |  | 		DAG_id_tag_update(obedit->data, 0); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return OPERATOR_FINISHED; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MBALL_OT_reveal_metaelems(wmOperatorType *ot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* identifiers */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->name = "Reveal"; | 
					
						
							|  |  |  | 	ot->description = "Reveal all hidden metaelements"; | 
					
						
							|  |  |  | 	ot->idname = "MBALL_OT_reveal_metaelems"; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* callback functions */ | 
					
						
							| 
									
										
										
										
											2012-03-22 07:26:09 +00:00
										 |  |  | 	ot->exec = reveal_metaelems_exec; | 
					
						
							|  |  |  | 	ot->poll = ED_operator_editmball; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* flags */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Select MetaElement with mouse click (user can select radius circle or
 | 
					
						
							|  |  |  |  * stiffness circle) */ | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int toggle) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	static MetaElem *startelem = NULL; | 
					
						
							|  |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	ViewContext vc; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	MetaBall *mb = (MetaBall *)obedit->data; | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 	MetaElem *ml, *ml_act = NULL; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	int a, hits; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	unsigned int buffer[4 * MAXPICKBUF]; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	rcti rect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	view3d_set_viewcontext(C, &vc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	rect.xmin = mval[0] - 12; | 
					
						
							|  |  |  | 	rect.xmax = mval[0] + 12; | 
					
						
							|  |  |  | 	rect.ymin = mval[1] - 12; | 
					
						
							|  |  |  | 	rect.ymax = mval[1] + 12; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* does startelem exist? */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = mb->editelems->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		if (ml == startelem) break; | 
					
						
							|  |  |  | 		ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	if (ml == NULL) startelem = mb->editelems->first; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	if (hits > 0) { | 
					
						
							|  |  |  | 		ml = startelem; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 		while (ml) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			for (a = 0; a < hits; a++) { | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				/* index converted for gl stuff */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 				if (ml->selcol1 == buffer[4 * a + 3]) { | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 					ml->flag |= MB_SCALE_RAD; | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 					ml_act = ml; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 				if (ml->selcol2 == buffer[4 * a + 3]) { | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 					ml->flag &= ~MB_SCALE_RAD; | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 					ml_act = ml; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 			if (ml_act) break; | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			ml = ml->next; | 
					
						
							|  |  |  | 			if (ml == NULL) ml = mb->editelems->first; | 
					
						
							|  |  |  | 			if (ml == startelem) break; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2010-07-20 10:41:08 +00:00
										 |  |  | 		/* When some metaelem was found, then it is necessary to select or
 | 
					
						
							| 
									
										
										
										
											2012-03-04 04:35:12 +00:00
										 |  |  | 		 * deselect it. */ | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 		if (ml_act) { | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			if (extend) { | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 				ml_act->flag |= SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (deselect) { | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 				ml_act->flag &= ~SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else if (toggle) { | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 				if (ml_act->flag & SELECT) | 
					
						
							|  |  |  | 					ml_act->flag &= ~SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 				else | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 					ml_act->flag |= SELECT; | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				/* Deselect all existing metaelems */ | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 				BKE_mball_deselect_all(mb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 				/* Select only metaelem clicked on */ | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 				ml_act->flag |= SELECT; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-24 21:05:27 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-10-06 03:02:14 +00:00
										 |  |  | 			mb->lastelem = ml_act; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 			WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); | 
					
						
							| 
									
										
										
										
											2009-11-24 04:59:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return 1; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-24 04:59:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*  ************* undo for MetaBalls ************* */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* free all MetaElems from ListBase */ | 
					
						
							|  |  |  | static void freeMetaElemlist(ListBase *lb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MetaElem *ml, *next; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	if (lb == NULL) return; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = lb->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		next = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		BLI_remlink(lb, ml); | 
					
						
							|  |  |  | 		MEM_freeN(ml); | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		ml = next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	lb->first = lb->last = NULL; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 14:32:55 +00:00
										 |  |  | static void undoMball_to_editMball(void *lbu, void *lbe, void *UNUSED(obe)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ListBase *lb = lbu; | 
					
						
							|  |  |  | 	ListBase *editelems = lbe; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	MetaElem *ml, *newml; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	freeMetaElemlist(editelems); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copy 'undo' MetaElems to 'edit' MetaElems */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = lb->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		newml = MEM_dupallocN(ml); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		BLI_addtail(editelems, newml); | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 14:32:55 +00:00
										 |  |  | static void *editMball_to_undoMball(void *lbe, void *UNUSED(obe)) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ListBase *editelems = lbe; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	ListBase *lb; | 
					
						
							|  |  |  | 	MetaElem *ml, *newml; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* allocate memory for undo ListBase */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	lb = MEM_callocN(sizeof(ListBase), "listbase undo"); | 
					
						
							|  |  |  | 	lb->first = lb->last = NULL; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* copy contents of current ListBase to the undo ListBase */ | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ml = editelems->first; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:38:07 +00:00
										 |  |  | 	while (ml) { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		newml = MEM_dupallocN(ml); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		BLI_addtail(lb, newml); | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 		ml = ml->next; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return lb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* free undo ListBase of MetaElems */ | 
					
						
							|  |  |  | static void free_undoMball(void *lbv) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	ListBase *lb = lbv; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	freeMetaElemlist(lb); | 
					
						
							|  |  |  | 	MEM_freeN(lb); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-14 17:55:27 +00:00
										 |  |  | static ListBase *metaball_get_editelems(Object *ob) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	if (ob && ob->type == OB_MBALL) { | 
					
						
							|  |  |  | 		struct MetaBall *mb = (struct MetaBall *)ob->data; | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 		return mb->editelems; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *get_data(bContext *C) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-08 18:29:02 +00:00
										 |  |  | 	Object *obedit = CTX_data_edit_object(C); | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | 	return metaball_get_editelems(obedit); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* this is undo system for MetaBalls */ | 
					
						
							| 
									
										
										
										
											2010-11-17 09:45:45 +00:00
										 |  |  | void undo_push_mball(bContext *C, const char *name) | 
					
						
							| 
									
										
										
										
											2009-07-29 12:35:09 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-11 10:56:21 +00:00
										 |  |  | /* matrix is 4x4 */ | 
					
						
							|  |  |  | void ED_mball_transform(MetaBall *mb, float *mat) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MetaElem *me; | 
					
						
							|  |  |  | 	float quat[4]; | 
					
						
							|  |  |  | 	const float scale = mat4_to_scale((float (*)[4])mat); | 
					
						
							|  |  |  | 	const float scale_sqrt = sqrtf(scale); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mat4_to_quat(quat, (float (*)[4])mat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (me = mb->elems.first; me; me = me->next) { | 
					
						
							|  |  |  | 		mul_m4_v3((float (*)[4])mat, &me->x); | 
					
						
							|  |  |  | 		mul_qt_qtqt(me->quat, quat, me->quat); | 
					
						
							|  |  |  | 		me->rad *= scale; | 
					
						
							|  |  |  | 		/* hrmf, probably elems shouldn't be
 | 
					
						
							|  |  |  | 		 * treating scale differently - campbell */ | 
					
						
							| 
									
										
										
										
											2013-02-11 13:07:26 +00:00
										 |  |  | 		if (!MB_TYPE_SIZE_SQUARED(me->type)) { | 
					
						
							| 
									
										
										
										
											2013-02-11 10:56:21 +00:00
										 |  |  | 			mul_v3_fl(&me->expx, scale); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			mul_v3_fl(&me->expx, scale_sqrt); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |