diff options
author | Joseph Eagar <joeedh@gmail.com> | 2011-03-25 03:32:38 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2011-03-25 03:32:38 +0300 |
commit | d88bb9115f836d8c6516104378683480a2cc64dc (patch) | |
tree | 6b7e5ee3c0218f105f6630ef04f0c4495b389930 /source/blender/modifiers | |
parent | 8fb3ab5ab21696fa805a00543e608431510c3d48 (diff) |
=bmesh=
Coded a new modifier, "Precision UV Interpolation",
that triangulates, subdivides, then uses brecht's mean
value interpolation to interpolate face data.
Textures on ngon faces get interpolated a bit nicer, in
other words (though concave cases, e.g. 'N', don't work very well).
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/modifiers/MOD_modifiertypes.h | 1 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_mirror.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_ngoninterp.c | 322 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.c | 1 |
5 files changed, 326 insertions, 1 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 0352aa8c05f..4a02306b443 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -60,6 +60,7 @@ set(SRC intern/MOD_meshdeform.c intern/MOD_mirror.c intern/MOD_multires.c + intern/MOD_ngoninterp.c intern/MOD_none.c intern/MOD_particleinstance.c intern/MOD_particlesystem.c diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 8486e2b5d29..44d06e3ef47 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -71,6 +71,7 @@ extern ModifierTypeInfo modifierType_Smoke; extern ModifierTypeInfo modifierType_ShapeKey; extern ModifierTypeInfo modifierType_Solidify; extern ModifierTypeInfo modifierType_Screw; +extern ModifierTypeInfo modifierType_NgonInterp; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index eceb1e356dc..31c7bd684b7 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -193,7 +193,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, ml->e += dm->numEdgeData; } - CDDM_recalc_tesselation(cddm); + CDDM_recalc_tesselation(cddm, 1); /*handle vgroup stuff*/ if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&cddm->vertData, CD_MDEFORMVERT)) { diff --git a/source/blender/modifiers/intern/MOD_ngoninterp.c b/source/blender/modifiers/intern/MOD_ngoninterp.c new file mode 100644 index 00000000000..cdb6f2e7eda --- /dev/null +++ b/source/blender/modifiers/intern/MOD_ngoninterp.c @@ -0,0 +1,322 @@ +/* +* $Id: MOD_mask.c 35213 2011-02-27 06:19:40Z joeedh $ +* +* ***** 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 ***** +* +*/ + +/** \file blender/modifiers/intern/MOD_mask.c + * \ingroup modifiers + */ + + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_array.h" +#include "BLI_smallhash.h" +#include "BLI_edgehash.h" +#include "BLI_math.h" + +#include "DNA_armature_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_deform.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + +static void copyData(ModifierData *md, ModifierData *target) +{ + NgonInterpModifierData *mmd = (NgonInterpModifierData*) md; + NgonInterpModifierData *tmmd = (NgonInterpModifierData*) target; + + tmmd->resolution = mmd->resolution; +} + +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + NgonInterpModifierData *nmd= (MaskModifierData *)md; + DerivedMesh *dm= derivedData, *result= NULL; + DerivedMesh *cddm, *dummy; + MFace *mf; + MPoly *mpoly; + MLoop *mloop; + MFace *mface = NULL, *mf2; + MVert *mvert = NULL, *mv2, *omvert; + BLI_array_declare(mface); + BLI_array_declare(mvert); + int *verts=NULL, *loops=NULL; + BLI_array_declare(verts); + BLI_array_declare(loops); + float *w = NULL, (*cos)[3] = NULL; + BLI_array_declare(w); + BLI_array_declare(cos); + int *origv = NULL, *origf = NULL, *of, *ov; + BLI_array_declare(origv); + BLI_array_declare(origf); + int i; + + if (nmd->resolution <= 0) + return dm; + + CDDM_recalc_tesselation(dm, 0); + + mf = dm->getTessFaceArray(dm); + of = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + mpoly = CDDM_get_polys(dm); + mloop = CDDM_get_loops(dm); + + /*eek!*/ + if (!of) + return dm; + + /*create a dummy mesh to compute interpolated loops on*/ + dummy = CDDM_from_template(dm, 0, 0, 0, 3, 0); + + /*copy original verts here, so indices stay correct*/ + omvert = dm->getVertArray(dm); + ov = dm->getVertDataArray(dm, CD_ORIGINDEX); + for (i=0; i<dm->numVertData; i++) { + BLI_array_append(mvert, omvert[i]); + BLI_array_append(origv, ov ? ov[i] : i); + } + + for (i=0; i<dm->numFaceData; i++, mf++, of++) { + int x, y, x2; + float fac; + + BLI_array_empty(verts); + +#define NG_MAKE_VERT(orig)\ + BLI_array_append(mvert, omvert[orig]);\ + BLI_array_append(origv, ov ? ov[orig] : orig);\ + BLI_array_append(verts, BLI_array_count(mvert)-1); + +#define NG_MAKE_VERTCO(orig, coord) NG_MAKE_VERT(orig); copy_v3_v3(mvert[BLI_array_count(mvert)-1].co, coord) + + y = 0; + fac = 1.0f / (float)(nmd->resolution + 1); + for (x=0; x<nmd->resolution+2; x++) { + float co1[3], co2[3], co3[3]; + + sub_v3_v3v3(co1, omvert[mf->v1].co, omvert[mf->v3].co); + sub_v3_v3v3(co2, omvert[mf->v2].co, omvert[mf->v3].co); + + mul_v3_fl(co1, 1.0 - fac*x); + mul_v3_fl(co2, 1.0 - fac*x); + + add_v3_v3(co1, omvert[mf->v3].co); + add_v3_v3(co2, omvert[mf->v3].co); + + if (x == 0) { + BLI_array_append(verts, mf->v1); + } else if (x == nmd->resolution+1) { + BLI_array_append(verts, mf->v3); + } else { + NG_MAKE_VERTCO(mf->v1, co1); + } + + for (x2=0; x2<(nmd->resolution-x); x2++) { + sub_v3_v3v3(co3, co1, co2); + mul_v3_fl(co3, 1.0 - (1.0f/(float)(nmd->resolution-x+1))*(x2+1)); + add_v3_v3(co3, co2); + + NG_MAKE_VERTCO(mf->v2, co3); + } + + if (x == 0) { + BLI_array_append(verts, mf->v2); + } else if (x != nmd->resolution+1) { + NG_MAKE_VERTCO(mf->v1, co2); + } + } + + y = 0; + for (x=0; x<BLI_array_count(verts)-2; x++) { + int v1, v2, v3; + + if (x2 == nmd->resolution-y+1) { + x2 = 0; + y++; + continue; + } else { + float co[3]; + int lindex[3] = {0, 1, 2}; + + v1 = verts[x]; + v2 = verts[x+1]; + v3 = verts[x+(nmd->resolution-y)+2]; + + BLI_array_growone(mface); + BLI_array_growone(origf); + + /*make first face*/ + origf[BLI_array_count(origf)-1] = *of; + mf2 = mface + BLI_array_count(mface)-1; + *mf2 = *mf; + + mf2->v1 = v1; + mf2->v2 = v2; + mf2->v3 = v3; + mf2->v4 = 0; + + if (x2 != nmd->resolution-y) { + /*make second face*/ + BLI_array_growone(mface); + BLI_array_growone(origf); + + origf[BLI_array_count(origf)-1] = *of; + mf2 = mface + BLI_array_count(mface)-1; + *mf2 = *mf; + + mf2->v1 = verts[x+(nmd->resolution-y)+3]; + mf2->v2 = v3; + mf2->v3 = v2; + mf2->v4 = 0; + } + } + + x2++; + } + } + + cddm = CDDM_from_template(dm, BLI_array_count(mvert), dm->numEdgeData, BLI_array_count(mface), 0, 0); + + mf2 = mface; + for (i=0; i<BLI_array_count(mface); i++, mf2++) { + MPoly *mp = mpoly + *of; + MLoop *ml; + float co[3], cent[3] = {0.0f, 0.0f, 0.0f}; + int j, lindex[3] = {0, 1, 2}; + + BLI_array_empty(w); + BLI_array_empty(cos); + BLI_array_empty(loops); + + mp = mpoly + origf[i]; + ml = mloop + mp->loopstart; + for (j=0; j<mp->totloop; j++, ml++) { + BLI_array_growone(cos); + BLI_array_growone(w); + BLI_array_append(loops, j+mp->loopstart); + copy_v3_v3(cos[j], mvert[ml->v].co); + } + + /*scale source face coordinates a bit, so points sitting directly on an + edge will work.*/ + mul_v3_fl(cent, 1.0/(float)(mp->totloop)); + for (j=0; j<mp->totloop; j++) { + float vec[3]; + + sub_v3_v3v3(vec, cent, cos[j]); + mul_v3_fl(vec, 0.000001); + add_v3_v3(cos[j], vec); + } + + copy_v3_v3(co, mvert + mf2->v1); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 0); + + copy_v3_v3(co, mvert + mf2->v2); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 1); + + copy_v3_v3(co, mvert + mf2->v3); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 2); + + mesh_loops_to_tri_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i]); + } + + CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData); + CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData); + + CDDM_set_mface(cddm, mface); + CDDM_set_mvert(cddm, mvert); + + /*set origindex pointer*/ + MEM_freeN(CustomData_get_layer(&cddm->faceData, CD_ORIGINDEX)); + CustomData_set_layer(&cddm->faceData, CD_MFACE, mface); + + if (CustomData_has_layer(&cddm->vertData, CD_ORIGINDEX)) + CustomData_set_layer(&cddm->vertData, CD_ORIGINDEX, origv); + + CustomData_set_layer(&cddm->faceData, CD_ORIGINDEX, origf); + + BLI_array_free(cos); + BLI_array_free(w); + + dummy->needsFree = 1; + dummy->release(dummy); + + /*create polys from mface triangles*/ + dummy = cddm; + cddm = CDDM_copy(cddm, 1); + dummy->needsFree = 1; + dummy->release(dummy); + + return cddm; +} + + +ModifierTypeInfo modifierType_NgonInterp = { + /* name */ "NgonInterp", + /* structName */ "NgonInterpModifierData", + /* structSize */ sizeof(NgonInterpModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping|eModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + /* deformVerts */ 0, + /* deformMatrices */ 0, + /* deformVertsEM */ 0, + /* deformMatricesEM */ 0, + /* applyModifier */ applyModifier, + /* applyModifierEM */ 0, + /* initData */ 0, + /* requiredDataMask */ 0, + /* freeData */ 0, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* dependsOnNormals */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; + diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 35571cd8e76..b3baf15ae29 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -189,5 +189,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(ShapeKey); INIT_TYPE(Solidify); INIT_TYPE(Screw); + INIT_TYPE(NgonInterp); #undef INIT_TYPE } |