2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
19 * All rights reserved.
21 * Contributor(s): Daniel Dunbar
27 * ***** END GPL LICENSE BLOCK *****
31 /** \file blender/modifiers/intern/MOD_mask.c
36 #include "MEM_guardedalloc.h"
38 #include "BLI_utildefines.h"
39 #include "BLI_ghash.h"
40 #include "BLI_array.h"
41 #include "BLI_smallhash.h"
42 #include "BLI_edgehash.h"
45 #include "DNA_armature_types.h"
46 #include "DNA_meshdata_types.h"
47 #include "DNA_modifier_types.h"
48 #include "DNA_object_types.h"
50 #include "BKE_cdderivedmesh.h"
52 #include "BKE_modifier.h"
53 #include "BKE_deform.h"
55 #include "depsgraph_private.h"
59 static void copyData(ModifierData *md, ModifierData *target)
61 NgonInterpModifierData *mmd = (NgonInterpModifierData*) md;
62 NgonInterpModifierData *tmmd = (NgonInterpModifierData*) target;
64 tmmd->resolution = mmd->resolution;
67 static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
68 DerivedMesh *derivedData,
69 int UNUSED(useRenderParams),
70 int UNUSED(isFinalCalc))
72 NgonInterpModifierData *nmd= (NgonInterpModifierData *)md;
73 DerivedMesh *dm= derivedData;
74 DerivedMesh *cddm, *dummy;
78 MFace *mface = NULL, *mf2;
79 MVert *mvert = NULL, *omvert;
80 BLI_array_declare(mface);
81 BLI_array_declare(mvert);
82 int *verts=NULL, *loops=NULL;
83 BLI_array_declare(verts);
84 BLI_array_declare(loops);
85 float *w = NULL, (*cos)[3] = NULL;
87 BLI_array_declare(cos);
88 int *origv = NULL, *origf = NULL, *of, *ov;
89 BLI_array_declare(origv);
90 BLI_array_declare(origf);
91 DerivedMesh *copy = NULL;
94 if (nmd->resolution <= 0)
97 if (!CDDM_Check(dm)) {
98 dm = copy = CDDM_copy(dm, 0);
101 CDDM_recalc_tesselation(dm);
103 mf = dm->getTessFaceArray(dm);
104 of = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
105 mpoly = CDDM_get_polys(dm);
106 mloop = CDDM_get_loops(dm);
112 /*create a dummy mesh to compute interpolated loops on*/
113 dummy = CDDM_from_template(dm, 0, 0, 0, 3, 0);
115 /*copy original verts here, so indices stay correct*/
116 omvert = dm->getVertArray(dm);
117 ov = dm->getVertDataArray(dm, CD_ORIGINDEX);
118 for (i=0; i<dm->numVertData; i++) {
119 BLI_array_append(mvert, omvert[i]);
120 BLI_array_append(origv, ov ? ov[i] : i);
123 for (i=0; i<dm->numFaceData; i++, mf++, of++) {
127 BLI_array_empty(verts);
129 #define NG_MAKE_VERT(orig)\
130 BLI_array_append(mvert, omvert[orig]);\
131 BLI_array_append(origv, ov ? ov[orig] : orig);\
132 BLI_array_append(verts, BLI_array_count(mvert)-1);
134 #define NG_MAKE_VERTCO(orig, coord) NG_MAKE_VERT(orig); copy_v3_v3(mvert[BLI_array_count(mvert)-1].co, coord)
137 fac = 1.0f / (float)(nmd->resolution + 1);
138 for (x=0; x<nmd->resolution+2; x++) {
139 float co1[3], co2[3], co3[3];
141 sub_v3_v3v3(co1, omvert[mf->v1].co, omvert[mf->v3].co);
142 sub_v3_v3v3(co2, omvert[mf->v2].co, omvert[mf->v3].co);
144 mul_v3_fl(co1, 1.0f - fac*x);
145 mul_v3_fl(co2, 1.0f - fac*x);
147 add_v3_v3(co1, omvert[mf->v3].co);
148 add_v3_v3(co2, omvert[mf->v3].co);
151 BLI_array_append(verts, mf->v1);
152 } else if (x == nmd->resolution+1) {
153 BLI_array_append(verts, mf->v3);
155 NG_MAKE_VERTCO(mf->v1, co1);
158 for (x2=0; x2<(nmd->resolution-x); x2++) {
159 sub_v3_v3v3(co3, co1, co2);
160 mul_v3_fl(co3, 1.0f - (1.0f/(float)(nmd->resolution-x+1))*(x2+1));
163 NG_MAKE_VERTCO(mf->v2, co3);
167 BLI_array_append(verts, mf->v2);
168 } else if (x != nmd->resolution+1) {
169 NG_MAKE_VERTCO(mf->v1, co2);
174 for (x=0; x<BLI_array_count(verts)-2; x++) {
177 if (x2 == nmd->resolution-y+1) {
182 /*int lindex[3] = {0, 1, 2};*/ /*UNUSED*/
186 v3 = verts[x+(nmd->resolution-y)+2];
188 BLI_array_growone(mface);
189 BLI_array_growone(origf);
192 origf[BLI_array_count(origf)-1] = *of;
193 mf2 = mface + BLI_array_count(mface)-1;
201 if (x2 != nmd->resolution-y) {
203 BLI_array_growone(mface);
204 BLI_array_growone(origf);
206 origf[BLI_array_count(origf)-1] = *of;
207 mf2 = mface + BLI_array_count(mface)-1;
210 mf2->v1 = verts[x+(nmd->resolution-y)+3];
221 cddm = CDDM_from_template(dm, BLI_array_count(mvert), dm->numEdgeData, BLI_array_count(mface), 0, 0);
224 for (i=0; i<BLI_array_count(mface); i++, mf2++) {
225 MPoly *mp = mpoly + *of;
227 float co[3], cent[3] = {0.0f, 0.0f, 0.0f};
228 int j, lindex[3] = {0, 1, 2};
231 BLI_array_empty(cos);
232 BLI_array_empty(loops);
234 mp = mpoly + origf[i];
235 ml = mloop + mp->loopstart;
236 for (j=0; j<mp->totloop; j++, ml++) {
237 BLI_array_growone(cos);
238 BLI_array_growone(w);
239 BLI_array_append(loops, j+mp->loopstart);
240 copy_v3_v3(cos[j], mvert[ml->v].co);
243 /*scale source face coordinates a bit, so points sitting directly on an
245 mul_v3_fl(cent, 1.0f/(float)(mp->totloop));
246 for (j=0; j<mp->totloop; j++) {
247 sub_v3_v3(cos[j], cent);
248 mul_v3_fl(cos[j], 1.0f+FLT_EPSILON*1500.0f);
249 add_v3_v3(cos[j], cent);
252 copy_v3_v3(co, (mvert + mf2->v1)->co);
253 interp_weights_poly_v3(w, cos, mp->totloop, co);
254 CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 0);
256 copy_v3_v3(co, (mvert + mf2->v2)->co);
257 interp_weights_poly_v3(w, cos, mp->totloop, co);
258 CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 1);
260 copy_v3_v3(co, (mvert + mf2->v3)->co);
261 interp_weights_poly_v3(w, cos, mp->totloop, co);
262 CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 2);
264 mesh_loops_to_tri_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i]);
267 CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData);
268 CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData);
270 CDDM_set_mface(cddm, mface);
271 CDDM_set_mvert(cddm, mvert);
273 /*set origindex pointer*/
274 MEM_freeN(CustomData_get_layer(&cddm->faceData, CD_ORIGINDEX));
275 CustomData_set_layer(&cddm->faceData, CD_MFACE, mface);
277 if (CustomData_has_layer(&cddm->vertData, CD_ORIGINDEX))
278 CustomData_set_layer(&cddm->vertData, CD_ORIGINDEX, origv);
280 CustomData_set_layer(&cddm->faceData, CD_ORIGINDEX, origf);
285 dummy->needsFree = 1;
286 dummy->release(dummy);
288 /*create polys from mface triangles*/
290 cddm = CDDM_copy(cddm, 1);
291 dummy->needsFree = 1;
292 dummy->release(dummy);
304 ModifierTypeInfo modifierType_NgonInterp = {
305 /* name */ "NgonInterp",
306 /* structName */ "NgonInterpModifierData",
307 /* structSize */ sizeof(NgonInterpModifierData),
308 /* type */ eModifierTypeType_Constructive,
309 /* flags */ eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping|eModifierTypeFlag_SupportsEditmode,
311 /* copyData */ copyData,
313 /* deformMatrices */ 0,
314 /* deformVertsEM */ 0,
315 /* deformMatricesEM */ 0,
316 /* applyModifier */ applyModifier,
317 /* applyModifierEM */ 0,
319 /* requiredDataMask */ 0,
322 /* updateDepgraph */ 0,
323 /* dependsOnTime */ 0,
324 /* dependsOnNormals */ 0,
325 /* foreachObjectLink */ 0,
326 /* foreachIDLink */ 0,