merge with/from trunk at r35190
[blender.git] / source / blender / modifiers / intern / MOD_surface.c
1 /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software  Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
21 * All rights reserved.
22 *
23 * Contributor(s): Daniel Dunbar
24 *                 Ton Roosendaal,
25 *                 Ben Batt,
26 *                 Brecht Van Lommel,
27 *                 Campbell Barton
28 *
29 * ***** END GPL LICENSE BLOCK *****
30 *
31 */
32
33 /** \file blender/modifiers/intern/MOD_surface.c
34  *  \ingroup modifiers
35  */
36
37
38 #include "DNA_scene_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_meshdata_types.h"
41
42 #include "BLI_math.h"
43 #include "BLI_utildefines.h"
44
45
46 #include "BKE_cdderivedmesh.h"
47
48 #include "MOD_modifiertypes.h"
49 #include "MOD_util.h"
50
51 #include "MEM_guardedalloc.h"
52
53
54 static void initData(ModifierData *md) 
55 {
56         SurfaceModifierData *surmd = (SurfaceModifierData*) md;
57         
58         surmd->bvhtree = NULL;
59 }
60
61 static void freeData(ModifierData *md)
62 {
63         SurfaceModifierData *surmd = (SurfaceModifierData*) md;
64         
65         if (surmd)
66         {
67                 if(surmd->bvhtree) {
68                         free_bvhtree_from_mesh(surmd->bvhtree);
69                         MEM_freeN(surmd->bvhtree);
70                 }
71
72                 if(surmd->dm)
73                         surmd->dm->release(surmd->dm);
74
75                 if(surmd->x)
76                         MEM_freeN(surmd->x);
77                 
78                 if(surmd->v)
79                         MEM_freeN(surmd->v);
80
81                 surmd->bvhtree = NULL;
82                 surmd->dm = NULL;
83         }
84 }
85
86 static int dependsOnTime(ModifierData *UNUSED(md))
87 {
88         return 1;
89 }
90
91 static void deformVerts(ModifierData *md, Object *ob,
92                                                 DerivedMesh *derivedData,
93                                                 float (*vertexCos)[3],
94                                                 int UNUSED(numVerts),
95                                                 int UNUSED(useRenderParams),
96                                                 int UNUSED(isFinalCalc))
97 {
98         SurfaceModifierData *surmd = (SurfaceModifierData*) md;
99         
100         if(surmd->dm)
101                 surmd->dm->release(surmd->dm);
102
103         /* if possible use/create DerivedMesh */
104         if(derivedData) surmd->dm = CDDM_copy(derivedData, 0);
105         else surmd->dm = get_dm(ob, NULL, NULL, NULL, 0);
106         
107         if(!ob->pd)
108         {
109                 printf("SurfaceModifier deformVerts: Should not happen!\n");
110                 return;
111         }
112         
113         if(surmd->dm)
114         {
115                 unsigned int numverts = 0, i = 0;
116                 int init = 0;
117                 float *vec;
118                 MVert *x, *v;
119
120                 CDDM_apply_vert_coords(surmd->dm, vertexCos);
121                 CDDM_calc_normals(surmd->dm);
122                 
123                 numverts = surmd->dm->getNumVerts ( surmd->dm );
124
125                 if(numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL || md->scene->r.cfra != surmd->cfra+1) {
126                         if(surmd->x) {
127                                 MEM_freeN(surmd->x);
128                                 surmd->x = NULL;
129                         }
130                         if(surmd->v) {
131                                 MEM_freeN(surmd->v);
132                                 surmd->v = NULL;
133                         }
134
135                         surmd->x = MEM_callocN(numverts * sizeof(MVert), "MVert");
136                         surmd->v = MEM_callocN(numverts * sizeof(MVert), "MVert");
137
138                         surmd->numverts = numverts;
139
140                         init = 1;
141                 }
142
143                 /* convert to global coordinates and calculate velocity */
144                 for(i = 0, x = surmd->x, v = surmd->v; i<numverts; i++, x++, v++) {
145                         vec = CDDM_get_vert(surmd->dm, i)->co;
146                         mul_m4_v3(ob->obmat, vec);
147
148                         if(init)
149                                 v->co[0] = v->co[1] = v->co[2] = 0.0f;
150                         else
151                                 sub_v3_v3v3(v->co, vec, x->co);
152                         
153                         copy_v3_v3(x->co, vec);
154                 }
155
156                 surmd->cfra = md->scene->r.cfra;
157
158                 if(surmd->bvhtree)
159                         free_bvhtree_from_mesh(surmd->bvhtree);
160                 else
161                         surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
162
163                 if(surmd->dm->getNumTessFaces(surmd->dm))
164                         bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
165                 else
166                         bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
167         }
168 }
169
170
171 ModifierTypeInfo modifierType_Surface = {
172         /* name */              "Surface",
173         /* structName */        "SurfaceModifierData",
174         /* structSize */        sizeof(SurfaceModifierData),
175         /* type */              eModifierTypeType_OnlyDeform,
176         /* flags */             eModifierTypeFlag_AcceptsMesh
177                                                         | eModifierTypeFlag_NoUserAdd,
178
179         /* copyData */          0,
180         /* deformVerts */       deformVerts,
181         /* deformMatrices */    0,
182         /* deformVertsEM */     0,
183         /* deformMatricesEM */  0,
184         /* applyModifier */     0,
185         /* applyModifierEM */   0,
186         /* initData */          initData,
187         /* requiredDataMask */  0,
188         /* freeData */          freeData,
189         /* isDisabled */        0,
190         /* updateDepgraph */    0,
191         /* dependsOnTime */     dependsOnTime,
192         /* dependsOnNormals */  0,
193         /* foreachObjectLink */ 0,
194         /* foreachIDLink */     0,
195 };