style cleanup: comment blocks
[blender-staging.git] / source / blender / modifiers / intern / MOD_particlesystem.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_particlesystem.c
32  *  \ingroup modifiers
33  */
34
35
36 #include <stddef.h>
37
38 #include "DNA_material_types.h"
39
40 #include "BLI_utildefines.h"
41
42
43 #include "BKE_cdderivedmesh.h"
44 #include "BKE_material.h"
45 #include "BKE_modifier.h"
46 #include "BKE_particle.h"
47
48 #include "MOD_util.h"
49
50
51 static void initData(ModifierData *md) 
52 {
53         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
54         psmd->psys= NULL;
55         psmd->dm= NULL;
56         psmd->totdmvert= psmd->totdmedge= psmd->totdmface= 0;
57 }
58 static void freeData(ModifierData *md)
59 {
60         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
61
62         if(psmd->dm){
63                 psmd->dm->needsFree = 1;
64                 psmd->dm->release(psmd->dm);
65                 psmd->dm = NULL;
66         }
67
68         /* ED_object_modifier_remove may have freed this first before calling
69          * modifier_free (which calls this function) */
70         if(psmd->psys)
71                 psmd->psys->flag |= PSYS_DELETE;
72 }
73 static void copyData(ModifierData *md, ModifierData *target)
74 {
75         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
76         ParticleSystemModifierData *tpsmd= (ParticleSystemModifierData*) target;
77
78         tpsmd->dm = NULL;
79         tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
80         //tpsmd->facepa = 0;
81         tpsmd->flag = psmd->flag;
82         /* need to keep this to recognise a bit later in copy_object */
83         tpsmd->psys = psmd->psys;
84 }
85
86 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
87 {
88         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
89         CustomDataMask dataMask = 0;
90         MTex *mtex;
91         int i;
92
93         if(!psmd->psys->part)
94                 return 0;
95
96         for(i=0; i<MAX_MTEX; i++) {
97                 mtex = psmd->psys->part->mtex[i];
98                 if(mtex && mtex->mapto && (mtex->texco & TEXCO_UV))
99                         dataMask |= CD_MASK_MTFACE;
100         }
101
102         if(psmd->psys->part->tanfac != 0.0f)
103                 dataMask |= CD_MASK_MTFACE;
104
105         /* ask for vertexgroups if we need them */
106         for(i=0; i<PSYS_TOT_VG; i++){
107                 if(psmd->psys->vgroup[i]){
108                         dataMask |= CD_MASK_MDEFORMVERT;
109                         break;
110                 }
111         }
112         
113         /* particles only need this if they are after a non deform modifier, and
114          * the modifier stack will only create them in that case. */
115         dataMask |= CD_MASK_ORIGSPACE_MLOOP|CD_MASK_ORIGINDEX;
116
117         dataMask |= CD_MASK_ORCO;
118         
119         return dataMask;
120 }
121
122 /* saves the current emitter state for a particle system and calculates particles */
123 static void deformVerts(ModifierData *md, Object *ob,
124                                                 DerivedMesh *derivedData,
125                                                 float (*vertexCos)[3],
126                                                 int UNUSED(numVerts),
127                                                 int UNUSED(useRenderParams),
128                                                 int UNUSED(isFinalCalc))
129 {
130         DerivedMesh *dm = derivedData;
131         ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
132         ParticleSystem * psys= NULL;
133         int needsFree=0;
134
135         if(ob->particlesystem.first)
136                 psys=psmd->psys;
137         else
138                 return;
139         
140         if(!psys_check_enabled(ob, psys))
141                 return;
142
143         if(dm==NULL) {
144                 dm= get_dm(ob, NULL, NULL, vertexCos, 1);
145
146                 if(!dm)
147                         return;
148
149                 needsFree= 1;
150         }
151
152         /* clear old dm */
153         if(psmd->dm){
154                 psmd->dm->needsFree = 1;
155                 psmd->dm->release(psmd->dm);
156         }
157         else if(psmd->flag & eParticleSystemFlag_file_loaded) {
158                 /* in file read dm just wasn't saved in file so no need to reset everything */
159                 psmd->flag &= ~eParticleSystemFlag_file_loaded;
160         }
161         else {
162                 /* no dm before, so recalc particles fully */
163                 psys->recalc |= PSYS_RECALC_RESET;
164         }
165
166         /* make new dm */
167         psmd->dm=CDDM_copy(dm);
168         CDDM_apply_vert_coords(psmd->dm, vertexCos);
169         CDDM_calc_normals(psmd->dm);
170
171         if(needsFree){
172                 dm->needsFree = 1;
173                 dm->release(dm);
174         }
175
176         /* protect dm */
177         psmd->dm->needsFree = 0;
178
179         /* report change in mesh structure */
180         if(psmd->dm->getNumVerts(psmd->dm)!=psmd->totdmvert ||
181                   psmd->dm->getNumEdges(psmd->dm)!=psmd->totdmedge ||
182                   psmd->dm->getNumTessFaces(psmd->dm)!=psmd->totdmface){
183
184                 psys->recalc |= PSYS_RECALC_RESET;
185
186                 psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
187                 psmd->totdmedge= psmd->dm->getNumEdges(psmd->dm);
188                 psmd->totdmface= psmd->dm->getNumTessFaces(psmd->dm);
189         }
190
191         if(psys) {
192                 psmd->flag &= ~eParticleSystemFlag_psys_updated;
193                 particle_system_update(md->scene, ob, psys);
194                 psmd->flag |= eParticleSystemFlag_psys_updated;
195         }
196 }
197
198 /* disabled particles in editmode for now, until support for proper derivedmesh
199  * updates is coded */
200 #if 0
201 static void deformVertsEM(
202                                 ModifierData *md, Object *ob, EditMesh *editData,
203                                 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
204 {
205         DerivedMesh *dm = derivedData;
206
207         if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
208
209         deformVerts(md, ob, dm, vertexCos, numVerts);
210
211         if(!derivedData) dm->release(dm);
212 }
213 #endif
214
215
216 ModifierTypeInfo modifierType_ParticleSystem = {
217         /* name */              "ParticleSystem",
218         /* structName */        "ParticleSystemModifierData",
219         /* structSize */        sizeof(ParticleSystemModifierData),
220         /* type */              eModifierTypeType_OnlyDeform,
221         /* flags */             eModifierTypeFlag_AcceptsMesh
222                                                         | eModifierTypeFlag_SupportsMapping
223                                                         | eModifierTypeFlag_UsesPointCache /*
224                                                         | eModifierTypeFlag_SupportsEditmode
225                                                         | eModifierTypeFlag_EnableInEditmode */,
226
227         /* copyData */          copyData,
228         /* deformVerts */       deformVerts,
229         /* deformVertsEM */     NULL /* deformVertsEM */ ,
230         /* deformMatrices */    NULL,
231         /* deformMatricesEM */  NULL,
232         /* applyModifier */     NULL,
233         /* applyModifierEM */   NULL,
234         /* initData */          initData,
235         /* requiredDataMask */  requiredDataMask,
236         /* freeData */          freeData,
237         /* isDisabled */        NULL,
238         /* updateDepgraph */    NULL,
239         /* dependsOnTime */     NULL,
240         /* dependsOnNormals */  NULL,
241         /* foreachObjectLink */ NULL,
242         /* foreachIDLink */     NULL,
243         /* foreachTexLink */    NULL,
244 };