diff options
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 75 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 5 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 1 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 7 | ||||
-rw-r--r-- | source/blender/src/editmesh_lib.c | 56 | ||||
-rw-r--r-- | source/blender/src/transform_generics.c | 79 |
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); + } + } + } + } } } |