Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Karhu <jhkarh@gmail.com>2011-02-16 13:57:58 +0300
committerJanne Karhu <jhkarh@gmail.com>2011-02-16 13:57:58 +0300
commitef920a50da2d9e31315e45ab225e1e52a66a8888 (patch)
treeae56b6da6cab3406c5a71d15b8efe9d24e6be07f
parentd450e35f217bf41b91b7a3d66b3d7cdc68dd8b2b (diff)
Particle settings can now be pinned too:
* Particle system's are comparable to texture slots, which can only exist within an id block. Particle settings on the other hand are idblocks which should be pinnable just like textures. * When particle settings are pinned only properties that make sense without the actual particle system are shown in the particle panel.
-rw-r--r--release/scripts/ui/properties_particle.py176
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c31
2 files changed, 137 insertions, 70 deletions
diff --git a/release/scripts/ui/properties_particle.py b/release/scripts/ui/properties_particle.py
index b48e354f526..6b635ce1ce8 100644
--- a/release/scripts/ui/properties_particle.py
+++ b/release/scripts/ui/properties_particle.py
@@ -27,6 +27,8 @@ from properties_physics_common import basic_force_field_falloff_ui
def particle_panel_enabled(context, psys):
+ if psys == None:
+ return True
phystype = psys.settings.physics_type
if psys.settings.type in ('EMITTER', 'REACTOR') and phystype in ('NO', 'KEYED'):
return True
@@ -37,11 +39,24 @@ def particle_panel_enabled(context, psys):
def particle_panel_poll(cls, context):
psys = context.particle_system
engine = context.scene.render.engine
- if psys is None:
- return False
- if psys.settings is None:
+ settings = 0
+
+ if psys:
+ settings = psys.settings
+ elif isinstance(context.space_data.pin_id, bpy.types.ParticleSettings):
+ settings = context.space_data.pin_id
+
+ if not settings:
return False
- return psys.settings.is_fluid == False and (engine in cls.COMPAT_ENGINES)
+
+ return settings.is_fluid == False and (engine in cls.COMPAT_ENGINES)
+
+def particle_get_settings(context):
+ if context.particle_system:
+ return context.particle_system.settings
+ elif isinstance(context.space_data.pin_id, bpy.types.ParticleSettings):
+ return context.space_data.pin_id
+ return None
class ParticleButtonsPanel():
@@ -62,13 +77,14 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
engine = context.scene.render.engine
- return (context.particle_system or context.object) and (engine in cls.COMPAT_ENGINES)
+ return (context.particle_system or context.object or context.space_data.pin_id) and (engine in cls.COMPAT_ENGINES)
def draw(self, context):
layout = self.layout
ob = context.object
psys = context.particle_system
+ part = 0
if ob:
row = layout.row()
@@ -79,7 +95,21 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
col.operator("object.particle_system_add", icon='ZOOMIN', text="")
col.operator("object.particle_system_remove", icon='ZOOMOUT', text="")
- if psys and not psys.settings:
+ if psys == None:
+ part = particle_get_settings(context)
+
+ if part == None:
+ return
+
+ layout.template_ID(context.space_data, "pin_id")
+
+ if part.is_fluid:
+ layout.label(text="Settings used for fluid.")
+ return
+
+ layout.prop(part, "type", text="Type")
+
+ elif not psys.settings:
split = layout.split(percentage=0.32)
col = split.column()
@@ -89,7 +119,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
col = split.column()
col.prop(psys, "name", text="")
col.template_ID(psys, "settings", new="particle.new")
- elif psys:
+ else:
part = psys.settings
split = layout.split(percentage=0.32)
@@ -110,39 +140,39 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, bpy.types.Panel):
#row.label(text="Viewport")
#row.label(text="Render")
- if part:
- if part.is_fluid:
- layout.label(text=str(part.count) + " fluid particles for this frame.")
- return
+ if part.is_fluid:
+ layout.label(text=str(part.count) + " fluid particles for this frame.")
+ return
- row = col.row()
- row.enabled = particle_panel_enabled(context, psys)
- row.prop(part, "type", text="")
- row.prop(psys, "seed")
+ row = col.row()
+ row.enabled = particle_panel_enabled(context, psys)
+ row.prop(part, "type", text="")
+ row.prop(psys, "seed")
- split = layout.split(percentage=0.65)
- if part.type == 'HAIR':
- if psys.is_edited:
- split.operator("particle.edited_clear", text="Free Edit")
- else:
- row = split.row()
- row.enabled = particle_panel_enabled(context, psys)
- row.prop(part, "regrow_hair")
- row.prop(part, "use_advanced_hair")
+ if part:
+ split = layout.split(percentage=0.65)
+ if part.type == 'HAIR':
+ if psys != None and psys.is_edited:
+ split.operator("particle.edited_clear", text="Free Edit")
+ else:
row = split.row()
row.enabled = particle_panel_enabled(context, psys)
- row.prop(part, "hair_step")
- if psys.is_edited:
- if psys.is_global_hair:
- layout.operator("particle.connect_hair")
- layout.label(text="Hair is disconnected.")
- else:
- layout.operator("particle.disconnect_hair")
- layout.label(text="")
- elif part.type == 'REACTOR':
- split.enabled = particle_panel_enabled(context, psys)
- split.prop(psys, "reactor_target_object")
- split.prop(psys, "reactor_target_particle_system", text="Particle System")
+ row.prop(part, "regrow_hair")
+ row.prop(part, "use_advanced_hair")
+ row = split.row()
+ row.enabled = particle_panel_enabled(context, psys)
+ row.prop(part, "hair_step")
+ if psys != None and psys.is_edited:
+ if psys.is_global_hair:
+ layout.operator("particle.connect_hair")
+ layout.label(text="Hair is disconnected.")
+ else:
+ layout.operator("particle.disconnect_hair")
+ layout.label(text="")
+ elif psys != None and part.type == 'REACTOR':
+ split.enabled = particle_panel_enabled(context, psys)
+ split.prop(psys, "reactor_target_object")
+ split.prop(psys, "reactor_target_particle_system", text="Particle System")
class PARTICLE_PT_emission(ParticleButtonsPanel, bpy.types.Panel):
@@ -152,23 +182,23 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
psys = context.particle_system
- if psys is None:
- return False
- if psys.settings is None:
+ settings = particle_get_settings(context)
+
+ if settings is None:
return False
- if psys.settings.is_fluid:
+ if settings.is_fluid:
return False
if particle_panel_poll(PARTICLE_PT_emission, context):
- return not context.particle_system.point_cache.use_external
+ return psys == None or not context.particle_system.point_cache.use_external
return False
def draw(self, context):
layout = self.layout
psys = context.particle_system
- part = psys.settings
+ part = particle_get_settings(context)
- layout.enabled = particle_panel_enabled(context, psys) and not psys.has_multiple_caches
+ layout.enabled = particle_panel_enabled(context, psys) and (psys == None or not psys.has_multiple_caches)
row = layout.row()
row.active = part.distribution != 'GRID'
@@ -309,9 +339,11 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, bpy.types.Panel):
def poll(cls, context):
if particle_panel_poll(PARTICLE_PT_velocity, context):
psys = context.particle_system
- if psys.settings.type == 'HAIR' and not psys.settings.use_advanced_hair:
+ settings = particle_get_settings(context)
+
+ if settings.type == 'HAIR' and not settings.use_advanced_hair:
return False
- return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.use_external
+ return settings.physics_type != 'BOIDS' and (psys == None or not psys.point_cache.use_external)
else:
return False
@@ -319,7 +351,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, bpy.types.Panel):
layout = self.layout
psys = context.particle_system
- part = psys.settings
+ part = particle_get_settings(context)
layout.enabled = particle_panel_enabled(context, psys)
@@ -359,9 +391,11 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, bpy.types.Panel):
def poll(cls, context):
if particle_panel_poll(PARTICLE_PT_rotation, context):
psys = context.particle_system
- if psys.settings.type == 'HAIR' and not psys.settings.use_advanced_hair:
+ settings = particle_get_settings(context)
+
+ if settings.type == 'HAIR' and not settings.use_advanced_hair:
return False
- return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.use_external
+ return settings.physics_type != 'BOIDS' and (psys == None or not psys.point_cache.use_external)
else:
return False
@@ -369,7 +403,10 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, bpy.types.Panel):
layout = self.layout
psys = context.particle_system
- part = psys.settings
+ if psys:
+ part = psys.settings
+ else:
+ part = context.space_data.pin_id
layout.enabled = particle_panel_enabled(context, psys)
@@ -404,9 +441,11 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
def poll(cls, context):
if particle_panel_poll(PARTICLE_PT_physics, context):
psys = context.particle_system
- if psys.settings.type == 'HAIR' and not psys.settings.use_advanced_hair:
+ settings = particle_get_settings(context)
+
+ if settings.type == 'HAIR' and not settings.use_advanced_hair:
return False
- return not psys.point_cache.use_external
+ return psys == None or not psys.point_cache.use_external
else:
return False
@@ -414,7 +453,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
layout = self.layout
psys = context.particle_system
- part = psys.settings
+ part = particle_get_settings(context)
layout.enabled = particle_panel_enabled(context, psys)
@@ -504,7 +543,8 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
col = row.column()
col.active = not psys.use_keyed_timing
col.prop(part, "keyed_loops", text="Loops")
- row.prop(psys, "use_keyed_timing", text="Use Timing")
+ if psys:
+ row.prop(psys, "use_keyed_timing", text="Use Timing")
layout.label(text="Keys:")
elif part.physics_type == 'BOIDS':
@@ -555,7 +595,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
col.prop(boids, "pitch", slider=True)
col.prop(boids, "height", slider=True)
- if part.physics_type == 'KEYED' or part.physics_type == 'BOIDS' or part.physics_type == 'FLUID':
+ if psys and part.physics_type in ('KEYED', 'BOIDS', 'FLUID'):
if part.physics_type == 'BOIDS':
layout.label(text="Relations:")
elif part.physics_type == 'FLUID':
@@ -610,19 +650,19 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
psys = context.particle_system
+ settings = particle_get_settings(context)
engine = context.scene.render.engine
- if psys is None:
- return False
- if psys.settings is None:
+
+ if settings is None:
return False
- if psys.point_cache.use_external:
+ if psys != None and psys.point_cache.use_external:
return False
- return psys.settings.physics_type == 'BOIDS' and engine in cls.COMPAT_ENGINES
+ return settings.physics_type == 'BOIDS' and engine in cls.COMPAT_ENGINES
def draw(self, context):
layout = self.layout
- boids = context.particle_system.settings.boids
+ boids = particle_get_settings(context).boids
layout.enabled = particle_panel_enabled(context, context.particle_system)
@@ -890,7 +930,7 @@ class PARTICLE_PT_draw(ParticleButtonsPanel, bpy.types.Panel):
layout = self.layout
psys = context.particle_system
- part = psys.settings
+ part = particle_get_settings(context)
row = layout.row()
row.prop(part, "draw_method", expand=True)
@@ -949,7 +989,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, bpy.types.Panel):
layout = self.layout
psys = context.particle_system
- part = psys.settings
+ part = particle_get_settings(context)
layout.row().prop(part, "child_type", expand=True)
@@ -964,7 +1004,8 @@ class PARTICLE_PT_children(ParticleButtonsPanel, bpy.types.Panel):
if part.child_type == 'INTERPOLATED':
col = row.column()
- col.prop(psys, "child_seed", text="Seed")
+ if psys:
+ col.prop(psys, "child_seed", text="Seed")
col.prop(part, "virtual_parents", slider=True)
col.prop(part, "create_long_hair_children")
else:
@@ -989,7 +1030,8 @@ class PARTICLE_PT_children(ParticleButtonsPanel, bpy.types.Panel):
sub = col.column(align=True)
sub.prop(part, "child_radius", text="Radius")
sub.prop(part, "child_roundness", text="Roundness", slider=True)
- sub.prop(psys, "child_seed", text="Seed")
+ if psys:
+ sub.prop(psys, "child_seed", text="Seed")
elif part.virtual_parents > 0.0:
sub = col.column(align=True)
sub.label(text="Parting not")
@@ -1044,7 +1086,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, bpy.types.Panel):
return particle_panel_poll(cls, context)
def draw(self, context):
- part = context.particle_system.settings
+ part = particle_get_settings(context)
effector_weights_ui(self, context, part.effector_weights)
if part.type == 'HAIR':
@@ -1063,7 +1105,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, bpy.types.Panel):
def draw(self, context):
layout = self.layout
- part = context.particle_system.settings
+ part = particle_get_settings(context)
row = layout.row()
row.prop(part, "use_self_effect")
@@ -1096,6 +1138,8 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, bpy.types.Panel):
@classmethod
def poll(cls, context):
+ if context.particle_system == None:
+ return False
return particle_panel_poll(cls, context)
def draw(self, context):
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index fe49c20c040..dda5887aef0 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -307,7 +307,12 @@ static int buttons_context_path_particle(ButsContextPath *path)
{
Object *ob;
ParticleSystem *psys;
+ PointerRNA *ptr= &path->ptr[path->len-1];
+ /* if we already have (pinned) particle settings, we're done */
+ if(RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) {
+ return 1;
+ }
/* if we have an object, get the active particle system */
if(buttons_context_path_object(path)) {
ob= path->ptr[path->len-1].data;
@@ -395,15 +400,25 @@ static int buttons_context_path_texture(ButsContextPath *path)
}
/* try particles */
if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
- psys= path->ptr[path->len-1].data;
-
- if(psys && psys->part && GS(psys->part->id.name)==ID_PA) {
- tex= give_current_particle_texture(psys->part);
+ if(path->ptr[path->len-1].type == &RNA_ParticleSettings) {
+ ParticleSettings *part = path->ptr[path->len-1].data;
+ tex= give_current_particle_texture(part);
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++;
return 1;
}
+ else {
+ psys= path->ptr[path->len-1].data;
+
+ if(psys && psys->part && GS(psys->part->id.name)==ID_PA) {
+ tex= give_current_particle_texture(psys->part);
+
+ RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+ path->len++;
+ return 1;
+ }
+ }
}
/* try material */
if(buttons_context_path_material(path)) {
@@ -930,6 +945,14 @@ ID *buttons_context_id_path(const bContext *C)
for(a=path->len-1; a>=0; a--) {
ptr= &path->ptr[a];
+ /* pin particle settings instead of system, since only settings are an idblock*/
+ if(sbuts->mainb == BCONTEXT_PARTICLE && sbuts->flag & SB_PIN_CONTEXT) {
+ if(ptr->type == &RNA_ParticleSystem && ptr->data) {
+ ParticleSystem *psys = (ParticleSystem *)ptr->data;
+ return &psys->part->id;
+ }
+ }
+
if(ptr->id.data) {
return ptr->id.data;
break;