diff options
author | Janne Karhu <jhkarh@gmail.com> | 2011-02-16 13:57:58 +0300 |
---|---|---|
committer | Janne Karhu <jhkarh@gmail.com> | 2011-02-16 13:57:58 +0300 |
commit | ef920a50da2d9e31315e45ab225e1e52a66a8888 (patch) | |
tree | ae56b6da6cab3406c5a71d15b8efe9d24e6be07f | |
parent | d450e35f217bf41b91b7a3d66b3d7cdc68dd8b2b (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.py | 176 | ||||
-rw-r--r-- | source/blender/editors/space_buttons/buttons_context.c | 31 |
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; |