f35d15bbb80ceadf47f7f24088bb776adc1b23eb
[blender.git] / release / ui / buttons_particle.py
1
2 import bpy
3
4 def particle_panel_enabled(psys):
5         return psys.point_cache.baked==False and psys.editable==False
6         
7 def particle_panel_poll(context):
8         psys = context.particle_system
9         if psys==None:  return False
10         if psys.settings==None:  return False
11         return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
12
13 class ParticleButtonsPanel(bpy.types.Panel):
14         __space_type__ = "BUTTONS_WINDOW"
15         __region_type__ = "WINDOW"
16         __context__ = "particle"
17
18         def poll(self, context):
19                 return particle_panel_poll(context)
20
21 class PARTICLE_PT_particles(ParticleButtonsPanel):
22         __show_header__ = False
23
24         def poll(self, context):
25                 return (context.particle_system or context.object)
26
27         def draw(self, context):
28                 layout = self.layout
29                 ob = context.object
30                 psys = context.particle_system
31
32                 if ob:
33                         row = layout.row()
34
35                         row.template_list(ob, "particle_systems", ob, "active_particle_system_index")
36
37                         col = row.column(align=True)
38                         col.itemO("object.particle_system_add", icon="ICON_ZOOMIN", text="")
39                         col.itemO("object.particle_system_remove", icon="ICON_ZOOMOUT", text="")
40
41                 if psys:
42                         part = psys.settings
43                         
44                         split = layout.split(percentage=0.32)
45                         col = split.column()
46                         col.itemL(text="Name:")
47                         if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
48                                 col.itemL(text="Settings:")
49                                 col.itemL(text="Type:")
50                         
51                         col = split.column()
52                         col.itemR(psys, "name", text="")
53                         if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
54                                 col.template_ID(psys, "settings", new="particle.new")
55                         
56                         #row = layout.row()
57                         #row.itemL(text="Viewport")
58                         #row.itemL(text="Render")
59                         
60                         if part:
61                                 if part.type not in ('EMITTER', 'REACTOR', 'HAIR'):
62                                         layout.itemL(text="No settings for fluid particles")
63                                         return
64                                 
65                                 row=col.row()
66                                 row.enabled = particle_panel_enabled(psys)
67                                 row.itemR(part, "type", text="")
68                                 row.itemR(psys, "seed")
69                                 
70                                 split = layout.split(percentage=0.65)
71                                 if part.type=='HAIR':
72                                         if psys.editable==True:
73                                                 split.itemO("particle.editable_set", text="Free Edit")
74                                         else:
75                                                 split.itemO("particle.editable_set", text="Make Editable")
76                                         row = split.row()
77                                         row.enabled = particle_panel_enabled(psys)
78                                         row.itemR(part, "hair_step")
79                                 elif part.type=='REACTOR':
80                                         split.enabled = particle_panel_enabled(psys)
81                                         split.itemR(psys, "reactor_target_object")
82                                         split.itemR(psys, "reactor_target_particle_system", text="Particle System")
83                 
84 class PARTICLE_PT_emission(ParticleButtonsPanel):
85         __label__ = "Emission"
86         
87         def poll(self, context):
88                 if particle_panel_poll(context):
89                         return not context.particle_system.point_cache.external
90                 else:
91                         return False
92         
93         def draw(self, context):
94                 layout = self.layout
95
96                 psys = context.particle_system
97                 part = psys.settings
98                 
99                 layout.enabled = particle_panel_enabled(psys)
100                 
101                 row = layout.row()
102                 row.itemR(part, "amount")
103                 
104                 split = layout.split()
105                 
106                 col = split.column(align=True)
107                 col.itemR(part, "start")
108                 col.itemR(part, "end")
109
110                 col = split.column(align=True)
111                 col.itemR(part, "lifetime")
112                 col.itemR(part, "random_lifetime", slider=True)
113                 
114                 layout.row().itemL(text="Emit From:")
115                 
116                 row = layout.row()
117                 row.itemR(part, "emit_from", expand=True)
118                 row = layout.row()
119                 row.itemR(part, "trand")
120                 if part.distribution!='GRID':
121                         row.itemR(part, "even_distribution")
122                 
123                 if part.emit_from=='FACE' or part.emit_from=='VOLUME':
124                         row = layout.row()
125                         row.itemR(part, "distribution", expand=True)
126                         
127                         row = layout.row()
128
129                         if part.distribution=='JIT':
130                                 row.itemR(part, "userjit", text="Particles/Face")
131                                 row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
132                         elif part.distribution=='GRID':
133                                 row.itemR(part, "grid_resolution")
134
135 class PARTICLE_PT_cache(ParticleButtonsPanel):
136         __label__ = "Cache"
137         __default_closed__ = True
138         
139         def poll(self, context):
140                 psys = context.particle_system
141                 if psys==None:  return False
142                 if psys.settings==None:  return False
143                 phystype = psys.settings.physics_type
144                 if phystype == 'NO' or phystype == 'KEYED':
145                         return False
146                 return psys.settings.type in ('EMITTER', 'REACTOR')
147
148         def draw(self, context):
149                 layout = self.layout
150
151                 psys = context.particle_system
152                 part = psys.settings
153                 cache = psys.point_cache
154                 
155                 row = layout.row()
156                 row.itemL(text="File Name:")
157                 row.itemR(cache, "external")
158                 
159                 if cache.external:
160                         split = layout.split(percentage=0.80)
161                         split.itemR(cache, "name", text="")
162                         split.itemR(cache, "index", text="")
163                         
164                         layout.itemL(text="File Path:")
165                         layout.itemR(cache, "filepath", text="")
166                         
167                         layout.itemL(text=cache.info)
168                         
169                         split = layout.split()
170                         
171                         col = split.column(align=True)
172                         col.itemR(part, "start")
173                         col.itemR(part, "end")
174
175                         col = split.column(align=True)
176                         col.itemR(part, "lifetime")
177                         col.itemR(part, "random_lifetime", slider=True)
178                 else:
179                         layout.itemR(cache, "name", text="")
180                         
181                         row = layout.row()
182                 
183                         if cache.baked == True:
184                                 row.itemO("ptcache.free_bake_particle_system", text="Free Bake")
185                         else:
186                                 row.item_booleanO("ptcache.cache_particle_system", "bake", True, text="Bake")
187                 
188                         subrow = row.row()
189                         subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
190                         subrow.itemO("ptcache.cache_particle_system", text="Calculate to Current Frame")
191                         
192                         row = layout.row()
193                         row.enabled = particle_panel_enabled(psys)
194                         row.itemO("ptcache.bake_from_particles_cache", text="Current Cache to Bake")
195                         row.itemR(cache, "step");
196                 
197                         row = layout.row()
198                         row.enabled = particle_panel_enabled(psys)
199                         row.itemR(cache, "quick_cache")
200                         row.itemR(cache, "disk_cache")
201                 
202                         layout.itemL(text=cache.info)
203                         
204                         layout.itemS()
205                         
206                         row = layout.row()
207                         row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
208                         row.itemO("ptcache.free_bake_all", text="Free All Bakes")
209                         layout.itemO("ptcache.bake_all", text="Update All Dynamics to current frame")
210                 
211                 # for particles these are figured out automatically
212                 #row.itemR(cache, "start_frame")
213                 #row.itemR(cache, "end_frame")
214
215 class PARTICLE_PT_initial(ParticleButtonsPanel):
216         __label__ = "Velocity"
217         
218         def poll(self, context):
219                 if particle_panel_poll(context):
220                         psys = context.particle_system
221                         return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
222                 else:
223                         return False
224
225         def draw(self, context):
226                 layout = self.layout
227
228                 psys = context.particle_system
229                 part = psys.settings
230                 
231                 layout.enabled = particle_panel_enabled(psys)
232                                 
233                 layout.row().itemL(text="Direction:")
234         
235                 split = layout.split()
236                         
237                 sub = split.column()
238                 sub.itemR(part, "normal_factor")
239                 if part.emit_from=='PARTICLE':
240                         sub.itemR(part, "particle_factor")
241                 else:
242                         sub.itemR(part, "object_factor", slider=True)
243                 sub.itemR(part, "random_factor")
244                 sub.itemR(part, "tangent_factor")
245                 sub.itemR(part, "tangent_phase", slider=True)
246                 
247                 sub = split.column()
248                 sub.itemL(text="TODO:")
249                 sub.itemL(text="Object aligned")
250                 sub.itemL(text="direction: X, Y, Z")
251                 
252                 if part.type=='REACTOR':
253                         sub.itemR(part, "reactor_factor")
254                         sub.itemR(part, "reaction_shape", slider=True)
255                 else:
256                         sub.itemL(text="")
257                 
258                 layout.row().itemL(text="Rotation:")
259                 split = layout.split()
260                         
261                 sub = split.column()
262                 
263                 sub.itemR(part, "rotation_mode", text="Axis")
264                 split = layout.split()
265                         
266                 sub = split.column()
267                 sub.itemR(part, "rotation_dynamic")
268                 sub.itemR(part, "random_rotation_factor", slider=True)
269                 sub = split.column()
270                 sub.itemR(part, "phase_factor", slider=True)
271                 sub.itemR(part, "random_phase_factor", text="Random", slider=True)
272
273                 layout.row().itemL(text="Angular velocity:")
274                 layout.row().itemR(part, "angular_velocity_mode", expand=True)
275                 split = layout.split()
276                         
277                 sub = split.column()
278                 
279                 sub.itemR(part, "angular_velocity_factor", text="")
280                 
281 class PARTICLE_PT_physics(ParticleButtonsPanel):
282         __label__ = "Physics"
283         
284         def poll(self, context):
285                 if particle_panel_poll(context):
286                         return not context.particle_system.point_cache.external
287                 else:
288                         return False
289
290         def draw(self, context):
291                 layout = self.layout
292
293                 psys = context.particle_system
294                 part = psys.settings
295                 
296                 layout.enabled = particle_panel_enabled(psys)
297
298                 row = layout.row()
299                 row.itemR(part, "physics_type", expand=True)
300                 if part.physics_type != 'NO':
301                         row = layout.row()
302                         col = row.column(align=True)
303                         col.itemR(part, "particle_size")
304                         col.itemR(part, "random_size", slider=True)
305                         col = row.column(align=True)
306                         col.itemR(part, "mass")
307                         col.itemR(part, "sizemass", text="Multiply mass with size")
308                         
309                 if part.physics_type == 'NEWTON':
310                         split = layout.split()
311                         sub = split.column()
312                         
313                         sub.itemL(text="Forces:")
314                         sub.itemR(part, "brownian_factor")
315                         sub.itemR(part, "drag_factor", slider=True)
316                         sub.itemR(part, "damp_factor", slider=True)
317                         sub.itemR(part, "integrator")
318                         sub = split.column()
319                         sub.itemR(part, "acceleration")
320                         
321                 elif part.physics_type == 'KEYED':
322                         split = layout.split()
323                         sub = split.column()
324                         
325                         row = layout.row()
326                         col = row.column()
327                         col.active = not psys.keyed_timing
328                         col.itemR(part, "keyed_loops", text="Loops")
329                         row.itemR(psys, "keyed_timing", text="Use Timing")
330                         
331                         layout.itemL(text="Keys:")
332                 elif part.physics_type=='BOIDS':
333                         boids = part.boids
334                         
335
336                         row = layout.row()
337                         row.itemR(boids, "allow_flight")
338                         row.itemR(boids, "allow_land")
339                         row.itemR(boids, "allow_climb")
340                         
341                         split = layout.split()
342                         
343                         sub = split.column()
344                         col = sub.column(align=True)
345                         col.active = boids.allow_flight
346                         col.itemR(boids, "air_max_speed")
347                         col.itemR(boids, "air_min_speed", slider="True")
348                         col.itemR(boids, "air_max_acc", slider="True")
349                         col.itemR(boids, "air_max_ave", slider="True")
350                         col.itemR(boids, "air_personal_space")
351                         row = col.row()
352                         row.active = (boids.allow_land or boids.allow_climb) and boids.allow_flight
353                         row.itemR(boids, "landing_smoothness")
354                         
355                         sub = split.column()
356                         col = sub.column(align=True)
357                         col.active = boids.allow_land or boids.allow_climb
358                         col.itemR(boids, "land_max_speed")
359                         col.itemR(boids, "land_jump_speed")
360                         col.itemR(boids, "land_max_acc", slider="True")
361                         col.itemR(boids, "land_max_ave", slider="True")
362                         col.itemR(boids, "land_personal_space")
363                         col.itemR(boids, "land_stick_force")
364                         
365                         row = layout.row()
366                         
367                         col = row.column(align=True)
368                         col.itemL(text="Battle:")
369                         col.itemR(boids, "health")
370                         col.itemR(boids, "strength")
371                         col.itemR(boids, "aggression")
372                         col.itemR(boids, "accuracy")
373                         col.itemR(boids, "range")
374                         
375                         col = row.column()
376                         col.itemL(text="Misc:")
377                         col.itemR(part, "gravity")
378                         col.itemR(boids, "banking", slider=True)
379                         col.itemR(boids, "height", slider=True)
380                         
381                 if part.physics_type=='NEWTON':
382                         sub.itemR(part, "size_deflect")
383                         sub.itemR(part, "die_on_collision")
384                         sub.itemR(part, "sticky")
385                 elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
386                         if part.physics_type=='BOIDS':
387                                 layout.itemL(text="Relations:")
388                         
389                         row = layout.row()
390                         row.template_list(psys, "targets", psys, "active_particle_target_index")
391                         
392                         col = row.column()
393                         subrow = col.row()
394                         subcol = subrow.column(align=True)
395                         subcol.itemO("particle.new_target", icon="ICON_ZOOMIN", text="")
396                         subcol.itemO("particle.remove_target", icon="ICON_ZOOMOUT", text="")
397                         subrow = col.row()
398                         subcol = subrow.column(align=True)
399                         subcol.itemO("particle.target_move_up", icon="VICON_MOVE_UP", text="")
400                         subcol.itemO("particle.target_move_down", icon="VICON_MOVE_DOWN", text="")
401                         
402                         key = psys.active_particle_target
403                         if key:
404                                 row = layout.row()
405                                 if part.physics_type=='KEYED':
406                                         col = row.column()
407                                         #doesn't work yet
408                                         #col.red_alert = key.valid
409                                         col.itemR(key, "object", text="")
410                                         col.itemR(key, "system", text="System")
411                                         col = row.column();
412                                         col.active = psys.keyed_timing
413                                         col.itemR(key, "time")
414                                         col.itemR(key, "duration")
415                                 else:
416                                         subrow = row.row()
417                                         #doesn't work yet
418                                         #subrow.red_alert = key.valid
419                                         subrow.itemR(key, "object", text="")
420                                         subrow.itemR(key, "system", text="System")
421                                         
422                                         layout.itemR(key, "mode", expand=True)
423
424 class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
425         __label__ = "Boid Brain"
426
427         def poll(self, context):
428                 psys = context.particle_system
429                 if psys==None:  return False
430                 if psys.settings==None:  return False
431                 if psys.point_cache.external: return False
432                 return psys.settings.physics_type=='BOIDS'
433         
434         def draw(self, context):
435                 boids = context.particle_system.settings.boids
436                 layout = self.layout
437                 
438                 layout.enabled = particle_panel_enabled(psys)
439                 
440                 # Currently boids can only use the first state so these are commented out for now.
441                 #row = layout.row()
442                 #row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
443                 #col = row.row()
444                 #subrow = col.row(align=True)
445                 #subrow.itemO("boid.boidstate_add", icon="ICON_ZOOMIN", text="")
446                 #subrow.itemO("boid.boidstate_del", icon="ICON_ZOOMOUT", text="")
447                 #subrow = row.row(align=True)
448                 #subrow.itemO("boid.boidstate_move_up", icon="VICON_MOVE_UP", text="")
449                 #subrow.itemO("boid.boidstate_move_down", icon="VICON_MOVE_DOWN", text="")
450                 
451                 state = boids.active_boid_state
452                 
453                 #layout.itemR(state, "name", text="State name")
454                 
455                 row = layout.row()
456                 row.itemR(state, "ruleset_type")
457                 if state.ruleset_type=='FUZZY':
458                         row.itemR(state, "rule_fuzziness", slider=True)
459                 else:
460                         row.itemL(text="")
461                 
462                 row = layout.row()
463                 row.template_list(state, "rules", state, "active_boid_rule_index")
464                 
465                 col = row.column()
466                 subrow = col.row()
467                 subcol = subrow.column(align=True)
468                 subcol.item_menu_enumO("boid.boidrule_add", "type", icon="ICON_ZOOMIN", text="")
469                 subcol.itemO("boid.boidrule_del", icon="ICON_ZOOMOUT", text="")
470                 subrow = col.row()
471                 subcol = subrow.column(align=True)
472                 subcol.itemO("boid.boidrule_move_up", icon="VICON_MOVE_UP", text="")
473                 subcol.itemO("boid.boidrule_move_down", icon="VICON_MOVE_DOWN", text="")
474                 
475                 rule = state.active_boid_rule
476                 
477                 if rule:
478                         row = layout.row()
479                         row.itemR(rule, "name", text="")
480                         #somebody make nice icons for boids here please! -jahka
481                         row.itemR(rule, "in_air", icon="VICON_MOVE_UP", text="")
482                         row.itemR(rule, "on_land", icon="VICON_MOVE_DOWN", text="")
483                         
484                         row = layout.row()
485
486                         if rule.type == 'GOAL':
487                                 row.itemR(rule, "object")
488                                 row = layout.row()
489                                 row.itemR(rule, "predict")
490                         elif rule.type == 'AVOID':
491                                 row.itemR(rule, "object")
492                                 row = layout.row()
493                                 row.itemR(rule, "predict")
494                                 row.itemR(rule, "fear_factor")
495                         elif rule.type == 'FOLLOW_PATH':
496                                 row.itemL(text="Not yet functional.")
497                         elif rule.type == 'AVOID_COLLISION':
498                                 row.itemR(rule, "boids")
499                                 row.itemR(rule, "deflectors")
500                                 row.itemR(rule, "look_ahead")
501                         elif rule.type == 'FOLLOW_LEADER':
502                                 row.itemR(rule, "object", text="")
503                                 row.itemR(rule, "distance")
504                                 row = layout.row()
505                                 row.itemR(rule, "line")
506                                 subrow = row.row()
507                                 subrow.active = rule.line
508                                 subrow.itemR(rule, "queue_size")
509                         elif rule.type == 'AVERAGE_SPEED':
510                                 row.itemR(rule, "speed", slider=True)
511                                 row.itemR(rule, "wander", slider=True)
512                                 row.itemR(rule, "level", slider=True)
513                         elif rule.type == 'FIGHT':
514                                 row.itemR(rule, "distance")
515                                 row.itemR(rule, "flee_distance")
516                 
517
518 class PARTICLE_PT_render(ParticleButtonsPanel):
519         __label__ = "Render"
520         
521         def poll(self, context):
522                 psys = context.particle_system
523                 if psys==None: return False
524                 if psys.settings==None: return False
525                 return True;
526                 
527         def draw(self, context):
528                 layout = self.layout
529
530                 psys = context.particle_system
531                 part = psys.settings
532
533                 row = layout.row()
534                 row.itemR(part, "material")
535                 row.itemR(psys, "parent");
536                 
537                 split = layout.split()
538                         
539                 sub = split.column()
540                 sub.itemR(part, "emitter");
541                 sub.itemR(part, "parent");
542                 sub = split.column()
543                 sub.itemR(part, "unborn");
544                 sub.itemR(part, "died");
545                 
546                 row = layout.row()
547                 row.itemR(part, "ren_as", expand=True)
548                 
549                 split = layout.split()
550                         
551                 sub = split.column()
552                 
553                 if part.ren_as == 'LINE':
554                         sub.itemR(part, "line_length_tail")
555                         sub.itemR(part, "line_length_head")
556                         sub = split.column()
557                         sub.itemR(part, "velocity_length")
558                 elif part.ren_as == 'PATH':
559                 
560                         if (part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False):
561                                 box = layout.box()
562                                 box.itemL(text="Baked or keyed particles needed for correct rendering.")
563                                 return
564                                 
565                         sub.itemR(part, "render_strand")
566                         colsub = sub.column()
567                         colsub.active = part.render_strand == False
568                         colsub.itemR(part, "render_adaptive")
569                         colsub = sub.column()
570                         colsub.active = part.render_adaptive or part.render_strand == True
571                         colsub.itemR(part, "adaptive_angle")
572                         colsub = sub.column()
573                         colsub.active = part.render_adaptive == True and part.render_strand == False
574                         colsub.itemR(part, "adaptive_pix")
575                         sub.itemR(part, "hair_bspline")
576                         sub.itemR(part, "render_step", text="Steps")
577                         sub = split.column()    
578
579                         sub.itemL(text="Timing:")
580                         sub.itemR(part, "abs_path_time")
581                         sub.itemR(part, "path_start", text="Start", slider= not part.abs_path_time)
582                         sub.itemR(part, "path_end", text="End", slider= not part.abs_path_time)         
583                         sub.itemR(part, "random_length", text="Random", slider=True)
584                         
585                         row = layout.row()
586                         col = row.column()
587                         
588                         if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
589                                 layout.itemR(part, "enable_simplify")
590                                 if part.enable_simplify==True:
591                                         row = layout.row()
592                                         row.itemR(part, "simplify_refsize")
593                                         row.itemR(part, "simplify_rate")
594                                         row.itemR(part, "simplify_transition")
595                                         row = layout.row()
596                                         row.itemR(part, "viewport")
597                                         subrow = row.row()
598                                         subrow.active = part.viewport==True
599                                         subrow.itemR(part, "simplify_viewport")
600                         
601
602                 elif part.ren_as == 'OBJECT':
603                         sub.itemR(part, "dupli_object")
604                 elif part.ren_as == 'GROUP':
605                         sub.itemR(part, "dupli_group")
606                         split = layout.split()
607                         sub = split.column()
608                         sub.itemR(part, "whole_group")
609                         sub = split.column()
610                         colsub = sub.column()
611                         colsub.active = part.whole_group == False
612                         colsub.itemR(part, "rand_group")
613                         
614                 elif part.ren_as == 'BILLBOARD':
615                         sub.itemL(text="Align:")
616                         
617                         row = layout.row()
618                         row.itemR(part, "billboard_align", expand=True)
619                         row.itemR(part, "billboard_lock", text="Lock")
620                         row = layout.row()
621                         row.itemR(part, "billboard_object")
622                 
623                         row = layout.row()
624                         col = row.column(align=True)
625                         col.itemL(text="Tilt:")
626                         col.itemR(part, "billboard_tilt", text="Angle", slider=True)
627                         col.itemR(part, "billboard_random_tilt", slider=True)
628                         col = row.column()
629                         col.itemR(part, "billboard_offset")
630                         
631                         row = layout.row()
632                         row.itemR(psys, "billboard_normal_uv")
633                         row = layout.row()
634                         row.itemR(psys, "billboard_time_index_uv")
635                         
636                         row = layout.row()
637                         row.itemL(text="Split uv's:")
638                         row.itemR(part, "billboard_uv_split", text="Number of splits")
639                         row = layout.row()
640                         row.itemR(psys, "billboard_split_uv")
641                         row = layout.row()
642                         row.itemL(text="Animate:")
643                         row.itemR(part, "billboard_animation", expand=True)
644                         row.itemL(text="Offset:")
645                         row.itemR(part, "billboard_split_offset", expand=True)
646                 if part.ren_as == 'HALO' or part.ren_as == 'LINE' or part.ren_as=='BILLBOARD':
647                         row = layout.row()
648                         col = row.column()
649                         col.itemR(part, "trail_count")
650                         if part.trail_count > 1:
651                                 col.itemR(part, "abs_path_time", text="Length in frames")
652                                 col = row.column()
653                                 col.itemR(part, "path_end", text="Length", slider=not part.abs_path_time)
654                                 col.itemR(part, "random_length", text="Random", slider=True)
655                         else:
656                                 col = row.column()
657                                 col.itemL(text="")
658                                 
659 class PARTICLE_PT_draw(ParticleButtonsPanel):
660         __label__ = "Display"
661         __default_closed__ = True
662         
663         def poll(self, context):
664                 psys = context.particle_system
665                 if psys==None: return False
666                 if psys.settings==None: return False
667                 return True;
668         
669         def draw(self, context):
670                 layout = self.layout
671
672                 psys = context.particle_system
673                 part = psys.settings
674                 
675                 row = layout.row()
676                 row.itemR(part, "draw_as", expand=True)
677                 
678                 if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
679                         return
680                         
681                 path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
682                         
683                 if path and part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False:
684                         box = layout.box()
685                         box.itemL(text="Baked or keyed particles needed for correct drawing.")
686                         return
687                 
688                 row = layout.row()
689                 row.itemR(part, "display", slider=True)
690                 if part.draw_as!='RENDER' or part.ren_as=='HALO':
691                         row.itemR(part, "draw_size")
692                 else:
693                         row.itemL(text="")
694                 
695                 row = layout.row()
696                 col = row.column()
697                 col.itemR(part, "show_size")
698                 col.itemR(part, "velocity")
699                 col.itemR(part, "num")
700                 if part.physics_type == 'BOIDS':
701                         col.itemR(part, "draw_health")
702                 
703                 col = row.column()
704                 col.itemR(part, "material_color", text="Use material color")
705                 
706                 if (path):
707                         box = col.box()                         
708                         box.itemR(part, "draw_step")
709                 else:
710                         subcol = col.column()
711                         subcol.active = part.material_color==False
712                         #subcol.itemL(text="color")
713                         #subcol.itemL(text="Override material color")
714
715 class PARTICLE_PT_children(ParticleButtonsPanel):
716         __label__ = "Children"
717         __default_closed__ = True
718
719         def draw(self, context):
720                 layout = self.layout
721
722                 psys = context.particle_system
723                 part = psys.settings
724                 
725                 layout.row().itemR(part, "child_type", expand=True)
726                 
727                 if part.child_type=='NONE':
728                         return
729                 
730                 row = layout.row()
731                 
732                 col = row.column(align=True)
733                 col.itemR(part, "child_nbr", text="Display")
734                 col.itemR(part, "rendered_child_nbr", text="Render")
735                 
736                 col = row.column(align=True)
737                 
738                 if part.child_type=='FACES':
739                         col.itemR(part, "virtual_parents", slider=True)
740                 else:
741                         col.itemR(part, "child_radius", text="Radius")
742                         col.itemR(part, "child_roundness", text="Roundness", slider=True)
743                 
744                         col = row.column(align=True)
745                         col.itemR(part, "child_size", text="Size")
746                         col.itemR(part, "child_random_size", text="Random")
747                 
748                 layout.row().itemL(text="Effects:")
749                 
750                 row = layout.row()
751                 
752                 col = row.column(align=True)
753                 col.itemR(part, "clump_factor", slider=True)
754                 col.itemR(part, "clumppow", slider=True)
755                 
756                 col = row.column(align=True)
757                 col.itemR(part, "rough_endpoint")
758                 col.itemR(part, "rough_end_shape")
759
760                 row = layout.row()
761                 
762                 col = row.column(align=True)
763                 col.itemR(part, "rough1")
764                 col.itemR(part, "rough1_size")
765
766                 col = row.column(align=True)
767                 col.itemR(part, "rough2")
768                 col.itemR(part, "rough2_size")
769                 col.itemR(part, "rough2_thres", slider=True)
770                 
771                 row = layout.row()
772                 col = row.column(align=True)
773                 col.itemR(part, "child_length", slider=True)
774                 col.itemR(part, "child_length_thres", slider=True)
775                 
776                 col = row.column(align=True)
777                 col.itemL(text="Space reserved for")
778                 col.itemL(text="hair parting controls")
779                 
780                 layout.row().itemL(text="Kink:")
781                 layout.row().itemR(part, "kink", expand=True)
782                 
783                 split = layout.split()
784                 
785                 sub = split.column()
786                 sub.itemR(part, "kink_amplitude")
787                 sub.itemR(part, "kink_frequency")
788                 sub = split.column()
789                 sub.itemR(part, "kink_shape", slider=True)
790
791 class PARTICLE_PT_effectors(ParticleButtonsPanel):
792         __label__ = "Effectors"
793         __default_closed__ = True
794         
795         def draw(self, context):
796                 layout = self.layout
797
798                 psys = context.particle_system
799                 part = psys.settings
800                 
801                 layout.itemR(part, "effector_group")
802                 
803                 layout.itemR(part, "eweight_all", slider=True)
804                 
805                 layout.itemS()
806                 layout.itemR(part, "eweight_spherical", slider=True)
807                 layout.itemR(part, "eweight_vortex", slider=True)
808                 layout.itemR(part, "eweight_magnetic", slider=True)
809                 layout.itemR(part, "eweight_wind", slider=True)
810                 layout.itemR(part, "eweight_curveguide", slider=True)
811                 layout.itemR(part, "eweight_texture", slider=True)
812                 layout.itemR(part, "eweight_harmonic", slider=True)
813                 layout.itemR(part, "eweight_charge", slider=True)
814                 layout.itemR(part, "eweight_lennardjones", slider=True)
815                 
816 class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
817         __label__ = "Vertexgroups"
818         __default_closed__ = True
819
820         def draw(self, context):
821                 layout = self.layout
822
823                 psys = context.particle_system
824                 part = psys.settings
825                 
826                 layout.itemL(text="Nothing here yet.")
827
828                 #row = layout.row()
829                 #row.itemL(text="Vertex Group")
830                 #row.itemL(text="Negate")
831
832                 
833                 #row = layout.row()
834                 #row.itemR(psys, "vertex_group_density")
835                 #row.itemR(psys, "vertex_group_density_negate", text="")
836                 
837                 #row = layout.row()
838                 #row.itemR(psys, "vertex_group_velocity")
839                 #row.itemR(psys, "vertex_group_velocity_negate", text="")
840                 
841                 #row = layout.row()
842                 #row.itemR(psys, "vertex_group_length")
843                 #row.itemR(psys, "vertex_group_length_negate", text="")
844                 
845                 #row = layout.row()
846                 #row.itemR(psys, "vertex_group_clump")
847                 #row.itemR(psys, "vertex_group_clump_negate", text="")
848                 
849                 #row = layout.row()
850                 #row.itemR(psys, "vertex_group_kink")
851                 #row.itemR(psys, "vertex_group_kink_negate", text="")
852                 
853                 #row = layout.row()
854                 #row.itemR(psys, "vertex_group_roughness1")
855                 #row.itemR(psys, "vertex_group_roughness1_negate", text="")
856                 
857                 #row = layout.row()
858                 #row.itemR(psys, "vertex_group_roughness2")
859                 #row.itemR(psys, "vertex_group_roughness2_negate", text="")
860                 
861                 #row = layout.row()
862                 #row.itemR(psys, "vertex_group_roughness_end")
863                 #row.itemR(psys, "vertex_group_roughness_end_negate", text="")
864
865                 #row = layout.row()
866                 #row.itemR(psys, "vertex_group_size")
867                 #row.itemR(psys, "vertex_group_size_negate", text="")
868                 
869                 #row = layout.row()
870                 #row.itemR(psys, "vertex_group_tangent")
871                 #row.itemR(psys, "vertex_group_tangent_negate", text="")
872                 
873                 #row = layout.row()
874                 #row.itemR(psys, "vertex_group_rotation")
875                 #row.itemR(psys, "vertex_group_rotation_negate", text="")
876                 
877                 #row = layout.row()
878                 #row.itemR(psys, "vertex_group_field")
879                 #row.itemR(psys, "vertex_group_field_negate", text="")
880                 
881 bpy.types.register(PARTICLE_PT_particles)
882 bpy.types.register(PARTICLE_PT_cache)
883 bpy.types.register(PARTICLE_PT_emission)
884 bpy.types.register(PARTICLE_PT_initial)
885 bpy.types.register(PARTICLE_PT_physics)
886 bpy.types.register(PARTICLE_PT_boidbrain)
887 bpy.types.register(PARTICLE_PT_render)
888 bpy.types.register(PARTICLE_PT_draw)
889 bpy.types.register(PARTICLE_PT_children)
890 bpy.types.register(PARTICLE_PT_effectors)
891 bpy.types.register(PARTICLE_PT_vertexgroups)