Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Want <cwant@ualberta.ca>2007-11-13 09:56:55 +0300
committerChris Want <cwant@ualberta.ca>2007-11-13 09:56:55 +0300
commite66f325dd7115351a40ddb72af8d347b141886c5 (patch)
treecf035bce9272602b8b0f78d7449a83d91d04999a
parent924f7e514612e653eea7a2b941351b62c737df62 (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
-rw-r--r--source/blender/blenkernel/intern/modifier.c75
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/src/buttons_editing.c7
-rw-r--r--source/blender/src/editmesh_lib.c56
-rw-r--r--source/blender/src/transform_generics.c79
6 files changed, 180 insertions, 43 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;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2e4c56dbc9c..3cb615bb74b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -7456,6 +7456,11 @@ static void expand_modifier(FileData *fd, Main *mainvar, ModifierData *md)
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)
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 80011c233a8..c55ae752ffb 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -160,6 +160,7 @@ typedef struct MirrorModifierData {
short axis, flag;
float tolerance;
+ struct Object *mirror_ob;
} MirrorModifierData;
/* MirrorModifierData->flag */
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index affa06ae6b2..24964b30ce9 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1604,7 +1604,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
} 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 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
&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,
diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c
index 14a522bdbff..d9b8fa93eb9 100644
--- a/source/blender/src/editmesh_lib.c
+++ b/source/blender/src/editmesh_lib.c
@@ -1142,22 +1142,38 @@ static short extrudeflag_edge(short flag, float *nor)
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 @@ short extrudeflag_vert(short flag, float *nor)
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;
}
}
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index bf9de8d4e3f..72937fb10b6 100644
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -154,6 +154,7 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
MirrorModifierData *mmd = (MirrorModifierData*) md;
if(mmd->flag & MOD_MIR_CLIPPING) {
+ axis = 0;
if(mmd->flag & MOD_MIR_AXIS_X) {
axis |= 1;
tolerance[0] = mmd->tolerance;
@@ -166,28 +167,68 @@ static void clipMirrorModifier(TransInfo *t, Object *ob)
axis |= 4;
tolerance[2] = mmd->tolerance;
}
- }
- }
- }
- if (axis) {
- TransData *td = t->data;
- int i;
+ if (axis) {
+ float mtx[4][4], imtx[4][4];
+ int i;
+ TransData *td = t->data;
- for(i = 0 ; i < t->total; i++, td++) {
- if (td->flag & TD_NOACTION)
- break;
- if (td->loc==NULL)
- break;
+ 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 < t->total; i++, td++) {
+ int clip;
+ float loc[3], iloc[3];
+
+ if (td->flag & TD_NOACTION)
+ break;
+ if (td->loc==NULL)
+ break;
- if(axis & 1) {
- if(fabs(td->iloc[0])<=tolerance[0] || td->loc[0]*td->iloc[0]<0.0f) td->loc[0]= 0.0f;
- }
+ VecCopyf(loc, td->loc);
+ VecCopyf(iloc, td->iloc);
+
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(loc, mtx, loc);
+ VecMat4MulVecfl(iloc, mtx, iloc);
+ }
+
+ clip = 0;
+ if(axis & 1) {
+ if(fabs(iloc[0])<=tolerance[0] ||
+ loc[0]*iloc[0]<0.0f) {
+ loc[0]= 0.0f;
+ clip = 1;
+ }
+ }
- if(axis & 2) {
- if(fabs(td->iloc[1])<=tolerance[1] || td->loc[1]*td->iloc[1]<0.0f) td->loc[1]= 0.0f;
- }
- if(axis & 4) {
- if(fabs(td->iloc[2])<=tolerance[2] || td->loc[2]*td->iloc[2]<0.0f) td->loc[2]= 0.0f;
+ if(axis & 2) {
+ if(fabs(iloc[1])<=tolerance[1] ||
+ loc[1]*iloc[1]<0.0f) {
+ loc[1]= 0.0f;
+ clip = 1;
+ }
+ }
+ if(axis & 4) {
+ if(fabs(iloc[2])<=tolerance[2] ||
+ loc[2]*iloc[2]<0.0f) {
+ loc[2]= 0.0f;
+ clip = 1;
+ }
+ }
+ if (clip) {
+ if (mmd->mirror_ob) {
+ VecMat4MulVecfl(loc, imtx, loc);
+ }
+ VecCopyf(td->loc, loc);
+ }
+ }
+ }
+
}
}
}