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:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_mirror.c')
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c267
1 files changed, 267 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
new file mode 100644
index 00000000000..2b9fa45ae9b
--- /dev/null
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -0,0 +1,267 @@
+/*
+* $Id$
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2005 by the Blender Foundation.
+* All rights reserved.
+*
+* Contributor(s): Daniel Dunbar
+* Ton Roosendaal,
+* Ben Batt,
+* Brecht Van Lommel,
+* Campbell Barton
+*
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
+
+
+#include "DNA_meshdata_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_cdderivedmesh.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_deform.h"
+#include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
+
+#include "MEM_guardedalloc.h"
+#include "depsgraph_private.h"
+
+static void initData(ModifierData *md)
+{
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ mmd->flag |= (MOD_MIR_AXIS_X | MOD_MIR_VGROUP);
+ mmd->tolerance = 0.001;
+ mmd->mirror_ob = NULL;
+}
+
+static void copyData(ModifierData *md, ModifierData *target)
+{
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+ MirrorModifierData *tmmd = (MirrorModifierData*) target;
+
+ tmmd->axis = mmd->axis;
+ tmmd->flag = mmd->flag;
+ tmmd->tolerance = mmd->tolerance;
+ tmmd->mirror_ob = mmd->mirror_ob;;
+}
+
+static void 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 updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *scene,
+ 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, "Mirror Modifier");
+ }
+}
+
+
+/* Mirror */
+#define VERT_NEW 1
+
+void vertgroup_flip_name (char *name, int strip_number);
+DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
+ Object *ob,
+ DerivedMesh *dm,
+ int initFlags,
+ int axis)
+{
+ float tolerance = mmd->tolerance;
+ DerivedMesh *result, *cddm;
+ BMEditMesh *em;
+ BMesh *bm;
+ BMOIter siter1;
+ BMOperator op;
+ BMVert *v1;
+ int vector_size=0, a, b;
+ bDeformGroup *def, *defb;
+ bDeformGroup **vector_def = NULL;
+ float mtx[4][4], imtx[4][4];
+ int j;
+
+ cddm = dm; //copying shouldn't be necassary here, as all modifiers return CDDM's
+ em = CDDM_To_BMesh(dm, NULL);
+
+ /*convienence variable*/
+ bm = em->bm;
+
+ if (mmd->flag & MOD_MIR_VGROUP) {
+ /* calculate the number of deformedGroups */
+ for(vector_size = 0, def = ob->defbase.first; def;
+ def = def->next, vector_size++);
+
+ /* load the deformedGroups for fast access */
+ vector_def =
+ (bDeformGroup **)MEM_mallocN(sizeof(bDeformGroup*) * vector_size,
+ "group_index");
+ for(a = 0, def = ob->defbase.first; def; def = def->next, a++) {
+ vector_def[a] = def;
+ }
+ }
+
+ if (mmd->mirror_ob) {
+ float mtx2[4][4], vec[3];
+
+ invert_m4_m4(mtx2, mmd->mirror_ob->obmat);
+ mul_m4_m4m4(mtx, ob->obmat, mtx2);
+ } else {
+ unit_m4(mtx);
+ }
+
+ BMO_InitOpf(bm, &op, "mirror geom=%avef mat=%m4 mergedist=%f axis=%d",
+ mtx, mmd->tolerance, axis);
+
+ BMO_Exec_Op(bm, &op);
+
+ BMO_CallOpf(bm, "reversefaces faces=%s", &op, "newout");
+
+ /*handle vgroup stuff*/
+ if (mmd->flag & MOD_MIR_VGROUP) {
+ BMO_ITER(v1, &siter1, bm, &op, "newout", BM_VERT) {
+ MDeformVert *dvert = CustomData_bmesh_get(&bm->vdata, v1->head.data, CD_MDEFORMVERT);
+
+ if (dvert) {
+ for(j = 0; j < dvert[0].totweight; ++j) {
+ char tmpname[32];
+
+ if(dvert->dw[j].def_nr < 0 ||
+ dvert->dw[j].def_nr >= vector_size)
+ continue;
+
+ def = vector_def[dvert->dw[j].def_nr];
+ strcpy(tmpname, def->name);
+ vertgroup_flip_name(tmpname,0);
+
+ for(b = 0, defb = ob->defbase.first; defb;
+ defb = defb->next, b++)
+ {
+ if(!strcmp(defb->name, tmpname))
+ {
+ dvert->dw[j].def_nr = b;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ BMO_Finish_Op(bm, &op);
+
+ BMEdit_RecalcTesselation(em);
+ result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL), 0);
+
+ BMEdit_Free(em);
+ MEM_freeN(em);
+
+ if (vector_def) MEM_freeN(vector_def);
+
+ return result;
+}
+
+static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
+ 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, ob, result, initFlags, 0);
+ }
+ if(mmd->flag & MOD_MIR_AXIS_Y) {
+ DerivedMesh *tmp = result;
+ 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, ob, result, initFlags, 2);
+ if(tmp != dm) tmp->release(tmp); /* free intermediate results */
+ }
+
+ return result;
+}
+
+static DerivedMesh *applyModifier(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ int useRenderParams, int isFinalCalc)
+{
+ DerivedMesh *result;
+ MirrorModifierData *mmd = (MirrorModifierData*) md;
+
+ result = mirrorModifier__doMirror(mmd, ob, derivedData, 0);
+
+ if(result != derivedData)
+ CDDM_calc_normals(result);
+
+ return result;
+}
+
+static DerivedMesh *applyModifierEM(
+ ModifierData *md, Object *ob, struct EditMesh *editData,
+ DerivedMesh *derivedData)
+{
+ return applyModifier(md, ob, derivedData, 0, 1);
+}
+
+
+ModifierTypeInfo modifierType_Mirror = {
+ /* name */ "Mirror",
+ /* structName */ "MirrorModifierData",
+ /* structSize */ sizeof(MirrorModifierData),
+ /* type */ eModifierTypeType_Constructive,
+ /* flags */ eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_SupportsMapping
+ | eModifierTypeFlag_SupportsEditmode
+ | eModifierTypeFlag_EnableInEditmode
+ | eModifierTypeFlag_AcceptsCVs,
+
+ /* copyData */ copyData,
+ /* deformVerts */ 0,
+ /* deformVertsEM */ 0,
+ /* deformMatricesEM */ 0,
+ /* applyModifier */ applyModifier,
+ /* applyModifierEM */ applyModifierEM,
+ /* initData */ initData,
+ /* requiredDataMask */ 0,
+ /* freeData */ 0,
+ /* isDisabled */ 0,
+ /* updateDepgraph */ updateDepgraph,
+ /* dependsOnTime */ 0,
+ /* foreachObjectLink */ foreachObjectLink,
+ /* foreachIDLink */ 0,
+};