diff options
author | Chris Want <cwant@ualberta.ca> | 2007-11-13 09:56:55 +0300 |
---|---|---|
committer | Chris Want <cwant@ualberta.ca> | 2007-11-13 09:56:55 +0300 |
commit | e66f325dd7115351a40ddb72af8d347b141886c5 (patch) | |
tree | cf035bce9272602b8b0f78d7449a83d91d04999a /source/blender/blenkernel/intern | |
parent | 924f7e514612e653eea7a2b941351b62c737df62 (diff) |
==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
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 75 |
1 files changed, 64 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 9c4280166ec..c2f3880ec19 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1230,6 +1230,7 @@ static void mirrorModifier_initData(ModifierData *md) 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 @@ static void mirrorModifier_copyData(ModifierData *md, ModifierData *target) 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 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, 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,13 +1289,28 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, 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 @@ -1282,7 +1324,12 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, 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 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, *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 *doMirrorOnAxis(MirrorModifierData *mmd, } 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 @@ static DerivedMesh *mirrorModifier_applyModifier( 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 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) | 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; |