From eccc047f7039ad57792356652a9c750ef02b1a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuk=20Garda=C3=85=C2=A1evi=C3=84=C2=87?= Date: Fri, 17 Aug 2018 12:02:33 +0200 Subject: Physics Force Field and Collision: Use Single Column and Grid Flow layout See D3609 --- .../startup/bl_ui/properties_physics_field.py | 339 +++++++++++++++------ 1 file changed, 245 insertions(+), 94 deletions(-) (limited to 'release/scripts/startup') diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 1a4e24fbc0c..aaa2892c5c4 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -17,9 +17,11 @@ # ##### END GPL LICENSE BLOCK ##### # -import bpy -from bpy.types import Panel +import bpy +from bpy.types import ( + Panel, +) from .properties_physics_common import ( basic_force_field_settings_ui, basic_force_field_falloff_ui, @@ -31,9 +33,13 @@ class PhysicButtonsPanel: bl_region_type = 'WINDOW' bl_context = "physics" - @classmethod - def poll(cls, context): - return (context.object) and (context.engine in cls.COMPAT_ENGINES) + def poll_force_field(context): + ob = context.object + return (ob and (ob.field) and (ob.field.type != 'NONE')) + + def poll_collision(context): + ob = context.object + return (ob and ob.type == 'MESH') and (context.collision) class PHYSICS_PT_field(PhysicButtonsPanel, Panel): @@ -42,10 +48,10 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): - ob = context.object - if not ob: + if not PhysicButtonsPanel.poll_force_field(context): return False - return (context.engine in cls.COMPAT_ENGINES) and (ob.field) and (ob.field.type != 'NONE') + + return (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -56,59 +62,135 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): layout.prop(field, "type") + +class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): + bl_label = "Settings" + bl_parent_id = 'PHYSICS_PT_field' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + if not PhysicButtonsPanel.poll_force_field(context): + return False + + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + field = ob.field + if field.type not in {'NONE', 'GUIDE', 'TEXTURE'}: layout.prop(field, "shape", text="Shape") - elif field.type == 'TEXTURE': - layout.row().template_ID(field, "texture", new="texture.new") + + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) if field.type == 'NONE': - return # nothing to draw + return # nothing to draw. + elif field.type == 'GUIDE': - col = layout.column() + col = flow.column() col.prop(field, "guide_minimum") col.prop(field, "guide_free") col.prop(field, "falloff_power") col.prop(field, "use_guide_path_add") col.prop(field, "use_guide_path_weight") - col.label(text="Clumping") - col.prop(field, "guide_clump_amount") - col.prop(field, "guide_clump_shape") + col.separator() + col = flow.column() + col.prop(field, "guide_clump_amount", text="Clumping amount") + col.prop(field, "guide_clump_shape") col.prop(field, "use_max_distance") + sub = col.column() sub.active = field.use_max_distance sub.prop(field, "distance_max") - layout.separator() - - layout.prop(field, "guide_kink_type") - if field.guide_kink_type != 'NONE': - layout.prop(field, "guide_kink_axis") + elif field.type == 'TEXTURE': + col = flow.column() + col.prop(field, "texture_mode") - col = layout.column() - col.prop(field, "guide_kink_frequency") - col.prop(field, "guide_kink_shape") - col.prop(field, "guide_kink_amplitude") + col.separator() - elif field.type == 'TEXTURE': - col = layout.column() col.prop(field, "strength") - col.prop(field, "texture_mode") - col.prop(field, "texture_nabla") + col = flow.column() + col.prop(field, "texture_nabla") col.prop(field, "use_object_coords") col.prop(field, "use_2d_force") + elif field.type == 'SMOKE_FLOW': - col = layout.column() + col = flow.column() col.prop(field, "strength") col.prop(field, "flow") + + col = flow.column() col.prop(field, "source_object") col.prop(field, "use_smoke_density") else: + del flow basic_force_field_settings_ui(self, context, field) +class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel): + bl_label = "Kink" + bl_parent_id = 'PHYSICS_PT_field_settings' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + if not PhysicButtonsPanel.poll_force_field(context): + return False + + ob = context.object + return ((ob.field.type == 'GUIDE') and (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + ob = context.object + field = ob.field + + layout.prop(field, "guide_kink_type", text="Type") + + if field.guide_kink_type != 'NONE': + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) + + col = flow.column() + col.prop(field, "guide_kink_axis") + col.prop(field, "guide_kink_frequency") + + col = flow.column() + col.prop(field, "guide_kink_shape") + col.prop(field, "guide_kink_amplitude") + + +class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel): + bl_label = "Texture" + bl_parent_id = 'PHYSICS_PT_field_settings' + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + if not PhysicButtonsPanel.poll_force_field(context): + return False + + ob = context.object + return ((ob.field.type == 'TEXTURE') and (context.engine in cls.COMPAT_ENGINES)) + + def draw(self, context): + layout = self.layout + + ob = context.object + field = ob.field + + layout.row().template_ID(field, "texture", new="texture.new") + + class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): bl_label = "Falloff" bl_parent_id = "PHYSICS_PT_field" @@ -116,8 +198,11 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): + if not PhysicButtonsPanel.poll_force_field(context): + return False + ob = context.object - return (context.engine in cls.COMPAT_ENGINES) and (ob.field) and (ob.field.type not in {'NONE', 'GUIDE'}) + return ((ob.field.type not in {'NONE', 'GUIDE'}) and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout @@ -130,70 +215,119 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): basic_force_field_falloff_ui(self, context, field) - if field.falloff_type == 'CONE': - layout.separator() - col = layout.column() - col.prop(field, "radial_falloff", text="Power") +class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): + bl_label = "Angular" + bl_parent_id = "PHYSICS_PT_field_falloff" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} - col.label(text="Angular") + @classmethod + def poll(cls, context): + if not PhysicButtonsPanel.poll_force_field(context): + return False - col.prop(field, "use_radial_min", text="Use Min Angle") - sub = col.column() - sub.active = field.use_radial_min - sub.prop(field, "radial_min", text="Min Angle") + ob = context.object + return ((ob.field.falloff_type == 'CONE') and (context.engine in cls.COMPAT_ENGINES)) - col.prop(field, "use_radial_max", text="Use Max Angle") - sub = col.column() - sub.active = field.use_radial_max - sub.prop(field, "radial_max", text="Max Angle") + def draw(self, context): + layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - elif field.falloff_type == 'TUBE': - layout.separator() + ob = context.object + field = ob.field - col = layout.column() + col = flow.column() + col.prop(field, "radial_falloff", text="Power") - col.prop(field, "radial_falloff", text="Power") + col = flow.column() + col.prop(field, "use_radial_min", text="Use Min Angle") - col.label(text="Radial") + sub = col.column() + sub.active = field.use_radial_min + sub.prop(field, "radial_min", text="Min Angle") - col.prop(field, "use_radial_min", text="Use Minimum") - sub = col.column() - sub.active = field.use_radial_min - sub.prop(field, "radial_min", text="Distance") + col = flow.column() + col.prop(field, "use_radial_max", text="Use Max Angle") - col.prop(field, "use_radial_max", text="Use Maximum") - sub = col.column() - sub.active = field.use_radial_max - sub.prop(field, "radial_max", text="Distance") + sub = col.column() + sub.active = field.use_radial_max + sub.prop(field, "radial_max", text="Max Angle") -class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): - bl_label = "Collision" +class PHYSICS_PT_field_falloff_radial(PhysicButtonsPanel, Panel): + bl_label = "Radial" + bl_parent_id = "PHYSICS_PT_field_falloff" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} @classmethod def poll(cls, context): + if not PhysicButtonsPanel.poll_force_field(context): + return False + ob = context.object - return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.collision) + return ((ob.field.falloff_type == 'TUBE') and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout + layout.use_property_split = True + flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True) - md = context.collision + ob = context.object + field = ob.field + + col = flow.column() + col.prop(field, "radial_falloff", text="Power") - split = layout.split() + col = flow.column() + col.prop(field, "use_radial_min", text="Use Minimum") + + sub = col.column() + sub.active = field.use_radial_min + sub.prop(field, "radial_min", text="Min Distance") + + col = flow.column() + col.prop(field, "use_radial_max", text="Use Maximum") + + sub = col.column() + sub.active = field.use_radial_max + sub.prop(field, "radial_max", text="Max Distance") + + +def collision_warning(layout): + row = layout.row(align=True) + row.alignment = 'RIGHT' + row.label("No collision settings available") + + +class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): + bl_label = "Collision" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'} + + @classmethod + def poll(cls, context): + if not PhysicButtonsPanel.poll_collision(context): + return False + + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout layout.use_property_split = True + md = context.collision coll = md.settings - if coll: - settings = context.object.collision + if not coll: + collision_warning(layout) + return + + settings = context.object.collision - layout.active = settings.use + layout.active = settings.use - col = layout.column() - col.prop(settings, "absorption", text="Force Field Absorption") + col = layout.column() + col.prop(settings, "absorption", text="Field Absorption") class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): @@ -203,8 +337,10 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): - ob = context.object - return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.collision) + if not PhysicButtonsPanel.poll_collision(context): + return False + + return (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -216,26 +352,28 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): coll = md.settings - if coll: - settings = context.object.collision + if not coll: + collision_warning(layout) + return - layout.active = settings.use + settings = context.object.collision - col = flow.column() - col.prop(settings, "permeability", slider=True) - col.prop(settings, "stickiness") - col = flow.column() - col.prop(settings, "use_particle_kill") + layout.active = settings.use - col = flow.column() - sub = col.column(align=True) - sub.prop(settings, "damping_factor", text="Damping", slider=True) - sub.prop(settings, "damping_random", text="Randomize", slider=True) + col = flow.column() + col.prop(settings, "permeability", slider=True) + col.prop(settings, "stickiness") + col.prop(settings, "use_particle_kill") - col = flow.column() - sub = col.column(align=True) - sub.prop(settings, "friction_factor", text="Friction", slider=True) - sub.prop(settings, "friction_random", text="Randomize", slider=True) + col = flow.column() + sub = col.column(align=True) + sub.prop(settings, "damping_factor", text="Damping", slider=True) + sub.prop(settings, "damping_random", text="Randomize", slider=True) + + col = flow.column() + sub = col.column(align=True) + sub.prop(settings, "friction_factor", text="Friction", slider=True) + sub.prop(settings, "friction_random", text="Randomize", slider=True) class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): @@ -245,8 +383,10 @@ class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): @classmethod def poll(cls, context): - ob = context.object - return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.collision) + if not PhysicButtonsPanel.poll_collision(context): + return False + + return (context.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout @@ -257,27 +397,38 @@ class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): md = context.collision coll = md.settings - if coll: - settings = context.object.collision + if not coll: + collision_warning(layout) + return - layout.active = settings.use + settings = context.object.collision - col = flow.column() - col.prop(settings, "damping", text="Damping", slider=True) + layout.active = settings.use - col = flow.column() - col.prop(settings, "thickness_outer", text="Thickness Outer", slider=True) - col.prop(settings, "thickness_inner", text="Inner", slider=True) + col = flow.column() + col.prop(settings, "damping", text="Damping", slider=True) + + col = flow.column() + col.prop(settings, "thickness_outer", text="Thickness Outer", slider=True) + + col = flow.column() + col.prop(settings, "thickness_inner", text="Inner", slider=True) classes = ( PHYSICS_PT_field, + PHYSICS_PT_field_settings, + PHYSICS_PT_field_settings_kink, + PHYSICS_PT_field_settings_texture_select, PHYSICS_PT_field_falloff, + PHYSICS_PT_field_falloff_angular, + PHYSICS_PT_field_falloff_radial, PHYSICS_PT_collision, PHYSICS_PT_collision_particle, PHYSICS_PT_collision_softbody, ) + if __name__ == "__main__": # only for live edit. from bpy.utils import register_class for cls in classes: -- cgit v1.2.3