| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-04-11 23:20:03 +00:00
										 |  |  | * $Id$ | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | * | 
					
						
							|  |  |  | * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  | * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  | * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  | * of the License, or (at your option) any later version. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | * GNU General Public License for more details. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | * along with this program; if not, write to the Free Software  Foundation, | 
					
						
							|  |  |  | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * The Original Code is Copyright (C) 2005 by the Blender Foundation. | 
					
						
							|  |  |  | * All rights reserved. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * Contributor(s): Daniel Dunbar | 
					
						
							|  |  |  | *                 Ton Roosendaal, | 
					
						
							|  |  |  | *                 Ben Batt, | 
					
						
							|  |  |  | *                 Brecht Van Lommel, | 
					
						
							|  |  |  | *                 Campbell Barton | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-04 04:01:27 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | #include "BLI_smallhash.h"
 | 
					
						
							|  |  |  | #include "BLI_array.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_cdderivedmesh.h"
 | 
					
						
							|  |  |  | #include "BKE_mesh.h"
 | 
					
						
							|  |  |  | #include "BKE_modifier.h"
 | 
					
						
							|  |  |  | #include "BKE_deform.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | #include "BKE_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | #include "BKE_tessmesh.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | #include "depsgraph_private.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void initData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MirrorModifierData *mmd = (MirrorModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP); | 
					
						
							|  |  |  | 	mmd->tolerance = 0.001; | 
					
						
							|  |  |  | 	mmd->mirror_ob = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copyData(ModifierData *md, ModifierData *target) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MirrorModifierData *mmd = (MirrorModifierData*) md; | 
					
						
							|  |  |  | 	MirrorModifierData *tmmd = (MirrorModifierData*) target; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tmmd->axis = mmd->axis; | 
					
						
							|  |  |  | 	tmmd->flag = mmd->flag; | 
					
						
							|  |  |  | 	tmmd->tolerance = mmd->tolerance; | 
					
						
							|  |  |  | 	tmmd->mirror_ob = mmd->mirror_ob;; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void foreachObjectLink( | 
					
						
							|  |  |  | 						 ModifierData *md, Object *ob, | 
					
						
							|  |  |  | 	  void (*walk)(void *userData, Object *ob, Object **obpoin), | 
					
						
							|  |  |  | 		 void *userData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MirrorModifierData *mmd = (MirrorModifierData*) md; | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (mmd->mirror_ob) | 
					
						
							|  |  |  | 		walk(userData, ob, &mmd->mirror_ob); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), | 
					
						
							|  |  |  | 					  Object *UNUSED(ob), DagNode *obNode) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	MirrorModifierData *mmd = (MirrorModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(mmd->mirror_ob) { | 
					
						
							|  |  |  | 		DagNode *latNode = dag_get_node(forest, mmd->mirror_ob); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dag_add_relation(forest, latNode, obNode, | 
					
						
							|  |  |  | 				 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mirror Modifier"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Mirror */ | 
					
						
							|  |  |  | #define VERT_NEW	1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void vertgroup_flip_name (char *name, int strip_number); | 
					
						
							|  |  |  | DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		Object *ob, | 
					
						
							|  |  |  | 		DerivedMesh *dm, | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 		int UNUSED(initFlags), | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		int axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float tolerance = mmd->tolerance; | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	DerivedMesh *cddm, *origdm; | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 	bDeformGroup *def, *defb; | 
					
						
							|  |  |  | 	bDeformGroup **vector_def = NULL; | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	MVert *mv; | 
					
						
							|  |  |  | 	MEdge *me; | 
					
						
							|  |  |  | 	MLoop *ml; | 
					
						
							|  |  |  | 	MPoly *mp; | 
					
						
							| 
									
										
										
										
											2011-05-13 13:17:30 +00:00
										 |  |  | 	float mtx[4][4]; | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	int i, j, *vtargetmap = NULL; | 
					
						
							|  |  |  | 	BLI_array_declare(vtargetmap); | 
					
						
							| 
									
										
										
										
											2011-04-15 05:20:18 +00:00
										 |  |  | 	int vector_size=0, a, b, totshape; | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	origdm = dm; | 
					
						
							|  |  |  | 	if (!CDDM_Check(dm)) | 
					
						
							|  |  |  | 		dm = CDDM_copy(dm, 0); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 	if (mmd->flag & MOD_MIR_VGROUP) { | 
					
						
							|  |  |  | 		/* calculate the number of deformedGroups */ | 
					
						
							|  |  |  | 		for(vector_size = 0, def = ob->defbase.first; def; | 
					
						
							|  |  |  | 			def = def->next, vector_size++); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 		/* load the deformedGroups for fast access */ | 
					
						
							|  |  |  | 		vector_def = | 
					
						
							|  |  |  | 			(bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size, | 
					
						
							|  |  |  | 										 "group_index"); | 
					
						
							|  |  |  | 		for(a = 0, def = ob->defbase.first; def; def = def->next, a++) { | 
					
						
							|  |  |  | 			vector_def[a] = def; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mmd->mirror_ob) { | 
					
						
							| 
									
										
										
										
											2011-02-15 01:16:32 +00:00
										 |  |  | 		float mtx2[4][4]; | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		invert_m4_m4(mtx2, mmd->mirror_ob->obmat); | 
					
						
							|  |  |  | 		mul_m4_m4m4(mtx, ob->obmat, mtx2); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		unit_m4(mtx); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	cddm = CDDM_from_template(dm, dm->numVertData*2, dm->numEdgeData*2, 0, dm->numLoopData*2, dm->numPolyData*2); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/*copy customdata to original geometry*/ | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData); | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData); | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->loopData, &cddm->loopData, 0, 0, dm->numLoopData); | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->polyData, &cddm->polyData, 0, 0, dm->numPolyData); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*copy customdata to new geometry*/ | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, dm->numVertData, dm->numVertData); | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, dm->numEdgeData, dm->numEdgeData); | 
					
						
							|  |  |  | 	CustomData_copy_data(&dm->polyData, &cddm->polyData, 0, dm->numPolyData, dm->numPolyData); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/*mirror vertex coordinates*/ | 
					
						
							|  |  |  | 	mv = CDDM_get_verts(cddm) + dm->numVertData; | 
					
						
							|  |  |  | 	for (i=0; i<dm->numVertData; i++, mv++) { | 
					
						
							|  |  |  | 		mv->co[axis] = -mv->co[axis]; | 
					
						
							|  |  |  | 		if (fabs(mv->co[axis]) < tolerance) { | 
					
						
							|  |  |  | 			BLI_array_append(vtargetmap, i+dm->numVertData); | 
					
						
							|  |  |  | 		} else BLI_array_append(vtargetmap, -1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-04-15 05:20:18 +00:00
										 |  |  | 	/*handle shape keys*/ | 
					
						
							|  |  |  | 	totshape = CustomData_number_of_layers(&cddm->vertData, CD_SHAPEKEY); | 
					
						
							|  |  |  | 	for (a=0; a<totshape; a++) { | 
					
						
							|  |  |  | 		float (*cos)[3] = CustomData_get_layer_n(&cddm->vertData, CD_SHAPEKEY, a); | 
					
						
							|  |  |  | 		for (i=dm->numVertData; i<cddm->numVertData; i++) { | 
					
						
							|  |  |  | 			cos[i][axis] = -cos[i][axis]; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	for (i=0; i<dm->numVertData; i++) { | 
					
						
							|  |  |  | 		BLI_array_append(vtargetmap, -1); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/*adjust mirrored edge vertex indices*/ | 
					
						
							|  |  |  | 	me = CDDM_get_edges(cddm) + dm->numEdgeData; | 
					
						
							|  |  |  | 	for (i=0; i<dm->numEdgeData; i++, me++) { | 
					
						
							|  |  |  | 		me->v1 += dm->numVertData; | 
					
						
							|  |  |  | 		me->v2 += dm->numVertData; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/*adjust mirrored poly loopstart indices, and reverse loop order (normals)*/	 | 
					
						
							|  |  |  | 	mp = CDDM_get_polys(cddm) + dm->numPolyData; | 
					
						
							| 
									
										
										
										
											2011-03-31 00:06:19 +00:00
										 |  |  | 	ml = CDDM_get_loops(cddm); | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	for (i=0; i<dm->numPolyData; i++, mp++) { | 
					
						
							| 
									
										
										
										
											2011-03-31 00:06:19 +00:00
										 |  |  | 		MLoop *ml2; | 
					
						
							|  |  |  | 		int e; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 		for (j=0; j<mp->totloop; j++) { | 
					
						
							|  |  |  | 			CustomData_copy_data(&dm->loopData, &cddm->loopData, mp->loopstart+j, | 
					
						
							|  |  |  | 								 mp->loopstart+dm->numLoopData+mp->totloop-j-1, 1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-03-31 00:06:19 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		ml2 = ml + mp->loopstart + dm->numLoopData; | 
					
						
							|  |  |  | 		e = ml2[0].e; | 
					
						
							|  |  |  | 		for (j=0; j<mp->totloop-1; j++) { | 
					
						
							|  |  |  | 			ml2[j].e = ml2[j+1].e; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ml2[mp->totloop-1].e = e; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 		mp->loopstart += dm->numLoopData; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	/*adjust mirrored loop vertex and edge indices*/	 | 
					
						
							|  |  |  | 	ml = CDDM_get_loops(cddm) + dm->numLoopData; | 
					
						
							|  |  |  | 	for (i=0; i<dm->numLoopData; i++, ml++) { | 
					
						
							|  |  |  | 		ml->v += dm->numVertData; | 
					
						
							|  |  |  | 		ml->e += dm->numEdgeData; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:32:38 +00:00
										 |  |  | 	CDDM_recalc_tesselation(cddm, 1); | 
					
						
							| 
									
										
										
										
											2011-02-15 01:16:32 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 	/*handle vgroup stuff*/ | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&cddm->vertData, CD_MDEFORMVERT)) { | 
					
						
							|  |  |  | 		MDeformVert *dvert = CustomData_get_layer(&cddm->vertData, CD_MDEFORMVERT); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		for (i=0; i<dm->numVertData; i++, dvert++) { | 
					
						
							|  |  |  | 			for(j = 0; j < dvert->totweight; ++j) { | 
					
						
							|  |  |  | 				char tmpname[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(dvert->dw[j].def_nr < 0 || | 
					
						
							|  |  |  | 				   dvert->dw[j].def_nr >= vector_size) | 
					
						
							|  |  |  | 					continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				def = vector_def[dvert->dw[j].def_nr]; | 
					
						
							|  |  |  | 				strcpy(tmpname, def->name); | 
					
						
							|  |  |  | 				vertgroup_flip_name(tmpname,0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				for(b = 0, defb = ob->defbase.first; defb; | 
					
						
							|  |  |  | 					defb = defb->next, b++) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if(!strcmp(defb->name, tmpname)) | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 						dvert->dw[j].def_nr = b; | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-03-03 07:10:42 +00:00
										 |  |  | 	if (!(mmd->flag & MOD_MIR_NO_MERGE)) | 
					
						
							|  |  |  | 		cddm = CDDM_merge_verts(cddm, vtargetmap); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	BLI_array_free(vtargetmap); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-02-15 01:16:32 +00:00
										 |  |  | 	if (vector_def) MEM_freeN(vector_def); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	if (dm != origdm) { | 
					
						
							|  |  |  | 		dm->needsFree = 1; | 
					
						
							|  |  |  | 		dm->release(dm); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-02-23 00:01:50 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 	return cddm; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, | 
					
						
							|  |  |  | 						Object *ob, DerivedMesh *dm, | 
					
						
							|  |  |  | 						int initFlags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	DerivedMesh *result = dm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* check which axes have been toggled and mirror accordingly */ | 
					
						
							|  |  |  | 	if(mmd->flag & MOD_MIR_AXIS_X) { | 
					
						
							|  |  |  | 		result = doMirrorOnAxis(mmd, ob, result, initFlags, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(mmd->flag & MOD_MIR_AXIS_Y) { | 
					
						
							|  |  |  | 		DerivedMesh *tmp = result; | 
					
						
							|  |  |  | 		result = doMirrorOnAxis(mmd, ob, result, initFlags, 1); | 
					
						
							|  |  |  | 		if(tmp != dm) tmp->release(tmp); /* free intermediate results */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(mmd->flag & MOD_MIR_AXIS_Z) { | 
					
						
							|  |  |  | 		DerivedMesh *tmp = result; | 
					
						
							|  |  |  | 		result = doMirrorOnAxis(mmd, ob, result, initFlags, 2); | 
					
						
							|  |  |  | 		if(tmp != dm) tmp->release(tmp); /* free intermediate results */ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DerivedMesh *applyModifier( | 
					
						
							|  |  |  | 		ModifierData *md, Object *ob, DerivedMesh *derivedData, | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  |   int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	DerivedMesh *result; | 
					
						
							|  |  |  | 	MirrorModifierData *mmd = (MirrorModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result = mirrorModifier__doMirror(mmd, ob, derivedData, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(result != derivedData) | 
					
						
							|  |  |  | 		CDDM_calc_normals(result); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DerivedMesh *applyModifierEM( | 
					
						
							| 
									
										
										
										
											2011-02-27 07:49:36 +00:00
										 |  |  | 		ModifierData *md, Object *ob, struct BMEditMesh *UNUSED(editData), | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  |   DerivedMesh *derivedData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return applyModifier(md, ob, derivedData, 0, 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ModifierTypeInfo modifierType_Mirror = { | 
					
						
							|  |  |  | 	/* name */              "Mirror", | 
					
						
							|  |  |  | 	/* structName */        "MirrorModifierData", | 
					
						
							|  |  |  | 	/* structSize */        sizeof(MirrorModifierData), | 
					
						
							|  |  |  | 	/* type */              eModifierTypeType_Constructive, | 
					
						
							|  |  |  | 	/* flags */             eModifierTypeFlag_AcceptsMesh | 
					
						
							|  |  |  | 							| eModifierTypeFlag_SupportsMapping | 
					
						
							|  |  |  | 							| eModifierTypeFlag_SupportsEditmode | 
					
						
							|  |  |  | 							| eModifierTypeFlag_EnableInEditmode | 
					
						
							|  |  |  | 							| eModifierTypeFlag_AcceptsCVs, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copyData */          copyData, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* deformVerts */       NULL, | 
					
						
							|  |  |  | 	/* deformMatrices */    NULL, | 
					
						
							|  |  |  | 	/* deformVertsEM */     NULL, | 
					
						
							|  |  |  | 	/* deformMatricesEM */  NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* applyModifier */     applyModifier, | 
					
						
							|  |  |  | 	/* applyModifierEM */   applyModifierEM, | 
					
						
							|  |  |  | 	/* initData */          initData, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* requiredDataMask */  NULL, | 
					
						
							|  |  |  | 	/* freeData */          NULL, | 
					
						
							|  |  |  | 	/* isDisabled */        NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* updateDepgraph */    updateDepgraph, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* dependsOnTime */     NULL, | 
					
						
							|  |  |  | 	/* dependsOnNormals */	NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* foreachObjectLink */ foreachObjectLink, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* foreachIDLink */     NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | }; |