style cleanup: comment blocks
[blender-staging.git] / source / blender / modifiers / intern / MOD_util.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 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Ben Batt
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/modifiers/intern/MOD_util.c
29  *  \ingroup modifiers
30  */
31
32
33 #include <string.h>
34
35 #include "DNA_lattice_types.h"
36 #include "DNA_modifier_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_curve_types.h"
39 #include "DNA_meshdata_types.h"
40
41 #include "BLI_utildefines.h"
42 #include "BLI_math_vector.h"
43 #include "BLI_math_matrix.h"
44
45 #include "BKE_cdderivedmesh.h"
46 #include "BKE_deform.h"
47 #include "BKE_lattice.h"
48 #include "BKE_mesh.h"
49 #include "BKE_displist.h"
50
51 #include "BKE_modifier.h"
52
53 #include "MOD_util.h"
54 #include "MOD_modifiertypes.h"
55
56 #include "MEM_guardedalloc.h"
57
58 #include "RE_shader_ext.h"
59
60 void get_texture_value(Tex *texture, float *tex_co, TexResult *texres)
61 {
62         int result_type;
63
64         /* no node textures for now */
65         result_type = multitex_ext_safe(texture, tex_co, texres);
66
67         /* if the texture gave an RGB value, we assume it didn't give a valid
68          * intensity, so calculate one (formula from do_material_tex).
69          * if the texture didn't give an RGB value, copy the intensity across
70          */
71         if(result_type & TEX_RGB)
72                 texres->tin = (0.35f * texres->tr + 0.45f * texres->tg
73                                 + 0.2f * texres->tb);
74         else
75                 texres->tr = texres->tg = texres->tb = texres->tin;
76 }
77
78 void get_texture_coords(MappingInfoModifierData *dmd, Object *ob,
79                         DerivedMesh *dm,
80                         float (*co)[3], float (*texco)[3],
81                         int numVerts)
82 {
83         int i;
84         int texmapping = dmd->texmapping;
85         float mapob_imat[4][4];
86
87         if(texmapping == MOD_DISP_MAP_OBJECT) {
88                 if(dmd->map_object)
89                         invert_m4_m4(mapob_imat, dmd->map_object->obmat);
90                 else /* if there is no map object, default to local */
91                         texmapping = MOD_DISP_MAP_LOCAL;
92         }
93
94         /* UVs need special handling, since they come from faces */
95         if(texmapping == MOD_DISP_MAP_UV) {
96                 if(CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
97                         MPoly *mpoly = dm->getPolyArray(dm);
98                         MPoly *mp;
99                         MLoop *mloop = dm->getLoopArray(dm);
100                         char *done = MEM_callocN(sizeof(*done) * numVerts,
101                                                  "get_texture_coords done");
102                         int numPolys = dm->getNumPolys(dm);
103                         char uvname[MAX_CUSTOMDATA_LAYER_NAME];
104                         MLoopUV *mloop_uv;
105
106                         CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, dmd->uvlayer_name, uvname);
107                         mloop_uv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, uvname);
108
109                         /* verts are given the UV from the first face that uses them */
110                         for(i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
111                                 unsigned int fidx= mp->totloop - 1;
112
113                                 do {
114                                         unsigned int lidx= mp->loopstart + fidx;
115                                         unsigned int vidx= mloop[lidx].v;
116
117                                         if (done[vidx] == 0) {
118                                                 /* remap UVs from [0, 1] to [-1, 1] */
119                                                 texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f;
120                                                 texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f;
121                                                 done[vidx] = 1;
122                                         }
123
124                                 } while (fidx--);
125                         }
126
127                         MEM_freeN(done);
128                         return;
129                 } else /* if there are no UVs, default to local */
130                         texmapping = MOD_DISP_MAP_LOCAL;
131         }
132
133         for(i = 0; i < numVerts; ++i, ++co, ++texco) {
134                 switch(texmapping) {
135                 case MOD_DISP_MAP_LOCAL:
136                         copy_v3_v3(*texco, *co);
137                         break;
138                 case MOD_DISP_MAP_GLOBAL:
139                         mul_v3_m4v3(*texco, ob->obmat, *co);
140                         break;
141                 case MOD_DISP_MAP_OBJECT:
142                         mul_v3_m4v3(*texco, ob->obmat, *co);
143                         mul_m4_v3(mapob_imat, *texco);
144                         break;
145                 }
146         }
147 }
148
149 void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
150 {
151         while((md=md->next) && md->type==eModifierType_Armature) {
152                 ArmatureModifierData *amd = (ArmatureModifierData*) md;
153                 if(amd->multi && amd->prevCos==NULL)
154                         amd->prevCos= MEM_dupallocN(vertexCos);
155                 else
156                         break;
157         }
158         /* lattice/mesh modifier too */
159 }
160
161 /* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */
162 DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3])
163 {
164         if(dm && dm->type == DM_TYPE_CDDM)
165                 return dm;
166
167         if(!dm) {
168                 dm= get_dm(ob, em, dm, vertexCos, 0);
169         }
170         else {
171                 dm= CDDM_copy(dm);
172                 CDDM_apply_vert_coords(dm, vertexCos);
173         }
174
175         if(dm)
176                 CDDM_calc_normals(dm);
177         
178         return dm;
179 }
180
181 /* returns a derived mesh if dm == NULL, for deforming modifiers that need it */
182 DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco)
183 {
184         if(dm)
185                 return dm;
186
187         if(ob->type==OB_MESH) {
188                 if(em) dm= CDDM_from_BMEditMesh(em, ob->data, FALSE, FALSE);
189                 else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob);
190
191                 if(vertexCos) {
192                         CDDM_apply_vert_coords(dm, vertexCos);
193                         //CDDM_calc_normals(dm);
194                 }
195                 
196                 if(orco)
197                         DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
198         }
199         else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) {
200                 dm= CDDM_from_curve(ob);
201         }
202
203         return dm;
204 }
205
206 void modifier_get_vgroup(Object *ob, DerivedMesh *dm, const char *name, MDeformVert **dvert, int *defgrp_index)
207 {
208         *defgrp_index = defgroup_name_index(ob, name);
209         *dvert = NULL;
210
211         if(*defgrp_index >= 0) {
212                 if(ob->type == OB_LATTICE)
213                         *dvert = lattice_get_deform_verts(ob);
214                 else if(dm)
215                         *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
216         }
217 }
218
219 /* only called by BKE_modifier.h/modifier.c */
220 void modifier_type_init(ModifierTypeInfo *types[])
221 {
222 #define INIT_TYPE(typeName) (types[eModifierType_##typeName] = &modifierType_##typeName)
223         INIT_TYPE(None);
224         INIT_TYPE(Curve);
225         INIT_TYPE(Lattice);
226         INIT_TYPE(Subsurf);
227         INIT_TYPE(Build);
228         INIT_TYPE(Array);
229         INIT_TYPE(Mirror);
230         INIT_TYPE(EdgeSplit);
231         INIT_TYPE(Bevel);
232         INIT_TYPE(Displace);
233         INIT_TYPE(UVProject);
234         INIT_TYPE(Decimate);
235         INIT_TYPE(Smooth);
236         INIT_TYPE(Cast);
237         INIT_TYPE(Wave);
238         INIT_TYPE(Armature);
239         INIT_TYPE(Hook);
240         INIT_TYPE(Softbody);
241         INIT_TYPE(Cloth);
242         INIT_TYPE(Collision);
243         INIT_TYPE(Boolean);
244         INIT_TYPE(MeshDeform);
245         INIT_TYPE(Ocean);
246         INIT_TYPE(ParticleSystem);
247         INIT_TYPE(ParticleInstance);
248         INIT_TYPE(Explode);
249         INIT_TYPE(Shrinkwrap);
250         INIT_TYPE(Fluidsim);
251         INIT_TYPE(Mask);
252         INIT_TYPE(SimpleDeform);
253         INIT_TYPE(Multires);
254         INIT_TYPE(Surface);
255         INIT_TYPE(Smoke);
256         INIT_TYPE(ShapeKey);
257         INIT_TYPE(Solidify);
258         INIT_TYPE(Screw);
259         INIT_TYPE(Warp);
260         INIT_TYPE(WeightVGEdit);
261         INIT_TYPE(WeightVGMix);
262         INIT_TYPE(WeightVGProximity);
263         INIT_TYPE(DynamicPaint);
264         INIT_TYPE(Remesh);
265 #undef INIT_TYPE
266 }