More DM func renames, fixing some build breaks, renaming more stuff, also seems like...
[blender.git] / source / blender / modifiers / intern / MOD_ngoninterp.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Daniel Dunbar
22  *                 Ton Roosendaal,
23  *                 Ben Batt,
24  *                 Brecht Van Lommel,
25  *                 Campbell Barton
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  */
30
31 /** \file blender/modifiers/intern/MOD_mask.c
32  *  \ingroup modifiers
33  */
34
35
36 #include "MEM_guardedalloc.h"
37
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"
43 #include "BLI_math.h"
44
45 #include "DNA_armature_types.h"
46 #include "DNA_meshdata_types.h"
47 #include "DNA_modifier_types.h"
48 #include "DNA_object_types.h"
49
50 #include "BKE_cdderivedmesh.h"
51 #include "BKE_mesh.h"
52 #include "BKE_modifier.h"
53 #include "BKE_deform.h"
54
55 #include "depsgraph_private.h"
56
57 #include "MOD_util.h"
58
59 static void copyData(ModifierData *md, ModifierData *target)
60 {
61         NgonInterpModifierData *mmd = (NgonInterpModifierData*) md;
62         NgonInterpModifierData *tmmd = (NgonInterpModifierData*) target;
63         
64         tmmd->resolution = mmd->resolution;
65 }
66
67 static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
68                                                 DerivedMesh *derivedData,
69                                                 int UNUSED(useRenderParams),
70                                                 int UNUSED(isFinalCalc))
71 {
72         NgonInterpModifierData *nmd= (NgonInterpModifierData *)md;
73         DerivedMesh *dm= derivedData;
74         DerivedMesh *cddm, *dummy;
75         MFace *mf;
76         MPoly *mpoly;
77         MLoop *mloop;
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;
86         BLI_array_declare(w);
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;
92         int i;
93         
94         if (nmd->resolution <= 0)
95                 return dm;
96         
97         if (!CDDM_Check(dm)) {
98                 dm = copy = CDDM_copy(dm, 0);
99         }
100         
101         CDDM_recalc_tesselation(dm);
102         
103         mf = dm->getTessFaceArray(dm);
104         of = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
105         mpoly = CDDM_get_polys(dm);
106         mloop = CDDM_get_loops(dm);
107         
108         /*eek!*/
109         if (!of)
110                 return dm;
111
112         /*create a dummy mesh to compute interpolated loops on*/
113         dummy = CDDM_from_template(dm, 0, 0, 0, 3, 0);
114         
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);
121         }
122         
123         for (i=0; i<dm->numTessFaceData; i++, mf++, of++) {
124                 int x, y, x2;
125                 float fac;
126                 
127                 BLI_array_empty(verts);
128                 
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);
133
134 #define NG_MAKE_VERTCO(orig, coord) NG_MAKE_VERT(orig); copy_v3_v3(mvert[BLI_array_count(mvert)-1].co, coord)
135
136                 y = 0;
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];
140                         
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);
143                         
144                         mul_v3_fl(co1, 1.0f - fac*x);
145                         mul_v3_fl(co2, 1.0f - fac*x);
146                         
147                         add_v3_v3(co1, omvert[mf->v3].co);
148                         add_v3_v3(co2, omvert[mf->v3].co);
149
150                         if (x == 0) {
151                                 BLI_array_append(verts, mf->v1);
152                         } else if (x == nmd->resolution+1) {
153                                 BLI_array_append(verts, mf->v3);
154                         } else {
155                                 NG_MAKE_VERTCO(mf->v1, co1);
156                         }
157                         
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));
161                                 add_v3_v3(co3, co2);
162                                 
163                                 NG_MAKE_VERTCO(mf->v2, co3);
164                         }
165                         
166                         if (x == 0) {
167                                 BLI_array_append(verts, mf->v2);
168                         } else if (x != nmd->resolution+1) {
169                                 NG_MAKE_VERTCO(mf->v1, co2);
170                         }
171                 }
172                 
173                 y = 0;
174                 for (x=0; x<BLI_array_count(verts)-2; x++) {
175                         int v1, v2, v3;
176                         
177                         if (x2 == nmd->resolution-y+1) {
178                                 x2 = 0;
179                                 y++;
180                                 continue;
181                         } else {
182                                 /*int lindex[3] = {0, 1, 2};*/ /*UNUSED*/
183                                 
184                                 v1 = verts[x];
185                                 v2 = verts[x+1];
186                                 v3 = verts[x+(nmd->resolution-y)+2];
187                                 
188                                 BLI_array_growone(mface);
189                                 BLI_array_growone(origf);
190                                 
191                                 /*make first face*/
192                                 origf[BLI_array_count(origf)-1] = *of;
193                                 mf2 = mface + BLI_array_count(mface)-1;
194                                 *mf2 = *mf;
195                                 
196                                 mf2->v1 = v1;
197                                 mf2->v2 = v2;
198                                 mf2->v3 = v3;
199                                 mf2->v4 = 0;
200                                 
201                                 if (x2 != nmd->resolution-y) {
202                                         /*make second face*/
203                                         BLI_array_growone(mface);
204                                         BLI_array_growone(origf);
205                                         
206                                         origf[BLI_array_count(origf)-1] = *of;
207                                         mf2 = mface + BLI_array_count(mface)-1;
208                                         *mf2 = *mf;
209                                         
210                                         mf2->v1 = verts[x+(nmd->resolution-y)+3];
211                                         mf2->v2 = v3;
212                                         mf2->v3 = v2;
213                                         mf2->v4 = 0;
214                                 }
215                         }
216                         
217                         x2++;
218                 }
219         }
220                 
221         cddm = CDDM_from_template(dm, BLI_array_count(mvert), dm->numEdgeData, BLI_array_count(mface), 0, 0);
222         
223         mf2 = mface;
224         for (i=0; i<BLI_array_count(mface); i++, mf2++) {
225                 MPoly *mp = mpoly + *of;
226                 MLoop *ml;
227                 float co[3], cent[3] = {0.0f, 0.0f, 0.0f};
228                 int j, lindex[3] = {0, 1, 2};
229                 
230                 BLI_array_empty(w);
231                 BLI_array_empty(cos);
232                 BLI_array_empty(loops);
233                 
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);
241                 }
242                 
243                 /*scale source face coordinates a bit, so points sitting directly on an
244                   edge will work.*/
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);
250                 }
251
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);
255                 
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);
259         
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);
263                 
264                 mesh_loops_to_tri_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i]);
265         }
266         
267         CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData);
268         CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData);
269         
270         CDDM_set_mface(cddm, mface);
271         CDDM_set_mvert(cddm, mvert);
272         
273         /*set origindex pointer*/
274         MEM_freeN(CustomData_get_layer(&cddm->faceData, CD_ORIGINDEX));
275         CustomData_set_layer(&cddm->faceData, CD_MFACE, mface);
276         
277         if (CustomData_has_layer(&cddm->vertData, CD_ORIGINDEX))
278                 CustomData_set_layer(&cddm->vertData, CD_ORIGINDEX, origv);
279
280         CustomData_set_layer(&cddm->faceData, CD_ORIGINDEX, origf);
281
282         BLI_array_free(cos);
283         BLI_array_free(w);
284         
285         dummy->needsFree = 1;
286         dummy->release(dummy);
287         
288         /*create polys from mface triangles*/
289         dummy = cddm;
290         cddm = CDDM_copy(cddm, 1);
291         dummy->needsFree = 1;
292         dummy->release(dummy);
293         
294         if (copy) {
295                 copy->needsFree = 1;
296                 copy->release(dm);
297                 copy = copy;
298         }
299
300         return cddm;
301 }
302
303
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,
310
311         /* copyData */          copyData,
312         /* deformVerts */       0,
313         /* deformMatrices */    0,
314         /* deformVertsEM */     0,
315         /* deformMatricesEM */  0,
316         /* applyModifier */     applyModifier,
317         /* applyModifierEM */   0,
318         /* initData */          0,
319         /* requiredDataMask */  0,
320         /* freeData */          0,
321         /* isDisabled */        0,
322         /* updateDepgraph */    0,
323         /* dependsOnTime */     0,
324         /* dependsOnNormals */  0,
325         /* foreachObjectLink */ 0,
326         /* foreachIDLink */     0,
327 };
328