[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12574] trunk/blender/source/blender: == Mirror Modifier==

Chris Want cwant at ualberta.ca
Tue Nov 13 07:56:56 CET 2007


Revision: 12574
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12574
Author:   hos
Date:     2007-11-13 07:56:55 +0100 (Tue, 13 Nov 2007)

Log Message:
-----------
==Mirror Modifier==

Support for using the axes of a different object as the line of mirror
symmetry for a mirror modifier. As a nice consequence, this allows
"clipping" to arbitrary planes in editmode.

A fun example of using a couple of mirror modifiers and an array
modifier to easily make a nice flower type model is here:

http://bebop.cns.ualberta.ca/~cwant/chocolateC05.blend

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_modifier_types.h
    trunk/blender/source/blender/src/buttons_editing.c
    trunk/blender/source/blender/src/editmesh_lib.c
    trunk/blender/source/blender/src/transform_generics.c

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2007-11-12 23:19:33 UTC (rev 12573)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2007-11-13 06:56:55 UTC (rev 12574)
@@ -1230,6 +1230,7 @@
 
 	mmd->flag |= MOD_MIR_AXIS_X;
 	mmd->tolerance = 0.001;
+	mmd->mirror_ob = NULL;
 }
 
 static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
@@ -1240,12 +1241,37 @@
 	tmmd->axis = mmd->axis;
 	tmmd->flag = mmd->flag;
 	tmmd->tolerance = mmd->tolerance;
+	tmmd->mirror_ob = mmd->mirror_ob;;
 }
 
+static void mirrorModifier_foreachObjectLink(
+                ModifierData *md, Object *ob,
+                void (*walk)(void *userData, Object *ob, Object **obpoin),
+                void *userData)
+{
+	MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+	walk(userData, ob, &mmd->mirror_ob);
+}
+
+static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+										  Object *ob, DagNode *obNode)
+{
+	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);
+	}
+}
+
 static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
-						   DerivedMesh *dm,
-						   int initFlags,
-						   int axis)
+								   Object *ob,
+								   DerivedMesh *dm,
+								   int initFlags,
+								   int axis)
 {
 	int i;
 	float tolerance = mmd->tolerance;
@@ -1255,6 +1281,7 @@
 	int maxEdges = dm->getNumEdges(dm);
 	int maxFaces = dm->getNumFaces(dm);
 	int (*indexMap)[2];
+	float mtx[4][4], imtx[4][4];
 
 	numVerts = numEdges = numFaces = 0;
 
@@ -1262,14 +1289,29 @@
 
 	result = CDDM_from_template(dm, maxVerts * 2, maxEdges * 2, maxFaces * 2);
 
+	if (mmd->mirror_ob) {
+		float obinv[4][4];
+
+		Mat4Invert(obinv, mmd->mirror_ob->obmat);
+		Mat4MulMat4(mtx, ob->obmat, obinv);
+		Mat4Invert(imtx, mtx);
+	}
+
 	for(i = 0; i < maxVerts; i++) {
 		MVert inMV;
 		MVert *mv = CDDM_get_vert(result, numVerts);
 		int isShared;
+		float co[3];
 
 		dm->getVert(dm, i, &inMV);
-		isShared = ABS(inMV.co[axis])<=tolerance;
 
+		VecCopyf(co, inMV.co);
+
+		if (mmd->mirror_ob) {
+			VecMat4MulVecfl(co, mtx, co);
+		}
+		isShared = ABS(co[axis])<=tolerance;
+
 		/* Because the topology result (# of vertices) must be the same if
 		 * the mesh data is overridden by vertex cos, have to calc sharedness
 		 * based on original coordinates. This is why we test before copy.
@@ -1282,7 +1324,12 @@
 		indexMap[i][1] = !isShared;
 
 		if(isShared) {
-			mv->co[axis] = 0;
+			co[axis] = 0;
+			if (mmd->mirror_ob) {
+				VecMat4MulVecfl(co, imtx, co);
+			}
+			VecCopyf(mv->co, co);
+			
 			mv->flag |= ME_VERT_MERGED;
 		} else {
 			MVert *mv2 = CDDM_get_vert(result, numVerts);
@@ -1291,7 +1338,11 @@
 			*mv2 = *mv;
 			numVerts++;
 
-			mv2->co[axis] = -mv2->co[axis];
+			co[axis] = -co[axis];
+			if (mmd->mirror_ob) {
+				VecMat4MulVecfl(co, imtx, co);
+			}
+			VecCopyf(mv2->co, co);
 		}
 	}
 
@@ -1385,23 +1436,23 @@
 }
 
 static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
-                                             DerivedMesh *dm,
+											 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, result, initFlags, 0);
+		result = doMirrorOnAxis(mmd, ob, result, initFlags, 0);
 	}
 	if(mmd->flag & MOD_MIR_AXIS_Y) {
 		DerivedMesh *tmp = result;
-		result = doMirrorOnAxis(mmd, result, initFlags, 1);
+		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, result, initFlags, 2);
+		result = doMirrorOnAxis(mmd, ob, result, initFlags, 2);
 		if(tmp != dm) tmp->release(tmp); /* free intermediate results */
 	}
 
@@ -1415,7 +1466,7 @@
 	DerivedMesh *result;
 	MirrorModifierData *mmd = (MirrorModifierData*) md;
 
-	result = mirrorModifier__doMirror(mmd, derivedData, 0);
+	result = mirrorModifier__doMirror(mmd, ob, derivedData, 0);
 
 	CDDM_calc_normals(result);
 	
@@ -5313,6 +5364,8 @@
 		             | eModifierTypeFlag_EnableInEditmode;
 		mti->initData = mirrorModifier_initData;
 		mti->copyData = mirrorModifier_copyData;
+		mti->foreachObjectLink = mirrorModifier_foreachObjectLink;
+		mti->updateDepgraph = mirrorModifier_updateDepgraph;
 		mti->applyModifier = mirrorModifier_applyModifier;
 		mti->applyModifierEM = mirrorModifier_applyModifierEM;
 

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2007-11-12 23:19:33 UTC (rev 12573)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2007-11-13 06:56:55 UTC (rev 12574)
@@ -7456,6 +7456,11 @@
 		expand_doit(fd, mainvar, amd->curve_ob);
 		expand_doit(fd, mainvar, amd->offset_ob);
 	}
+	else if (md->type==eModifierType_Mirror) {
+		MirrorModifierData *mmd = (MirrorModifierData*) md;
+			
+		expand_doit(fd, mainvar, mmd->mirror_ob);
+	}
 }
 
 static void expand_scriptlink(FileData *fd, Main *mainvar, ScriptLink *slink)

Modified: trunk/blender/source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2007-11-12 23:19:33 UTC (rev 12573)
+++ trunk/blender/source/blender/makesdna/DNA_modifier_types.h	2007-11-13 06:56:55 UTC (rev 12574)
@@ -160,6 +160,7 @@
 
 	short axis, flag;
 	float tolerance;
+	struct Object *mirror_ob;
 } MirrorModifierData;
 
 /* MirrorModifierData->flag */

Modified: trunk/blender/source/blender/src/buttons_editing.c
===================================================================
--- trunk/blender/source/blender/src/buttons_editing.c	2007-11-12 23:19:33 UTC (rev 12573)
+++ trunk/blender/source/blender/src/buttons_editing.c	2007-11-13 06:56:55 UTC (rev 12574)
@@ -1604,7 +1604,7 @@
 		} else if (md->type==eModifierType_Build) {
 			height = 86;
 		} else if (md->type==eModifierType_Mirror) {
-			height = 67;
+			height = 86;
 		} else if (md->type==eModifierType_EdgeSplit) {
 			EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
 			height = 48;
@@ -1728,6 +1728,11 @@
 			             &mmd->flag, 0, 0, 0, 0,
 			             "Mirror the V texture coordinate around "
 			             "the 0.5 point");
+			uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP,
+			               "Ob: ", lx, (cy -= 19), buttonWidth, 19,
+			               &mmd->mirror_ob,
+			               "Object to use as mirrot");
+
 		} else if (md->type==eModifierType_EdgeSplit) {
 			EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md;
 			uiDefButBitI(block, TOG, MOD_EDGESPLIT_FROMANGLE,

Modified: trunk/blender/source/blender/src/editmesh_lib.c
===================================================================
--- trunk/blender/source/blender/src/editmesh_lib.c	2007-11-12 23:19:33 UTC (rev 12573)
+++ trunk/blender/source/blender/src/editmesh_lib.c	2007-11-13 06:56:55 UTC (rev 12574)
@@ -1142,22 +1142,38 @@
 			MirrorModifierData *mmd = (MirrorModifierData*) md;	
 		
 			if(mmd->flag & MOD_MIR_CLIPPING) {
+				float mtx[4][4];
+				if (mmd->mirror_ob) {
+					float imtx[4][4];
+					Mat4Invert(imtx, mmd->mirror_ob->obmat);
+					Mat4MulMat4(mtx, G.obedit->obmat, imtx);
+				}
+
 				for (eed= em->edges.first; eed; eed= eed->next) {
 					if(eed->f2 == 1) {
+						float co1[3], co2[3];
 
+						VecCopyf(co1, eed->v1->co);
+						VecCopyf(co2, eed->v2->co);
+
+						if (mmd->mirror_ob) {
+							VecMat4MulVecfl(co1, mtx, co1);
+							VecMat4MulVecfl(co2, mtx, co2);
+						}
+
 						if (mmd->flag & MOD_MIR_AXIS_X)
-							if ( (fabs(eed->v1->co[0]) < mmd->tolerance) &&
-								 (fabs(eed->v2->co[0]) < mmd->tolerance) )
+							if ( (fabs(co1[0]) < mmd->tolerance) &&
+								 (fabs(co2[0]) < mmd->tolerance) )
 								++eed->f2;
 
 						if (mmd->flag & MOD_MIR_AXIS_Y)
-							if ( (fabs(eed->v1->co[1]) < mmd->tolerance) &&
-								 (fabs(eed->v2->co[1]) < mmd->tolerance) )
+							if ( (fabs(co1[1]) < mmd->tolerance) &&
+								 (fabs(co2[1]) < mmd->tolerance) )
 								++eed->f2;
 
 						if (mmd->flag & MOD_MIR_AXIS_Z)
-							if ( (fabs(eed->v1->co[2]) < mmd->tolerance) &&
-								 (fabs(eed->v2->co[2]) < mmd->tolerance) )
+							if ( (fabs(co1[2]) < mmd->tolerance) &&
+								 (fabs(co2[2]) < mmd->tolerance) )
 								++eed->f2;
 					}
 				}
@@ -1408,21 +1424,37 @@
 			MirrorModifierData *mmd = (MirrorModifierData*) md;	
 		
 			if(mmd->flag & MOD_MIR_CLIPPING) {
+				float mtx[4][4];
+				if (mmd->mirror_ob) {
+					float imtx[4][4];
+					Mat4Invert(imtx, mmd->mirror_ob->obmat);
+					Mat4MulMat4(mtx, G.obedit->obmat, imtx);
+				}
+
 				for (eed= em->edges.first; eed; eed= eed->next) {
 					if(eed->f2 == 2) {
+						float co1[3], co2[3];
 
+						VecCopyf(co1, eed->v1->co);
+						VecCopyf(co2, eed->v2->co);
+
+						if (mmd->mirror_ob) {
+							VecMat4MulVecfl(co1, mtx, co1);
+							VecMat4MulVecfl(co2, mtx, co2);
+						}
+
 						if (mmd->flag & MOD_MIR_AXIS_X)
-							if ( (fabs(eed->v1->co[0]) < mmd->tolerance) &&
-								 (fabs(eed->v2->co[0]) < mmd->tolerance) )
+							if ( (fabs(co1[0]) < mmd->tolerance) &&
+								 (fabs(co2[0]) < mmd->tolerance) )
 								++eed->f2;
 
 						if (mmd->flag & MOD_MIR_AXIS_Y)
-							if ( (fabs(eed->v1->co[1]) < mmd->tolerance) &&
-								 (fabs(eed->v2->co[1]) < mmd->tolerance) )
+							if ( (fabs(co1[1]) < mmd->tolerance) &&
+								 (fabs(co2[1]) < mmd->tolerance) )
 								++eed->f2;
 						if (mmd->flag & MOD_MIR_AXIS_Z)
-							if ( (fabs(eed->v1->co[2]) < mmd->tolerance) &&
-								 (fabs(eed->v2->co[2]) < mmd->tolerance) )
+							if ( (fabs(co1[2]) < mmd->tolerance) &&
+								 (fabs(co2[2]) < mmd->tolerance) )
 								++eed->f2;
 					}
 				}

Modified: trunk/blender/source/blender/src/transform_generics.c
===================================================================
--- trunk/blender/source/blender/src/transform_generics.c	2007-11-12 23:19:33 UTC (rev 12573)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list