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:
authorDaniel Dunbar <daniel@zuster.org>2005-07-20 11:11:26 +0400
committerDaniel Dunbar <daniel@zuster.org>2005-07-20 11:11:26 +0400
commitdc232fda472ac6e25578455ec4345a4e3fea1596 (patch)
treef926d7c2daf0b693b2055d30293673bf7e4507b5
parenteb9d466b486339aeee879917bc02e686bc2fa049 (diff)
Wow! A new feature!
- made ModifierData.isDisabled optional - Added new modifier type: Mirror o modifier system isn't running in editmode yet so still don't have mirrored editing, but otherwise it is pretty cool. code even goes to tricks to make sure mirror join looks nice in degenerate cases. o this kind of commit is basically the upshot of all the previous commits - in that implementing a new modifier changes only about 3 files and still integrates nearly completely.
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/modifier.c239
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h8
-rw-r--r--source/blender/src/buttons_object.c6
5 files changed, 244 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 9e10e77dfe7..b0736a1ab72 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -76,7 +76,7 @@ typedef struct ModifierTypeInfo {
* tested by the system, this is just if the data validates (for example, a
* lattice will return false if the lattice object is not defined).
*
- * This function must be present.
+ * This function is optional (assumes never disabled if not present).
*/
int (*isDisabled)(struct ModifierData *md);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 6ad09edee43..b5a22913be6 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1022,7 +1022,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
ModifierTypeInfo *mti = modifierType_get_info(md->type);
if (!(md->mode&(1<<useRenderParams))) continue;
- if (mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md)) continue;
if (mti->type==eModifierTypeType_OnlyDeform) {
mti->deformVerts(md, ob, deformedVerts, numVerts);
@@ -1049,7 +1049,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
if (!(md->mode&(1<<useRenderParams))) continue;
if (mti->type==eModifierTypeType_OnlyDeform && !useDeform) continue;
- if (mti->isDisabled(md)) continue;
+ if (mti->isDisabled && mti->isDisabled(md)) continue;
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 49c6c5186b2..709d6f0cd40 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -118,11 +118,6 @@ static ModifierData *subsurfModifier_allocData(void)
return (ModifierData*) smd;
}
-static int subsurfModifier_isDisabled(ModifierData *md)
-{
- return 0;
-}
-
static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
{
SubsurfModifierData *smd = (SubsurfModifierData*) md;
@@ -163,11 +158,6 @@ static ModifierData *buildModifier_allocData(void)
return (ModifierData*) bmd;
}
-static int buildModifier_isDisabled(ModifierData *md)
-{
- return 0;
-}
-
static int buildModifier_dependsOnTime(ModifierData *md)
{
return 1;
@@ -381,6 +371,225 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
return derivedmesh_from_displistmesh(ndlm);
}
+/* Mirror */
+
+static ModifierData *mirrorModifier_allocData(void)
+{
+ MirrorModifierData *mmd = allocModifierData(eModifierType_Mirror, sizeof(MirrorModifierData));
+
+ mmd->axis = 0;
+ mmd->tolerance = 0.001;
+
+ return (ModifierData*) mmd;
+}
+
+static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
+{
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+ DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*dlm), "mm_dlm");
+ MVert *mvert;
+ MEdge *medge;
+ MFace *mface;
+ TFace *tface;
+ MCol *mcol;
+ int i, j, totvert, totedge, totface;
+ int axis = mmd->axis;
+ float tolerance = mmd->tolerance;
+
+ if (dm) {
+ dlm = dm->convertToDispListMesh(dm);
+
+ mvert = dlm->mvert;
+ medge = dlm->medge;
+ mface = dlm->mface;
+ tface = dlm->tface;
+ mcol = dlm->mcol;
+ totvert = dlm->totvert;
+ totedge = dlm->totedge;
+ totface = dlm->totface;
+ } else {
+ Mesh *me = ob->data;
+
+ mvert = me->mvert;
+ medge = me->medge;
+ mface = me->mface;
+ tface = me->tface;
+ mcol = me->mcol;
+ totvert = me->totvert;
+ totedge = me->totedge;
+ totface = me->totface;
+ }
+
+ ndlm->mvert = MEM_mallocN(sizeof(*mvert)*totvert*2, "mm_mv");
+ for (i=0,j=totvert; i<totvert; i++) {
+ MVert *mv = &mvert[i];
+ MVert *nmv = &ndlm->mvert[i];
+
+ memcpy(nmv, mv, sizeof(*mv));
+
+ if (ABS(nmv->co[axis])<=tolerance) {
+ nmv->co[axis] = 0;
+ *((int*) nmv->no) = i;
+ } else {
+ MVert *nmvMirror = &ndlm->mvert[j];
+
+ /* Because the topology result (# of vertices) must stuff the same
+ * if the mesh data is overridden by vertex cos, have to calc sharedness
+ * based on original coordinates. Only write new cos for non-shared
+ * vertices.
+ */
+ if (vertexCos) {
+ VECCOPY(nmv->co, vertexCos[i]);
+ }
+
+ memcpy(nmvMirror, nmv, sizeof(*mv));
+ nmvMirror->co[axis] = -nmvMirror->co[axis];
+
+ *((int*) nmv->no) = j++;
+ }
+ }
+ ndlm->totvert = j;
+
+ if (medge) {
+ ndlm->medge = MEM_mallocN(sizeof(*medge)*totedge*2, "mm_med");
+ memcpy(ndlm->medge, medge, sizeof(*medge)*totedge);
+ ndlm->totedge = totedge;
+
+ for (i=0; i<totedge; i++) {
+ MEdge *med = &ndlm->medge[i];
+ MEdge *nmed = &ndlm->medge[ndlm->totedge];
+
+ memcpy(nmed, med, sizeof(*med));
+
+ nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
+ nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
+
+ if (nmed->v1!=med->v1 || nmed->v2!=med->v2) {
+ ndlm->totedge++;
+ }
+ }
+ }
+
+ ndlm->mface = MEM_mallocN(sizeof(*mface)*totface*2, "mm_mf");
+ memcpy(ndlm->mface, mface, sizeof(*mface)*totface);
+
+ if (tface) {
+ ndlm->tface = MEM_mallocN(sizeof(*tface)*totface*2, "mm_tf");
+ memcpy(ndlm->tface, tface, sizeof(*tface)*totface);
+ } else if (mcol) {
+ ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*totface*2, "mm_mcol");
+ memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*totface);
+ }
+
+ ndlm->totface = totface;
+ for (i=0; i<totface; i++) {
+ MFace *mf = &ndlm->mface[i];
+ MFace *nmf = &ndlm->mface[ndlm->totface];
+ TFace *tf, *ntf;
+ MCol *mc, *nmc;
+
+ memcpy(nmf, mf, sizeof(*mf));
+ if (tface) {
+ ntf = &ndlm->tface[ndlm->totface];
+ tf = &ndlm->tface[i];
+ memcpy(ntf, tf, sizeof(*tface));
+ } else if (mcol) {
+ nmc = &ndlm->mcol[ndlm->totface*4];
+ mc = &ndlm->mcol[i*4];
+ memcpy(nmc, mc, sizeof(*mcol)*4);
+ }
+
+ /* Map vertices to shared */
+
+ nmf->v1 = *((int*) ndlm->mvert[nmf->v1].no);
+ nmf->v2 = *((int*) ndlm->mvert[nmf->v2].no);
+ if (nmf->v3) {
+ nmf->v3 = *((int*) ndlm->mvert[nmf->v3].no);
+ if (nmf->v4) nmf->v4 = *((int*) ndlm->mvert[nmf->v4].no);
+ }
+
+ /* If all vertices shared don't duplicate face */
+ if (nmf->v1==mf->v1 && nmf->v2==mf->v2 && nmf->v3==mf->v3 && nmf->v4==mf->v4)
+ continue;
+
+ if (nmf->v3) {
+ if (nmf->v4) {
+ int copyIdx;
+
+ /* If three in order vertices are shared then duplicating the face
+ * will be strange (don't want two quads sharing three vertices in a
+ * mesh. Instead modify the original quad to leave out the middle vertice
+ * and span the gap. Vertice will remain in mesh and still have edges
+ * to it but will not interfere with normals.
+ */
+ if (nmf->v4==mf->v4 && nmf->v1==mf->v1 && nmf->v2==mf->v2) {
+ mf->v1 = nmf->v3;
+ copyIdx = 0;
+ } else if (nmf->v1==mf->v1 && nmf->v2==mf->v2 && nmf->v3==mf->v3) {
+ mf->v2 = nmf->v4;
+ copyIdx = 1;
+ } else if (nmf->v2==mf->v2 && nmf->v3==mf->v3 && nmf->v4==mf->v4) {
+ mf->v3 = nmf->v1;
+ copyIdx = 2;
+ } else if (nmf->v3==mf->v3 && nmf->v4==mf->v4 && nmf->v1==mf->v1) {
+ mf->v4 = nmf->v2;
+ copyIdx = 3;
+ } else {
+ copyIdx = -1;
+ }
+
+ if (copyIdx!=-1) {
+ int fromIdx = (copyIdx+2)%4;
+
+ if (tface) {
+ tf->col[copyIdx] = ntf->col[fromIdx];
+ tf->uv[copyIdx][0] = ntf->uv[fromIdx][0];
+ tf->uv[copyIdx][1] = ntf->uv[fromIdx][1];
+ } else if (mcol) {
+ mc[copyIdx] = nmc[fromIdx];
+ }
+
+ continue;
+ }
+ }
+
+ /* Need to flip face normal, pick which verts to flip
+ * in order to prevent nmf->v3==0 or nmf->v4==0
+ */
+ if (nmf->v1) {
+ SWAP(int, nmf->v1, nmf->v3);
+
+ if (tface) {
+ SWAP(unsigned int, ntf->col[0], ntf->col[2]);
+ SWAP(float, ntf->uv[0][0], ntf->uv[2][0]);
+ SWAP(float, ntf->uv[0][1], ntf->uv[2][1]);
+ } else if (mcol) {
+ SWAP(MCol, nmc[0], nmc[2]);
+ }
+ } else {
+ SWAP(int, nmf->v2, nmf->v4);
+
+ if (tface) {
+ SWAP(unsigned int, ntf->col[1], ntf->col[3]);
+ SWAP(float, ntf->uv[1][0], ntf->uv[3][0]);
+ SWAP(float, ntf->uv[1][1], ntf->uv[3][1]);
+ } else if (mcol) {
+ SWAP(MCol, nmc[1], nmc[3]);
+ }
+ }
+ }
+
+ ndlm->totface++;
+ }
+
+ if (dlm) displistmesh_free(dlm);
+ if (dm) dm->release(dm);
+
+ mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
+
+ return derivedmesh_from_displistmesh(ndlm);
+}
+
/***/
static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -427,7 +636,6 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
mti->allocData = subsurfModifier_allocData;
- mti->isDisabled = subsurfModifier_isDisabled;
mti->applyModifier = subsurfModifier_applyModifier;
mti = &typeArr[eModifierType_Build];
@@ -436,10 +644,17 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
mti->type = eModifierTypeType_Nonconstructive;
mti->flags = eModifierTypeFlag_AcceptsMesh;
mti->allocData = buildModifier_allocData;
- mti->isDisabled = buildModifier_isDisabled;
mti->dependsOnTime = buildModifier_dependsOnTime;
mti->applyModifier = buildModifier_applyModifier;
+ mti = &typeArr[eModifierType_Mirror];
+ strcpy(mti->name, "Mirror");
+ strcpy(mti->structName, "MirrorModifierData");
+ mti->type = eModifierTypeType_Constructive;
+ mti->flags = eModifierTypeFlag_AcceptsMesh;
+ mti->allocData = mirrorModifier_allocData;
+ mti->applyModifier = mirrorModifier_applyModifier;
+
typeArrInit = 0;
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index baa2a77bf10..5eb00c4f21b 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -11,6 +11,7 @@ typedef enum ModifierType {
eModifierType_Lattice,
eModifierType_Curve,
eModifierType_Build,
+ eModifierType_Mirror,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -57,4 +58,11 @@ typedef struct BuildModifierData {
int randomize, seed;
} BuildModifierData;
+typedef struct MirrorModifierData {
+ ModifierData modifier;
+
+ int axis;
+ float tolerance;
+} MirrorModifierData;
+
#endif
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 4f3e6ec9fcb..204f580096e 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -1832,6 +1832,12 @@ static void object_panel_modifiers(Object *ob)
uiDefButF(block, NUM, B_MAKEDISP, "Length:", 550, 300, 150,19, &bmd->length, 1.0, 9000.0, 100, 0, "Specify the total time the build effect requires");
uiDefButI(block, TOG, B_MAKEDISP, "Randomize", 550, 280, 150,19, &bmd->randomize, 0, 0, 1, 0, "Randomize the faces or edges during build.");
uiDefButI(block, NUM, B_MAKEDISP, "Seed:", 700, 280, 150,19, &bmd->seed, 1.0, 9000.0, 100, 0, "Specify the seed for random if used.");
+ } else if (md->type==eModifierType_Mirror) {
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+ uiDefButF(block, NUM, B_MAKEDISP, "Tolerance:", 550, 320, 150,19, &mmd->tolerance, 0.0, 1, 0, 0, "Distance from axis within which to share vertices");
+ uiDefButI(block, ROW, B_MAKEDISP, "X", 550, 300, 20,19, &mmd->axis, 1, 0, 0, 0, "Specify the axis to mirror about");
+ uiDefButI(block, ROW, B_MAKEDISP, "Y", 570, 300, 20,19, &mmd->axis, 1, 1, 0, 0, "Specify the axis to mirror about");
+ uiDefButI(block, ROW, B_MAKEDISP, "Z", 590, 300, 20,19, &mmd->axis, 1, 2, 0, 0, "Specify the axis to mirror about");
}
uiBlockEndAlign(block);