2009-06-01 11:39:11 +00:00
|
|
|
|
|
|
|
import bpy
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
def particle_panel_enabled(psys):
|
|
|
|
return psys.point_cache.baked==False and psys.editable==False
|
|
|
|
|
|
|
|
def particle_panel_poll(context):
|
|
|
|
psys = context.particle_system
|
2009-06-06 12:48:56 +00:00
|
|
|
if psys==None: return False
|
2009-06-27 15:41:47 +00:00
|
|
|
if psys.settings==None: return False
|
2009-06-06 12:48:56 +00:00
|
|
|
return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
|
2009-06-05 23:59:33 +00:00
|
|
|
|
2009-06-01 11:39:11 +00:00
|
|
|
class ParticleButtonsPanel(bpy.types.Panel):
|
|
|
|
__space_type__ = "BUTTONS_WINDOW"
|
|
|
|
__region_type__ = "WINDOW"
|
|
|
|
__context__ = "particle"
|
|
|
|
|
|
|
|
def poll(self, context):
|
2009-06-06 12:48:56 +00:00
|
|
|
return particle_panel_poll(context)
|
2009-06-01 11:39:11 +00:00
|
|
|
|
|
|
|
class PARTICLE_PT_particles(ParticleButtonsPanel):
|
2009-07-26 03:54:17 +00:00
|
|
|
__show_header__ = False
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def poll(self, context):
|
2009-06-07 13:36:12 +00:00
|
|
|
return (context.particle_system or context.object)
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
2009-06-07 13:36:12 +00:00
|
|
|
ob = context.object
|
2009-06-05 23:59:33 +00:00
|
|
|
psys = context.particle_system
|
2009-06-07 13:36:12 +00:00
|
|
|
|
2009-06-27 15:41:47 +00:00
|
|
|
if ob:
|
|
|
|
row = layout.row()
|
2009-06-07 13:36:12 +00:00
|
|
|
|
2009-07-01 22:25:49 +00:00
|
|
|
row.template_list(ob, "particle_systems", ob, "active_particle_system_index")
|
2009-06-27 15:41:47 +00:00
|
|
|
|
|
|
|
col = row.column(align=True)
|
2009-07-17 12:26:40 +00:00
|
|
|
col.itemO("object.particle_system_add", icon="ICON_ZOOMIN", text="")
|
|
|
|
col.itemO("object.particle_system_remove", icon="ICON_ZOOMOUT", text="")
|
2009-06-07 13:36:12 +00:00
|
|
|
|
|
|
|
if psys:
|
2009-07-20 23:52:53 +00:00
|
|
|
part = psys.settings
|
|
|
|
|
|
|
|
split = layout.split(percentage=0.32)
|
|
|
|
col = split.column()
|
|
|
|
col.itemL(text="Name:")
|
|
|
|
if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
|
|
|
|
col.itemL(text="Settings:")
|
|
|
|
col.itemL(text="Type:")
|
2009-06-27 15:41:47 +00:00
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
col = split.column()
|
|
|
|
col.itemR(psys, "name", text="")
|
|
|
|
if part.type in ('EMITTER', 'REACTOR', 'HAIR'):
|
|
|
|
col.template_ID(psys, "settings", new="particle.new")
|
2009-06-27 15:41:47 +00:00
|
|
|
|
2009-06-07 13:36:12 +00:00
|
|
|
#row = layout.row()
|
|
|
|
#row.itemL(text="Viewport")
|
|
|
|
#row.itemL(text="Render")
|
|
|
|
|
2009-06-27 15:41:47 +00:00
|
|
|
if part:
|
2009-07-20 23:52:53 +00:00
|
|
|
if part.type not in ('EMITTER', 'REACTOR', 'HAIR'):
|
2009-06-27 15:41:47 +00:00
|
|
|
layout.itemL(text="No settings for fluid particles")
|
|
|
|
return
|
2009-06-21 10:16:52 +00:00
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
row=col.row()
|
|
|
|
row.enabled = particle_panel_enabled(psys)
|
|
|
|
row.itemR(part, "type", text="")
|
|
|
|
row.itemR(psys, "seed")
|
2009-06-27 15:41:47 +00:00
|
|
|
|
|
|
|
split = layout.split(percentage=0.65)
|
|
|
|
if part.type=='HAIR':
|
|
|
|
if psys.editable==True:
|
2009-07-17 12:26:40 +00:00
|
|
|
split.itemO("particle.editable_set", text="Free Edit")
|
2009-06-27 15:41:47 +00:00
|
|
|
else:
|
2009-07-17 12:26:40 +00:00
|
|
|
split.itemO("particle.editable_set", text="Make Editable")
|
2009-06-27 15:41:47 +00:00
|
|
|
row = split.row()
|
|
|
|
row.enabled = particle_panel_enabled(psys)
|
|
|
|
row.itemR(part, "hair_step")
|
|
|
|
elif part.type=='REACTOR':
|
|
|
|
split.enabled = particle_panel_enabled(psys)
|
|
|
|
split.itemR(psys, "reactor_target_object")
|
|
|
|
split.itemR(psys, "reactor_target_particle_system", text="Particle System")
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
class PARTICLE_PT_emission(ParticleButtonsPanel):
|
|
|
|
__label__ = "Emission"
|
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
def poll(self, context):
|
|
|
|
if particle_panel_poll(context):
|
|
|
|
return not context.particle_system.point_cache.external
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
|
|
|
|
layout.enabled = particle_panel_enabled(psys)
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "amount")
|
|
|
|
|
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
col = split.column(align=True)
|
|
|
|
col.itemR(part, "start")
|
|
|
|
col.itemR(part, "end")
|
|
|
|
|
|
|
|
col = split.column(align=True)
|
|
|
|
col.itemR(part, "lifetime")
|
|
|
|
col.itemR(part, "random_lifetime", slider=True)
|
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
layout.row().itemL(text="Emit From:")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "emit_from", expand=True)
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "trand")
|
|
|
|
if part.distribution!='GRID':
|
|
|
|
row.itemR(part, "even_distribution")
|
|
|
|
|
|
|
|
if part.emit_from=='FACE' or part.emit_from=='VOLUME':
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "distribution", expand=True)
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
if part.distribution=='JIT':
|
|
|
|
row.itemR(part, "userjit", text="Particles/Face")
|
|
|
|
row.itemR(part, "jitter_factor", text="Jittering Amount", slider=True)
|
|
|
|
elif part.distribution=='GRID':
|
|
|
|
row.itemR(part, "grid_resolution")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
class PARTICLE_PT_cache(ParticleButtonsPanel):
|
|
|
|
__label__ = "Cache"
|
2009-06-21 10:16:52 +00:00
|
|
|
__default_closed__ = True
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def poll(self, context):
|
|
|
|
psys = context.particle_system
|
2009-06-06 12:48:56 +00:00
|
|
|
if psys==None: return False
|
2009-06-27 15:41:47 +00:00
|
|
|
if psys.settings==None: return False
|
2009-07-12 23:38:47 +00:00
|
|
|
phystype = psys.settings.physics_type
|
|
|
|
if phystype == 'NO' or phystype == 'KEYED':
|
|
|
|
return False
|
2009-06-06 12:48:56 +00:00
|
|
|
return psys.settings.type in ('EMITTER', 'REACTOR')
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
cache = psys.point_cache
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
layout.set_context_pointer("PointCache", cache)
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.template_list(cache, "point_cache_list", cache, "active_point_cache_index")
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemO("ptcache.add_new", icon="ICON_ZOOMIN", text="")
|
|
|
|
col.itemO("ptcache.remove", icon="ICON_ZOOMOUT", text="")
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
2009-07-23 00:19:01 +00:00
|
|
|
row.itemL(text="File Name:")
|
|
|
|
row.itemR(cache, "external")
|
2009-06-21 10:16:52 +00:00
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
if cache.external:
|
|
|
|
split = layout.split(percentage=0.80)
|
|
|
|
split.itemR(cache, "name", text="")
|
|
|
|
split.itemR(cache, "index", text="")
|
|
|
|
|
|
|
|
layout.itemL(text="File Path:")
|
|
|
|
layout.itemR(cache, "filepath", text="")
|
|
|
|
|
|
|
|
layout.itemL(text=cache.info)
|
|
|
|
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
#split = layout.split()
|
2009-07-23 00:19:01 +00:00
|
|
|
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
#col = split.column(align=True)
|
|
|
|
#col.itemR(part, "start")
|
|
|
|
#col.itemR(part, "end")
|
2009-07-23 00:19:01 +00:00
|
|
|
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
#col = split.column(align=True)
|
|
|
|
#col.itemR(part, "lifetime")
|
|
|
|
#col.itemR(part, "random_lifetime", slider=True)
|
2009-06-21 10:16:52 +00:00
|
|
|
else:
|
2009-07-23 00:19:01 +00:00
|
|
|
layout.itemR(cache, "name", text="")
|
|
|
|
|
|
|
|
row = layout.row()
|
Pointcache refresh part 2
* Based on what happens during simulation the cache is marked (also in cache panel, this could possibly be extended to 3d view as well) as:
- exact (not marked)
- outdated (simulation is not done completely with current settings)
- non-exact (frames were skipped during simulation)
* The parameter "cache step" effects the number of frames between saved cache frames.
- This can save a lot of memory (or disk space) if absolutely frame accurate simulation is not required.
- Speeds up the "quick caching" very much.
- Frames between cached frames are interpolated from the cached frames.
- Current default value of 10 frames works nicely with up/down-arrows (skip 10 frames forwards/backwards on timeline), but can be changed if wanted.
* The caching can work in normal or "quick" mode:
[Normal cache]
- Basic: Calculate what even happens (settings change, big frame steps etc.) and cache results, if possible try to use "cache step" when saving cache frames.
- Becomes non-exact: After larger than 1 frame steps.
- Becomes outdated: After any change effecting the simulation other than frame steps.
- Pros/cons: Freedom of doing anything and playing with particles, but exact results have to calculated from the beginning.
[Quick cache]
- Basic: Calculate simulation up to current frame automatically on changes with cache step sized jumps in simulation. With multiple "quick cached" simulations the smallest cache step is used.
- Becomes non-exact: Always from frame 1 (unless cache step = 1).
- Becomes outdated: Never.
- Pros/cons: Not very accurate, but super fast!
- Todo: Transform of any animated (non-autokeyed) object is locked! Probably needs some tinkering with anim sys overrides.
* The simulation can be run forwards or backwards even if it's cache is outdated or non-exact, the following rules apply in these situations:
- step forwards (to unknown) -> simulate from last exact frame, store result
- step backwards (to known) -> result is interpolated from existing frames, store result, clear cache forwards if current frame is after last exact frame
* "Calculate to current frame" runs the simulation from start to current frame with a frame steps of 1.
- Baking does the same, but runs the simulation all the way to the end of simulation.
- Rendering does this automatically if the simulation is outdated of non-exact, so all rendered simulations will always be updated and exact.
* Every cache panel also holds buttons to "Bake all dynamics", "Free all dynamics" and "Update all dynamics to current frame".
* Cloth simulation supports the new cache too.
2009-06-27 15:28:58 +00:00
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
if cache.baked == True:
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
row.itemO("ptcache.free_bake", text="Free Bake")
|
2009-07-23 00:19:01 +00:00
|
|
|
else:
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
row.item_booleanO("ptcache.bake", "bake", True, text="Bake")
|
Pointcache refresh part 2
* Based on what happens during simulation the cache is marked (also in cache panel, this could possibly be extended to 3d view as well) as:
- exact (not marked)
- outdated (simulation is not done completely with current settings)
- non-exact (frames were skipped during simulation)
* The parameter "cache step" effects the number of frames between saved cache frames.
- This can save a lot of memory (or disk space) if absolutely frame accurate simulation is not required.
- Speeds up the "quick caching" very much.
- Frames between cached frames are interpolated from the cached frames.
- Current default value of 10 frames works nicely with up/down-arrows (skip 10 frames forwards/backwards on timeline), but can be changed if wanted.
* The caching can work in normal or "quick" mode:
[Normal cache]
- Basic: Calculate what even happens (settings change, big frame steps etc.) and cache results, if possible try to use "cache step" when saving cache frames.
- Becomes non-exact: After larger than 1 frame steps.
- Becomes outdated: After any change effecting the simulation other than frame steps.
- Pros/cons: Freedom of doing anything and playing with particles, but exact results have to calculated from the beginning.
[Quick cache]
- Basic: Calculate simulation up to current frame automatically on changes with cache step sized jumps in simulation. With multiple "quick cached" simulations the smallest cache step is used.
- Becomes non-exact: Always from frame 1 (unless cache step = 1).
- Becomes outdated: Never.
- Pros/cons: Not very accurate, but super fast!
- Todo: Transform of any animated (non-autokeyed) object is locked! Probably needs some tinkering with anim sys overrides.
* The simulation can be run forwards or backwards even if it's cache is outdated or non-exact, the following rules apply in these situations:
- step forwards (to unknown) -> simulate from last exact frame, store result
- step backwards (to known) -> result is interpolated from existing frames, store result, clear cache forwards if current frame is after last exact frame
* "Calculate to current frame" runs the simulation from start to current frame with a frame steps of 1.
- Baking does the same, but runs the simulation all the way to the end of simulation.
- Rendering does this automatically if the simulation is outdated of non-exact, so all rendered simulations will always be updated and exact.
* Every cache panel also holds buttons to "Bake all dynamics", "Free all dynamics" and "Update all dynamics to current frame".
* Cloth simulation supports the new cache too.
2009-06-27 15:28:58 +00:00
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
subrow = row.row()
|
|
|
|
subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
subrow.itemO("ptcache.bake", "bake", False, text="Calculate to Current Frame")
|
2009-07-23 00:19:01 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.enabled = particle_panel_enabled(psys)
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
row.itemO("ptcache.bake_from_cache", text="Current Cache to Bake")
|
2009-07-23 00:19:01 +00:00
|
|
|
row.itemR(cache, "step");
|
Pointcache refresh part 2
* Based on what happens during simulation the cache is marked (also in cache panel, this could possibly be extended to 3d view as well) as:
- exact (not marked)
- outdated (simulation is not done completely with current settings)
- non-exact (frames were skipped during simulation)
* The parameter "cache step" effects the number of frames between saved cache frames.
- This can save a lot of memory (or disk space) if absolutely frame accurate simulation is not required.
- Speeds up the "quick caching" very much.
- Frames between cached frames are interpolated from the cached frames.
- Current default value of 10 frames works nicely with up/down-arrows (skip 10 frames forwards/backwards on timeline), but can be changed if wanted.
* The caching can work in normal or "quick" mode:
[Normal cache]
- Basic: Calculate what even happens (settings change, big frame steps etc.) and cache results, if possible try to use "cache step" when saving cache frames.
- Becomes non-exact: After larger than 1 frame steps.
- Becomes outdated: After any change effecting the simulation other than frame steps.
- Pros/cons: Freedom of doing anything and playing with particles, but exact results have to calculated from the beginning.
[Quick cache]
- Basic: Calculate simulation up to current frame automatically on changes with cache step sized jumps in simulation. With multiple "quick cached" simulations the smallest cache step is used.
- Becomes non-exact: Always from frame 1 (unless cache step = 1).
- Becomes outdated: Never.
- Pros/cons: Not very accurate, but super fast!
- Todo: Transform of any animated (non-autokeyed) object is locked! Probably needs some tinkering with anim sys overrides.
* The simulation can be run forwards or backwards even if it's cache is outdated or non-exact, the following rules apply in these situations:
- step forwards (to unknown) -> simulate from last exact frame, store result
- step backwards (to known) -> result is interpolated from existing frames, store result, clear cache forwards if current frame is after last exact frame
* "Calculate to current frame" runs the simulation from start to current frame with a frame steps of 1.
- Baking does the same, but runs the simulation all the way to the end of simulation.
- Rendering does this automatically if the simulation is outdated of non-exact, so all rendered simulations will always be updated and exact.
* Every cache panel also holds buttons to "Bake all dynamics", "Free all dynamics" and "Update all dynamics to current frame".
* Cloth simulation supports the new cache too.
2009-06-27 15:28:58 +00:00
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
row = layout.row()
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
subrow = row.row()
|
|
|
|
subrow.enabled = particle_panel_enabled(psys)
|
|
|
|
subrow.itemR(cache, "quick_cache")
|
2009-07-23 00:19:01 +00:00
|
|
|
row.itemR(cache, "disk_cache")
|
Pointcache refresh part 2
* Based on what happens during simulation the cache is marked (also in cache panel, this could possibly be extended to 3d view as well) as:
- exact (not marked)
- outdated (simulation is not done completely with current settings)
- non-exact (frames were skipped during simulation)
* The parameter "cache step" effects the number of frames between saved cache frames.
- This can save a lot of memory (or disk space) if absolutely frame accurate simulation is not required.
- Speeds up the "quick caching" very much.
- Frames between cached frames are interpolated from the cached frames.
- Current default value of 10 frames works nicely with up/down-arrows (skip 10 frames forwards/backwards on timeline), but can be changed if wanted.
* The caching can work in normal or "quick" mode:
[Normal cache]
- Basic: Calculate what even happens (settings change, big frame steps etc.) and cache results, if possible try to use "cache step" when saving cache frames.
- Becomes non-exact: After larger than 1 frame steps.
- Becomes outdated: After any change effecting the simulation other than frame steps.
- Pros/cons: Freedom of doing anything and playing with particles, but exact results have to calculated from the beginning.
[Quick cache]
- Basic: Calculate simulation up to current frame automatically on changes with cache step sized jumps in simulation. With multiple "quick cached" simulations the smallest cache step is used.
- Becomes non-exact: Always from frame 1 (unless cache step = 1).
- Becomes outdated: Never.
- Pros/cons: Not very accurate, but super fast!
- Todo: Transform of any animated (non-autokeyed) object is locked! Probably needs some tinkering with anim sys overrides.
* The simulation can be run forwards or backwards even if it's cache is outdated or non-exact, the following rules apply in these situations:
- step forwards (to unknown) -> simulate from last exact frame, store result
- step backwards (to known) -> result is interpolated from existing frames, store result, clear cache forwards if current frame is after last exact frame
* "Calculate to current frame" runs the simulation from start to current frame with a frame steps of 1.
- Baking does the same, but runs the simulation all the way to the end of simulation.
- Rendering does this automatically if the simulation is outdated of non-exact, so all rendered simulations will always be updated and exact.
* Every cache panel also holds buttons to "Bake all dynamics", "Free all dynamics" and "Update all dynamics to current frame".
* Cloth simulation supports the new cache too.
2009-06-27 15:28:58 +00:00
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
layout.itemL(text=cache.info)
|
|
|
|
|
|
|
|
layout.itemS()
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics")
|
|
|
|
row.itemO("ptcache.free_bake_all", text="Free All Bakes")
|
New point cache file format:
- HEADER (beginning of each file)
* general header:
+ 8 char: "BPHYSICS"
+ 1 int: simulation type (same as PTCacheID->type)
* custom header (same for sb, particles and cloth, but can be different for new dynamics)
+ 1 int: totpoint (number of points)
+ 1 int: data_types (bit flags for what the stored data is)
- DATA (directly after header)
*totpoint times the data as specified in data_types flags
- simulation type
soft body = 0, particles = 1, cloth = 2
- data types (more can be added easily when needed)
data flag contains
----------------------------------------
index (1<<0) 1 int (index of current point)
location (1<<1) 3 float
velocity (1<<2) 3 float
rotation (1<<3) 4 float (quaternion)
avelocity (1<<4) 3 float (used for particles)
xconst (1<<4) 3 float (used for cloth)
size (1<<5) 1 float
times (1<<6) 3 float (birth, die & lifetime of particle)
boids (1<<7) 1 BoidData
Notes:
- Every frame is not nescessary since data is interpolated for the inbetween frames.
- For now every point is needed for every cached frame, the "index" data type is reserved for future usage.
- For loading external particle caches only "location" data is necessary, other needed values are determined from the given data.
- Non-dynamic data should be written into an info file if external usage is desired.
* Info file is named as normal cache files, but with frame number 0;
* "Non-dynamic" means data such as particle times.
* Written automatically when baking to disk so basically a library of particle simulations should be possible.
- Old disk cache format is supported for reading, so pre 2.5 files shouldn't break. However old style memory cache (added during 2.5 development) is not supported. To keep memory cached simulations convert the cache to disk cache before svn update and save the blend.
- External sb and cloth caches should be perfectly possible, but due to lack of testing these are not yet enabled in ui.
Other changes:
- Multiple point caches per dynamics system.
* In the future these will hopefully be nla editable etc, but for now things are simple and the current (selected) point cache is used.
* Changing the amount of cached points (for example particle count) is allowed, but might not give correct results if multiple caches are present.
- Generalization of point cache baking etc operator & rna code.
- Comb brushing particle hair didn't work smoothly.
2009-08-12 09:54:29 +00:00
|
|
|
layout.itemO("ptcache.bake_all", "bake", False, text="Update All Dynamics to current frame")
|
2009-06-21 10:16:52 +00:00
|
|
|
|
|
|
|
# for particles these are figured out automatically
|
|
|
|
#row.itemR(cache, "start_frame")
|
|
|
|
#row.itemR(cache, "end_frame")
|
2009-06-06 16:18:19 +00:00
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
class PARTICLE_PT_initial(ParticleButtonsPanel):
|
2009-06-06 16:18:19 +00:00
|
|
|
__label__ = "Velocity"
|
2009-07-20 23:52:53 +00:00
|
|
|
|
|
|
|
def poll(self, context):
|
|
|
|
if particle_panel_poll(context):
|
|
|
|
psys = context.particle_system
|
2009-07-23 00:19:01 +00:00
|
|
|
return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external
|
2009-07-20 23:52:53 +00:00
|
|
|
else:
|
|
|
|
return False
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
|
|
|
|
layout.enabled = particle_panel_enabled(psys)
|
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
layout.row().itemL(text="Direction:")
|
|
|
|
|
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "normal_factor")
|
2009-06-05 23:59:33 +00:00
|
|
|
if part.emit_from=='PARTICLE':
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "particle_factor")
|
2009-06-05 23:59:33 +00:00
|
|
|
else:
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "object_factor", slider=True)
|
|
|
|
sub.itemR(part, "random_factor")
|
|
|
|
sub.itemR(part, "tangent_factor")
|
|
|
|
sub.itemR(part, "tangent_phase", slider=True)
|
2009-06-05 23:59:33 +00:00
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
sub = split.column()
|
|
|
|
sub.itemL(text="TODO:")
|
|
|
|
sub.itemL(text="Object aligned")
|
|
|
|
sub.itemL(text="direction: X, Y, Z")
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
if part.type=='REACTOR':
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "reactor_factor")
|
|
|
|
sub.itemR(part, "reaction_shape", slider=True)
|
2009-06-05 23:59:33 +00:00
|
|
|
else:
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemL(text="")
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
layout.row().itemL(text="Rotation:")
|
2009-06-06 16:18:19 +00:00
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
2009-06-05 23:59:33 +00:00
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "rotation_mode", text="Axis")
|
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "rotation_dynamic")
|
|
|
|
sub.itemR(part, "random_rotation_factor", slider=True)
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "phase_factor", slider=True)
|
|
|
|
sub.itemR(part, "random_phase_factor", text="Random", slider=True)
|
2009-06-01 11:39:11 +00:00
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
layout.row().itemL(text="Angular velocity:")
|
|
|
|
layout.row().itemR(part, "angular_velocity_mode", expand=True)
|
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
|
|
|
|
|
|
|
sub.itemR(part, "angular_velocity_factor", text="")
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
class PARTICLE_PT_physics(ParticleButtonsPanel):
|
|
|
|
__label__ = "Physics"
|
2009-07-23 00:19:01 +00:00
|
|
|
|
|
|
|
def poll(self, context):
|
|
|
|
if particle_panel_poll(context):
|
|
|
|
return not context.particle_system.point_cache.external
|
|
|
|
else:
|
|
|
|
return False
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
layout.enabled = particle_panel_enabled(psys)
|
2009-06-06 16:18:19 +00:00
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "physics_type", expand=True)
|
|
|
|
if part.physics_type != 'NO':
|
2009-06-06 16:18:19 +00:00
|
|
|
row = layout.row()
|
2009-06-05 23:59:33 +00:00
|
|
|
col = row.column(align=True)
|
2009-06-06 16:18:19 +00:00
|
|
|
col.itemR(part, "particle_size")
|
|
|
|
col.itemR(part, "random_size", slider=True)
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "mass")
|
|
|
|
col.itemR(part, "sizemass", text="Multiply mass with size")
|
|
|
|
|
|
|
|
if part.physics_type == 'NEWTON':
|
2009-07-20 23:52:53 +00:00
|
|
|
split = layout.split()
|
|
|
|
sub = split.column()
|
2009-06-06 16:18:19 +00:00
|
|
|
|
|
|
|
sub.itemL(text="Forces:")
|
|
|
|
sub.itemR(part, "brownian_factor")
|
|
|
|
sub.itemR(part, "drag_factor", slider=True)
|
|
|
|
sub.itemR(part, "damp_factor", slider=True)
|
|
|
|
sub.itemR(part, "integrator")
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "acceleration")
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
elif part.physics_type == 'KEYED':
|
2009-07-20 23:52:53 +00:00
|
|
|
split = layout.split()
|
|
|
|
sub = split.column()
|
|
|
|
|
2009-07-12 23:38:47 +00:00
|
|
|
row = layout.row()
|
|
|
|
col = row.column()
|
|
|
|
col.active = not psys.keyed_timing
|
|
|
|
col.itemR(part, "keyed_loops", text="Loops")
|
|
|
|
row.itemR(psys, "keyed_timing", text="Use Timing")
|
|
|
|
|
|
|
|
layout.itemL(text="Keys:")
|
2009-07-20 23:52:53 +00:00
|
|
|
elif part.physics_type=='BOIDS':
|
|
|
|
boids = part.boids
|
|
|
|
|
|
|
|
|
2009-07-12 23:38:47 +00:00
|
|
|
row = layout.row()
|
2009-07-20 23:52:53 +00:00
|
|
|
row.itemR(boids, "allow_flight")
|
|
|
|
row.itemR(boids, "allow_land")
|
|
|
|
row.itemR(boids, "allow_climb")
|
2009-07-12 23:38:47 +00:00
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
|
|
|
col = sub.column(align=True)
|
|
|
|
col.active = boids.allow_flight
|
|
|
|
col.itemR(boids, "air_max_speed")
|
|
|
|
col.itemR(boids, "air_min_speed", slider="True")
|
|
|
|
col.itemR(boids, "air_max_acc", slider="True")
|
|
|
|
col.itemR(boids, "air_max_ave", slider="True")
|
|
|
|
col.itemR(boids, "air_personal_space")
|
|
|
|
row = col.row()
|
|
|
|
row.active = (boids.allow_land or boids.allow_climb) and boids.allow_flight
|
|
|
|
row.itemR(boids, "landing_smoothness")
|
|
|
|
|
|
|
|
sub = split.column()
|
|
|
|
col = sub.column(align=True)
|
|
|
|
col.active = boids.allow_land or boids.allow_climb
|
|
|
|
col.itemR(boids, "land_max_speed")
|
|
|
|
col.itemR(boids, "land_jump_speed")
|
|
|
|
col.itemR(boids, "land_max_acc", slider="True")
|
|
|
|
col.itemR(boids, "land_max_ave", slider="True")
|
|
|
|
col.itemR(boids, "land_personal_space")
|
|
|
|
col.itemR(boids, "land_stick_force")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemL(text="Battle:")
|
|
|
|
col.itemR(boids, "health")
|
|
|
|
col.itemR(boids, "strength")
|
|
|
|
col.itemR(boids, "aggression")
|
|
|
|
col.itemR(boids, "accuracy")
|
|
|
|
col.itemR(boids, "range")
|
|
|
|
|
|
|
|
col = row.column()
|
|
|
|
col.itemL(text="Misc:")
|
|
|
|
col.itemR(part, "gravity")
|
|
|
|
col.itemR(boids, "banking", slider=True)
|
|
|
|
col.itemR(boids, "height", slider=True)
|
|
|
|
|
|
|
|
if part.physics_type=='NEWTON':
|
|
|
|
sub.itemR(part, "size_deflect")
|
|
|
|
sub.itemR(part, "die_on_collision")
|
|
|
|
sub.itemR(part, "sticky")
|
|
|
|
elif part.physics_type=='KEYED' or part.physics_type=='BOIDS':
|
|
|
|
if part.physics_type=='BOIDS':
|
|
|
|
layout.itemL(text="Relations:")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.template_list(psys, "targets", psys, "active_particle_target_index")
|
2009-07-12 23:38:47 +00:00
|
|
|
|
|
|
|
col = row.column()
|
|
|
|
subrow = col.row()
|
|
|
|
subcol = subrow.column(align=True)
|
2009-07-20 23:52:53 +00:00
|
|
|
subcol.itemO("particle.new_target", icon="ICON_ZOOMIN", text="")
|
|
|
|
subcol.itemO("particle.remove_target", icon="ICON_ZOOMOUT", text="")
|
2009-07-12 23:38:47 +00:00
|
|
|
subrow = col.row()
|
|
|
|
subcol = subrow.column(align=True)
|
2009-07-20 23:52:53 +00:00
|
|
|
subcol.itemO("particle.target_move_up", icon="VICON_MOVE_UP", text="")
|
|
|
|
subcol.itemO("particle.target_move_down", icon="VICON_MOVE_DOWN", text="")
|
2009-07-12 23:38:47 +00:00
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
key = psys.active_particle_target
|
2009-07-12 23:38:47 +00:00
|
|
|
if key:
|
|
|
|
row = layout.row()
|
2009-07-20 23:52:53 +00:00
|
|
|
if part.physics_type=='KEYED':
|
|
|
|
col = row.column()
|
|
|
|
#doesn't work yet
|
|
|
|
#col.red_alert = key.valid
|
|
|
|
col.itemR(key, "object", text="")
|
|
|
|
col.itemR(key, "system", text="System")
|
|
|
|
col = row.column();
|
|
|
|
col.active = psys.keyed_timing
|
|
|
|
col.itemR(key, "time")
|
|
|
|
col.itemR(key, "duration")
|
|
|
|
else:
|
|
|
|
subrow = row.row()
|
|
|
|
#doesn't work yet
|
|
|
|
#subrow.red_alert = key.valid
|
|
|
|
subrow.itemR(key, "object", text="")
|
|
|
|
subrow.itemR(key, "system", text="System")
|
|
|
|
|
|
|
|
layout.itemR(key, "mode", expand=True)
|
|
|
|
|
|
|
|
class PARTICLE_PT_boidbrain(ParticleButtonsPanel):
|
|
|
|
__label__ = "Boid Brain"
|
|
|
|
|
|
|
|
def poll(self, context):
|
|
|
|
psys = context.particle_system
|
|
|
|
if psys==None: return False
|
|
|
|
if psys.settings==None: return False
|
2009-07-23 00:19:01 +00:00
|
|
|
if psys.point_cache.external: return False
|
2009-07-20 23:52:53 +00:00
|
|
|
return psys.settings.physics_type=='BOIDS'
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
boids = context.particle_system.settings.boids
|
|
|
|
layout = self.layout
|
|
|
|
|
2009-07-23 00:19:01 +00:00
|
|
|
layout.enabled = particle_panel_enabled(psys)
|
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
# Currently boids can only use the first state so these are commented out for now.
|
|
|
|
#row = layout.row()
|
|
|
|
#row.template_list(boids, "states", boids, "active_boid_state_index", compact="True")
|
|
|
|
#col = row.row()
|
|
|
|
#subrow = col.row(align=True)
|
|
|
|
#subrow.itemO("boid.boidstate_add", icon="ICON_ZOOMIN", text="")
|
|
|
|
#subrow.itemO("boid.boidstate_del", icon="ICON_ZOOMOUT", text="")
|
|
|
|
#subrow = row.row(align=True)
|
|
|
|
#subrow.itemO("boid.boidstate_move_up", icon="VICON_MOVE_UP", text="")
|
|
|
|
#subrow.itemO("boid.boidstate_move_down", icon="VICON_MOVE_DOWN", text="")
|
|
|
|
|
|
|
|
state = boids.active_boid_state
|
|
|
|
|
|
|
|
#layout.itemR(state, "name", text="State name")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(state, "ruleset_type")
|
|
|
|
if state.ruleset_type=='FUZZY':
|
|
|
|
row.itemR(state, "rule_fuzziness", slider=True)
|
|
|
|
else:
|
|
|
|
row.itemL(text="")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.template_list(state, "rules", state, "active_boid_rule_index")
|
|
|
|
|
|
|
|
col = row.column()
|
|
|
|
subrow = col.row()
|
|
|
|
subcol = subrow.column(align=True)
|
|
|
|
subcol.item_menu_enumO("boid.boidrule_add", "type", icon="ICON_ZOOMIN", text="")
|
|
|
|
subcol.itemO("boid.boidrule_del", icon="ICON_ZOOMOUT", text="")
|
|
|
|
subrow = col.row()
|
|
|
|
subcol = subrow.column(align=True)
|
|
|
|
subcol.itemO("boid.boidrule_move_up", icon="VICON_MOVE_UP", text="")
|
|
|
|
subcol.itemO("boid.boidrule_move_down", icon="VICON_MOVE_DOWN", text="")
|
|
|
|
|
|
|
|
rule = state.active_boid_rule
|
|
|
|
|
|
|
|
if rule:
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(rule, "name", text="")
|
|
|
|
#somebody make nice icons for boids here please! -jahka
|
|
|
|
row.itemR(rule, "in_air", icon="VICON_MOVE_UP", text="")
|
|
|
|
row.itemR(rule, "on_land", icon="VICON_MOVE_DOWN", text="")
|
2009-07-12 23:38:47 +00:00
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
row = layout.row()
|
2009-06-06 16:18:19 +00:00
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
if rule.type == 'GOAL':
|
|
|
|
row.itemR(rule, "object")
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(rule, "predict")
|
|
|
|
elif rule.type == 'AVOID':
|
|
|
|
row.itemR(rule, "object")
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(rule, "predict")
|
|
|
|
row.itemR(rule, "fear_factor")
|
|
|
|
elif rule.type == 'FOLLOW_PATH':
|
|
|
|
row.itemL(text="Not yet functional.")
|
|
|
|
elif rule.type == 'AVOID_COLLISION':
|
|
|
|
row.itemR(rule, "boids")
|
|
|
|
row.itemR(rule, "deflectors")
|
|
|
|
row.itemR(rule, "look_ahead")
|
|
|
|
elif rule.type == 'FOLLOW_LEADER':
|
|
|
|
row.itemR(rule, "object", text="")
|
|
|
|
row.itemR(rule, "distance")
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(rule, "line")
|
|
|
|
subrow = row.row()
|
|
|
|
subrow.active = rule.line
|
|
|
|
subrow.itemR(rule, "queue_size")
|
|
|
|
elif rule.type == 'AVERAGE_SPEED':
|
|
|
|
row.itemR(rule, "speed", slider=True)
|
|
|
|
row.itemR(rule, "wander", slider=True)
|
|
|
|
row.itemR(rule, "level", slider=True)
|
|
|
|
elif rule.type == 'FIGHT':
|
|
|
|
row.itemR(rule, "distance")
|
|
|
|
row.itemR(rule, "flee_distance")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
class PARTICLE_PT_render(ParticleButtonsPanel):
|
|
|
|
__label__ = "Render"
|
|
|
|
|
|
|
|
def poll(self, context):
|
2009-06-27 15:41:47 +00:00
|
|
|
psys = context.particle_system
|
|
|
|
if psys==None: return False
|
|
|
|
if psys.settings==None: return False
|
|
|
|
return True;
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
2009-07-12 23:38:47 +00:00
|
|
|
|
2009-06-21 11:09:16 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "material")
|
|
|
|
row.itemR(psys, "parent");
|
2009-06-06 16:18:19 +00:00
|
|
|
|
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "emitter");
|
|
|
|
sub.itemR(part, "parent");
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "unborn");
|
|
|
|
sub.itemR(part, "died");
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "ren_as", expand=True)
|
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
split = layout.split()
|
|
|
|
|
|
|
|
sub = split.column()
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
if part.ren_as == 'LINE':
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "line_length_tail")
|
|
|
|
sub.itemR(part, "line_length_head")
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "velocity_length")
|
2009-06-05 23:59:33 +00:00
|
|
|
elif part.ren_as == 'PATH':
|
|
|
|
|
2009-07-12 23:38:47 +00:00
|
|
|
if (part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False):
|
2009-06-05 23:59:33 +00:00
|
|
|
box = layout.box()
|
|
|
|
box.itemL(text="Baked or keyed particles needed for correct rendering.")
|
|
|
|
return
|
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "render_strand")
|
|
|
|
colsub = sub.column()
|
|
|
|
colsub.active = part.render_strand == False
|
|
|
|
colsub.itemR(part, "render_adaptive")
|
|
|
|
colsub = sub.column()
|
|
|
|
colsub.active = part.render_adaptive or part.render_strand == True
|
|
|
|
colsub.itemR(part, "adaptive_angle")
|
|
|
|
colsub = sub.column()
|
|
|
|
colsub.active = part.render_adaptive == True and part.render_strand == False
|
|
|
|
colsub.itemR(part, "adaptive_pix")
|
|
|
|
sub.itemR(part, "hair_bspline")
|
|
|
|
sub.itemR(part, "render_step", text="Steps")
|
2009-07-04 03:50:12 +00:00
|
|
|
sub = split.column()
|
|
|
|
|
|
|
|
sub.itemL(text="Timing:")
|
|
|
|
sub.itemR(part, "abs_path_time")
|
|
|
|
sub.itemR(part, "path_start", text="Start", slider= not part.abs_path_time)
|
|
|
|
sub.itemR(part, "path_end", text="End", slider= not part.abs_path_time)
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "random_length", text="Random", slider=True)
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
col = row.column()
|
|
|
|
|
|
|
|
if part.type=='HAIR' and part.render_strand==True and part.child_type=='FACES':
|
|
|
|
layout.itemR(part, "enable_simplify")
|
|
|
|
if part.enable_simplify==True:
|
2009-06-21 10:16:52 +00:00
|
|
|
row = layout.row()
|
2009-06-05 23:59:33 +00:00
|
|
|
row.itemR(part, "simplify_refsize")
|
|
|
|
row.itemR(part, "simplify_rate")
|
|
|
|
row.itemR(part, "simplify_transition")
|
2009-06-21 10:16:52 +00:00
|
|
|
row = layout.row()
|
2009-06-05 23:59:33 +00:00
|
|
|
row.itemR(part, "viewport")
|
|
|
|
subrow = row.row()
|
|
|
|
subrow.active = part.viewport==True
|
|
|
|
subrow.itemR(part, "simplify_viewport")
|
|
|
|
|
|
|
|
|
|
|
|
elif part.ren_as == 'OBJECT':
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "dupli_object")
|
2009-06-05 23:59:33 +00:00
|
|
|
elif part.ren_as == 'GROUP':
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemR(part, "dupli_group")
|
2009-06-05 23:59:33 +00:00
|
|
|
split = layout.split()
|
2009-06-06 16:18:19 +00:00
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "whole_group")
|
|
|
|
sub = split.column()
|
|
|
|
colsub = sub.column()
|
|
|
|
colsub.active = part.whole_group == False
|
|
|
|
colsub.itemR(part, "rand_group")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
elif part.ren_as == 'BILLBOARD':
|
2009-06-06 16:18:19 +00:00
|
|
|
sub.itemL(text="Align:")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "billboard_align", expand=True)
|
2009-06-06 16:18:19 +00:00
|
|
|
row.itemR(part, "billboard_lock", text="Lock")
|
2009-06-05 23:59:33 +00:00
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "billboard_object")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemL(text="Tilt:")
|
|
|
|
col.itemR(part, "billboard_tilt", text="Angle", slider=True)
|
|
|
|
col.itemR(part, "billboard_random_tilt", slider=True)
|
|
|
|
col = row.column()
|
|
|
|
col.itemR(part, "billboard_offset")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(psys, "billboard_normal_uv")
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(psys, "billboard_time_index_uv")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemL(text="Split uv's:")
|
|
|
|
row.itemR(part, "billboard_uv_split", text="Number of splits")
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(psys, "billboard_split_uv")
|
|
|
|
row = layout.row()
|
|
|
|
row.itemL(text="Animate:")
|
|
|
|
row.itemR(part, "billboard_animation", expand=True)
|
|
|
|
row.itemL(text="Offset:")
|
|
|
|
row.itemR(part, "billboard_split_offset", expand=True)
|
2009-07-04 03:50:12 +00:00
|
|
|
if part.ren_as == 'HALO' or part.ren_as == 'LINE' or part.ren_as=='BILLBOARD':
|
|
|
|
row = layout.row()
|
|
|
|
col = row.column()
|
|
|
|
col.itemR(part, "trail_count")
|
|
|
|
if part.trail_count > 1:
|
|
|
|
col.itemR(part, "abs_path_time", text="Length in frames")
|
|
|
|
col = row.column()
|
|
|
|
col.itemR(part, "path_end", text="Length", slider=not part.abs_path_time)
|
|
|
|
col.itemR(part, "random_length", text="Random", slider=True)
|
|
|
|
else:
|
|
|
|
col = row.column()
|
|
|
|
col.itemL(text="")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
class PARTICLE_PT_draw(ParticleButtonsPanel):
|
2009-06-06 16:18:19 +00:00
|
|
|
__label__ = "Display"
|
2009-06-21 10:16:52 +00:00
|
|
|
__default_closed__ = True
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def poll(self, context):
|
2009-06-27 15:41:47 +00:00
|
|
|
psys = context.particle_system
|
|
|
|
if psys==None: return False
|
|
|
|
if psys.settings==None: return False
|
|
|
|
return True;
|
2009-06-05 23:59:33 +00:00
|
|
|
|
2009-06-01 11:39:11 +00:00
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
2009-06-03 00:17:35 +00:00
|
|
|
psys = context.particle_system
|
2009-06-01 11:39:11 +00:00
|
|
|
part = psys.settings
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "draw_as", expand=True)
|
|
|
|
|
|
|
|
if part.draw_as=='NONE' or (part.ren_as=='NONE' and part.draw_as=='RENDER'):
|
|
|
|
return
|
|
|
|
|
|
|
|
path = (part.ren_as=='PATH' and part.draw_as=='RENDER') or part.draw_as=='PATH'
|
|
|
|
|
2009-07-12 23:38:47 +00:00
|
|
|
if path and part.type!='HAIR' and part.physics_type!='KEYED' and psys.point_cache.baked==False:
|
2009-06-05 23:59:33 +00:00
|
|
|
box = layout.box()
|
|
|
|
box.itemL(text="Baked or keyed particles needed for correct drawing.")
|
|
|
|
return
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
row.itemR(part, "display", slider=True)
|
|
|
|
if part.draw_as!='RENDER' or part.ren_as=='HALO':
|
|
|
|
row.itemR(part, "draw_size")
|
|
|
|
else:
|
|
|
|
row.itemL(text="")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
col = row.column()
|
|
|
|
col.itemR(part, "show_size")
|
|
|
|
col.itemR(part, "velocity")
|
|
|
|
col.itemR(part, "num")
|
|
|
|
if part.physics_type == 'BOIDS':
|
|
|
|
col.itemR(part, "draw_health")
|
|
|
|
|
|
|
|
col = row.column()
|
2009-07-04 03:50:12 +00:00
|
|
|
col.itemR(part, "material_color", text="Use material color")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
if (path):
|
|
|
|
box = col.box()
|
|
|
|
box.itemR(part, "draw_step")
|
|
|
|
else:
|
|
|
|
subcol = col.column()
|
|
|
|
subcol.active = part.material_color==False
|
|
|
|
#subcol.itemL(text="color")
|
|
|
|
#subcol.itemL(text="Override material color")
|
|
|
|
|
|
|
|
class PARTICLE_PT_children(ParticleButtonsPanel):
|
|
|
|
__label__ = "Children"
|
2009-06-21 10:16:52 +00:00
|
|
|
__default_closed__ = True
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
|
|
|
|
layout.row().itemR(part, "child_type", expand=True)
|
|
|
|
|
|
|
|
if part.child_type=='NONE':
|
|
|
|
return
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
2009-06-06 16:18:19 +00:00
|
|
|
col.itemR(part, "child_nbr", text="Display")
|
2009-06-05 23:59:33 +00:00
|
|
|
col.itemR(part, "rendered_child_nbr", text="Render")
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
|
|
|
|
if part.child_type=='FACES':
|
|
|
|
col.itemR(part, "virtual_parents", slider=True)
|
|
|
|
else:
|
|
|
|
col.itemR(part, "child_radius", text="Radius")
|
|
|
|
col.itemR(part, "child_roundness", text="Roundness", slider=True)
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "child_size", text="Size")
|
|
|
|
col.itemR(part, "child_random_size", text="Random")
|
|
|
|
|
|
|
|
layout.row().itemL(text="Effects:")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "clump_factor", slider=True)
|
|
|
|
col.itemR(part, "clumppow", slider=True)
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "rough_endpoint")
|
|
|
|
col.itemR(part, "rough_end_shape")
|
|
|
|
|
|
|
|
row = layout.row()
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "rough1")
|
|
|
|
col.itemR(part, "rough1_size")
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "rough2")
|
|
|
|
col.itemR(part, "rough2_size")
|
|
|
|
col.itemR(part, "rough2_thres", slider=True)
|
|
|
|
|
2009-07-12 23:38:47 +00:00
|
|
|
row = layout.row()
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemR(part, "child_length", slider=True)
|
|
|
|
col.itemR(part, "child_length_thres", slider=True)
|
|
|
|
|
|
|
|
col = row.column(align=True)
|
|
|
|
col.itemL(text="Space reserved for")
|
|
|
|
col.itemL(text="hair parting controls")
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
layout.row().itemL(text="Kink:")
|
|
|
|
layout.row().itemR(part, "kink", expand=True)
|
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
split = layout.split()
|
2009-06-05 23:59:33 +00:00
|
|
|
|
2009-06-06 16:18:19 +00:00
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "kink_amplitude")
|
|
|
|
sub.itemR(part, "kink_frequency")
|
|
|
|
sub = split.column()
|
|
|
|
sub.itemR(part, "kink_shape", slider=True)
|
|
|
|
|
2009-07-20 23:52:53 +00:00
|
|
|
class PARTICLE_PT_effectors(ParticleButtonsPanel):
|
|
|
|
__label__ = "Effectors"
|
|
|
|
__default_closed__ = True
|
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
|
|
|
|
layout.itemR(part, "effector_group")
|
|
|
|
|
|
|
|
layout.itemR(part, "eweight_all", slider=True)
|
|
|
|
|
|
|
|
layout.itemS()
|
|
|
|
layout.itemR(part, "eweight_spherical", slider=True)
|
|
|
|
layout.itemR(part, "eweight_vortex", slider=True)
|
|
|
|
layout.itemR(part, "eweight_magnetic", slider=True)
|
|
|
|
layout.itemR(part, "eweight_wind", slider=True)
|
|
|
|
layout.itemR(part, "eweight_curveguide", slider=True)
|
|
|
|
layout.itemR(part, "eweight_texture", slider=True)
|
|
|
|
layout.itemR(part, "eweight_harmonic", slider=True)
|
|
|
|
layout.itemR(part, "eweight_charge", slider=True)
|
|
|
|
layout.itemR(part, "eweight_lennardjones", slider=True)
|
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
class PARTICLE_PT_vertexgroups(ParticleButtonsPanel):
|
|
|
|
__label__ = "Vertexgroups"
|
2009-06-21 10:16:52 +00:00
|
|
|
__default_closed__ = True
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
def draw(self, context):
|
|
|
|
layout = self.layout
|
|
|
|
|
|
|
|
psys = context.particle_system
|
|
|
|
part = psys.settings
|
|
|
|
|
|
|
|
layout.itemL(text="Nothing here yet.")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemL(text="Vertex Group")
|
|
|
|
#row.itemL(text="Negate")
|
2009-06-01 11:39:11 +00:00
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_density")
|
|
|
|
#row.itemR(psys, "vertex_group_density_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_velocity")
|
|
|
|
#row.itemR(psys, "vertex_group_velocity_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_length")
|
|
|
|
#row.itemR(psys, "vertex_group_length_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_clump")
|
|
|
|
#row.itemR(psys, "vertex_group_clump_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_kink")
|
|
|
|
#row.itemR(psys, "vertex_group_kink_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_roughness1")
|
|
|
|
#row.itemR(psys, "vertex_group_roughness1_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_roughness2")
|
|
|
|
#row.itemR(psys, "vertex_group_roughness2_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_roughness_end")
|
|
|
|
#row.itemR(psys, "vertex_group_roughness_end_negate", text="")
|
2009-06-01 11:39:11 +00:00
|
|
|
|
2009-06-05 23:59:33 +00:00
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_size")
|
|
|
|
#row.itemR(psys, "vertex_group_size_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_tangent")
|
|
|
|
#row.itemR(psys, "vertex_group_tangent_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_rotation")
|
|
|
|
#row.itemR(psys, "vertex_group_rotation_negate", text="")
|
|
|
|
|
|
|
|
#row = layout.row()
|
|
|
|
#row.itemR(psys, "vertex_group_field")
|
|
|
|
#row.itemR(psys, "vertex_group_field_negate", text="")
|
|
|
|
|
2009-06-01 11:39:11 +00:00
|
|
|
bpy.types.register(PARTICLE_PT_particles)
|
2009-06-05 23:59:33 +00:00
|
|
|
bpy.types.register(PARTICLE_PT_cache)
|
|
|
|
bpy.types.register(PARTICLE_PT_emission)
|
|
|
|
bpy.types.register(PARTICLE_PT_initial)
|
|
|
|
bpy.types.register(PARTICLE_PT_physics)
|
2009-07-20 23:52:53 +00:00
|
|
|
bpy.types.register(PARTICLE_PT_boidbrain)
|
2009-06-05 23:59:33 +00:00
|
|
|
bpy.types.register(PARTICLE_PT_render)
|
|
|
|
bpy.types.register(PARTICLE_PT_draw)
|
|
|
|
bpy.types.register(PARTICLE_PT_children)
|
2009-07-20 23:52:53 +00:00
|
|
|
bpy.types.register(PARTICLE_PT_effectors)
|
2009-06-07 13:36:12 +00:00
|
|
|
bpy.types.register(PARTICLE_PT_vertexgroups)
|