4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * This is a new part of Blender.
26 * Original version: Jacques Guignot, Jean-Michel Soler
27 * Rewrite : Cedric Paille, Stephen Swaney, Joilnen Leite
29 * ***** END GPL LICENSE BLOCK *****
33 #include "gen_utils.h"
34 #include "BKE_object.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"
47 #include "DNA_modifier_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_material_types.h"
50 #include "BLI_blenlib.h"
55 #include "MEM_guardedalloc.h"
60 static PyObject *M_ParticleSys_New( PyObject * self, PyObject * args );
61 static PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args );
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_GetMat( BPy_PartSys * self, PyObject * args );
68 static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args );
69 static int Part_setSeed( BPy_PartSys * self, PyObject * args );
70 static PyObject *Part_getSeed( BPy_PartSys * self );
71 static int Part_setType( BPy_PartSys * self, PyObject * args );
72 static PyObject *Part_getType( BPy_PartSys * self );
73 static int Part_setResol( BPy_PartSys * self, PyObject * args );
74 static PyObject *Part_getResol( BPy_PartSys * self );
75 static int Part_setStart( BPy_PartSys * self, PyObject * args );
76 static PyObject *Part_getStart( BPy_PartSys * self );
77 static int Part_setEnd( BPy_PartSys * self, PyObject * args );
78 static PyObject *Part_getEnd( BPy_PartSys * self );
79 static int Part_setEditable( BPy_PartSys * self, PyObject * args );
80 static PyObject *Part_getEditable( BPy_PartSys * self );
81 static int Part_setAmount( BPy_PartSys * self, PyObject * args );
82 static PyObject *Part_getAmount( BPy_PartSys * self );
83 static int Part_setMultiReact( BPy_PartSys * self, PyObject * args );
84 static PyObject *Part_getMultiReact( BPy_PartSys * self );
85 static int Part_setReactShape( BPy_PartSys * self, PyObject * args );
86 static PyObject *Part_getReactShape( BPy_PartSys * self );
87 static int Part_setSegments( BPy_PartSys * self, PyObject * args );
88 static PyObject *Part_getSegments( BPy_PartSys * self );
89 static int Part_setLife( BPy_PartSys * self, PyObject * args );
90 static PyObject *Part_getLife( BPy_PartSys * self );
91 static int Part_setRandLife( BPy_PartSys * self, PyObject * args );
92 static PyObject *Part_getRandLife( BPy_PartSys * self );
93 static int Part_set2d( BPy_PartSys * self, PyObject * args );
94 static PyObject *Part_get2d( BPy_PartSys * self );
95 static int Part_setMaxVel( BPy_PartSys * self, PyObject * args );
96 static PyObject *Part_getMaxVel( BPy_PartSys * self );
97 static int Part_setAvVel( BPy_PartSys * self, PyObject * args );
98 static PyObject *Part_getAvVel( BPy_PartSys * self );
99 static int Part_setLatAcc( BPy_PartSys * self, PyObject * args );
100 static PyObject *Part_getLatAcc( BPy_PartSys * self );
101 static int Part_setMaxTan( BPy_PartSys * self, PyObject * args );
102 static PyObject *Part_getMaxTan( BPy_PartSys * self );
103 static int Part_setGroundZ( BPy_PartSys * self, PyObject * args );
104 static PyObject *Part_getGroundZ( BPy_PartSys * self );
105 static int Part_setOb( BPy_PartSys * self, PyObject * args );
106 static PyObject *Part_getOb( BPy_PartSys * self );
107 static PyObject *Part_getRandEmission( BPy_PartSys * self );
108 static int Part_setRandEmission( BPy_PartSys * self, PyObject * args );
109 static PyObject *Part_getRandEmission( BPy_PartSys * self );
110 static int Part_setParticleDist( BPy_PartSys * self, PyObject * args );
111 static PyObject *Part_getParticleDist( BPy_PartSys * self );
112 static int Part_setEvenDist( BPy_PartSys * self, PyObject * args );
113 static PyObject *Part_getEvenDist( BPy_PartSys * self );
114 static int Part_setDist( BPy_PartSys * self, PyObject * args );
115 static PyObject *Part_getDist( BPy_PartSys * self );
116 static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args );
117 static PyObject *Part_getParticleDisp( BPy_PartSys * self );
118 static int Part_setJitterAmount( BPy_PartSys * self, PyObject * args );
119 static PyObject *Part_getJitterAmount( BPy_PartSys * self );
120 static int Part_setPF( BPy_PartSys * self, PyObject * args );
121 static PyObject *Part_getPF( BPy_PartSys * self );
122 static int Part_setInvert( BPy_PartSys * self, PyObject * args );
123 static PyObject *Part_getInvert( BPy_PartSys * self );
124 static int Part_setTargetOb( BPy_PartSys * self, PyObject * args );
125 static PyObject *Part_getTargetOb( BPy_PartSys * self );
126 static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args );
127 static PyObject *Part_getTargetPsys( BPy_PartSys * self );
128 static int Part_setRenderObject( BPy_PartSys * self, PyObject * args );
129 static PyObject *Part_getRenderObject( BPy_PartSys * self );
130 static int Part_setStep( BPy_PartSys * self, PyObject * args );
131 static PyObject *Part_getStep( BPy_PartSys * self );
132 static int Part_setRenderStep( BPy_PartSys * self, PyObject * args );
133 static PyObject *Part_getRenderStep( BPy_PartSys * self );
134 static PyObject *Part_getDupOb( BPy_PartSys * self );
135 static PyObject *Part_getDrawAs( BPy_PartSys * self );
136 static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args );
138 /*****************************************************************************/
139 /* Python Effect_Type callback function prototypes: */
140 /*****************************************************************************/
141 static PyObject *ParticleSys_repr( void );
143 /*****************************************************************************/
144 /* The following string definitions are used for documentation strings. */
145 /* In Python these will be written to the console when doing a */
146 /* Blender.Particle.__doc__ */
147 /*****************************************************************************/
148 static char M_ParticleSys_doc[] = "The Blender Effect module\n\n\
149 This module provides access to **Object Data** in Blender.\n\
151 Get(name) : retreives particle system (as list) with the given name\n";
152 static char M_ParticleSys_Get_doc[] = "xxx";
153 static char M_ParticleSys_New_doc[] = "xxx";
155 /*****************************************************************************/
156 /* Python BPy_ParticleSys methods table: */
157 /*****************************************************************************/
159 static PyMethodDef BPy_ParticleSys_methods[] = {
160 {"freeEdit", ( PyCFunction ) Part_freeEdit,
161 METH_NOARGS, "() - Free from edit mode"},
162 {"getLoc", ( PyCFunction ) Part_GetLoc,
163 METH_VARARGS, "() - Get particles location"},
164 {"getRot", ( PyCFunction ) Part_GetRot,
165 METH_VARARGS, "() - Get particles rotations (list of 4 floats quaternion)"},
166 {"getMat", ( PyCFunction ) Part_GetMat,
167 METH_NOARGS, "() - Get particles material"},
168 {"getSize", ( PyCFunction ) Part_GetSize,
169 METH_VARARGS, "() - Get particles size in a list"},
170 {"getAge", ( PyCFunction ) Part_GetAge,
171 METH_VARARGS, "() - Get particles life in a list"},
172 {NULL, NULL, 0, NULL}
175 /*****************************************************************************/
176 /* Python BPy_ParticleSys attributes get/set structure: */
177 /*****************************************************************************/
178 static PyGetSetDef BPy_ParticleSys_getseters[] = {
181 (getter)Part_getSeed, (setter)Part_setSeed,
182 "Set an offset in the random table",
186 (getter)Part_getType, (setter)Part_setType,
187 "Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] )",
190 (getter)Part_getResol, (setter)Part_setResol,
191 "The resolution of the particle grid",
194 (getter)Part_getStart, (setter)Part_setStart,
195 "Frame # to start emitting particles",
198 (getter)Part_getEnd, (setter)Part_setEnd,
199 "Frame # to stop emitting particles",
202 (getter)Part_getEditable, (setter)Part_setEditable,
203 "Finalize hair to enable editing in particle mode",
206 (getter)Part_getAmount, (setter)Part_setAmount,
207 "The total number of particles",
210 (getter)Part_getMultiReact, (setter)Part_setMultiReact,
211 "React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] )",
214 (getter)Part_getReactShape, (setter)Part_setReactShape,
215 "Power of reaction strength dependence on distance to target",
218 (getter)Part_getSegments, (setter)Part_setSegments,
219 "Amount of hair segments",
222 (getter)Part_getLife, (setter)Part_setLife,
223 "Specify the life span of the particles",
226 (getter)Part_getRandLife, (setter)Part_setRandLife,
227 "Give the particle life a random variation",
230 (getter)Part_getRandEmission, (setter)Part_setRandEmission,
231 "Give the particle life a random variation",
233 {"particleDistribution",
234 (getter)Part_getParticleDist, (setter)Part_setParticleDist,
235 "Where to emit particles from Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )",
238 (getter)Part_getEvenDist, (setter)Part_setEvenDist,
239 "Use even distribution from faces based on face areas or edge lengths",
242 (getter)Part_getDist, (setter)Part_setDist,
243 "How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] )",
246 (getter)Part_getJitterAmount, (setter)Part_setJitterAmount,
247 "Amount of jitter applied to the sampling",
250 (getter)Part_getPF, (setter)Part_setPF,
251 "Emission locations / face (0 = automatic)",
254 (getter)Part_getInvert, (setter)Part_setInvert,
255 "Invert what is considered object and what is not.",
258 (getter)Part_getTargetOb, (setter)Part_setTargetOb,
259 "The object that has the target particle system (empty if same object)",
262 (getter)Part_getTargetPsys, (setter)Part_setTargetPsys,
263 "The target particle system number in the object",
267 (getter)Part_get2d, (setter)Part_set2d,
268 "Constrain boids to a surface",
271 (getter)Part_getMaxVel, (setter)Part_setMaxVel,
275 (getter)Part_getAvVel, (setter)Part_setAvVel,
276 "The usual speed % of max velocity",
279 (getter)Part_getLatAcc, (setter)Part_setLatAcc,
280 "Lateral acceleration % of max velocity",
283 (getter)Part_getMaxTan, (setter)Part_setMaxTan,
284 "Tangential acceleration % of max velocity",
287 (getter)Part_getGroundZ, (setter)Part_setGroundZ,
291 (getter)Part_getOb, (setter)Part_setOb,
292 "Constrain boids to object's surface",
296 (getter)Part_getRenderObject, (setter)Part_setRenderObject,
297 "Render emitter object",
299 {"displayPercentage",
300 (getter)Part_getParticleDisp, (setter)Part_setParticleDisp,
301 "Particle display percentage",
304 (getter)Part_getStep, (setter)Part_setStep,
305 "How many steps paths are drawn with (power of 2)",
308 (getter)Part_getRenderStep, (setter)Part_setRenderStep,
309 "How many steps paths are rendered with (power of 2)",
312 (getter)Part_getDupOb, NULL,
313 "Get the duplicate ob",
316 (getter)Part_getDrawAs, NULL,
317 "Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )",
319 {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
322 /*****************************************************************************/
323 /* Python method structure definition for Blender.Particle module: */
324 /*****************************************************************************/
325 static struct PyMethodDef M_ParticleSys_methods[] = {
326 {"New", ( PyCFunction ) M_ParticleSys_New, METH_VARARGS, M_ParticleSys_New_doc},
327 {"Get", M_ParticleSys_Get, METH_VARARGS, M_ParticleSys_Get_doc},
328 {NULL, NULL, 0, NULL}
331 /*****************************************************************************/
332 /* Python ParticleSys_Type structure definition: */
333 /*****************************************************************************/
334 PyTypeObject ParticleSys_Type = {
335 PyObject_HEAD_INIT( NULL ) /* required py macro */
337 /* For printing, in format "<module>.<name>" */
338 "Blender ParticleSys", /* char *tp_name; */
339 sizeof( BPy_PartSys ), /* int tp_basicsize; */
340 0, /* tp_itemsize; For allocation */
342 /* Methods to implement standard operations */
344 NULL, /* destructor tp_dealloc; */
345 NULL, /* printfunc tp_print; */
346 NULL, /* getattrfunc tp_getattr; */
347 NULL, /* setattrfunc tp_setattr; */
348 NULL, /* cmpfunc tp_compare; */
349 ( reprfunc ) ParticleSys_repr,/* reprfunc tp_repr; */
351 /* Method suites for standard classes */
353 NULL, /* PyNumberMethods *tp_as_number; */
354 NULL, /* PySequenceMethods *tp_as_sequence; */
355 NULL, /* PyMappingMethods *tp_as_mapping; */
357 /* More standard operations (here for binary compatibility) */
359 NULL, /* hashfunc tp_hash; */
360 NULL, /* ternaryfunc tp_call; */
361 NULL, /* reprfunc tp_str; */
362 NULL, /* getattrofunc tp_getattro; */
363 NULL, /* setattrofunc tp_setattro; */
365 /* Functions to access object as input/output buffer */
366 NULL, /* PyBufferProcs *tp_as_buffer; */
368 /*** Flags to define presence of optional/expanded features ***/
369 Py_TPFLAGS_DEFAULT, /* long tp_flags; */
371 NULL, /* char *tp_doc; Documentation string */
372 /*** Assigned meaning in release 2.0 ***/
373 /* call function for all accessible objects */
374 NULL, /* traverseproc tp_traverse; */
376 /* delete references to contained objects */
377 NULL, /* inquiry tp_clear; */
379 /*** Assigned meaning in release 2.1 ***/
380 /*** rich comparisons ***/
381 NULL, /* richcmpfunc tp_richcompare; */
383 /*** weak reference enabler ***/
384 0, /* long tp_weaklistoffset; */
386 /*** Added in release 2.2 ***/
388 NULL, /* getiterfunc tp_iter; */
389 NULL, /* iternextfunc tp_iternext; */
391 /*** Attribute descriptor and subclassing stuff ***/
392 BPy_ParticleSys_methods, /* struct PyMethodDef *tp_methods; */
393 NULL, /* struct PyMemberDef *tp_members; */
394 BPy_ParticleSys_getseters, /* struct PyGetSetDef *tp_getset; */
395 NULL, /* struct _typeobject *tp_base; */
396 NULL, /* PyObject *tp_dict; */
397 NULL, /* descrgetfunc tp_descr_get; */
398 NULL, /* descrsetfunc tp_descr_set; */
399 0, /* long tp_dictoffset; */
400 NULL, /* initproc tp_init; */
401 NULL, /* allocfunc tp_alloc; */
402 NULL, /* newfunc tp_new; */
403 /* Low-level free-memory routine */
404 NULL, /* freefunc tp_free; */
405 /* For PyObject_IS_GC */
406 NULL, /* inquiry tp_is_gc; */
407 NULL, /* PyObject *tp_bases; */
408 /* method resolution order */
409 NULL, /* PyObject *tp_mro; */
410 NULL, /* PyObject *tp_cache; */
411 NULL, /* PyObject *tp_subclasses; */
412 NULL, /* PyObject *tp_weaklist; */
416 /*****************************************************************************/
417 /* Function: PARTICLESYS_repr */
418 /* Description: This is a callback function for the BPy_Effect type. It */
419 /* builds a meaninful string to represent effcte objects. */
420 /*****************************************************************************/
422 static PyObject *ParticleSys_repr( void )
424 return PyString_FromString( "ParticleSys" );
427 /*****************************************************************************/
428 /* Function : P_sys_FromPyObject */
429 /*****************************************************************************/
431 struct ParticleSystem *P_sys_FromPyObject( BPy_PartSys * py_obj )
433 BPy_PartSys *blen_obj;
435 blen_obj = ( BPy_PartSys * ) py_obj;
436 return ( blen_obj->psys );
439 /*****************************************************************************/
440 /* Function : ParticleSysCreatePyObject */
441 /*****************************************************************************/
442 PyObject *ParticleSys_CreatePyObject( ParticleSystem * psystem, Object *ob )
444 BPy_PartSys *blen_object;
447 ( BPy_PartSys * ) PyObject_NEW( BPy_PartSys, &ParticleSys_Type );
450 blen_object->psys = (ParticleSystem *)psystem;
452 blen_object->object = ob;
454 return ( PyObject * ) blen_object;
458 PyObject *M_ParticleSys_New( PyObject * self, PyObject * args ){
459 ParticleSystem *psys = 0;
460 ParticleSystem *rpsys = 0;
462 ParticleSystemModifierData *psmd;
468 if( !PyArg_ParseTuple( args, "s", &name ) )
469 return EXPP_ReturnPyObjError( PyExc_TypeError,
470 "expected string argument" );
472 for( ob = G.main->object.first; ob; ob = ob->id.next )
473 if( !strcmp( name, ob->id.name + 2 ) )
477 return EXPP_ReturnPyObjError( PyExc_AttributeError,
478 "object does not exist" );
480 id = (ID *)psys_new_settings("PSys", G.main);
482 psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
483 psys->pointcache = BKE_ptcache_add();
484 psys->flag |= PSYS_ENABLED;
485 BLI_addtail(&ob->particlesystem,psys);
487 md = modifier_new(eModifierType_ParticleSystem);
488 sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
489 psmd = (ParticleSystemModifierData*) md;
491 BLI_addtail(&ob->modifiers, md);
493 psys->part=(ParticleSettings*)id;
495 psys->flag=PSYS_ENABLED|PSYS_CURRENT;
496 psys->cfra=bsystem_time(ob,(float)G.scene->r.cfra+1,0.0);
499 /* check need for dupliobjects */
502 for(psys=ob->particlesystem.first; psys; psys=psys->next){
503 if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
507 ob->transflag |= OB_DUPLIPARTS;
509 ob->transflag &= ~OB_DUPLIPARTS;
511 BIF_undo_push("Browse Particle System");
513 DAG_scene_sort(G.scene);
514 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
516 return ParticleSys_CreatePyObject(rpsys,ob);
522 Get( name ) returns named particle sys or list of all
523 throws NameError if name not found
527 PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args )
529 ParticleSettings *psys_iter;
533 ParticleSystem *blparticlesys = 0;
536 PyObject *partsyslist,*current;
538 if( !PyArg_ParseTuple( args, "|s", &name ) )
539 return EXPP_ReturnPyObjError( PyExc_TypeError,
540 "expected string argument" );
542 psys_iter = G.main->particle.first; /* initialize our iterator */
544 if( name ) { /* find psys by name */
546 PyObject *wanted_obj = NULL;
548 while( psys_iter && ! wanted_obj ){
549 if( !strcmp( name, psys_iter->id.name + 2)){
550 printf("** found %s\n", psys_iter->id.name+2);
551 //wanted_obj = ParticleSys_CreatePyObject( psys_iter );
554 psys_iter = psys_iter->id.next;
557 if( !wanted_obj){ /* requested object not found */
559 PyOS_snprintf( error_msg, sizeof( error_msg ),
560 "Particle System '%s' not found", name);
561 return EXPP_ReturnPyObjError( PyExc_NameError, error_msg );
566 }else { /* no arg - return a list of bpy objs all P. systems */
571 pylist = PyList_New( BLI_countlist( &G.main->particle ));
572 printf("** list is %d long\n", PyList_Size( pylist));
574 return EXPP_ReturnPyObjError(
576 "could not create ParticleSystem list");
581 pyobj = ParticleSystem_CreatePyObject( psys_iter);
584 return EXPP_ReturnPyObjError(
586 "could not create ParticleSystem PyObject");
588 PyList_SET_ITEM( pylist, index, pyobj);
590 printf("name is %s\n", psys_iter->id.name+2);
591 psys_iter = psys_iter->id.next;
603 for( ob = G.main->particlesystem.first; ob; ob = ob->id.next )
604 if( !strcmp( name, ob->id.name + 2 ) )
608 return EXPP_ReturnPyObjError( PyExc_AttributeError,
609 "object does not exist" );
611 blparticlesys = ob->particlesystem.first;
614 partsyslist = PyList_New( 0 );
619 current = ParticleSys_CreatePyObject( blparticlesys, ob );
620 PyList_Append(partsyslist,current);
623 while((blparticlesys = blparticlesys->next)){
624 current = ParticleSys_CreatePyObject( blparticlesys, ob );
625 PyList_Append(partsyslist,current);
634 /*****************************************************************************/
635 /* Function: ParticleSys_Init */
636 /*****************************************************************************/
638 /* create the Blender.Particle.Type constant dict */
640 static PyObject *Particle_TypeDict( void )
642 PyObject *Types = PyConstant_New( );
645 BPy_constant *c = ( BPy_constant * ) Types;
647 PyConstant_Insert( c, "HAIR",
648 PyInt_FromLong( 2 ) );
649 PyConstant_Insert( c, "REACTOR",
650 PyInt_FromLong( 1 ) );
651 PyConstant_Insert( c, "EMITTER",
652 PyInt_FromLong( 0 ) );
657 /* create the Blender.Particle.Distribution constant dict */
659 static PyObject *Particle_DistrDict( void )
661 PyObject *Distr = PyConstant_New( );
664 BPy_constant *c = ( BPy_constant * ) Distr;
666 PyConstant_Insert( c, "GRID",
667 PyInt_FromLong( 2 ) );
668 PyConstant_Insert( c, "RANDOM",
669 PyInt_FromLong( 1 ) );
670 PyConstant_Insert( c, "JITTERED",
671 PyInt_FromLong( 0 ) );
676 /* create the Blender.Particle.EmitFrom constant dict */
678 static PyObject *Particle_EmitFrom( void )
680 PyObject *EmitFrom = PyConstant_New( );
683 BPy_constant *c = ( BPy_constant * ) EmitFrom;
685 PyConstant_Insert( c, "VERTS",
686 PyInt_FromLong( 0 ) );
687 PyConstant_Insert( c, "FACES",
688 PyInt_FromLong( 1 ) );
689 PyConstant_Insert( c, "VOLUME",
690 PyInt_FromLong( 2 ) );
691 PyConstant_Insert( c, "PARTICLE",
692 PyInt_FromLong( 3 ) );
697 /* create the Blender.Particle.Collision constant dict */
699 static PyObject *Particle_ReactOnDict( void )
701 PyObject *ReactOn = PyConstant_New( );
704 BPy_constant *c = ( BPy_constant * ) ReactOn;
706 PyConstant_Insert( c, "NEAR",
707 PyInt_FromLong( 2 ) );
708 PyConstant_Insert( c, "COLLISION",
709 PyInt_FromLong( 1 ) );
710 PyConstant_Insert( c, "DEATH",
711 PyInt_FromLong( 0 ) );
716 static PyObject *Particle_DrawAs( void )
718 PyObject *DrawAs = PyConstant_New( );
721 BPy_constant *c = ( BPy_constant * ) DrawAs;
723 PyConstant_Insert( c, "NONE",
724 PyInt_FromLong( 0 ) );
725 PyConstant_Insert( c, "POINT",
726 PyInt_FromLong( 1 ) );
727 PyConstant_Insert( c, "CIRCLE",
728 PyInt_FromLong( 2 ) );
729 PyConstant_Insert( c, "CROSS",
730 PyInt_FromLong( 3 ) );
731 PyConstant_Insert( c, "AXIS",
732 PyInt_FromLong( 4 ) );
733 PyConstant_Insert( c, "LINE",
734 PyInt_FromLong( 5 ) );
735 PyConstant_Insert( c, "PATH",
736 PyInt_FromLong( 6 ) );
737 PyConstant_Insert( c, "OBJECT",
738 PyInt_FromLong( 7 ) );
739 PyConstant_Insert( c, "GROUP",
740 PyInt_FromLong( 8 ) );
741 PyConstant_Insert( c, "BILLBOARD",
742 PyInt_FromLong( 9 ) );
747 void Particle_Recalc(BPy_PartSys* self,int child){
748 psys_flush_settings(self->psys->part,0,child );
751 void Particle_RecalcPsys_distr(BPy_PartSys* self,int child){
752 psys_flush_settings(self->psys->part,PSYS_DISTR,child);
755 PyObject *ParticleSys_Init( void ){
763 if( PyType_Ready( &ParticleSys_Type ) < 0)
766 Types = Particle_TypeDict ();
767 React = Particle_ReactOnDict();
768 EmitFrom = Particle_EmitFrom();
769 DrawAs = Particle_DrawAs();
770 Dist = Particle_DistrDict();
772 submodule = Py_InitModule3( "Blender.Particle",
773 M_ParticleSys_methods, M_ParticleSys_doc );
776 PyModule_AddObject( submodule, "TYPE", Types );
778 PyModule_AddObject( submodule, "REACTON", React );
780 PyModule_AddObject( submodule, "EMITFROM", EmitFrom );
782 PyModule_AddObject( submodule, "DISTRIBUTION", Dist );
784 PyModule_AddObject( submodule, "DRAWAS", DrawAs );
786 return ( submodule );
789 static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args ){
791 if(self->psys->flag & PSYS_EDITED){
793 PE_free_particle_edit(self->psys);
795 self->psys->flag &= ~PSYS_EDITED;
796 self->psys->recalc |= PSYS_RECALC_HAIR;
798 DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
803 static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args )
805 ParticleSystem *psys = 0L;
807 PyObject *partlist,*seglist=0L;
808 ParticleCacheKey **cache,*path;
814 float vm[4][4],wm[4][4];
819 cfra = bsystem_time(ob,(float)CFRA,0.0);
821 if( !PyArg_ParseTuple( args, "|ii", &all,&id ) )
822 return EXPP_ReturnPyObjError( PyExc_TypeError,
823 "expected two optional integers as arguments" );
833 /* Just to create a valid rendering context */
834 psys_render_set(ob,psys,vm,wm,0,0,0);
836 dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
839 if ( !psys_check_enabled(ob,psys) ){
841 psys_render_restore(ob,psys);
842 Particle_Recalc(self,1);
846 partlist = PyList_New( 0 );
848 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
852 if (psys->part->type == PART_HAIR){
853 cache = psys->pathcache;
855 if ( ((self->psys->part->draw & PART_DRAW_PARENT) && (self->psys->part->childtype != 0)) || (self->psys->part->childtype == 0) ){
857 for(i = 0; i < psys->totpart; i++){
858 seglist = PyList_New( 0 );
860 PyErr_SetString( PyExc_MemoryError,
861 "PyList_New() failed" );
867 for( j = 0; j < k ; j++, path++){
868 loc = Py_BuildValue("(fff)",(double)path->co[0],
869 (double)path->co[1], (double)path->co[2]);
872 PyErr_SetString( PyExc_RuntimeError,
873 "Couldn't build tuple" );
877 if ( (PyList_Append(seglist,loc) < 0) ){
878 PyErr_SetString( PyExc_RuntimeError,
879 "Couldn't append item to PyList" );
882 Py_DECREF(loc); /* PyList_Append increfs */
886 if ( PyList_Append(partlist,seglist) < 0 ){
887 PyErr_SetString( PyExc_RuntimeError,
888 "Couldn't append item to PyList" );
891 Py_DECREF(seglist); /* PyList_Append increfs */
896 cache=psys->childcache;
898 for(i = 0; i < psys->totchild; i++){
899 seglist = PyList_New( 0 );
901 PyErr_SetString( PyExc_MemoryError,
902 "PyList_New() failed" );
908 for( j = 0; j < k ; j++, path++ ){
909 loc = Py_BuildValue("(fff)",(double)path->co[0],
910 (double)path->co[1], (double)path->co[2]);
913 PyErr_SetString( PyExc_RuntimeError,
914 "Couldn't build tuple" );
918 if ( PyList_Append(seglist,loc) < 0){
919 PyErr_SetString( PyExc_RuntimeError,
920 "Couldn't append item to PyList" );
923 Py_DECREF(loc);/* PyList_Append increfs */
927 if ( PyList_Append(partlist,seglist) < 0){
928 PyErr_SetString( PyExc_RuntimeError,
929 "Couldn't append item to PyList" );
932 Py_DECREF(seglist); /* PyList_Append increfs */
944 if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
947 for (i = 0; i < psys->totpart + psys->totchild; i++){
948 if (childexists && (i < psys->totpart))
952 if(psys_get_particle_state(ob,psys,i,&state,0)==0)
958 loc = Py_BuildValue(fmt,(double)state.co[0],
959 (double)state.co[1], (double)state.co[2],i);
962 PyErr_SetString( PyExc_RuntimeError,
963 "Couldn't build tuple" );
967 if ( PyList_Append(partlist,loc) < 0 ){
968 PyErr_SetString( PyExc_RuntimeError,
969 "Couldn't append item to PyList" );
975 if ( all && PyList_Append(partlist,Py_None) < 0 ){
976 PyErr_SetString( PyExc_RuntimeError,
977 "Couldn't append item to PyList" );
984 psys_render_restore(ob,psys);
986 Particle_Recalc(self,1);
990 Py_XDECREF(partlist);
993 psys_render_restore(ob,psys);
995 Particle_Recalc(self,1);
999 static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args )
1001 ParticleSystem *psys = 0L;
1003 PyObject *partlist = 0L;
1007 float vm[4][4],wm[4][4];
1009 int childexists = 0;
1014 float cfra=bsystem_time(ob,(float)CFRA,0.0);
1016 if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
1017 return EXPP_ReturnPyObjError( PyExc_TypeError,
1018 "expected two optional integers as arguments" );
1028 /* Just to create a valid rendering context */
1029 psys_render_set(ob,psys,vm,wm,0,0,0);
1031 dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1034 if ( !psys_check_enabled(ob,psys) ){
1036 psys_render_restore(ob,psys);
1037 Particle_Recalc(self,1);
1041 if (psys->part->type != PART_HAIR){
1042 partlist = PyList_New( 0 );
1045 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1049 if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1057 for (i = 0; i < psys->totpart + psys->totchild; i++){
1058 if (childexists && (i < psys->totpart))
1062 if(psys_get_particle_state(ob,psys,i,&state,0)==0){
1063 if ( all && PyList_Append(partlist,Py_None) < 0){
1064 PyErr_SetString( PyExc_RuntimeError,
1065 "Couldn't append item to PyList" );
1069 loc = Py_BuildValue(fmt,(double)state.rot[0], (double)state.rot[1],
1070 (double)state.rot[2], (double)state.rot[3], i);
1073 PyErr_SetString( PyExc_RuntimeError,
1074 "Couldn't build tuple" );
1077 if (PyList_Append(partlist,loc) < 0){
1078 PyErr_SetString ( PyExc_RuntimeError,
1079 "Couldn't append item to PyList" );
1082 Py_DECREF(loc); /* PyList_Append increfs */
1087 partlist = EXPP_incr_ret( Py_None );
1090 psys_render_restore(ob,psys);
1092 Particle_Recalc(self,1);
1096 Py_XDECREF(partlist);
1098 psys_render_restore(ob,psys);
1100 Particle_Recalc(self,1);
1104 static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args )
1107 ParticleSystem *psys = 0L;
1110 PyObject *partlist,*tuple=0L;
1112 float vm[4][4],wm[4][4];
1115 int childexists = 0;
1120 float cfra=bsystem_time(ob,(float)CFRA,0.0);
1122 if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
1123 return EXPP_ReturnPyObjError( PyExc_TypeError,
1124 "expected two optional integers as arguments" );
1134 /* Just to create a valid rendering context */
1135 psys_render_set(ob,psys,vm,wm,0,0,0);
1137 dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1139 data = self->psys->particles;
1141 if ( !psys_check_enabled(ob,psys) ){
1142 psys_render_restore(ob,psys);
1144 Particle_Recalc(self,1);
1148 partlist = PyList_New( 0 );
1151 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1155 if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1163 for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
1164 if (psys->part->type != PART_HAIR){
1165 if (childexists && (i < psys->totpart))
1170 if(psys_get_particle_state(ob,psys,i,&state,0)==0)
1174 if (i < psys->totpart){
1177 ChildParticle *cpa= &psys->child[i-psys->totpart];
1178 size = psys_get_child_size(psys,cpa,cfra,0);
1181 tuple = Py_BuildValue(fmt,(double)size,i);
1184 PyErr_SetString( PyExc_RuntimeError,
1185 "Couldn't build tuple" );
1189 if (PyList_Append(partlist,tuple) < 0){
1190 PyErr_SetString( PyExc_RuntimeError,
1191 "Couldn't append item to PyList" );
1199 psys_render_restore(ob,psys);
1201 Particle_Recalc(self,1);
1205 Py_XDECREF(partlist);
1207 psys_render_restore(ob,psys);
1209 Particle_Recalc(self,1);
1214 static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args )
1217 ParticleSystem *psys = 0L;
1220 PyObject *partlist,*tuple=0L;
1222 float vm[4][4],wm[4][4];
1225 int childexists = 0;
1230 float cfra=bsystem_time(ob,(float)CFRA,0.0);
1232 if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
1233 return EXPP_ReturnPyObjError( PyExc_TypeError,
1234 "expected two optional integers as arguments" );
1244 /* Just to create a valid rendering context */
1245 psys_render_set(ob,psys,vm,wm,0,0,0);
1247 dm = mesh_create_derived_render(ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
1249 data = self->psys->particles;
1251 if ( !psys_check_enabled(ob,psys) ){
1252 psys_render_restore(ob,psys);
1257 partlist = PyList_New( 0 );
1259 PyErr_SetString( PyExc_MemoryError, "PyList_New() failed" );
1263 if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
1271 for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
1272 if (psys->part->type != PART_HAIR){
1274 if (childexists && (i < psys->totpart))
1279 if(psys_get_particle_state(ob,psys,i,&state,0)==0)
1283 if (i < psys->totpart){
1284 life = (cfra-data->time)/data->lifetime;
1286 ChildParticle *cpa= &psys->child[i-psys->totpart];
1287 life = psys_get_child_time(psys,cpa,cfra);
1290 tuple = Py_BuildValue(fmt,(double)life,i);
1293 PyErr_SetString( PyExc_RuntimeError,
1294 "Couldn't build tuple" );
1298 if (PyList_Append(partlist,tuple) < 0){
1299 PyErr_SetString( PyExc_RuntimeError,
1300 "Couldn't append item to PyList" );
1308 psys_render_restore(ob,psys);
1310 Particle_Recalc(self,1);
1314 Py_XDECREF(partlist);
1316 psys_render_restore(ob,psys);
1318 Particle_Recalc(self,1);
1323 static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ){
1326 ma = give_current_material(self->object,self->psys->part->omat);
1330 mat = Material_CreatePyObject(ma);
1335 /*****************************************************************************/
1336 /* Function: Set/Get Seed */
1337 /*****************************************************************************/
1339 static int Part_setSeed( BPy_PartSys * self, PyObject * args )
1341 return EXPP_setIValueRange( args, &self->psys->seed,
1345 static PyObject *Part_getSeed( BPy_PartSys * self )
1347 return PyInt_FromLong( (long)( self->psys->seed ) );
1350 static int Part_setType( BPy_PartSys * self, PyObject * args )
1352 int res = EXPP_setIValueRange( args, &self->psys->part->type,
1355 psys_flush_settings( self->psys->part, PSYS_TYPE, 1 );
1360 static PyObject *Part_getType( BPy_PartSys * self )
1362 return PyInt_FromLong( (short)( self->psys->part->type ) );
1365 static int Part_setResol( BPy_PartSys * self, PyObject * args )
1367 int res = EXPP_setIValueRange( args, &self->psys->part->grid_res,
1370 psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
1375 static PyObject *Part_getResol( BPy_PartSys * self )
1377 return PyInt_FromLong( ((int)( self->psys->part->grid_res )) );
1380 static int Part_setStart( BPy_PartSys * self, PyObject * args )
1382 int res = EXPP_setFloatRange( args, &self->psys->part->sta,
1385 psys_flush_settings(self->psys->part,PSYS_INIT,1);
1390 static PyObject *Part_getStart( BPy_PartSys * self )
1392 return PyFloat_FromDouble( (float)( self->psys->part->sta ) );
1395 static int Part_setEnd( BPy_PartSys * self, PyObject * args )
1397 int res = EXPP_setFloatRange( args, &self->psys->part->end,
1400 psys_flush_settings(self->psys->part,PSYS_INIT,1);
1405 static PyObject *Part_getEnd( BPy_PartSys * self )
1407 return PyFloat_FromDouble( (long)( self->psys->part->end ) );
1410 static int Part_setEditable( BPy_PartSys * self, PyObject * args )
1414 if( !PyInt_Check( args ) ) {
1416 sprintf ( errstr, "expected int argument" );
1417 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1420 number = PyInt_AS_LONG( args );
1423 if(self->psys->edit)
1424 PE_free_particle_edit(self->psys);
1426 self->psys->flag &= ~PSYS_EDITED;
1427 self->psys->recalc |= PSYS_RECALC_HAIR;
1429 DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
1433 self->psys->flag |= PSYS_EDITED;
1434 if(G.f & G_PARTICLEEDIT)
1435 PE_create_particle_edit(self->object, self->psys);
1441 static PyObject *Part_getEditable( BPy_PartSys * self )
1443 return PyInt_FromLong( ((long)( self->psys->flag & PSYS_EDITED )) > 0 );
1446 static int Part_setAmount( BPy_PartSys * self, PyObject * args )
1448 int res = EXPP_setIValueRange( args, &self->psys->part->totpart,
1451 psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
1456 static PyObject *Part_getAmount( BPy_PartSys * self )
1458 return PyInt_FromLong( ((int)( self->psys->part->totpart )) );
1461 static int Part_setMultiReact( BPy_PartSys * self, PyObject * args )
1465 if( !PyInt_Check( args ) ) {
1467 sprintf ( errstr, "expected int argument" );
1468 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1471 number = PyInt_AS_LONG( args );
1475 self->psys->part->flag |= PART_REACT_MULTIPLE;
1477 self->psys->part->flag &= ~PART_REACT_MULTIPLE;
1480 Particle_Recalc(self,1);
1485 static PyObject *Part_getMultiReact( BPy_PartSys * self )
1487 return PyInt_FromLong( ((long)( self->psys->part->flag & PART_REACT_MULTIPLE )) > 0 );
1490 static int Part_setReactShape( BPy_PartSys * self, PyObject * args )
1492 int res = EXPP_setFloatRange( args, &self->psys->part->reactshape,
1495 Particle_Recalc(self,1);
1500 static PyObject *Part_getReactShape( BPy_PartSys * self )
1502 return PyFloat_FromDouble( ((double)( self->psys->part->reactshape )) );
1505 static int Part_setSegments( BPy_PartSys * self, PyObject * args )
1507 int res = EXPP_setIValueRange( args, &self->psys->part->hair_step,
1510 Particle_Recalc(self,1);
1515 static PyObject *Part_getSegments( BPy_PartSys * self )
1517 return PyInt_FromLong( ((long)( self->psys->part->hair_step )) );
1520 static int Part_setLife( BPy_PartSys * self, PyObject * args )
1522 int res = EXPP_setFloatRange( args, &self->psys->part->lifetime,
1525 Particle_Recalc(self,1);
1530 static PyObject *Part_getLife( BPy_PartSys * self )
1532 return PyFloat_FromDouble( ((double)( self->psys->part->lifetime )) );
1535 static int Part_setRandLife( BPy_PartSys * self, PyObject * args )
1537 int res = EXPP_setFloatRange( args, &self->psys->part->randlife,
1540 Particle_Recalc(self,1);
1545 static PyObject *Part_getRandLife( BPy_PartSys * self )
1547 return PyFloat_FromDouble( ((double)( self->psys->part->randlife )) );
1550 static int Part_set2d( BPy_PartSys * self, PyObject * args )
1554 if( !PyInt_Check( args ) )
1555 return EXPP_ReturnIntError( PyExc_TypeError, "expected int argument" );
1557 number = PyInt_AS_LONG( args );
1560 self->psys->part->flag |= PART_BOIDS_2D;
1562 self->psys->part->flag &= ~PART_BOIDS_2D;
1565 Particle_Recalc(self,1);
1570 static PyObject *Part_get2d( BPy_PartSys * self )
1572 return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 );
1575 static int Part_setMaxVel( BPy_PartSys * self, PyObject * args )
1577 int res = EXPP_setFloatRange( args, &self->psys->part->max_vel,
1580 Particle_Recalc(self,1);
1585 static PyObject *Part_getMaxVel( BPy_PartSys * self )
1587 return PyFloat_FromDouble( ((double)( self->psys->part->max_vel )) );
1590 static int Part_setAvVel( BPy_PartSys * self, PyObject * args )
1592 int res = EXPP_setFloatRange( args, &self->psys->part->average_vel,
1595 Particle_Recalc(self,1);
1600 static PyObject *Part_getAvVel( BPy_PartSys * self )
1602 return PyFloat_FromDouble( ((double)( self->psys->part->average_vel )) );
1605 static int Part_setLatAcc( BPy_PartSys * self, PyObject * args )
1607 int res = EXPP_setFloatRange( args, &self->psys->part->max_lat_acc,
1610 Particle_Recalc(self,1);
1615 static PyObject *Part_getLatAcc( BPy_PartSys * self )
1617 return PyFloat_FromDouble( ((double)( self->psys->part->max_lat_acc )) );
1620 static int Part_setMaxTan( BPy_PartSys * self, PyObject * args )
1622 int res = EXPP_setFloatRange( args, &self->psys->part->max_tan_acc,
1625 Particle_Recalc(self,1);
1630 static PyObject *Part_getMaxTan( BPy_PartSys * self )
1632 return PyFloat_FromDouble( ((double)( self->psys->part->max_tan_acc )) );
1635 static int Part_setGroundZ( BPy_PartSys * self, PyObject * args )
1637 int res = EXPP_setFloatRange( args, &self->psys->part->groundz,
1640 Particle_Recalc(self,1);
1645 static PyObject *Part_getGroundZ( BPy_PartSys * self )
1647 return PyFloat_FromDouble( ((double)( self->psys->part->groundz )) );
1650 static int Part_setOb( BPy_PartSys * self, PyObject * args )
1653 if( !BPy_Object_Check( args ) ) {
1655 sprintf ( errstr, "expected object argument" );
1656 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1659 obj = Object_FromPyObject(args);
1661 self->psys->keyed_ob = obj;
1666 static PyObject *Part_getOb( BPy_PartSys * self )
1669 obj = self->psys->keyed_ob;
1673 return Object_CreatePyObject( obj );
1676 static int Part_setRandEmission( BPy_PartSys * self, PyObject * args )
1680 if( !PyInt_Check( args ) ) {
1682 sprintf ( errstr, "expected int argument" );
1683 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1686 number = PyInt_AS_LONG( args );
1689 self->psys->part->flag |= PART_TRAND;
1691 self->psys->part->flag &= ~PART_TRAND;
1694 Particle_RecalcPsys_distr(self,1);
1699 static PyObject *Part_getRandEmission( BPy_PartSys * self )
1701 return PyInt_FromLong( ((long)( self->psys->part->flag & PART_TRAND )) > 0 );
1704 static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
1709 if( !PyInt_Check( args ) ) {
1710 sprintf ( errstr, "expected int argument" );
1711 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1714 number = PyInt_AS_LONG( args );
1716 if (number < 0 || number > 3){
1717 sprintf ( errstr, "expected int argument between 0 - 3" );
1718 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1721 self->psys->part->from = (short)number;
1723 Particle_RecalcPsys_distr(self,1);
1728 static PyObject *Part_getParticleDist( BPy_PartSys * self )
1730 return PyInt_FromLong( (long)( self->psys->part->from ) );
1733 static int Part_setEvenDist( BPy_PartSys * self, PyObject * args )
1737 if( !PyInt_Check( args ) ) {
1739 sprintf ( errstr, "expected int argument" );
1740 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1743 number = PyInt_AS_LONG( args );
1746 self->psys->part->flag |= PART_EDISTR;
1748 self->psys->part->flag &= ~PART_EDISTR;
1751 Particle_RecalcPsys_distr(self,1);
1756 static PyObject *Part_getEvenDist( BPy_PartSys * self )
1758 return PyInt_FromLong( ((long)( self->psys->part->flag & PART_EDISTR )) > 0 );
1761 static int Part_setDist( BPy_PartSys * self, PyObject * args )
1766 if( !PyInt_Check( args ) ) {
1767 sprintf ( errstr, "expected int argument" );
1768 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1771 number = PyInt_AS_LONG( args );
1773 if (number < 0 || number > 2){
1774 sprintf ( errstr, "expected int argument between 0 - 2" );
1775 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1778 self->psys->part->distr = (short)number;
1780 Particle_RecalcPsys_distr(self,1);
1785 static PyObject *Part_getDist( BPy_PartSys * self )
1787 return PyInt_FromLong( (long)( self->psys->part->distr ) );
1790 static int Part_setJitterAmount( BPy_PartSys * self, PyObject * args )
1792 int res = EXPP_setFloatRange( args, &self->psys->part->jitfac,
1795 Particle_RecalcPsys_distr(self,1);
1800 static PyObject *Part_getJitterAmount( BPy_PartSys * self )
1802 return PyFloat_FromDouble( ((double)( self->psys->part->jitfac )) );
1807 static int Part_setPF( BPy_PartSys * self, PyObject * args )
1809 int res = EXPP_setIValueRange( args, &self->psys->part->userjit,
1812 Particle_RecalcPsys_distr(self,1);
1817 static PyObject *Part_getPF( BPy_PartSys * self )
1819 return PyInt_FromLong( ((short)( self->psys->part->userjit )) );
1822 static int Part_setInvert( BPy_PartSys * self, PyObject * args )
1826 if( !PyInt_Check( args ) ) {
1828 sprintf ( errstr, "expected int argument" );
1829 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1832 number = PyInt_AS_LONG( args );
1835 self->psys->part->flag |= PART_GRID_INVERT;
1837 self->psys->part->flag &= ~PART_GRID_INVERT;
1840 Particle_RecalcPsys_distr(self,1);
1845 static PyObject *Part_getInvert( BPy_PartSys * self )
1847 return PyInt_FromLong( ((long)( self->psys->part->flag & PART_GRID_INVERT )) > 0 );
1850 static int Part_setTargetOb( BPy_PartSys * self, PyObject * args )
1853 if( !BPy_Object_Check( args ) ) {
1855 sprintf ( errstr, "expected object argument" );
1856 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1859 obj = Object_FromPyObject(args);
1861 self->psys->target_ob = obj;
1866 static PyObject *Part_getTargetOb( BPy_PartSys * self )
1869 obj = self->psys->target_ob;
1873 return Object_CreatePyObject( obj );
1878 PyObject *Part_getDupOb( BPy_PartSys * self )
1881 obj = self->psys->part->dup_ob;
1885 return Object_CreatePyObject( obj );
1888 static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args ){
1892 ParticleSystem *psys = self->psys;
1898 tob=psys->target_ob;
1902 tottpsys = BLI_countlist(&tob->particlesystem);
1904 res = EXPP_setIValueRange( args, &self->psys->target_psys, 0, tottpsys, 'h' );
1906 if( ( psys = psys_get_current(ob) ) ){
1907 if(psys->keyed_ob==ob || psys->target_ob==ob){
1908 if(psys->keyed_ob==ob)
1909 psys->keyed_ob=NULL;
1911 psys->target_ob=NULL;
1914 DAG_scene_sort(G.scene);
1915 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1922 static PyObject *Part_getTargetPsys( BPy_PartSys * self ){
1923 return PyInt_FromLong( (short)( self->psys->target_psys ) );
1926 static int Part_setRenderObject( BPy_PartSys * self, PyObject * args )
1929 ParticleSystem *psys = 0L;
1931 if( !PyInt_Check( args ) ) {
1933 sprintf ( errstr, "expected int argument" );
1934 return EXPP_ReturnIntError( PyExc_TypeError, errstr );
1937 number = PyInt_AS_LONG( args );
1940 self->psys->part->draw |= PART_DRAW_EMITTER;
1942 self->psys->part->draw &= ~PART_DRAW_EMITTER;
1945 /* check need for dupliobjects */
1947 for(psys=self->object->particlesystem.first; psys; psys=psys->next){
1948 if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
1952 self->object->transflag |= OB_DUPLIPARTS;
1954 self->object->transflag &= ~OB_DUPLIPARTS;
1959 static PyObject *Part_getRenderObject( BPy_PartSys * self )
1961 return PyInt_FromLong( ((long)( self->psys->part->draw & PART_DRAW_EMITTER )) > 0 );
1964 static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args )
1966 int res = EXPP_setIValueRange( args, &self->psys->part->disp,
1969 Particle_Recalc(self,0);
1975 static PyObject *Part_getParticleDisp( BPy_PartSys * self )
1977 return PyInt_FromLong( ((short)( self->psys->part->disp )) );
1980 static int Part_setStep( BPy_PartSys * self, PyObject * args )
1982 int res = EXPP_setIValueRange( args, &self->psys->part->draw_step,
1985 Particle_Recalc(self,1);
1991 static PyObject *Part_getStep( BPy_PartSys * self )
1993 return PyInt_FromLong( ((short)( self->psys->part->draw_step )) );
1996 static int Part_setRenderStep( BPy_PartSys * self, PyObject * args )
1998 int res = EXPP_setIValueRange( args, &self->psys->part->ren_step,
2001 /*Particle_Recalc(self,1);*/
2007 static PyObject *Part_getRenderStep( BPy_PartSys * self )
2009 return PyInt_FromLong( ((short)( self->psys->part->ren_step )) );
2012 static PyObject *Part_getDrawAs( BPy_PartSys * self )
2014 return PyInt_FromLong( (long)( self->psys->part->draw_as ) );