21697779ca44f7315b2867234f45ad2c53405801
[blender.git] / source / blender / python / api2_2x / Particle.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * This is a new part of Blender.
24  *
25  * Contributor(s): 
26  *    Original version: Jacques Guignot, Jean-Michel Soler
27  *    Rewrite :        Cedric Paille, Stephen Swaney, Joilnen Leite
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 #include "Particle.h"
33 #include "gen_utils.h"
34 #include "BKE_object.h"
35 #include "BKE_main.h"
36 #include "BKE_particle.h"
37 #include "BKE_global.h"
38 #include "BKE_depsgraph.h"
39 #include "BKE_modifier.h"
40 #include "BKE_material.h"
41 #include "BKE_utildefines.h"
42 #include "BKE_pointcache.h"
43 #include "BKE_DerivedMesh.h"
44 #include "BIF_editparticle.h"
45 #include "BIF_space.h"
46 #include "blendef.h"
47 #include "DNA_modifier_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_material_types.h"
50 #include "BLI_blenlib.h"
51 #include "mydevice.h"
52 #include "Object.h"
53 #include "Material.h"
54
55 #include "MEM_guardedalloc.h"
56
57
58
59 /* Type Methods */
60 static PyObject *M_ParticleSys_New( PyObject * self, PyObject * value );
61 static PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args );
62
63 /* Particle Methods */
64 static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args );
65 static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args );
66 static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args );
67 static PyObject *Part_SetMat( BPy_PartSys * self, PyObject * args );
68 static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args );
69 static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args );
70 static PyObject *Part_GetVertGroup( BPy_PartSys * self, PyObject * args );
71 static PyObject *Part_SetVertGroup( BPy_PartSys * self, PyObject * args );
72 static int Part_setSeed( BPy_PartSys * self, PyObject * args );
73 static PyObject *Part_getSeed( BPy_PartSys * self );
74 static int Part_setType( BPy_PartSys * self, PyObject * args );
75 static PyObject *Part_getType( BPy_PartSys * self );
76 static int Part_setResol( BPy_PartSys * self, PyObject * args );
77 static PyObject *Part_getResol( BPy_PartSys * self );
78 static int Part_setStart( BPy_PartSys * self, PyObject * args );
79 static PyObject *Part_getStart( BPy_PartSys * self );
80 static int Part_setEnd( BPy_PartSys * self, PyObject * args );
81 static PyObject *Part_getEnd( BPy_PartSys * self );
82 static int Part_setEditable( BPy_PartSys * self, PyObject * args );
83 static PyObject *Part_getEditable( BPy_PartSys * self );
84 static int Part_setAmount( BPy_PartSys * self, PyObject * args );
85 static PyObject *Part_getAmount( BPy_PartSys * self );
86 static int Part_setMultiReact( BPy_PartSys * self, PyObject * args );
87 static PyObject *Part_getMultiReact( BPy_PartSys * self );
88 static int Part_setReactShape( BPy_PartSys * self, PyObject * args );
89 static PyObject *Part_getReactShape( BPy_PartSys * self );
90 static int Part_setSegments( BPy_PartSys * self, PyObject * args );
91 static PyObject *Part_getSegments( BPy_PartSys * self );
92 static int Part_setLife( BPy_PartSys * self, PyObject * args );
93 static PyObject *Part_getLife( BPy_PartSys * self );
94 static int Part_setRandLife( BPy_PartSys * self, PyObject * args );
95 static PyObject *Part_getRandLife( BPy_PartSys * self );
96 static int Part_set2d( BPy_PartSys * self, PyObject * args );
97 static PyObject *Part_get2d( BPy_PartSys * self );
98 static int Part_setMaxVel( BPy_PartSys * self, PyObject * args );
99 static PyObject *Part_getMaxVel( BPy_PartSys * self );
100 static int Part_setAvVel( BPy_PartSys * self, PyObject * args );
101 static PyObject *Part_getAvVel( BPy_PartSys * self );
102 static int Part_setLatAcc( BPy_PartSys * self, PyObject * args );
103 static PyObject *Part_getLatAcc( BPy_PartSys * self );
104 static int Part_setMaxTan( BPy_PartSys * self, PyObject * args );
105 static PyObject *Part_getMaxTan( BPy_PartSys * self );
106 static int Part_setGroundZ( BPy_PartSys * self, PyObject * args );
107 static PyObject *Part_getGroundZ( BPy_PartSys * self );
108 static int Part_setOb( BPy_PartSys * self, PyObject * args );
109 static PyObject *Part_getOb( BPy_PartSys * self );
110 static PyObject *Part_getRandEmission( BPy_PartSys * self );
111 static int Part_setRandEmission( BPy_PartSys * self, PyObject * args );
112 static PyObject *Part_getRandEmission( BPy_PartSys * self );
113 static int Part_setParticleDist( BPy_PartSys * self, PyObject * args );
114 static PyObject *Part_getParticleDist( BPy_PartSys * self );
115 static int Part_setEvenDist( BPy_PartSys * self, PyObject * args );
116 static PyObject *Part_getEvenDist( BPy_PartSys * self );
117 static int Part_setDist( BPy_PartSys * self, PyObject * args );
118 static PyObject *Part_getDist( BPy_PartSys * self );
119 static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args );
120 static PyObject *Part_getParticleDisp( BPy_PartSys * self );
121 static int Part_setJitterAmount( BPy_PartSys * self, PyObject * args );
122 static PyObject *Part_getJitterAmount( BPy_PartSys * self );
123 static int Part_setPF( BPy_PartSys * self, PyObject * args );
124 static PyObject *Part_getPF( BPy_PartSys * self );
125 static int Part_setInvert( BPy_PartSys * self, PyObject * args );
126 static PyObject *Part_getInvert( BPy_PartSys * self );
127 static int Part_setTargetOb( BPy_PartSys * self, PyObject * args );
128 static PyObject *Part_getTargetOb( BPy_PartSys * self );
129 static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args );
130 static PyObject *Part_getTargetPsys( BPy_PartSys * self );
131 static int Part_setRenderObject( BPy_PartSys * self, PyObject * args );
132 static PyObject *Part_getRenderObject( BPy_PartSys * self );
133 static int Part_setRenderMaterialColor( BPy_PartSys * self, PyObject * args );
134 static PyObject *Part_getRenderMaterialColor( BPy_PartSys * self );
135 static int Part_setRenderParents( BPy_PartSys * self, PyObject * args );
136 static PyObject *Part_getRenderParents( BPy_PartSys * self );
137 static int Part_setRenderUnborn( BPy_PartSys * self, PyObject * args );
138 static PyObject *Part_getRenderUnborn( BPy_PartSys * self );
139 static int Part_setRenderDied( BPy_PartSys * self, PyObject * args );
140 static PyObject *Part_getRenderDied( BPy_PartSys * self );
141 static int Part_setRenderMaterialIndex( BPy_PartSys * self, PyObject * args );
142 static PyObject *Part_getRenderMaterialIndex( BPy_PartSys * self );
143 static int Part_setStep( BPy_PartSys * self, PyObject * args );
144 static PyObject *Part_getStep( BPy_PartSys * self );
145 static int Part_setRenderStep( BPy_PartSys * self, PyObject * args );
146 static PyObject *Part_getRenderStep( BPy_PartSys * self );
147 static PyObject *Part_getDupOb( BPy_PartSys * self );
148 static PyObject *Part_getDrawAs( BPy_PartSys * self );
149 static int Part_setPhysType( BPy_PartSys * self, PyObject * args );
150 static PyObject *Part_getPhysType( BPy_PartSys * self );
151 static int Part_setIntegrator( BPy_PartSys * self, PyObject * args );
152 static PyObject *Part_getIntegrator( BPy_PartSys * self );
153 static int Part_setIniVelObject( BPy_PartSys * self, PyObject * args );
154 static PyObject *Part_getIniVelObject( BPy_PartSys * self );
155 static int Part_setIniVelNormal( BPy_PartSys * self, PyObject * args );
156 static PyObject *Part_getIniVelNormal( BPy_PartSys * self );
157 static int Part_setIniVelRandom( BPy_PartSys * self, PyObject * args );
158 static PyObject *Part_getIniVelRandom( BPy_PartSys * self );
159 static int Part_setIniVelTan( BPy_PartSys * self, PyObject * args );
160 static PyObject *Part_getIniVelTan( BPy_PartSys * self );
161 static int Part_setIniVelRot( BPy_PartSys * self, PyObject * args );
162 static PyObject *Part_getIniVelRot( BPy_PartSys * self );
163 static int Part_setIniVelPart( BPy_PartSys * self, PyObject * args );
164 static PyObject *Part_getIniVelPart( BPy_PartSys * self );
165 static int Part_setIniVelReact( BPy_PartSys * self, PyObject * args );
166 static PyObject *Part_getIniVelReact( BPy_PartSys * self );
167 static int Part_setRotDynamic( BPy_PartSys * self, PyObject * args );
168 static PyObject *Part_getRotDynamic( BPy_PartSys * self );
169 static int Part_setRotation( BPy_PartSys * self, PyObject * args );
170 static PyObject *Part_getRotation( BPy_PartSys * self );
171 static int Part_setRotRandom( BPy_PartSys * self, PyObject * args );
172 static PyObject *Part_getRotRandom( BPy_PartSys * self );
173 static int Part_setRotPhase( BPy_PartSys * self, PyObject * args );
174 static PyObject *Part_getRotPhase( BPy_PartSys * self );
175 static int Part_setRotPhaseR( BPy_PartSys * self, PyObject * args );
176 static PyObject *Part_getRotPhaseR( BPy_PartSys * self );
177 static int Part_setRotAngularV( BPy_PartSys * self, PyObject * args );
178 static PyObject *Part_getRotAngularV( BPy_PartSys * self );
179 static int Part_setRotAngularVAm( BPy_PartSys * self, PyObject * args );
180 static PyObject *Part_getRotAngularVAm( BPy_PartSys * self );
181 static int Part_setGlobAccX( BPy_PartSys * self, PyObject * args );
182 static PyObject *Part_getGlobAccX( BPy_PartSys * self );
183 static int Part_setGlobAccY( BPy_PartSys * self, PyObject * args );
184 static PyObject *Part_getGlobAccY( BPy_PartSys * self );
185 static int Part_setGlobAccZ( BPy_PartSys * self, PyObject * args );
186 static PyObject *Part_getGlobAccZ( BPy_PartSys * self );
187 static int Part_setGlobDrag( BPy_PartSys * self, PyObject * args );
188 static PyObject *Part_getGlobDrag( BPy_PartSys * self );
189 static int Part_setGlobBrown( BPy_PartSys * self, PyObject * args );
190 static PyObject *Part_getGlobBrown( BPy_PartSys * self );
191 static int Part_setGlobDamp( BPy_PartSys * self, PyObject * args );
192 static PyObject *Part_getGlobDamp( BPy_PartSys * self );
193 static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args );
194 static int Part_setChildAmount( BPy_PartSys * self, PyObject * args );
195 static PyObject *Part_getChildAmount( BPy_PartSys * self );
196 static int Part_setChildType( BPy_PartSys * self, PyObject * args );
197 static PyObject *Part_getChildType( BPy_PartSys * self );
198 static int Part_setChildRenderAmount( BPy_PartSys * self, PyObject * args );
199 static PyObject *Part_getChildRenderAmount( BPy_PartSys * self );
200 static int Part_setChildRadius( BPy_PartSys * self, PyObject * args );
201 static PyObject *Part_getChildRadius( BPy_PartSys * self );
202 static int Part_setChildRoundness( BPy_PartSys * self, PyObject * args );
203 static PyObject *Part_getChildRoundness( BPy_PartSys * self );
204 static int Part_setChildClumping( BPy_PartSys * self, PyObject * args );
205 static PyObject *Part_getChildClumping( BPy_PartSys * self );
206 static int Part_setChildShape( BPy_PartSys * self, PyObject * args );
207 static PyObject *Part_getChildShape( BPy_PartSys * self );
208 static int Part_setChildSize( BPy_PartSys * self, PyObject * args );
209 static PyObject *Part_getChildSize( BPy_PartSys * self );
210 static int Part_setChildRandom( BPy_PartSys * self, PyObject * args );
211 static PyObject *Part_getChildRandom( BPy_PartSys * self );
212 static int Part_setChildRough1( BPy_PartSys * self, PyObject * args );
213 static PyObject *Part_getChildRough1( BPy_PartSys * self );
214 static int Part_setChildRough1Size( BPy_PartSys * self, PyObject * args );
215 static PyObject *Part_getChildRough1Size( BPy_PartSys * self );
216 static int Part_setChildRough2( BPy_PartSys * self, PyObject * args );
217 static PyObject *Part_getChildRough2( BPy_PartSys * self );
218 static int Part_setChildRough2Size( BPy_PartSys * self, PyObject * args );
219 static PyObject *Part_getChildRough2Size( BPy_PartSys * self );
220 static int Part_setChildRough2Thres( BPy_PartSys * self, PyObject * args );
221 static PyObject *Part_getChildRough2Thres( BPy_PartSys * self );
222 static int Part_setChildRoughE( BPy_PartSys * self, PyObject * args );
223 static PyObject *Part_getChildRoughE( BPy_PartSys * self );
224 static int Part_setChildRoughEShape( BPy_PartSys * self, PyObject * args );
225 static PyObject *Part_getChildRoughEShape( BPy_PartSys * self );
226 static int Part_setChildKink( BPy_PartSys * self, PyObject * args );
227 static PyObject *Part_getChildKink( BPy_PartSys * self );
228 static int Part_setChildKinkAxis( BPy_PartSys * self, PyObject * args );
229 static PyObject *Part_getChildKinkAxis( BPy_PartSys * self );
230 static int Part_setChildKinkFreq( BPy_PartSys * self, PyObject * args );
231 static PyObject *Part_getChildKinkFreq( BPy_PartSys * self );
232 static int Part_setChildKinkShape( BPy_PartSys * self, PyObject * args );
233 static PyObject *Part_getChildKinkShape( BPy_PartSys * self );
234 static int Part_setChildKinkAmp( BPy_PartSys * self, PyObject * args );
235 static PyObject *Part_getChildKinkAmp( BPy_PartSys * self );
236 static int Part_setChildBranch( BPy_PartSys * self, PyObject * args );
237 static PyObject *Part_getChildBranch( BPy_PartSys * self );
238 static int Part_setChildBranchAnim( BPy_PartSys * self, PyObject * args );
239 static PyObject *Part_getChildBranchAnim( BPy_PartSys * self );
240 static int Part_setChildBranchSymm( BPy_PartSys * self, PyObject * args );
241 static PyObject *Part_getChildBranchSymm( BPy_PartSys * self );
242 static int Part_setChildBranchThre( BPy_PartSys * self, PyObject * args );
243 static PyObject *Part_getChildBranchThre( BPy_PartSys * self );
244
245 /*****************************************************************************/
246 /* Python Effect_Type callback function prototypes:                           */
247 /*****************************************************************************/
248 static PyObject *ParticleSys_repr( BPy_PartSys * self );
249
250 /*****************************************************************************/
251 /* The following string definitions are used for documentation strings.      */
252 /* In Python these will be written to the console when doing a               */
253 /* Blender.Particle.__doc__                                                  */
254 /*****************************************************************************/
255 static char M_ParticleSys_doc[] = "The Blender Effect module\n\n\
256 This module provides access to **Object Data** in Blender.\n\
257 Functions :\n\
258         Get(name) : retreives particle system (as list)  with the given name\n";
259 static char M_ParticleSys_Get_doc[] = "xxx";
260 static char M_ParticleSys_New_doc[] = "xxx";
261
262 /*****************************************************************************/
263 /* Python BPy_ParticleSys methods table:                                     */
264 /*****************************************************************************/
265
266 static PyMethodDef BPy_ParticleSys_methods[] = {
267         {"freeEdit", ( PyCFunction ) Part_freeEdit,
268          METH_NOARGS, "() - Free from edit mode"},
269         {"getLoc", ( PyCFunction ) Part_GetLoc,
270          METH_VARARGS, "() - Get particles location"},
271         {"getRot", ( PyCFunction ) Part_GetRot,
272          METH_VARARGS, "() - Get particles rotations (list of 4 floats quaternion)"},
273     {"setMat", ( PyCFunction ) Part_SetMat,
274          METH_VARARGS, "() - Set particles material"},
275         {"getMat", ( PyCFunction ) Part_GetMat,
276          METH_NOARGS, "() - Get particles material"},
277         {"getSize", ( PyCFunction ) Part_GetSize,
278          METH_VARARGS, "() - Get particles size in a list"},
279         {"getAge", ( PyCFunction ) Part_GetAge,
280          METH_VARARGS, "() - Get particles life in a list"},
281         {"getVertGroup", ( PyCFunction ) Part_GetVertGroup,
282          METH_VARARGS, "() - Get the vertex group which affects a particles attribute"},
283         {"setVertGroup", ( PyCFunction ) Part_SetVertGroup,
284          METH_VARARGS, "() - Set the vertex group to affect a particles attribute"},
285         {NULL, NULL, 0, NULL}
286 };
287
288 /*****************************************************************************/
289 /* Python BPy_ParticleSys attributes get/set structure:                           */
290 /*****************************************************************************/
291 static PyGetSetDef BPy_ParticleSys_getseters[] = {
292 /* Extras */
293         {"seed",
294          (getter)Part_getSeed, (setter)Part_setSeed,
295          "Set an offset in the random table",
296          NULL},
297  /* basics */
298         {"type",
299          (getter)Part_getType, (setter)Part_setType,
300          "Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] )",
301          NULL},
302         {"resolutionGrid",
303          (getter)Part_getResol, (setter)Part_setResol,
304          "The resolution of the particle grid",
305          NULL},
306         {"startFrame",
307          (getter)Part_getStart, (setter)Part_setStart,
308          "Frame # to start emitting particles",
309          NULL},
310         {"endFrame",
311          (getter)Part_getEnd, (setter)Part_setEnd,
312          "Frame # to stop emitting particles",
313          NULL},
314         {"editable",
315          (getter)Part_getEditable, (setter)Part_setEditable,
316          "Finalize hair to enable editing in particle mode",
317          NULL},
318     {"amount",
319          (getter)Part_getAmount, (setter)Part_setAmount,
320          "The total number of particles",
321          NULL},
322     {"multireact",
323          (getter)Part_getMultiReact, (setter)Part_setMultiReact,
324          "React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] )",
325          NULL},
326     {"reactshape",
327          (getter)Part_getReactShape, (setter)Part_setReactShape,
328          "Power of reaction strength dependence on distance to target",
329          NULL},
330     {"hairSegments",
331          (getter)Part_getSegments, (setter)Part_setSegments,
332          "Amount of hair segments",
333          NULL},
334     {"lifetime",
335          (getter)Part_getLife, (setter)Part_setLife,
336          "Specify the life span of the particles",
337          NULL},
338     {"randlife",
339          (getter)Part_getRandLife, (setter)Part_setRandLife,
340          "Give the particle life a random variation",
341          NULL},
342      {"randemission",
343          (getter)Part_getRandEmission, (setter)Part_setRandEmission,
344          "Give the particle life a random variation",
345          NULL},
346      {"particleDistribution",
347          (getter)Part_getParticleDist, (setter)Part_setParticleDist,
348          "Where to emit particles from  Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )",
349          NULL},
350      {"evenDistribution",
351          (getter)Part_getEvenDist, (setter)Part_setEvenDist,
352          "Use even distribution from faces based on face areas or edge lengths",
353          NULL},
354      {"distribution",
355          (getter)Part_getDist, (setter)Part_setDist,
356          "How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] )",
357          NULL},
358      {"jitterAmount",
359          (getter)Part_getJitterAmount, (setter)Part_setJitterAmount,
360          "Amount of jitter applied to the sampling",
361          NULL},
362      {"pf",
363          (getter)Part_getPF, (setter)Part_setPF,
364          "Emission locations / face (0 = automatic)",
365          NULL},
366      {"invert",
367          (getter)Part_getInvert, (setter)Part_setInvert,
368          "Invert what is considered object and what is not.",
369          NULL},
370      {"targetObject",
371          (getter)Part_getTargetOb, (setter)Part_setTargetOb,
372          "The object that has the target particle system (empty if same object)",
373          NULL},
374      {"targetpsys",
375          (getter)Part_getTargetPsys, (setter)Part_setTargetPsys,
376          "The target particle system number in the object",
377          NULL},
378 /* Physics */
379     {"2d",
380          (getter)Part_get2d, (setter)Part_set2d,
381          "Constrain boids to a surface",
382          NULL},
383     {"maxvel",
384          (getter)Part_getMaxVel, (setter)Part_setMaxVel,
385          "Maximum velocity",
386          NULL},
387     {"avvel",
388          (getter)Part_getAvVel, (setter)Part_setAvVel,
389          "The usual speed % of max velocity",
390          NULL},
391     {"latacc",
392          (getter)Part_getLatAcc, (setter)Part_setLatAcc,
393          "Lateral acceleration % of max velocity",
394          NULL},
395     {"tanacc",
396          (getter)Part_getMaxTan, (setter)Part_setMaxTan,
397          "Tangential acceleration % of max velocity",
398          NULL},
399     {"groundz",
400          (getter)Part_getGroundZ, (setter)Part_setGroundZ,
401          "Default Z value",
402          NULL},
403      {"object",
404          (getter)Part_getOb, (setter)Part_setOb,
405          "Constrain boids to object's surface",
406          NULL},
407 /* Visualisation */
408      {"renderEmitter",
409          (getter)Part_getRenderObject, (setter)Part_setRenderObject,
410          "Render emitter object",
411          NULL},
412          {"renderMatCol",
413          (getter)Part_getRenderMaterialColor, (setter)Part_setRenderMaterialColor,
414          "Draw particles using material's diffuse color",
415          NULL},
416          {"renderParents",
417          (getter)Part_getRenderParents, (setter)Part_setRenderParents,
418          "Render parent particles",
419          NULL},
420          {"renderUnborn",
421          (getter)Part_getRenderUnborn, (setter)Part_setRenderUnborn,
422          "Show particles before they are emitted",
423          NULL},
424          {"renderDied",
425          (getter)Part_getRenderDied, (setter)Part_setRenderDied,
426          "Show particles after they have died",
427          NULL},
428          {"renderMaterial",
429          (getter)Part_getRenderMaterialIndex, (setter)Part_setRenderMaterialIndex,
430          "Specify material index used for the particles",
431          NULL},
432      {"displayPercentage",
433          (getter)Part_getParticleDisp, (setter)Part_setParticleDisp,
434          "Particle display percentage",
435          NULL},
436      {"hairDisplayStep",
437          (getter)Part_getStep, (setter)Part_setStep,
438          "How many steps paths are drawn with (power of 2)",
439          NULL},
440      {"hairRenderStep",
441          (getter)Part_getRenderStep, (setter)Part_setRenderStep,
442          "How many steps paths are rendered with (power of 2)",
443          NULL},
444      {"duplicateObject",
445          (getter)Part_getDupOb, NULL,
446          "Get the duplicate ob",
447          NULL},
448      {"drawAs",
449          (getter)Part_getDrawAs, NULL,
450          "Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )",
451          NULL},
452 /* Newtonian Physics */
453         {"physics",
454          (getter)Part_getPhysType, (setter)Part_setPhysType,
455          "Select particle physics type Particle.PHYSICS([ 'BOIDS' | 'KEYED' | 'NEWTONIAN' | 'NONE' ])",
456          NULL},
457         {"integration",
458          (getter)Part_getIntegrator, (setter)Part_setIntegrator,
459          "Select physics integrator type Particle.INTEGRATOR([ 'RK4' | 'MIDPOINT' | 'EULER' ])",
460          NULL},
461          {"inVelObj",
462          (getter)Part_getIniVelObject, (setter)Part_setIniVelObject,
463          "Let the object give the particle a starting speed",
464          NULL},
465          {"inVelNor",
466          (getter)Part_getIniVelNormal, (setter)Part_setIniVelNormal,
467          "Let the surface normal give the particle a starting speed",
468          NULL},
469          {"inVelRan",
470          (getter)Part_getIniVelRandom, (setter)Part_setIniVelRandom,
471          "Give the starting speed a random variation",
472          NULL},
473          {"inVelTan",
474          (getter)Part_getIniVelTan, (setter)Part_setIniVelTan,
475          "Let the surface tangent give the particle a starting speed",
476          NULL},
477          {"inVelRot",
478          (getter)Part_getIniVelRot, (setter)Part_setIniVelRot,
479          "Rotate the surface tangent",
480          NULL},
481          {"inVelPart",
482          (getter)Part_getIniVelPart, (setter)Part_setIniVelPart,
483          "Let the target particle give the particle a starting speed",
484          NULL},
485          {"inVelReact",
486          (getter)Part_getIniVelReact, (setter)Part_setIniVelReact,
487          "Let the vector away from the target particles location give the particle a starting speed",
488          NULL},
489          {"rotation",
490          (getter)Part_getRotation, (setter)Part_setRotation,
491          "Particles initial rotation Particle.ROTATION([ 'OBZ' | 'OBY' | 'OBX' | 'GLZ' | 'GLY' | 'GLX' | 'VEL' | 'NOR' | 'NONE' ])",
492          NULL},
493          {"rotDyn",
494          (getter)Part_getRotDynamic, (setter)Part_setRotDynamic,
495          "Sets rotation to dynamic/constant",
496          NULL},
497          {"rotRand",
498          (getter)Part_getRotRandom, (setter)Part_setRotRandom,
499          "Randomize rotation",
500          NULL},
501          {"rotPhase",
502          (getter)Part_getRotPhase, (setter)Part_setRotPhase,
503          "Initial rotation phase",
504          NULL},
505          {"rotPhaseR",
506          (getter)Part_getRotPhaseR, (setter)Part_setRotPhaseR,
507          "Randomize rotation phase",
508          NULL},
509          {"rotAnV",
510          (getter)Part_getRotAngularV, (setter)Part_setRotAngularV,
511          "Select particle angular velocity mode Particle.ANGULARV([ 'RANDOM' | 'SPIN' | 'NONE' ])",
512          NULL},
513          {"rotAnVAm",
514          (getter)Part_getRotAngularVAm, (setter)Part_setRotAngularVAm,
515          "Angular velocity amount",
516          NULL},
517          {"glAccX",
518          (getter)Part_getGlobAccX, (setter)Part_setGlobAccX,
519          "Specify a constant acceleration along the X-axis",
520          NULL},
521          {"glAccY",
522          (getter)Part_getGlobAccY, (setter)Part_setGlobAccY,
523          "Specify a constant acceleration along the Y-axis",
524          NULL},
525          {"glAccZ",
526          (getter)Part_getGlobAccZ, (setter)Part_setGlobAccZ,
527          "Specify a constant acceleration along the Z-axis",
528          NULL},
529          {"glDrag",
530          (getter)Part_getGlobDrag, (setter)Part_setGlobDrag,
531          "Specify the amount of air-drag",
532          NULL},
533          {"glBrown",
534          (getter)Part_getGlobBrown, (setter)Part_setGlobBrown,
535          "Specify the amount of brownian motion",
536          NULL},
537          {"glDamp",
538          (getter)Part_getGlobDamp, (setter)Part_setGlobDamp,
539          "Specify the amount of damping",
540          NULL},
541 /* Children */
542         {"childAmount",
543          (getter)Part_getChildAmount, (setter)Part_setChildAmount,
544          "The total number of children",
545          NULL},
546          {"childType",
547          (getter)Part_getChildType, (setter)Part_setChildType,
548          "Type of childrens ( Particle.CHILDTYPE[ 'FACES' | 'PARTICLES' | 'NONE' ] )",
549          NULL},
550          {"childRenderAmount",
551          (getter)Part_getChildRenderAmount, (setter)Part_setChildRenderAmount,
552          "Amount of children/parent for rendering",
553          NULL},
554          {"childRadius",
555          (getter)Part_getChildRadius, (setter)Part_setChildRadius,
556          "Radius of children around parent",
557          NULL},
558          {"childRound",
559          (getter)Part_getChildRoundness, (setter)Part_setChildRoundness,
560          "Roundness of children around parent",
561          NULL},
562          {"childClump",
563          (getter)Part_getChildClumping, (setter)Part_setChildClumping,
564          "Amount of clumpimg",
565          NULL},
566          {"childShape",
567          (getter)Part_getChildShape, (setter)Part_setChildShape,
568          "Shape of clumpimg",
569          NULL},
570          {"childSize",
571          (getter)Part_getChildSize, (setter)Part_setChildSize,
572          "A multiplier for the child particle size",
573          NULL},
574          {"childRand",
575          (getter)Part_getChildRandom, (setter)Part_setChildRandom,
576          "Random variation to the size of the child particles",
577          NULL},
578          {"childRough1",
579          (getter)Part_getChildRough1, (setter)Part_setChildRough1,
580          "Amount of location dependant rough",
581          NULL},
582          {"childRough1Size",
583          (getter)Part_getChildRough1Size, (setter)Part_setChildRough1Size,
584          "Size of location dependant rough",
585          NULL},
586          {"childRough2",
587          (getter)Part_getChildRough2, (setter)Part_setChildRough2,
588          "Amount of random rough",
589          NULL},
590          {"childRough2Size",
591          (getter)Part_getChildRough2Size, (setter)Part_setChildRough2Size,
592          "Size of random rough",
593          NULL},
594          {"childRough2Thresh",
595          (getter)Part_getChildRough2Thres, (setter)Part_setChildRough2Thres,
596          "Amount of particles left untouched by random rough",
597          NULL},
598          {"childRoughE",
599          (getter)Part_getChildRoughE, (setter)Part_setChildRoughE,
600          "Amount of end point rough",
601          NULL},
602          {"childRoughEShape",
603          (getter)Part_getChildRoughEShape, (setter)Part_setChildRoughEShape,
604          "Shape of end point rough",
605          NULL},
606          {"childKink",
607          (getter)Part_getChildKink, (setter)Part_setChildKink,
608          "Type of periodic offset on the path (Particle.CHILDKINK[ 'BRAID' | 'WAVE' | 'RADIAL' | 'CURL' | 'NOTHING' ])",
609          NULL},
610          {"childKinkAxis",
611          (getter)Part_getChildKinkAxis, (setter)Part_setChildKinkAxis,
612          "Which axis to use for offset (Particle.CHILDKINKAXIS[ 'Z' | 'Y' | 'X' ])",
613          NULL},
614          {"childKinkFreq",
615          (getter)Part_getChildKinkFreq, (setter)Part_setChildKinkFreq,
616          "The frequency of the offset (1/total length)",
617          NULL},
618          {"childKinkShape",
619          (getter)Part_getChildKinkShape, (setter)Part_setChildKinkShape,
620          "Adjust the offset to the beginning/end",
621          NULL},
622          {"childKinkAmp",
623          (getter)Part_getChildKinkAmp, (setter)Part_setChildKinkAmp,
624          "The amplitude of the offset",
625          NULL},
626          {"childBranch",
627          (getter)Part_getChildBranch, (setter)Part_setChildBranch,
628          "Branch child paths from eachother",
629          NULL},
630          {"childBranchAnim",
631          (getter)Part_getChildBranchAnim, (setter)Part_setChildBranchAnim,
632          "Animate branching",
633          NULL},
634          {"childBranchSymm",
635          (getter)Part_getChildBranchSymm, (setter)Part_setChildBranchSymm,
636          "Start and end points are the same",
637          NULL},
638          {"childBranchThre",
639          (getter)Part_getChildBranchThre, (setter)Part_setChildBranchThre,
640          "Threshold of branching",
641          NULL},
642         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
643 };
644
645 /*****************************************************************************/
646 /* Python method structure definition for Blender.Particle module:           */
647 /*****************************************************************************/
648 static struct PyMethodDef M_ParticleSys_methods[] = {
649         {"New", ( PyCFunction ) M_ParticleSys_New, METH_O, M_ParticleSys_New_doc},
650         {"Get", M_ParticleSys_Get, METH_VARARGS, M_ParticleSys_Get_doc},
651         {NULL, NULL, 0, NULL}
652 };
653
654 /*****************************************************************************/
655 /* Python ParticleSys_Type structure definition:                                  */
656 /*****************************************************************************/
657 PyTypeObject ParticleSys_Type = {
658         PyObject_HEAD_INIT( NULL )  /* required py macro */
659         0,                          /* ob_size */
660         /*  For printing, in format "<module>.<name>" */
661         "Blender ParticleSys",           /* char *tp_name; */
662         sizeof( BPy_PartSys ),       /* int tp_basicsize; */
663         0,                          /* tp_itemsize;  For allocation */
664
665         /* Methods to implement standard operations */
666
667         NULL,                                           /* destructor tp_dealloc; */
668         NULL,                       /* printfunc tp_print; */
669         NULL,                       /* getattrfunc tp_getattr; */
670         NULL,                       /* setattrfunc tp_setattr; */
671         NULL,                       /* cmpfunc tp_compare; */
672         ( reprfunc ) ParticleSys_repr,/* reprfunc tp_repr; */
673
674         /* Method suites for standard classes */
675
676         NULL,                       /* PyNumberMethods *tp_as_number; */
677         NULL,                       /* PySequenceMethods *tp_as_sequence; */
678         NULL,                       /* PyMappingMethods *tp_as_mapping; */
679
680         /* More standard operations (here for binary compatibility) */
681
682         NULL,                       /* hashfunc tp_hash; */
683         NULL,                       /* ternaryfunc tp_call; */
684         NULL,                       /* reprfunc tp_str; */
685         NULL,                       /* getattrofunc tp_getattro; */
686         NULL,                       /* setattrofunc tp_setattro; */
687
688         /* Functions to access object as input/output buffer */
689         NULL,                       /* PyBufferProcs *tp_as_buffer; */
690
691   /*** Flags to define presence of optional/expanded features ***/
692         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
693
694         NULL,                       /*  char *tp_doc;  Documentation string */
695   /*** Assigned meaning in release 2.0 ***/
696         /* call function for all accessible objects */
697         NULL,                       /* traverseproc tp_traverse; */
698
699         /* delete references to contained objects */
700         NULL,                       /* inquiry tp_clear; */
701
702   /***  Assigned meaning in release 2.1 ***/
703   /*** rich comparisons ***/
704         NULL,                       /* richcmpfunc tp_richcompare; */
705
706   /***  weak reference enabler ***/
707         0,                          /* long tp_weaklistoffset; */
708
709   /*** Added in release 2.2 ***/
710         /*   Iterators */
711         NULL,                       /* getiterfunc tp_iter; */
712         NULL,                       /* iternextfunc tp_iternext; */
713
714   /*** Attribute descriptor and subclassing stuff ***/
715         BPy_ParticleSys_methods,      /* struct PyMethodDef *tp_methods; */
716         NULL,                       /* struct PyMemberDef *tp_members; */
717         BPy_ParticleSys_getseters,  /* struct PyGetSetDef *tp_getset; */
718         NULL,                       /* struct _typeobject *tp_base; */
719         NULL,                       /* PyObject *tp_dict; */
720         NULL,                       /* descrgetfunc tp_descr_get; */
721         NULL,                       /* descrsetfunc tp_descr_set; */
722         0,                          /* long tp_dictoffset; */
723         NULL,                       /* initproc tp_init; */
724         NULL,                       /* allocfunc tp_alloc; */
725         NULL,                       /* newfunc tp_new; */
726         /*  Low-level free-memory routine */
727         NULL,                       /* freefunc tp_free;  */
728         /* For PyObject_IS_GC */
729         NULL,                       /* inquiry tp_is_gc;  */
730         NULL,                       /* PyObject *tp_bases; */
731         /* method resolution order */
732         NULL,                       /* PyObject *tp_mro;  */
733         NULL,                       /* PyObject *tp_cache; */
734         NULL,                       /* PyObject *tp_subclasses; */
735         NULL,                       /* PyObject *tp_weaklist; */
736         NULL
737 };
738
739 /*****************************************************************************/
740 /* Function:    PARTICLESYS_repr                                             */
741 /* Description: This is a callback function for the BPy_PartSys type. It     */
742 /*              builds a meaningful string to represent effect objects.      */
743 /*****************************************************************************/
744
745 static PyObject *ParticleSys_repr( BPy_PartSys * self )
746 {
747         return PyString_FromFormat( "ParticleSys \"%s\"",
748                         self->psys->part->id.name+2 );
749 }
750
751 /*****************************************************************************/
752 /* Function : P_sys_FromPyObject                                           */
753 /*****************************************************************************/
754
755 struct ParticleSystem *P_sys_FromPyObject( BPy_PartSys * py_obj )
756 {
757         BPy_PartSys *blen_obj;
758
759         blen_obj = ( BPy_PartSys * ) py_obj;
760         return ( blen_obj->psys );
761 }
762
763 /*****************************************************************************/
764 /* Function : ParticleSysCreatePyObject                                            */
765 /*****************************************************************************/
766 PyObject *ParticleSys_CreatePyObject( ParticleSystem * psystem, Object *ob )
767 {
768         BPy_PartSys *blen_object;
769
770         blen_object =
771                 ( BPy_PartSys * ) PyObject_NEW( BPy_PartSys, &ParticleSys_Type );
772
773         if( blen_object )
774                 blen_object->psys = (ParticleSystem *)psystem;
775
776         blen_object->object = ob;
777
778         return ( PyObject * ) blen_object;
779 }
780
781
782 PyObject *M_ParticleSys_New( PyObject * self, PyObject * value)
783 {
784         ParticleSystem *psys = 0;
785         ParticleSystem *rpsys = 0;
786         ModifierData *md;
787         ParticleSystemModifierData *psmd;
788         Object *ob = NULL;
789         ID *id;
790         int nr;
791         
792         if ( PyString_Check( value ) ) {
793                 char *name;
794                 name = PyString_AsString ( value );
795                 ob = ( Object * ) GetIdFromList( &( G.main->object ), name );
796                 if( !ob )
797                         return EXPP_ReturnPyObjError( PyExc_AttributeError, name );
798         } else if ( BPy_Object_Check(value) ) {
799                 ob = (( BPy_Object * ) value)->object;
800         } else {
801                 return EXPP_ReturnPyObjError( PyExc_TypeError, "expected object or string" );
802         }
803
804         id = (ID *)psys_new_settings("PSys", G.main);
805
806         psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
807         psys->pointcache = BKE_ptcache_add();
808         psys->flag |= PSYS_ENABLED;
809         BLI_addtail(&ob->particlesystem,psys);
810
811         md = modifier_new(eModifierType_ParticleSystem);
812         sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
813         psmd = (ParticleSystemModifierData*) md;
814         psmd->psys=psys;
815         BLI_addtail(&ob->modifiers, md);
816
817         psys->part=(ParticleSettings*)id;
818         psys->totpart=0;
819         psys->flag=PSYS_ENABLED|PSYS_CURRENT;
820         psys->cfra=bsystem_time(ob,(float)G.scene->r.cfra+1,0.0);
821         rpsys = psys;
822
823         /* check need for dupliobjects */
824
825         nr=0;
826         for(psys=ob->particlesystem.first; psys; psys=psys->next){
827                 if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
828                         nr++;
829         }
830         if(nr)
831                 ob->transflag |= OB_DUPLIPARTS;
832         else
833                 ob->transflag &= ~OB_DUPLIPARTS;
834
835         BIF_undo_push("Browse Particle System");
836
837         DAG_scene_sort(G.scene);
838         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
839
840         return ParticleSys_CreatePyObject(rpsys,ob);
841 }
842
843
844 /* 
845
846 Get( name ) returns named particle sys or list of all
847 throws NameError if name not found
848
849 */
850
851 PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args ) 
852 {
853 #if 1
854         return EXPP_ReturnPyObjError( PyExc_NotImplementedError,
855                 "Particle.Get() not implemented" );
856 #else
857         ParticleSettings *psys_iter;
858         char *name = NULL;
859
860         ParticleSystem *blparticlesys = 0;
861         Object *ob;
862
863         PyObject *partsyslist,*current;
864
865         if( !PyArg_ParseTuple( args, "|s", &name ) )
866                 return EXPP_ReturnPyObjError( PyExc_TypeError,
867                                 "expected string argument" );
868
869         psys_iter = G.main->particle.first; /* initialize our iterator */
870
871         if( name ) {   /* find psys by name */
872
873                 PyObject *wanted_obj = NULL;
874         
875                 while( psys_iter && ! wanted_obj ){
876                         if( !strcmp( name, psys_iter->id.name + 2)){
877                                 printf("** found %s\n", psys_iter->id.name+2);
878                                 //wanted_obj = ParticleSys_CreatePyObject( psys_iter );
879                                 break;
880                         }
881                         psys_iter = psys_iter->id.next;
882                 }
883
884                 if( !wanted_obj){  /* requested object not found */
885                         PyErr_Format(PyExc_NameError, "Particle System '%s' not found", name);
886                         return NULL;
887                 }
888
889                 return wanted_obj;
890
891         }else {  /* no arg - return a list of bpy objs all P. systems */
892
893                 PyObject *pylist;
894                 int index = 0;
895
896                 pylist = PyList_New( BLI_countlist( &G.main->particle ));
897                 printf("** list is %d long\n", PyList_Size( pylist));
898                 if( ! pylist ){
899                         return EXPP_ReturnPyObjError( 
900                                 PyExc_MemoryError,
901                                 "could not create ParticleSystem list");
902                 }
903                 
904                 while( psys_iter ){
905                         pyobj = ParticleSystem_CreatePyObject( psys_iter);
906                         if( !pyobj){
907                                 Py_DECREF( pylist );
908                                 return EXPP_ReturnPyObjError(
909                                         PyExc_MemoryError, 
910                                         "could not create ParticleSystem PyObject");
911                         }
912                         PyList_SET_ITEM( pylist, index, pyobj);
913                         printf("name is %s\n", psys_iter->id.name+2);
914                         psys_iter = psys_iter->id.next;
915                         index++;
916                 }
917
918                 return pylist;
919                         
920         }
921                         
922         for( ob = G.main->particlesystem.first; ob; ob = ob->id.next )
923                 if( !strcmp( name, ob->id.name + 2 ) )
924                         break;
925
926         if( !ob )
927                 return EXPP_ReturnPyObjError( PyExc_AttributeError, 
928                                 "object does not exist" );
929
930         blparticlesys = ob->particlesystem.first;
931         
932
933         partsyslist = PyList_New( 0 );
934
935         if (!blparticlesys)
936                 return partsyslist;
937
938         current = ParticleSys_CreatePyObject( blparticlesys, ob );
939         PyList_Append(partsyslist,current);
940
941
942         while((blparticlesys = blparticlesys->next)){
943                 current = ParticleSys_CreatePyObject( blparticlesys, ob );
944                 PyList_Append(partsyslist,current);
945         }
946
947         return partsyslist;
948 #endif
949 }
950
951
952 /*****************************************************************************/
953 /* Function:              ParticleSys_Init                                   */
954 /*****************************************************************************/
955
956 /* create the Blender.Particle.Type constant dict */
957
958 static PyObject *Particle_TypeDict( void )
959 {
960         PyObject *Types = PyConstant_New(  );
961
962         if( Types ) {
963                 BPy_constant *c = ( BPy_constant * ) Types;
964
965                 PyConstant_Insert( c, "HAIR",
966                                  PyInt_FromLong( 2 ) );
967                 PyConstant_Insert( c, "REACTOR",
968                                  PyInt_FromLong( 1 ) );
969                 PyConstant_Insert( c, "EMITTER",
970                                  PyInt_FromLong( 0 ) );
971         }
972         return Types;
973 }
974
975 /* create the Blender.Particle.Distribution constant dict */
976
977 static PyObject *Particle_DistrDict( void )
978 {
979         PyObject *Distr = PyConstant_New(  );
980
981         if( Distr ) {
982                 BPy_constant *c = ( BPy_constant * ) Distr;
983
984                 PyConstant_Insert( c, "GRID",
985                                  PyInt_FromLong( 2 ) );
986                 PyConstant_Insert( c, "RANDOM",
987                                  PyInt_FromLong( 1 ) );
988                 PyConstant_Insert( c, "JITTERED",
989                                  PyInt_FromLong( 0 ) );
990         }
991         return Distr;
992 }
993
994 /* create the Blender.Particle.EmitFrom constant dict */
995
996 static PyObject *Particle_EmitFrom( void )
997 {
998         PyObject *EmitFrom = PyConstant_New(  );
999
1000         if( EmitFrom ) {
1001                 BPy_constant *c = ( BPy_constant * ) EmitFrom;
1002
1003                 PyConstant_Insert( c, "VERTS",
1004                                  PyInt_FromLong( 0 ) );
1005                 PyConstant_Insert( c, "FACES",
1006                                  PyInt_FromLong( 1 ) );
1007                 PyConstant_Insert( c, "VOLUME",
1008                                  PyInt_FromLong( 2 ) );
1009                 PyConstant_Insert( c, "PARTICLE",
1010                                  PyInt_FromLong( 3 ) );
1011         }
1012         return EmitFrom;
1013 }
1014
1015 /* create the Blender.Particle.Collision constant dict */
1016
1017 static PyObject *Particle_ReactOnDict( void )
1018 {
1019         PyObject *ReactOn = PyConstant_New(  );
1020
1021         if( ReactOn ) {
1022                 BPy_constant *c = ( BPy_constant * ) ReactOn;
1023
1024                 PyConstant_Insert( c, "NEAR",
1025                                  PyInt_FromLong( 2 ) );
1026                 PyConstant_Insert( c, "COLLISION",
1027                                  PyInt_FromLong( 1 ) );
1028                 PyConstant_Insert( c, "DEATH",
1029                                  PyInt_FromLong( 0 ) );
1030         }
1031         return ReactOn;
1032 }
1033
1034 /* create the Blender.Particle.Physics constant dict */
1035
1036 static PyObject *Particle_PhysicsDict( void )
1037 {
1038         PyObject *Physics = PyConstant_New(  );
1039
1040         if( Physics ) {
1041                 BPy_constant *c = ( BPy_constant * ) Physics;
1042
1043                 PyConstant_Insert( c, "BOIDS",
1044                                  PyInt_FromLong( 3 ) );
1045                 PyConstant_Insert( c, "KEYED",
1046                                  PyInt_FromLong( 2 ) );
1047                 PyConstant_Insert( c, "NEWTONIAN",
1048                                  PyInt_FromLong( 1 ) );
1049                 PyConstant_Insert( c, "NONE",
1050                                  PyInt_FromLong( 0 ) );
1051         }
1052         return Physics;
1053 }
1054
1055 /* create the Blender.Particle.Integrator constant dict */
1056
1057 static PyObject *Particle_IntegratorDict( void )
1058 {
1059         PyObject *Integrator = PyConstant_New(  );
1060
1061         if( Integrator ) {
1062                 BPy_constant *c = ( BPy_constant * ) Integrator;
1063
1064                 PyConstant_Insert( c, "EULER",
1065                                  PyInt_FromLong( 2 ) );
1066                 PyConstant_Insert( c, "MIDPOINT",
1067                                  PyInt_FromLong( 1 ) );
1068                 PyConstant_Insert( c, "EULER",
1069                                  PyInt_FromLong( 0 ) );
1070         }
1071         return Integrator;
1072 }
1073
1074 /* create the Blender.Particle.Rotation constant dict */
1075
1076 static PyObject *Particle_RotationDict( void )
1077 {
1078         PyObject *Rotation = PyConstant_New(  );
1079
1080         if( Rotation ) {
1081                 BPy_constant *c = ( BPy_constant * ) Rotation;
1082
1083                 PyConstant_Insert( c, "OBZ",
1084                                  PyInt_FromLong( 8 ) );
1085                 PyConstant_Insert( c, "OBY",
1086                                  PyInt_FromLong( 7 ) );
1087                 PyConstant_Insert( c, "OBX",
1088                                  PyInt_FromLong( 6 ) );
1089                 PyConstant_Insert( c, "GLZ",
1090                                  PyInt_FromLong( 5 ) );
1091                 PyConstant_Insert( c, "GLY",
1092                                  PyInt_FromLong( 4 ) );
1093                 PyConstant_Insert( c, "GLX",
1094                                  PyInt_FromLong( 3 ) );
1095                 PyConstant_Insert( c, "VEL",
1096                                  PyInt_FromLong( 2 ) );
1097                 PyConstant_Insert( c, "NOR",
1098                                  PyInt_FromLong( 1 ) );
1099                 PyConstant_Insert( c, "NONE",
1100                                  PyInt_FromLong( 0 ) );
1101         }
1102         return Rotation;
1103 }
1104
1105 /* create the Blender.Particle.AngularV constant dict */
1106
1107 static PyObject *Particle_AngularVDict( void )
1108 {
1109         PyObject *AngularV = PyConstant_New(  );
1110
1111         if( AngularV ) {
1112                 BPy_constant *c = ( BPy_constant * ) AngularV;
1113
1114                 PyConstant_Insert( c, "RANDOM",
1115                                  PyInt_FromLong( 2 ) );
1116                 PyConstant_Insert( c, "SPIN",
1117                                  PyInt_FromLong( 1 ) );
1118                 PyConstant_Insert( c, "NONE",
1119                                  PyInt_FromLong( 0 ) );
1120         }
1121         return AngularV;
1122 }
1123
1124 /* create the Blender.Particle.ChildType constant dict */
1125
1126 static PyObject *Particle_ChildTypeDict( void )
1127 {
1128         PyObject *ChildTypes = PyConstant_New(  );
1129
1130         if( ChildTypes ) {
1131                 BPy_constant *c = ( BPy_constant * ) ChildTypes;
1132
1133                 PyConstant_Insert( c, "FACES",
1134                                  PyInt_FromLong( 2 ) );
1135                 PyConstant_Insert( c, "PARTICLES",
1136                                  PyInt_FromLong( 1 ) );
1137                 PyConstant_Insert( c, "NONE",
1138                                  PyInt_FromLong( 0 ) );
1139         }
1140         return ChildTypes;
1141 }
1142
1143 /* create the Blender.Particle.VertexGroups constant dict */
1144
1145 static PyObject *Particle_VertexGroupsDict( void )
1146 {
1147         PyObject *VertexGroups = PyConstant_New(  );
1148
1149         if( VertexGroups ) {
1150                 BPy_constant *c = ( BPy_constant * ) VertexGroups;
1151
1152                 PyConstant_Insert( c, "EFFECTOR",
1153                                  PyInt_FromLong( 11 ) );
1154                 PyConstant_Insert( c, "TANROT",
1155                                  PyInt_FromLong( 10 ) );
1156                 PyConstant_Insert( c, "TANVEL",
1157                                  PyInt_FromLong( 9 ) );
1158                 PyConstant_Insert( c, "SIZE",
1159                                  PyInt_FromLong( 8 ) );
1160                 PyConstant_Insert( c, "ROUGHE",
1161                                  PyInt_FromLong( 7 ) );
1162                 PyConstant_Insert( c, "ROUGH2",
1163                                  PyInt_FromLong( 6 ) );
1164                 PyConstant_Insert( c, "ROUGH1",
1165                                  PyInt_FromLong( 5 ) );
1166                 PyConstant_Insert( c, "KINK",
1167                                  PyInt_FromLong( 4 ) );
1168                 PyConstant_Insert( c, "CLUMP",
1169                                  PyInt_FromLong( 3 ) );
1170                 PyConstant_Insert( c, "LENGHT",
1171                                  PyInt_FromLong( 2 ) );
1172                 PyConstant_Insert( c, "VELOCITY",
1173                                  PyInt_FromLong( 1 ) );
1174                 PyConstant_Insert( c, "DENSITY",
1175                                  PyInt_FromLong( 0 ) );
1176         }
1177         return VertexGroups;
1178 }
1179
1180
1181 /* create the Blender.Particle.ChildKink constant dict */
1182
1183 static PyObject *Particle_ChildKinkDict( void )
1184 {
1185         PyObject *ChildKinks = PyConstant_New(  );
1186
1187         if( ChildKinks ) {
1188                 BPy_constant *c = ( BPy_constant * ) ChildKinks;
1189
1190                 PyConstant_Insert( c, "BRAID",
1191                                  PyInt_FromLong( 4 ) );
1192                 PyConstant_Insert( c, "WAVE",
1193                                  PyInt_FromLong( 3 ) );
1194                 PyConstant_Insert( c, "RADIAL",
1195                                  PyInt_FromLong( 2 ) );
1196                 PyConstant_Insert( c, "CURL",
1197                                  PyInt_FromLong( 1 ) );
1198                 PyConstant_Insert( c, "NOTHING",
1199                                  PyInt_FromLong( 0 ) );
1200         }
1201         return ChildKinks;
1202 }
1203
1204 /* create the Blender.Particle.ChildKinkAxis constant dict */
1205
1206 static PyObject *Particle_ChildKinkAxisDict( void )
1207 {
1208         PyObject *ChildKinkAxes = PyConstant_New(  );
1209
1210         if( ChildKinkAxes ) {
1211                 BPy_constant *c = ( BPy_constant * ) ChildKinkAxes;
1212
1213                 PyConstant_Insert( c, "Z",
1214                                  PyInt_FromLong( 2 ) );
1215                 PyConstant_Insert( c, "Y",
1216                                  PyInt_FromLong( 1 ) );
1217                 PyConstant_Insert( c, "X",
1218                                  PyInt_FromLong( 0 ) );
1219         }
1220         return ChildKinkAxes;
1221 }
1222
1223 static PyObject *Particle_DrawAs( void )
1224 {
1225         PyObject *DrawAs = PyConstant_New(  );
1226
1227         if( DrawAs ) {
1228                 BPy_constant *c = ( BPy_constant * ) DrawAs;
1229
1230                 PyConstant_Insert( c, "NONE",
1231                                  PyInt_FromLong( 0 ) );
1232                 PyConstant_Insert( c, "POINT",
1233                                  PyInt_FromLong( 1 ) );
1234                 PyConstant_Insert( c, "CIRCLE",
1235                                  PyInt_FromLong( 2 ) );
1236                 PyConstant_Insert( c, "CROSS",
1237                                  PyInt_FromLong( 3 ) );
1238                 PyConstant_Insert( c, "AXIS",
1239                                  PyInt_FromLong( 4 ) );
1240                 PyConstant_Insert( c, "LINE",
1241                                  PyInt_FromLong( 5 ) );
1242                 PyConstant_Insert( c, "PATH",
1243                                  PyInt_FromLong( 6 ) );
1244                 PyConstant_Insert( c, "OBJECT",
1245                                  PyInt_FromLong( 7 ) );
1246                 PyConstant_Insert( c, "GROUP",
1247                                  PyInt_FromLong( 8 ) );
1248                 PyConstant_Insert( c, "BILLBOARD",
1249                                  PyInt_FromLong( 9 ) );
1250         }
1251         return DrawAs;
1252 }
1253
1254 void Particle_Recalc(BPy_PartSys* self,int child){
1255         psys_flush_settings(self->psys->part,0,child );
1256 }
1257
1258 void Particle_RecalcPsys_distr(BPy_PartSys* self,int child){
1259         psys_flush_settings(self->psys->part,PSYS_DISTR,child);
1260 }
1261
1262 PyObject *ParticleSys_Init( void ){
1263         PyObject *submodule;
1264         PyObject *Types;
1265         PyObject *React;
1266         PyObject *EmitFrom;
1267         PyObject *Dist;
1268         PyObject *DrawAs;
1269         PyObject *Physics;
1270         PyObject *Integrator;
1271         PyObject *Rotation;
1272         PyObject *AngularV;
1273         PyObject *ChildTypes;
1274         PyObject *VertexGroups;
1275         PyObject *ChildKinks;
1276         PyObject *ChildKinkAxes;
1277
1278
1279         if( PyType_Ready( &ParticleSys_Type ) < 0)
1280                 return NULL;
1281
1282         Types = Particle_TypeDict ();
1283         React = Particle_ReactOnDict();
1284         EmitFrom = Particle_EmitFrom();
1285         DrawAs = Particle_DrawAs();
1286         Dist = Particle_DistrDict();
1287         Physics = Particle_PhysicsDict();
1288         Integrator = Particle_IntegratorDict();
1289         Rotation = Particle_RotationDict();
1290         AngularV = Particle_AngularVDict();
1291         VertexGroups = Particle_VertexGroupsDict();
1292         ChildTypes = Particle_ChildTypeDict();
1293         ChildKinks = Particle_ChildKinkDict();
1294         ChildKinkAxes = Particle_ChildKinkAxisDict();
1295
1296         submodule = Py_InitModule3( "Blender.Particle", 
1297                                                                 M_ParticleSys_methods, M_ParticleSys_doc );
1298
1299         if( Types )
1300                 PyModule_AddObject( submodule, "TYPE", Types );
1301         if( React )
1302                 PyModule_AddObject( submodule, "REACTON", React );
1303         if( EmitFrom )
1304                 PyModule_AddObject( submodule, "EMITFROM", EmitFrom );
1305         if( Dist )
1306                 PyModule_AddObject( submodule, "DISTRIBUTION", Dist );
1307         if( DrawAs )
1308                 PyModule_AddObject( submodule, "DRAWAS", DrawAs );
1309         if( Physics )
1310                 PyModule_AddObject( submodule, "PHYSICS", Physics );
1311         if( Integrator )
1312                 PyModule_AddObject( submodule, "INTEGRATOR", Integrator );
1313         if( Rotation )
1314                 PyModule_AddObject( submodule, "ROTATION", Rotation );
1315         if( AngularV )
1316                 PyModule_AddObject( submodule, "ANGULARV", AngularV );
1317         if( VertexGroups )
1318                 PyModule_AddObject( submodule, "VERTEXGROUPS", VertexGroups );
1319         if( ChildTypes )
1320                 PyModule_AddObject( submodule, "CHILDTYPE", ChildTypes );
1321         if( ChildKinks )
1322                 PyModule_AddObject( submodule, "CHILDKINK", ChildKinks );
1323         if( ChildKinkAxes )
1324                 PyModule_AddObject( submodule, "CHILDKINKAXIS", ChildKinkAxes );
1325
1326         return ( submodule );
1327 }
1328
1329 static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args ){
1330
1331         if(self->psys->flag & PSYS_EDITED){
1332                 if(self->psys->edit)
1333                         PE_free_particle_edit(self->psys);
1334
1335                 self->psys->flag &= ~PSYS_EDITED;
1336                 self->psys->recalc |= PSYS_RECALC_HAIR;
1337
1338                 DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
1339         }
1340         Py_RETURN_NONE;
1341 }
1342
1343 static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args )
1344 {
1345         ParticleSystem *psys = 0L;
1346         Object *ob = 0L;
1347         PyObject *partlist,*seglist=0L;
1348         ParticleCacheKey **cache,*path;
1349         PyObject* loc = 0L;
1350         ParticleKey state;
1351         DerivedMesh* dm;
1352         float cfra;
1353         int i,j,k;
1354         float vm[4][4],wm[4][4];
1355         int     childexists = 0;
1356         int all = 0;
1357         int id = 0;
1358
1359         cfra = bsystem_time(ob,(float)CFRA,0.0);
1360
1361         if( !PyArg_ParseTuple( args, "|ii", &all,&id ) )
1362                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1363                                 "expected two optional integers as arguments" );
1364
1365         psys = self->psys;
1366         ob = self->object;
1367         
1368         if (!ob || !psys)
1369                 Py_RETURN_NONE;
1370
1371         G.rendering = 1;
1372
1373         /* Just to create a valid rendering context */
1374         psys_render_set(ob,psys,vm,wm,0,0,0);
1375
1376         dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1377         dm->release(dm);
1378
1379         if ( !psys_check_enabled(ob,psys) ){
1380                 G.rendering = 0;
1381                 psys_render_restore(ob,psys);
1382                 Particle_Recalc(self,1);
1383                 Py_RETURN_NONE;
1384         }
1385
1386         partlist = PyList_New( 0 );
1387         if( !partlist ){
1388                 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1389                 goto error;
1390         }
1391
1392         if (psys->part->type == PART_HAIR){
1393                 cache = psys->pathcache;
1394
1395                 if ( ((self->psys->part->draw & PART_DRAW_PARENT) && (self->psys->part->childtype != 0)) || (self->psys->part->childtype == 0) ){
1396
1397                         for(i = 0; i < psys->totpart; i++){
1398                                 seglist = PyList_New( 0 );
1399                                 if (!seglist){
1400                                         PyErr_SetString( PyExc_MemoryError,
1401                                                         "PyList_New() failed" );
1402                                         goto error;
1403                                 }
1404
1405                                 path=cache[i];
1406                                 k = path->steps+1;
1407                                 for( j = 0; j < k ; j++, path++){
1408                                         loc = Py_BuildValue("(fff)",(double)path->co[0],
1409                                                         (double)path->co[1], (double)path->co[2]);
1410
1411                                         if (!loc){
1412                                                 PyErr_SetString( PyExc_RuntimeError,
1413                                                                 "Couldn't build tuple" );
1414                                                 goto error;
1415                                         }
1416
1417                                         if ( (PyList_Append(seglist,loc) < 0) ){
1418                                                 PyErr_SetString( PyExc_RuntimeError,
1419                                                                 "Couldn't append item to PyList" );
1420                                                 goto error;
1421                                         }
1422                                         Py_DECREF(loc); /* PyList_Append increfs */
1423                                         loc = NULL;
1424                                 }
1425
1426                                 if ( PyList_Append(partlist,seglist) < 0 ){
1427                                         PyErr_SetString( PyExc_RuntimeError,
1428                                                         "Couldn't append item to PyList" );             
1429                                         goto error;
1430                                 }
1431                                 Py_DECREF(seglist); /* PyList_Append increfs */
1432                                 seglist = NULL;
1433                         }
1434                 }
1435
1436                 cache=psys->childcache;
1437
1438                 for(i = 0; i < psys->totchild; i++){
1439                         seglist = PyList_New( 0 );
1440                         if (!seglist){
1441                                 PyErr_SetString( PyExc_MemoryError,
1442                                                 "PyList_New() failed" );
1443                                 goto error;
1444                         }
1445
1446                         path=cache[i];
1447                         k = path->steps+1;
1448                         for( j = 0; j < k ; j++, path++ ){
1449                                 loc = Py_BuildValue("(fff)",(double)path->co[0],
1450                                                 (double)path->co[1], (double)path->co[2]);
1451
1452                                 if (!loc){
1453                                         PyErr_SetString( PyExc_RuntimeError,
1454                                                         "Couldn't build tuple" );
1455                                         goto error;
1456                                 }
1457
1458                                 if ( PyList_Append(seglist,loc) < 0){
1459                                         PyErr_SetString( PyExc_RuntimeError,
1460                                                         "Couldn't append item to PyList" );
1461                                         goto error;
1462                                 }
1463                                 Py_DECREF(loc);/* PyList_Append increfs */
1464                                 loc = NULL;
1465                         }
1466
1467                         if ( PyList_Append(partlist,seglist) < 0){
1468                                 PyErr_SetString( PyExc_RuntimeError,
1469                                                 "Couldn't append item to PyList" );     
1470                                 goto error;
1471                         }
1472                         Py_DECREF(seglist); /* PyList_Append increfs */
1473                         seglist = NULL;
1474                 }
1475         } else {
1476                 int init;
1477                 char *fmt = NULL;
1478
1479                 if(id)
1480                         fmt = "(fffi)";
1481                 else
1482                         fmt = "(fff)";
1483
1484                 if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1485                         childexists = 1;
1486
1487                 for (i = 0; i < psys->totpart + psys->totchild; i++){
1488                         if (childexists && (i < psys->totpart))
1489                                 continue;
1490
1491                         state.time = cfra;
1492                         if(psys_get_particle_state(ob,psys,i,&state,0)==0)
1493                                 init = 0;
1494                         else
1495                                 init = 1;
1496
1497                         if (init){
1498                                 loc = Py_BuildValue(fmt,(double)state.co[0],
1499                                                 (double)state.co[1], (double)state.co[2],i);
1500                                 
1501                                 if (!loc){
1502                                         PyErr_SetString( PyExc_RuntimeError,
1503                                                         "Couldn't build tuple" );
1504                                         goto error;
1505                                 }
1506
1507                                 if ( PyList_Append(partlist,loc) < 0 ){
1508                                         PyErr_SetString( PyExc_RuntimeError,
1509                                                         "Couldn't append item to PyList" );
1510                                         goto error;
1511                                 }
1512                                 Py_DECREF(loc);
1513                                 loc = NULL;
1514                         } else {
1515                                 if ( all && PyList_Append(partlist,Py_None) < 0 ){
1516                                         PyErr_SetString( PyExc_RuntimeError,
1517                                                         "Couldn't append item to PyList" );
1518                                         goto error;
1519                                 }
1520                         }
1521                 }
1522         }
1523
1524         psys_render_restore(ob,psys);
1525         G.rendering = 0;
1526         Particle_Recalc(self,1);
1527         return partlist;
1528
1529 error:
1530         Py_XDECREF(partlist);
1531         Py_XDECREF(seglist);
1532         Py_XDECREF(loc);
1533         psys_render_restore(ob,psys);
1534         G.rendering = 0;
1535         Particle_Recalc(self,1);
1536         return NULL;
1537 }
1538
1539 static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args )
1540 {
1541         ParticleSystem *psys = 0L;
1542         Object *ob = 0L;
1543         PyObject *partlist = 0L;
1544         PyObject* loc = 0L;
1545         ParticleKey state;
1546         DerivedMesh* dm;
1547         float vm[4][4],wm[4][4];
1548         int i;
1549         int childexists = 0;
1550         int all = 0;
1551         int id = 0;
1552     char *fmt = NULL;
1553
1554         float cfra=bsystem_time(ob,(float)CFRA,0.0);
1555
1556         if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
1557                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1558                                 "expected two optional integers as arguments" );
1559
1560         psys = self->psys;
1561         ob = self->object;
1562         
1563         if (!ob || !psys)
1564                 Py_RETURN_NONE;
1565
1566         G.rendering = 1;
1567
1568         /* Just to create a valid rendering context */
1569         psys_render_set(ob,psys,vm,wm,0,0,0);
1570
1571         dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1572         dm->release(dm);
1573
1574         if ( !psys_check_enabled(ob,psys) ){
1575                 G.rendering = 0;
1576                 psys_render_restore(ob,psys);
1577                 Particle_Recalc(self,1);
1578                 Py_RETURN_NONE;
1579         }
1580
1581         if (psys->part->type != PART_HAIR){
1582                 partlist = PyList_New( 0 );
1583
1584                 if( !partlist ){
1585                         PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1586                         goto error;
1587                 }
1588
1589                 if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1590                         childexists = 1;
1591
1592                 if(id)
1593                         fmt = "(ffffi)";
1594                 else
1595                         fmt = "(ffff)";
1596
1597                 for (i = 0; i < psys->totpart + psys->totchild; i++){
1598                         if (childexists && (i < psys->totpart))
1599                                 continue;
1600
1601                         state.time = cfra;
1602                         if(psys_get_particle_state(ob,psys,i,&state,0)==0){
1603                                 if ( all && PyList_Append(partlist,Py_None) < 0){
1604                                         PyErr_SetString( PyExc_RuntimeError,
1605                                                 "Couldn't append item to PyList" );
1606                                         goto error;
1607                                 }
1608                         } else {
1609                                 loc = Py_BuildValue(fmt,(double)state.rot[0], (double)state.rot[1],
1610                                                 (double)state.rot[2], (double)state.rot[3], i);
1611
1612                                 if (!loc){
1613                                         PyErr_SetString( PyExc_RuntimeError,
1614                                                         "Couldn't build tuple" );
1615                                         goto error;
1616                                 }
1617                                 if (PyList_Append(partlist,loc) < 0){
1618                                         PyErr_SetString ( PyExc_RuntimeError,
1619                                                         "Couldn't append item to PyList" );
1620                                         goto error;
1621                                 }
1622                                 Py_DECREF(loc); /* PyList_Append increfs */
1623                                 loc = NULL;
1624                         }
1625                 }
1626         } else {
1627                 partlist = EXPP_incr_ret( Py_None );
1628         }
1629
1630         psys_render_restore(ob,psys);
1631         G.rendering = 0;
1632         Particle_Recalc(self,1);
1633         return partlist;
1634
1635 error:
1636         Py_XDECREF(partlist);
1637         Py_XDECREF(loc);
1638         psys_render_restore(ob,psys);
1639         G.rendering = 0;
1640         Particle_Recalc(self,1);
1641         return NULL;
1642 }
1643
1644 static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args )
1645 {
1646         ParticleKey state;
1647         ParticleSystem *psys = 0L;
1648         ParticleData *data;
1649         Object *ob = 0L;
1650         PyObject *partlist,*tuple=0L;
1651         DerivedMesh* dm;
1652         float vm[4][4],wm[4][4];
1653         float size;
1654         int i;
1655         int childexists = 0;
1656         int all = 0;
1657         int id = 0;
1658     char *fmt = NULL;
1659
1660         float cfra=bsystem_time(ob,(float)CFRA,0.0);
1661
1662         if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
1663                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1664                                 "expected two optional integers as arguments" );
1665
1666         psys = self->psys;
1667         ob = self->object;
1668         
1669         if (!ob || !psys)
1670                 Py_RETURN_NONE;
1671
1672         G.rendering = 1;
1673
1674         /* Just to create a valid rendering context */
1675         psys_render_set(ob,psys,vm,wm,0,0,0);
1676
1677         dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1678         dm->release(dm);
1679         data = self->psys->particles;
1680
1681         if ( !psys_check_enabled(ob,psys) ){
1682                 psys_render_restore(ob,psys);
1683                 G.rendering = 0;
1684                 Particle_Recalc(self,1);
1685                 Py_RETURN_NONE;
1686         }
1687
1688         partlist = PyList_New( 0 );
1689
1690         if( !partlist ){
1691                 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1692                 goto error;
1693         }
1694
1695         if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1696                 childexists = 1;
1697
1698         if(id)
1699                 fmt = "(fi)";
1700         else
1701                 fmt = "f";
1702
1703         for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
1704                 if (psys->part->type != PART_HAIR){
1705                         if (childexists && (i < psys->totpart))
1706                                 continue;
1707
1708                         if ( !all ){
1709                                 state.time = cfra;
1710                                 if(psys_get_particle_state(ob,psys,i,&state,0)==0)
1711                                         continue;
1712                         }
1713
1714                         if (i < psys->totpart){
1715                                 size = data->size;
1716                         } else {
1717                                 ChildParticle *cpa= &psys->child[i-psys->totpart];
1718                                 size = psys_get_child_size(psys,cpa,cfra,0);
1719                         }
1720
1721                         tuple = Py_BuildValue(fmt,(double)size,i);
1722
1723                         if (!tuple){
1724                                 PyErr_SetString( PyExc_RuntimeError,
1725                                                 "Couldn't build tuple" );
1726                                 goto error;
1727                         }
1728
1729                         if (PyList_Append(partlist,tuple) < 0){
1730                                 PyErr_SetString( PyExc_RuntimeError,
1731                                                 "Couldn't append item to PyList" );
1732                                 goto error;
1733                         }
1734                         Py_DECREF(tuple);
1735                         tuple = NULL;
1736                 }
1737         }
1738
1739         psys_render_restore(ob,psys);
1740         G.rendering = 0;
1741         Particle_Recalc(self,1);
1742         return partlist;
1743
1744 error:
1745         Py_XDECREF(partlist);
1746         Py_XDECREF(tuple);
1747         psys_render_restore(ob,psys);
1748         G.rendering = 0;
1749         Particle_Recalc(self,1);
1750         return NULL;
1751 }
1752
1753
1754 static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args )
1755 {
1756         ParticleKey state;
1757         ParticleSystem *psys = 0L;
1758         ParticleData *data;
1759         Object *ob = 0L;
1760         PyObject *partlist,*tuple=0L;
1761         DerivedMesh* dm;
1762         float vm[4][4],wm[4][4];
1763         float life;
1764         int i;
1765         int childexists = 0;
1766         int all = 0;
1767         int id = 0;
1768         char *fmt = NULL;
1769
1770         float cfra=bsystem_time(ob,(float)CFRA,0.0);
1771
1772         if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
1773                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1774                                 "expected two optional integers as arguments" );
1775
1776         psys = self->psys;
1777         ob = self->object;
1778         
1779         if (!ob || !psys)
1780                 Py_RETURN_NONE;
1781
1782         G.rendering = 1;
1783
1784         /* Just to create a valid rendering context */
1785         psys_render_set(ob,psys,vm,wm,0,0,0);
1786
1787         dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1788         dm->release(dm);
1789         data = self->psys->particles;
1790
1791         if ( !psys_check_enabled(ob,psys) ){
1792                 psys_render_restore(ob,psys);
1793                 G.rendering = 0;
1794                 Py_RETURN_NONE;
1795         }
1796
1797         partlist = PyList_New( 0 );
1798         if( !partlist ){
1799                 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1800                 goto error;
1801         }
1802
1803         if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1804                 childexists = 1;
1805
1806         if(id)
1807                 fmt = "(fi)";
1808         else
1809                 fmt = "f";
1810
1811         for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
1812                 if (psys->part->type != PART_HAIR){
1813
1814                         if (childexists && (i < psys->totpart))
1815                                 continue;
1816
1817                         if ( !all ){
1818                                 state.time = cfra;
1819                                 if(psys_get_particle_state(ob,psys,i,&state,0)==0)
1820                                         continue;
1821                         }
1822
1823                         if (i < psys->totpart){
1824                                 life = (cfra-data->time)/data->lifetime;
1825                         } else {
1826                                 ChildParticle *cpa= &psys->child[i-psys->totpart];
1827                                 life = psys_get_child_time(psys,cpa,cfra);
1828                         }
1829
1830                         tuple = Py_BuildValue(fmt,(double)life,i);
1831
1832                         if (!tuple){
1833                                 PyErr_SetString( PyExc_RuntimeError,
1834                                                 "Couldn't build tuple" );
1835                                 goto error;
1836                         }
1837
1838                         if (PyList_Append(partlist,tuple) < 0){
1839                                 PyErr_SetString( PyExc_RuntimeError,
1840                                                 "Couldn't append item to PyList" );
1841                                 goto error;
1842                         }
1843                         Py_DECREF(tuple);
1844                         tuple = NULL;
1845                 }
1846         }
1847
1848         psys_render_restore(ob,psys);
1849         G.rendering = 0;
1850         Particle_Recalc(self,1);
1851         return partlist;
1852
1853 error:
1854         Py_XDECREF(partlist);
1855         Py_XDECREF(tuple);
1856         psys_render_restore(ob,psys);
1857         G.rendering = 0;
1858         Particle_Recalc(self,1);
1859         return NULL;
1860 }
1861
1862 static PyObject *Part_SetMat( BPy_PartSys * self, PyObject * args )
1863 {
1864         Object *ob = self->object;
1865         BPy_Material *pymat;
1866         Material *mat;
1867         short index;
1868
1869         if( !PyArg_ParseTuple( args, "O!", &Material_Type, &pymat ) )
1870                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1871                                               "expected Blender Material PyObject" );
1872
1873         mat = pymat->material;
1874
1875         if( ob->totcol >= MAXMAT )
1876                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1877                                               "object data material lists can't have more than 16 materials" );
1878
1879         index = find_material_index(ob,mat);
1880         if (index == 0){        /*Not found*/
1881                 assign_material(ob,mat,ob->totcol+1);
1882                 index = find_material_index(ob,mat);
1883         }
1884
1885         if (index>0 && index<MAXMAT)
1886                 self->psys->part->omat = index;
1887
1888         /* since we have messed with object, we need to flag for DAG recalc */
1889         self->object->recalc |= OB_RECALC_OB;
1890
1891         Py_RETURN_NONE;
1892 }
1893
1894 static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ){
1895         Material *ma;
1896         PyObject* mat = 0L;
1897         ma = give_current_material(self->object,self->psys->part->omat);
1898         if(!ma)
1899                 Py_RETURN_NONE;
1900
1901         mat = Material_CreatePyObject(ma);
1902         return mat;
1903 }
1904
1905 static PyObject *Part_GetVertGroup( BPy_PartSys * self, PyObject * args ){
1906         PyObject *list;
1907         char errstr[128];
1908         bDeformGroup *defGroup = NULL;
1909         Object *obj = self->object;
1910         int vg_attribute = 0;
1911         int vg_number = 0;
1912         int count;
1913         PyObject *vg_neg;
1914         PyObject *vg_name;
1915
1916         if( !obj )
1917                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1918                                               "particle system must be linked to an object first" );
1919         
1920         if( obj->type != OB_MESH )
1921                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1922                                               "linked object is not a mesh" );
1923         
1924         if( !PyArg_ParseTuple( args, "i", &vg_attribute ) )
1925                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1926                                               "expected integer argument" );
1927         
1928         if( vg_attribute < 0 || vg_attribute > PSYS_TOT_VG-1 ){
1929                 sprintf ( errstr, "expected int argument in [0,%d]", PSYS_TOT_VG-1 );
1930                 return EXPP_ReturnPyObjError( PyExc_TypeError, errstr );
1931         }
1932
1933         /*search*/
1934         vg_number = self->psys->vgroup[vg_attribute];
1935         count = 1;
1936         defGroup = obj->defbase.first;
1937         while(count<vg_number && defGroup){
1938                 defGroup = defGroup->next;
1939                 count++;
1940         }
1941
1942         /*vg_name*/
1943         if (defGroup && vg_number>0)
1944                 vg_name = PyString_FromString( defGroup->name );
1945         else
1946                 vg_name = PyString_FromString( "" );
1947         
1948         /*vg_neg*/
1949         vg_neg = PyInt_FromLong( ((long)( self->psys->vg_neg & (1<<vg_attribute) )) > 0 );
1950
1951         list = PyList_New( 2 );
1952         PyList_SET_ITEM( list, 0, vg_name );
1953         PyList_SET_ITEM( list, 1, vg_neg );
1954
1955         return list;
1956 }
1957
1958 static PyObject *Part_SetVertGroup( BPy_PartSys * self, PyObject * args ){
1959         char errstr[128];
1960         bDeformGroup *defGroup;
1961         Object *obj = self->object;
1962         char *vg_name = NULL;
1963         int vg_attribute = 0;
1964         int vg_neg = 0;
1965         int vg_number = 0;
1966         int count;
1967
1968         if( !obj )
1969                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1970                                               "particle system must be linked to an object first" );
1971         
1972         if( obj->type != OB_MESH )
1973                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1974                                               "linked object is not a mesh" );
1975         
1976         if( !PyArg_ParseTuple( args, "sii", &vg_name, &vg_attribute, &vg_neg ) )
1977                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1978                                               "expected one string and two integers arguments" );
1979         
1980         if( vg_attribute < 0 || vg_attribute > PSYS_TOT_VG-1 ){
1981                 sprintf ( errstr, "expected int argument in [0,%d]", PSYS_TOT_VG-1 );
1982                 return EXPP_ReturnPyObjError( PyExc_TypeError, errstr );
1983         }
1984
1985         /*search*/
1986         count = 1;
1987         defGroup = obj->defbase.first;
1988         while (defGroup){
1989                 if (strcmp(vg_name,defGroup->name)==0)
1990                         vg_number = count;
1991                 defGroup = defGroup->next;
1992                 count++;
1993         }
1994
1995         /*vgroup*/
1996         self->psys->vgroup[vg_attribute] = vg_number;
1997
1998         /*vg_neg*/
1999         if (vg_neg){
2000                 self->psys->vg_neg |= (1<<vg_attribute);
2001         }else{
2002                 self->psys->vg_neg &= ~(1<<vg_attribute);
2003         }
2004
2005         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2006
2007         Py_RETURN_NONE;
2008 }
2009
2010
2011 /*****************************************************************************/
2012 /* Function:              Set/Get Seed                                       */
2013 /*****************************************************************************/
2014
2015 static int Part_setSeed( BPy_PartSys * self, PyObject * args )
2016 {
2017         return EXPP_setIValueRange( args, &self->psys->seed,
2018                         0, 255, 'i' );
2019 }
2020
2021 static PyObject *Part_getSeed( BPy_PartSys * self )
2022 {
2023         return PyInt_FromLong( (long)( self->psys->seed ) );
2024 }
2025
2026 static int Part_setType( BPy_PartSys * self, PyObject * args )
2027 {
2028         int res = EXPP_setIValueRange( args, &self->psys->part->type,
2029                         0, 2, 'h' );
2030
2031         psys_flush_settings( self->psys->part, PSYS_TYPE, 1 );
2032
2033         return res;
2034 }
2035
2036 static PyObject *Part_getType( BPy_PartSys * self )
2037 {
2038         return PyInt_FromLong( (short)( self->psys->part->type ) );
2039 }
2040
2041 static int Part_setResol( BPy_PartSys * self, PyObject * args )
2042 {
2043         int res = EXPP_setIValueRange( args, &self->psys->part->grid_res,
2044                         0, 100, 'i' );
2045
2046         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2047
2048         return res;
2049 }
2050
2051 static PyObject *Part_getResol( BPy_PartSys * self )
2052 {
2053         return PyInt_FromLong( ((int)( self->psys->part->grid_res )) );
2054 }
2055
2056 static int Part_setStart( BPy_PartSys * self, PyObject * args )
2057 {
2058         int res = EXPP_setFloatRange( args, &self->psys->part->sta,
2059                         0.0f, 100000.0f );
2060
2061         psys_flush_settings(self->psys->part,PSYS_INIT,1);
2062
2063         return res;
2064 }
2065
2066 static PyObject *Part_getStart( BPy_PartSys * self )
2067 {
2068         return PyFloat_FromDouble( (float)( self->psys->part->sta ) );
2069 }
2070
2071 static int Part_setEnd( BPy_PartSys * self, PyObject * args )
2072 {
2073         int res = EXPP_setFloatRange( args, &self->psys->part->end,
2074                         0.0f, 100000.0f );
2075
2076         psys_flush_settings(self->psys->part,PSYS_INIT,1);
2077
2078         return res;
2079 }
2080
2081 static PyObject *Part_getEnd( BPy_PartSys * self )
2082 {
2083         return PyFloat_FromDouble( (long)( self->psys->part->end ) );
2084 }
2085
2086 static int Part_setEditable( BPy_PartSys * self, PyObject * args )
2087 {
2088         int number;
2089
2090         if( !PyInt_Check( args ) )
2091                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2092
2093         number = PyInt_AS_LONG( args );
2094
2095         if(!number){
2096                 if(self->psys->edit)
2097                         PE_free_particle_edit(self->psys);
2098
2099                 self->psys->flag &= ~PSYS_EDITED;
2100                 self->psys->recalc |= PSYS_RECALC_HAIR;
2101
2102                 DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
2103         }
2104         else
2105         {
2106                 self->psys->flag |= PSYS_EDITED;
2107                 if(G.f & G_PARTICLEEDIT)
2108                         PE_create_particle_edit(self->object, self->psys);
2109         }
2110
2111         return 0;
2112 }
2113
2114 static PyObject *Part_getEditable( BPy_PartSys * self )
2115 {
2116         return PyInt_FromLong( ((long)( self->psys->flag & PSYS_EDITED )) > 0  );
2117 }
2118
2119 static int Part_setAmount( BPy_PartSys * self, PyObject * args )
2120 {
2121         int res = EXPP_setIValueRange( args, &self->psys->part->totpart,
2122                         0, 100000, 'i' );
2123
2124         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2125
2126         return res;
2127 }
2128
2129 static PyObject *Part_getAmount( BPy_PartSys * self )
2130 {
2131         return PyInt_FromLong( ((int)( self->psys->part->totpart )) );
2132 }
2133
2134 static int Part_setMultiReact( BPy_PartSys * self, PyObject * args )
2135 {
2136         int number;
2137
2138         if( !PyInt_Check( args ) )
2139                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2140
2141         number = PyInt_AS_LONG( args );
2142
2143
2144         if (number){
2145                 self->psys->part->flag |= PART_REACT_MULTIPLE;
2146         }else{
2147                 self->psys->part->flag &= ~PART_REACT_MULTIPLE;
2148         }
2149
2150         Particle_Recalc(self,1);
2151
2152         return 0;
2153 }
2154
2155 static PyObject *Part_getMultiReact( BPy_PartSys * self )
2156 {
2157         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_REACT_MULTIPLE )) > 0 );
2158 }
2159
2160 static int Part_setReactShape( BPy_PartSys * self, PyObject * args )
2161 {
2162         int res = EXPP_setFloatRange( args, &self->psys->part->reactshape,
2163                         0.0f, 10.0f );
2164
2165         Particle_Recalc(self,1);
2166
2167         return res;
2168 }
2169
2170 static PyObject *Part_getReactShape( BPy_PartSys * self )
2171 {
2172         return PyFloat_FromDouble( ((double)( self->psys->part->reactshape )) );
2173 }
2174
2175 static int Part_setSegments( BPy_PartSys * self, PyObject * args )
2176 {
2177         int res = EXPP_setIValueRange( args, &self->psys->part->hair_step,
2178                         2, 50, 'h' );
2179
2180         Particle_Recalc(self,1);
2181
2182         return res;
2183 }
2184
2185 static PyObject *Part_getSegments( BPy_PartSys * self )
2186 {
2187         return PyInt_FromLong( ((long)( self->psys->part->hair_step )) );
2188 }
2189
2190 static int Part_setLife( BPy_PartSys * self, PyObject * args )
2191 {
2192         int res = EXPP_setFloatRange( args, &self->psys->part->lifetime,
2193                         1.0f, MAXFRAMEF );
2194
2195         Particle_Recalc(self,1);
2196
2197         return res;
2198 }
2199
2200 static PyObject *Part_getLife( BPy_PartSys * self )
2201 {
2202         return PyFloat_FromDouble( ((double)( self->psys->part->lifetime )) );
2203 }
2204
2205 static int Part_setRandLife( BPy_PartSys * self, PyObject * args )
2206 {
2207         int res = EXPP_setFloatRange( args, &self->psys->part->randlife,
2208                         0.0f, 2.0f );
2209
2210         Particle_Recalc(self,1);
2211
2212         return res;
2213 }
2214
2215 static PyObject *Part_getRandLife( BPy_PartSys * self )
2216 {
2217         return PyFloat_FromDouble( ((double)( self->psys->part->randlife )) );
2218 }
2219
2220 static int Part_set2d( BPy_PartSys * self, PyObject * args )
2221 {
2222         int number;
2223
2224         if( !PyInt_Check( args ) )
2225                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2226
2227         number = PyInt_AS_LONG( args );
2228
2229         if (number){
2230                 self->psys->part->flag |= PART_BOIDS_2D;
2231         }else{
2232                 self->psys->part->flag &= ~PART_BOIDS_2D;
2233         }
2234
2235         Particle_Recalc(self,1);
2236
2237         return 0;
2238 }
2239
2240 static PyObject *Part_get2d( BPy_PartSys * self )
2241 {
2242         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 );
2243 }
2244
2245 static int Part_setMaxVel( BPy_PartSys * self, PyObject * args )
2246 {
2247         int res = EXPP_setFloatRange( args, &self->psys->part->max_vel,
2248                         0.0f, 200.0f );
2249
2250         Particle_Recalc(self,1);
2251
2252         return res;
2253 }
2254
2255 static PyObject *Part_getMaxVel( BPy_PartSys * self )
2256 {
2257         return PyFloat_FromDouble( ((double)( self->psys->part->max_vel )) );
2258 }
2259
2260 static int Part_setAvVel( BPy_PartSys * self, PyObject * args )
2261 {
2262         int res = EXPP_setFloatRange( args, &self->psys->part->average_vel,
2263                         0.0f, 1.0f );
2264
2265         Particle_Recalc(self,1);
2266
2267         return res;
2268 }
2269
2270 static PyObject *Part_getAvVel( BPy_PartSys * self )
2271 {
2272         return PyFloat_FromDouble( ((double)( self->psys->part->average_vel )) );
2273 }
2274
2275 static int Part_setLatAcc( BPy_PartSys * self, PyObject * args )
2276 {
2277         int res = EXPP_setFloatRange( args, &self->psys->part->max_lat_acc,
2278                         0.0f, 1.0f );
2279
2280         Particle_Recalc(self,1);
2281
2282         return res;
2283 }
2284
2285 static PyObject *Part_getLatAcc( BPy_PartSys * self )
2286 {
2287         return PyFloat_FromDouble( ((double)( self->psys->part->max_lat_acc )) );
2288 }
2289
2290 static int Part_setMaxTan( BPy_PartSys * self, PyObject * args )
2291 {
2292         int res = EXPP_setFloatRange( args, &self->psys->part->max_tan_acc,
2293                         0.0f, 1.0f );
2294
2295         Particle_Recalc(self,1);
2296
2297         return res;
2298 }
2299
2300 static PyObject *Part_getMaxTan( BPy_PartSys * self )
2301 {
2302         return PyFloat_FromDouble( ((double)( self->psys->part->max_tan_acc )) );
2303 }
2304
2305 static int Part_setGroundZ( BPy_PartSys * self, PyObject * args )
2306 {
2307         int res = EXPP_setFloatRange( args, &self->psys->part->groundz,
2308                         -100.0f, 100.0f );
2309
2310         Particle_Recalc(self,1);
2311
2312         return res;
2313 }
2314
2315 static PyObject *Part_getGroundZ( BPy_PartSys * self )
2316 {
2317         return PyFloat_FromDouble( ((double)( self->psys->part->groundz )) );
2318 }
2319
2320 static int Part_setOb( BPy_PartSys * self, PyObject * args )
2321 {
2322         Object *obj;
2323         if( !BPy_Object_Check( args ) )
2324                 return EXPP_ReturnIntError( PyExc_TypeError, "expected object argument" );
2325
2326         obj = Object_FromPyObject(args);
2327
2328         self->psys->keyed_ob = obj;
2329
2330         return 0;
2331 }
2332
2333 static PyObject *Part_getOb( BPy_PartSys * self )
2334 {
2335         Object * obj;
2336         obj = self->psys->keyed_ob;
2337         if (!obj)
2338                 Py_RETURN_NONE;
2339
2340         return Object_CreatePyObject( obj );
2341 }
2342
2343 static int Part_setRandEmission( BPy_PartSys * self, PyObject * args )
2344 {
2345         int number;
2346
2347         if( !PyInt_Check( args ) )
2348                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2349
2350         number = PyInt_AS_LONG( args );
2351
2352         if (number){
2353                 self->psys->part->flag |= PART_TRAND;
2354         }else{
2355                 self->psys->part->flag &= ~PART_TRAND;
2356         }
2357
2358         Particle_RecalcPsys_distr(self,1);
2359
2360         return 0;
2361 }
2362
2363 static PyObject *Part_getRandEmission( BPy_PartSys * self )
2364 {
2365         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_TRAND )) > 0 );
2366 }
2367
2368 static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
2369 {
2370         int number;
2371
2372         if( !PyInt_Check( args ) )
2373                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2374
2375         number = PyInt_AS_LONG( args );
2376
2377         if (number < 0 || number > 3)
2378                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument between 0 - 3" );
2379
2380         self->psys->part->from = (short)number;
2381
2382         Particle_RecalcPsys_distr(self,1);
2383
2384         return 0;
2385 }
2386
2387 static PyObject *Part_getParticleDist( BPy_PartSys * self )
2388 {
2389         return PyInt_FromLong( (long)( self->psys->part->from ) );
2390 }
2391
2392 static int Part_setEvenDist( BPy_PartSys * self, PyObject * args )
2393 {
2394         int number;
2395
2396         if( !PyInt_Check( args ) )
2397                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2398
2399         number = PyInt_AS_LONG( args );
2400
2401         if (number){
2402                 self->psys->part->flag |= PART_EDISTR;
2403         }else{
2404                 self->psys->part->flag &= ~PART_EDISTR;
2405         }
2406
2407         Particle_RecalcPsys_distr(self,1);
2408
2409         return 0;
2410 }
2411
2412 static PyObject *Part_getEvenDist( BPy_PartSys * self )
2413 {
2414         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_EDISTR )) > 0 );
2415 }
2416
2417 static int Part_setDist( BPy_PartSys * self, PyObject * args )
2418 {
2419         int number;
2420
2421         if( !PyInt_Check( args ) )
2422                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2423
2424         number = PyInt_AS_LONG( args );
2425
2426         if (number < 0 || number > 2)
2427                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument between 0 - 2" );
2428
2429         self->psys->part->distr = (short)number;
2430
2431         Particle_RecalcPsys_distr(self,1);
2432
2433         return 0;
2434 }
2435
2436 static PyObject *Part_getDist( BPy_PartSys * self )
2437 {
2438         return PyInt_FromLong( (long)( self->psys->part->distr ) );
2439 }
2440
2441 static int Part_setJitterAmount( BPy_PartSys * self, PyObject * args )
2442 {
2443         int res = EXPP_setFloatRange( args, &self->psys->part->jitfac,
2444                         0.0f, 2.0f );
2445
2446         Particle_RecalcPsys_distr(self,1);
2447
2448         return res;
2449 }
2450
2451 static PyObject *Part_getJitterAmount( BPy_PartSys * self )
2452 {
2453         return PyFloat_FromDouble( ((double)( self->psys->part->jitfac )) );
2454 }
2455
2456
2457
2458 static int Part_setPF( BPy_PartSys * self, PyObject * args )
2459 {
2460         int res = EXPP_setIValueRange( args, &self->psys->part->userjit,
2461                         0, 1000, 'i' );
2462
2463         Particle_RecalcPsys_distr(self,1);
2464
2465         return res;
2466 }
2467
2468 static PyObject *Part_getPF( BPy_PartSys * self )
2469 {
2470         return PyInt_FromLong( ((short)( self->psys->part->userjit )) );
2471 }
2472
2473 static int Part_setInvert( BPy_PartSys * self, PyObject * args )
2474 {
2475         int number;
2476
2477         if( !PyInt_Check( args ) )
2478                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2479
2480         number = PyInt_AS_LONG( args );
2481
2482         if (number){
2483                 self->psys->part->flag |= PART_GRID_INVERT;
2484         }else{
2485                 self->psys->part->flag &= ~PART_GRID_INVERT;
2486         }
2487
2488         Particle_RecalcPsys_distr(self,1);
2489
2490         return 0;
2491 }
2492
2493 static PyObject *Part_getInvert( BPy_PartSys * self )
2494 {
2495         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_GRID_INVERT )) > 0 );
2496 }
2497
2498 static int Part_setTargetOb( BPy_PartSys * self, PyObject * args )
2499 {
2500         Object *obj;
2501         
2502         if( !BPy_Object_Check( args ) )
2503                 return EXPP_ReturnIntError( PyExc_TypeError, "expected object argument" );
2504
2505         obj = Object_FromPyObject(args);
2506
2507         self->psys->target_ob = obj;
2508
2509         return 0;
2510 }
2511
2512 static PyObject *Part_getTargetOb( BPy_PartSys * self )
2513 {
2514         Object * obj;
2515         obj = self->psys->target_ob;
2516         if (!obj)
2517                 Py_RETURN_NONE;
2518
2519         return Object_CreatePyObject( obj );
2520 }
2521
2522
2523
2524 PyObject *Part_getDupOb( BPy_PartSys * self )
2525 {
2526         Object * obj;
2527         obj = self->psys->part->dup_ob;
2528         if (!obj)
2529                 Py_RETURN_NONE;
2530
2531         return Object_CreatePyObject( obj );
2532 }
2533
2534 static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args ){
2535         int tottpsys;
2536         int res;
2537         Object *tob=0;
2538         ParticleSystem *psys = self->psys;
2539         Object *ob;
2540
2541         ob = self->object;
2542
2543         if(psys->target_ob)
2544                 tob=psys->target_ob;
2545         else
2546                 tob=ob;
2547
2548         tottpsys = BLI_countlist(&tob->particlesystem);
2549
2550         res = EXPP_setIValueRange( args, &self->psys->target_psys, 0, tottpsys, 'h' );
2551
2552         if( ( psys = psys_get_current(ob) ) ){
2553                 if(psys->keyed_ob==ob || psys->target_ob==ob){
2554                         if(psys->keyed_ob==ob)
2555                                 psys->keyed_ob=NULL;
2556                         else
2557                                 psys->target_ob=NULL;
2558                 }
2559                 else{
2560                         DAG_scene_sort(G.scene);
2561                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
2562                 }
2563         }
2564
2565         return res;
2566 }
2567
2568 static PyObject *Part_getTargetPsys( BPy_PartSys * self ){
2569         return PyInt_FromLong( (short)( self->psys->target_psys ) );
2570 }
2571
2572 static int Part_setRenderObject( BPy_PartSys * self, PyObject * args )
2573 {
2574         int number,nr;
2575         ParticleSystem *psys = 0L;
2576
2577         if( !PyInt_Check( args ) )
2578                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2579
2580         number = PyInt_AS_LONG( args );
2581
2582         if (number){
2583                 self->psys->part->draw |= PART_DRAW_EMITTER;
2584         }else{
2585                 self->psys->part->draw &= ~PART_DRAW_EMITTER;
2586         }
2587
2588         /* check need for dupliobjects */
2589         nr=0;
2590         for(psys=self->object->particlesystem.first; psys; psys=psys->next){
2591                 if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
2592                         nr++;
2593         }
2594         if(nr)
2595                 self->object->transflag |= OB_DUPLIPARTS;
2596         else
2597                 self->object->transflag &= ~OB_DUPLIPARTS;
2598
2599         return 0;
2600 }
2601
2602 static PyObject *Part_getRenderObject( BPy_PartSys * self )
2603 {
2604         return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_EMITTER )) > 0 );
2605 }
2606
2607 static int Part_setRenderMaterialColor( BPy_PartSys * self, PyObject * args )
2608 {
2609         int number;
2610
2611         if( !PyInt_Check( args ) )
2612                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2613
2614         number = PyInt_AS_LONG( args );
2615
2616         if (number){
2617                 self->psys->part->draw |= PART_DRAW_MAT_COL;
2618         }else{
2619                 self->psys->part->draw &= ~PART_DRAW_MAT_COL;
2620         }
2621
2622         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2623
2624         return 0;
2625 }
2626
2627 static PyObject *Part_getRenderMaterialColor( BPy_PartSys * self )
2628 {
2629         return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_MAT_COL )) > 0 );
2630 }
2631
2632 static int Part_setRenderParents( BPy_PartSys * self, PyObject * args )
2633 {
2634         int number;
2635
2636         if( !PyInt_Check( args ) )
2637                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2638
2639         number = PyInt_AS_LONG( args );
2640
2641         if (number){
2642                 self->psys->part->draw |= PART_DRAW_PARENT;
2643         }else{
2644                 self->psys->part->draw &= ~PART_DRAW_PARENT;
2645         }
2646
2647         return 0;
2648 }
2649
2650 static PyObject *Part_getRenderParents( BPy_PartSys * self )
2651 {
2652         return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_PARENT )) > 0 );
2653 }
2654
2655 static int Part_setRenderUnborn( BPy_PartSys * self, PyObject * args )
2656 {
2657         int number;
2658
2659         if( !PyInt_Check( args ) )
2660                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2661
2662         number = PyInt_AS_LONG( args );
2663
2664         if (number){
2665                 self->psys->part->flag |= PART_UNBORN;
2666         }else{
2667                 self->psys->part->flag &= ~PART_UNBORN;
2668         }
2669
2670         return 0;
2671 }
2672
2673 static PyObject *Part_getRenderUnborn( BPy_PartSys * self )
2674 {
2675         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_UNBORN )) > 0 );
2676 }
2677
2678 static int Part_setRenderDied( BPy_PartSys * self, PyObject * args )
2679 {
2680         int number;
2681
2682         if( !PyInt_Check( args ) )
2683                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2684
2685         number = PyInt_AS_LONG( args );
2686
2687         if (number){
2688                 self->psys->part->flag |= PART_DIED;
2689         }else{
2690                 self->psys->part->flag &= ~PART_DIED;
2691         }
2692
2693         return 0;
2694 }
2695
2696 static int Part_setRenderMaterialIndex( BPy_PartSys * self, PyObject * args )
2697 {
2698         int res = EXPP_setIValueRange( args, &self->psys->part->omat,
2699                         1, 16, 'i' );
2700
2701         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2702
2703         return res;
2704 }
2705
2706 static PyObject *Part_getRenderMaterialIndex( BPy_PartSys * self )
2707 {
2708         return PyInt_FromLong( ((int)( self->psys->part->omat )) );
2709 }
2710
2711 static PyObject *Part_getRenderDied( BPy_PartSys * self )
2712 {
2713         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_DIED )) > 0 );
2714 }
2715
2716 static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args )
2717 {
2718         int res = EXPP_setIValueRange( args, &self->psys->part->disp,
2719                         0, 100, 'i' );
2720
2721         Particle_Recalc(self,0);
2722
2723
2724         return res;
2725 }
2726
2727 static PyObject *Part_getParticleDisp( BPy_PartSys * self )
2728 {
2729         return PyInt_FromLong( ((short)( self->psys->part->disp )) );
2730 }
2731
2732 static int Part_setStep( BPy_PartSys * self, PyObject * args )
2733 {
2734         int res = EXPP_setIValueRange( args, &self->psys->part->draw_step,
2735                         0, 7, 'i' );
2736
2737         Particle_Recalc(self,1);
2738
2739
2740         return res;
2741 }
2742
2743 static PyObject *Part_getStep( BPy_PartSys * self )
2744 {
2745         return PyInt_FromLong( ((short)( self->psys->part->draw_step )) );
2746 }
2747
2748 static int Part_setRenderStep( BPy_PartSys * self, PyObject * args )
2749 {
2750         int res = EXPP_setIValueRange( args, &self->psys->part->ren_step,
2751                         0, 7, 'i' );
2752
2753         /*Particle_Recalc(self,1);*/
2754
2755
2756         return res;
2757 }
2758
2759 static PyObject *Part_getRenderStep( BPy_PartSys * self )
2760 {
2761         return PyInt_FromLong( ((short)( self->psys->part->ren_step )) );
2762 }
2763
2764 static PyObject *Part_getDrawAs( BPy_PartSys * self )
2765 {
2766         return PyInt_FromLong( (long)( self->psys->part->draw_as ) );
2767 }
2768
2769 static int Part_setPhysType( BPy_PartSys * self, PyObject * args )
2770 {
2771         int res = EXPP_setIValueRange( args, &self->psys->part->phystype,
2772                         0, 3, 'h' );
2773
2774         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2775
2776         return res;
2777 }
2778
2779 static PyObject *Part_getPhysType( BPy_PartSys * self )
2780 {
2781         return PyInt_FromLong( (short)( self->psys->part->phystype ) );
2782 }
2783
2784 static int Part_setIntegrator( BPy_PartSys * self, PyObject * args )
2785 {
2786         int res = EXPP_setIValueRange( args, &self->psys->part->integrator,
2787                         0, 2, 'h' );
2788
2789         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2790
2791         return res;
2792 }
2793
2794 static PyObject *Part_getIntegrator( BPy_PartSys * self )
2795 {
2796         return PyInt_FromLong( (short)( self->psys->part->integrator ) );
2797 }
2798
2799 static int Part_setIniVelObject( BPy_PartSys * self, PyObject * args )
2800 {
2801         int res = EXPP_setFloatRange( args, &self->psys->part->obfac,
2802                         -1.0, 1.0 );
2803
2804         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2805
2806         return res;
2807 }
2808
2809 static PyObject *Part_getIniVelObject( BPy_PartSys * self )
2810 {
2811         return PyFloat_FromDouble( ((float)( self->psys->part->obfac )) );
2812 }
2813
2814 static int Part_setIniVelNormal( BPy_PartSys * self, PyObject * args )
2815 {
2816         int res = EXPP_setFloatRange( args, &self->psys->part->normfac,
2817                         -200.0, 200.0 );
2818
2819         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2820
2821         return res;
2822 }
2823
2824 static PyObject *Part_getIniVelNormal( BPy_PartSys * self )
2825 {
2826         return PyFloat_FromDouble( ((float)( self->psys->part->normfac )) );
2827 }
2828
2829 static int Part_setIniVelRandom( BPy_PartSys * self, PyObject * args )
2830 {
2831         int res = EXPP_setFloatRange( args, &self->psys->part->randfac,
2832                         0.0, 200.0 );
2833
2834         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2835
2836         return res;
2837 }
2838
2839 static PyObject *Part_getIniVelRandom( BPy_PartSys * self )
2840 {
2841         return PyFloat_FromDouble( ((float)( self->psys->part->randfac )) );
2842 }
2843
2844 static int Part_setIniVelTan( BPy_PartSys * self, PyObject * args )
2845 {
2846         int res = EXPP_setFloatRange( args, &self->psys->part->tanfac,
2847                         -200.0, 200.0 );
2848
2849         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2850
2851         return res;
2852 }
2853
2854 static PyObject *Part_getIniVelTan( BPy_PartSys * self )
2855 {
2856         return PyFloat_FromDouble( ((float)( self->psys->part->tanfac )) );
2857 }
2858
2859 static int Part_setIniVelRot( BPy_PartSys * self, PyObject * args )
2860 {
2861         int res = EXPP_setFloatRange( args, &self->psys->part->tanphase,
2862                         -1.0, 1.0 );
2863
2864         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2865
2866         return res;
2867 }
2868
2869 static PyObject *Part_getIniVelRot( BPy_PartSys * self )
2870 {
2871         return PyFloat_FromDouble( ((float)( self->psys->part->tanphase )) );
2872 }
2873
2874 static int Part_setIniVelPart( BPy_PartSys * self, PyObject * args )
2875 {
2876         int res = EXPP_setFloatRange( args, &self->psys->part->partfac,
2877                         -10.0, 10.0 );
2878
2879         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2880
2881         return res;
2882 }
2883
2884 static PyObject *Part_getIniVelPart( BPy_PartSys * self )
2885 {
2886         return PyFloat_FromDouble( ((float)( self->psys->part->partfac )) );
2887 }
2888
2889 static int Part_setIniVelReact( BPy_PartSys * self, PyObject * args )
2890 {
2891         int res = EXPP_setFloatRange( args, &self->psys->part->reactfac,
2892                         -10.0, 10.0 );
2893
2894         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2895
2896         return res;
2897 }
2898
2899 static PyObject *Part_getIniVelReact( BPy_PartSys * self )
2900 {
2901         return PyFloat_FromDouble( ((float)( self->psys->part->reactfac )) );
2902 }
2903
2904 static int Part_setRotation( BPy_PartSys * self, PyObject * args )
2905 {
2906         int res = EXPP_setIValueRange( args, &self->psys->part->rotmode,
2907                         0, 8, 'h' );
2908
2909         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2910
2911         return res;
2912 }
2913
2914 static PyObject *Part_getRotation( BPy_PartSys * self )
2915 {
2916         return PyInt_FromLong( (short)( self->psys->part->rotmode ) );
2917 }
2918
2919 static int Part_setRotDynamic( BPy_PartSys * self, PyObject * args )
2920 {
2921         int number;
2922
2923         if( !PyInt_Check( args ) )
2924                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
2925
2926         number = PyInt_AS_LONG( args );
2927
2928         if (number){
2929                 self->psys->part->flag |= PART_ROT_DYN;
2930         }else{
2931                 self->psys->part->flag &= ~PART_ROT_DYN;
2932         }
2933
2934         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2935
2936         return 0;
2937 }
2938
2939 static PyObject *Part_getRotDynamic( BPy_PartSys * self )
2940 {
2941         return PyInt_FromLong( ((long)( self->psys->part->flag & PART_ROT_DYN )) > 0 );
2942 }
2943
2944 static int Part_setRotRandom( BPy_PartSys * self, PyObject * args )
2945 {
2946         int res = EXPP_setFloatRange( args, &self->psys->part->randrotfac,
2947                         0.0, 1.0 );
2948
2949         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2950
2951         return res;
2952 }
2953
2954 static PyObject *Part_getRotRandom( BPy_PartSys * self )
2955 {
2956         return PyFloat_FromDouble( ((float)( self->psys->part->randrotfac )) );
2957 }
2958
2959 static int Part_setRotPhase( BPy_PartSys * self, PyObject * args )
2960 {
2961         int res = EXPP_setFloatRange( args, &self->psys->part->phasefac,
2962                         -1.0, 1.0 );
2963
2964         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2965
2966         return res;
2967 }
2968
2969 static PyObject *Part_getRotPhase( BPy_PartSys * self )
2970 {
2971         return PyFloat_FromDouble( ((float)( self->psys->part->phasefac )) );
2972 }
2973
2974 static int Part_setRotPhaseR( BPy_PartSys * self, PyObject * args )
2975 {
2976         int res = EXPP_setFloatRange( args, &self->psys->part->randphasefac,
2977                         0.0, 1.0 );
2978
2979         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2980
2981         return res;
2982 }
2983
2984 static PyObject *Part_getRotPhaseR( BPy_PartSys * self )
2985 {
2986         return PyFloat_FromDouble( ((float)( self->psys->part->randphasefac )) );
2987 }
2988
2989 static int Part_setRotAngularV( BPy_PartSys * self, PyObject * args )
2990 {
2991         int res = EXPP_setIValueRange( args, &self->psys->part->avemode,
2992                         0, 2, 'h' );
2993
2994         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
2995
2996         return res;
2997 }
2998
2999 static PyObject *Part_getRotAngularV( BPy_PartSys * self )
3000 {
3001         return PyInt_FromLong( ((int)( self->psys->part->avemode )) );
3002 }
3003
3004 static int Part_setRotAngularVAm( BPy_PartSys * self, PyObject * args )
3005 {
3006         int res = EXPP_setFloatRange( args, &self->psys->part->avefac,
3007                         -200.0, 200.0 );
3008
3009         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3010
3011         return res;
3012 }
3013
3014 static PyObject *Part_getRotAngularVAm( BPy_PartSys * self )
3015 {
3016         return PyFloat_FromDouble( ((float)( self->psys->part->avefac )) );
3017 }
3018
3019 static int Part_setGlobAccX( BPy_PartSys * self, PyObject * args )
3020 {
3021         int res = EXPP_setFloatRange( args, &self->psys->part->acc[0],
3022                         -200.0, 200.0 );
3023
3024         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3025
3026         return res;
3027 }
3028
3029 static PyObject *Part_getGlobAccX( BPy_PartSys * self )
3030 {
3031         return PyFloat_FromDouble( ((float)( self->psys->part->acc[0] )) );
3032 }
3033
3034 static int Part_setGlobAccY( BPy_PartSys * self, PyObject * args )
3035 {
3036         int res = EXPP_setFloatRange( args, &self->psys->part->acc[1],
3037                         -200.0, 200.0 );
3038
3039         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3040
3041         return res;
3042 }
3043
3044 static PyObject *Part_getGlobAccY( BPy_PartSys * self )
3045 {
3046         return PyFloat_FromDouble( ((float)( self->psys->part->acc[1] )) );
3047 }
3048
3049 static int Part_setGlobAccZ( BPy_PartSys * self, PyObject * args )
3050 {
3051         int res = EXPP_setFloatRange( args, &self->psys->part->acc[2],
3052                         -200.0, 200.0 );
3053
3054         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3055
3056         return res;
3057 }
3058
3059 static PyObject *Part_getGlobAccZ( BPy_PartSys * self )
3060 {
3061         return PyFloat_FromDouble( ((float)( self->psys->part->acc[2] )) );
3062 }
3063
3064 static int Part_setGlobDrag( BPy_PartSys * self, PyObject * args )
3065 {
3066         int res = EXPP_setFloatRange( args, &self->psys->part->dragfac,
3067                         0.0, 1.0 );
3068
3069         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3070
3071         return res;
3072 }
3073
3074 static PyObject *Part_getGlobDrag( BPy_PartSys * self )
3075 {
3076         return PyFloat_FromDouble( ((float)( self->psys->part->dragfac )) );
3077 }
3078
3079 static int Part_setGlobBrown( BPy_PartSys * self, PyObject * args )
3080 {
3081         int res = EXPP_setFloatRange( args, &self->psys->part->brownfac,
3082                         0.0, 200.0 );
3083
3084         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3085
3086         return res;
3087 }
3088
3089 static PyObject *Part_getGlobBrown( BPy_PartSys * self )
3090 {
3091         return PyFloat_FromDouble( ((float)( self->psys->part->brownfac )) );
3092 }
3093
3094 static int Part_setGlobDamp( BPy_PartSys * self, PyObject * args )
3095 {
3096         int res = EXPP_setFloatRange( args, &self->psys->part->dampfac,
3097                         0.0, 1.0 );
3098
3099         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3100
3101         return res;
3102 }
3103
3104 static PyObject *Part_getGlobDamp( BPy_PartSys * self )
3105 {
3106         return PyFloat_FromDouble( ((float)( self->psys->part->dampfac )) );
3107 }
3108
3109 static int Part_setChildAmount( BPy_PartSys * self, PyObject * args )
3110 {
3111         int res = EXPP_setIValueRange( args, &self->psys->part->child_nbr,
3112                         0, MAX_PART_CHILDREN, 'i' );
3113
3114         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3115
3116         return res;
3117 }
3118
3119 static PyObject *Part_getChildAmount( BPy_PartSys * self )
3120 {
3121         return PyInt_FromLong( ((int)( self->psys->part->child_nbr )) );
3122 }
3123
3124 static int Part_setChildType( BPy_PartSys * self, PyObject * args )
3125 {
3126         int res = EXPP_setIValueRange( args, &self->psys->part->childtype,
3127                         0, 2, 'h' );
3128
3129         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3130
3131         return res;
3132 }
3133
3134 static PyObject *Part_getChildType( BPy_PartSys * self )
3135 {
3136         return PyInt_FromLong( (short)( self->psys->part->childtype ) );
3137 }
3138
3139 static int Part_setChildRenderAmount( BPy_PartSys * self, PyObject * args )
3140 {
3141         int res = EXPP_setIValueRange( args, &self->psys->part->ren_child_nbr,
3142                         0, MAX_PART_CHILDREN, 'i' );
3143
3144         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3145
3146         return res;
3147 }
3148
3149 static PyObject *Part_getChildRenderAmount( BPy_PartSys * self )
3150 {
3151         return PyInt_FromLong( ((int)( self->psys->part->ren_child_nbr )) );
3152 }
3153
3154 static int Part_setChildRadius( BPy_PartSys * self, PyObject * args )
3155 {
3156         int res = EXPP_setFloatRange( args, &self->psys->part->childrad,
3157                         0.0, 10.0 );
3158
3159         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3160
3161         return res;
3162 }
3163
3164 static PyObject *Part_getChildRadius( BPy_PartSys * self )
3165 {
3166         return PyFloat_FromDouble( ((float)( self->psys->part->childrad )) );
3167 }
3168
3169 static int Part_setChildRoundness( BPy_PartSys * self, PyObject * args )
3170 {
3171         int res = EXPP_setFloatRange( args, &self->psys->part->childflat,
3172                         0.0, 1.0 );
3173
3174         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3175
3176         return res;
3177 }
3178
3179 static PyObject *Part_getChildRoundness( BPy_PartSys * self )
3180 {
3181         return PyFloat_FromDouble( ((float)( self->psys->part->childflat )) );
3182 }
3183
3184 static int Part_setChildClumping( BPy_PartSys * self, PyObject * args )
3185 {
3186         int res = EXPP_setFloatRange( args, &self->psys->part->clumpfac,
3187                         -1.0, 1.0 );
3188
3189         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3190
3191         return res;
3192 }
3193
3194 static PyObject *Part_getChildClumping( BPy_PartSys * self )
3195 {
3196         return PyFloat_FromDouble( ((float)( self->psys->part->clumpfac )) );
3197 }
3198
3199 static int Part_setChildShape( BPy_PartSys * self, PyObject * args )
3200 {
3201         int res = EXPP_setFloatRange( args, &self->psys->part->clumppow,
3202                         -0.999, 0.999 );
3203
3204         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3205
3206         return res;
3207 }
3208
3209 static PyObject *Part_getChildShape( BPy_PartSys * self )
3210 {
3211         return PyFloat_FromDouble( ((float)( self->psys->part->clumppow )) );
3212 }
3213
3214 static int Part_setChildSize( BPy_PartSys * self, PyObject * args )
3215 {
3216         int res = EXPP_setFloatRange( args, &self->psys->part->childsize,
3217                         0.01, 100.0 );
3218
3219         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3220
3221         return res;
3222 }
3223
3224 static PyObject *Part_getChildSize( BPy_PartSys * self )
3225 {
3226         return PyFloat_FromDouble( ((float)( self->psys->part->childsize )) );
3227 }
3228
3229 static int Part_setChildRandom( BPy_PartSys * self, PyObject * args )
3230 {
3231         int res = EXPP_setFloatRange( args, &self->psys->part->childrandsize,
3232                         0.0, 1.0 );
3233
3234         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3235
3236         return res;
3237 }
3238
3239 static PyObject *Part_getChildRandom( BPy_PartSys * self )
3240 {
3241         return PyFloat_FromDouble( ((float)( self->psys->part->childrandsize )) );
3242 }
3243
3244 static int Part_setChildRough1( BPy_PartSys * self, PyObject * args )
3245 {
3246         int res = EXPP_setFloatRange( args, &self->psys->part->rough1,
3247                         0.0, 10.0 );
3248
3249         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3250
3251         return res;
3252 }
3253
3254 static PyObject *Part_getChildRough1( BPy_PartSys * self )
3255 {
3256         return PyFloat_FromDouble( ((float)( self->psys->part->rough1 )) );
3257 }
3258
3259 static int Part_setChildRough1Size( BPy_PartSys * self, PyObject * args )
3260 {
3261         int res = EXPP_setFloatRange( args, &self->psys->part->rough1_size,
3262                         0.01, 10.0 );
3263
3264         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3265
3266         return res;
3267 }
3268
3269 static PyObject *Part_getChildRough1Size( BPy_PartSys * self )
3270 {
3271         return PyFloat_FromDouble( ((float)( self->psys->part->rough1_size )) );
3272 }
3273
3274 static int Part_setChildRough2( BPy_PartSys * self, PyObject * args )
3275 {
3276         int res = EXPP_setFloatRange( args, &self->psys->part->rough2,
3277                         0.0, 10.0 );
3278
3279         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3280
3281         return res;
3282 }
3283
3284 static PyObject *Part_getChildRough2( BPy_PartSys * self )
3285 {
3286         return PyFloat_FromDouble( ((float)( self->psys->part->rough2 )) );
3287 }
3288
3289 static int Part_setChildRough2Size( BPy_PartSys * self, PyObject * args )
3290 {
3291         int res = EXPP_setFloatRange( args, &self->psys->part->rough2_size,
3292                         0.01, 10.0 );
3293
3294         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3295
3296         return res;
3297 }
3298
3299 static PyObject *Part_getChildRough2Size( BPy_PartSys * self )
3300 {
3301         return PyFloat_FromDouble( ((float)( self->psys->part->rough2_size )) );
3302 }
3303
3304 static int Part_setChildRough2Thres( BPy_PartSys * self, PyObject * args )
3305 {
3306         int res = EXPP_setFloatRange( args, &self->psys->part->rough2_thres,
3307                         0.0, 10.0 );
3308
3309         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3310
3311         return res;
3312 }
3313
3314 static PyObject *Part_getChildRough2Thres( BPy_PartSys * self )
3315 {
3316         return PyFloat_FromDouble( ((float)( self->psys->part->rough2_thres )) );
3317 }
3318
3319 static int Part_setChildRoughE( BPy_PartSys * self, PyObject * args )
3320 {
3321         int res = EXPP_setFloatRange( args, &self->psys->part->rough_end,
3322                         0.0, 10.0 );
3323
3324         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3325
3326         return res;
3327 }
3328
3329 static PyObject *Part_getChildRoughE( BPy_PartSys * self )
3330 {
3331         return PyFloat_FromDouble( ((float)( self->psys->part->rough_end )) );
3332 }
3333
3334 static int Part_setChildRoughEShape( BPy_PartSys * self, PyObject * args )
3335 {
3336         int res = EXPP_setFloatRange( args, &self->psys->part->rough_end_shape,
3337                         0.0, 10.0 );
3338
3339         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3340
3341         return res;
3342 }
3343
3344 static PyObject *Part_getChildRoughEShape( BPy_PartSys * self )
3345 {
3346         return PyFloat_FromDouble( ((float)( self->psys->part->rough_end_shape )) );
3347 }
3348
3349 static int Part_setChildKink( BPy_PartSys * self, PyObject * args )
3350 {
3351         int res = EXPP_setIValueRange( args, &self->psys->part->kink,
3352                         0, 4, 'h' );
3353
3354         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3355
3356         return res;
3357 }
3358
3359 static PyObject *Part_getChildKink( BPy_PartSys * self )
3360 {
3361         return PyInt_FromLong( (short)( self->psys->part->kink ) );
3362 }
3363
3364 static int Part_setChildKinkAxis( BPy_PartSys * self, PyObject * args )
3365 {
3366         int res = EXPP_setIValueRange( args, &self->psys->part->kink_axis,
3367                         0, 2, 'h' );
3368
3369         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3370
3371         return res;
3372 }
3373
3374 static PyObject *Part_getChildKinkAxis( BPy_PartSys * self )
3375 {
3376         return PyInt_FromLong( (short)( self->psys->part->kink_axis ) );
3377 }
3378
3379 static int Part_setChildKinkFreq( BPy_PartSys * self, PyObject * args )
3380 {
3381         int res = EXPP_setFloatRange( args, &self->psys->part->kink_freq,
3382                         0.0, 10.0 );
3383
3384         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3385
3386         return res;
3387 }
3388
3389 static PyObject *Part_getChildKinkFreq( BPy_PartSys * self )
3390 {
3391         return PyFloat_FromDouble( ((float)( self->psys->part->kink_freq )) );
3392 }
3393
3394 static int Part_setChildKinkShape( BPy_PartSys * self, PyObject * args )
3395 {
3396         int res = EXPP_setFloatRange( args, &self->psys->part->kink_shape,
3397                         -0.999, 0.999 );
3398
3399         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3400
3401         return res;
3402 }
3403
3404 static PyObject *Part_getChildKinkShape( BPy_PartSys * self )
3405 {
3406         return PyFloat_FromDouble( ((float)( self->psys->part->kink_shape )) );
3407 }
3408
3409 static int Part_setChildKinkAmp( BPy_PartSys * self, PyObject * args )
3410 {
3411         int res = EXPP_setFloatRange( args, &self->psys->part->kink_amp,
3412                         0.0, 10.0 );
3413
3414         psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
3415
3416         return res;
3417 }
3418
3419 static PyObject *Part_getChildKinkAmp( BPy_PartSys * self )
3420 {
3421         return PyFloat_FromDouble( ((float)( self->psys->part->kink_amp )) );
3422 }
3423
3424 static int Part_setChildBranch( BPy_PartSys * self, PyObject * args )
3425 {
3426         int number;
3427
3428         if( !PyInt_Check( args ) )
3429                 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
3430
3431         number = PyInt_AS_LONG( args );
3432