import bpy #-------------------------------------------------------------- # Specify which existing Blender UI panels Psychopath # uses/is compatible with. import bl_ui def register_engine_with_panels(area, list): # TODO: reverse this, so we're checking if the list item is # in the real panels, and throw an error if it's not. That # way things don't just silently fail. for p in list: eval("bl_ui.{}.{}.COMPAT_ENGINES.add('PSYCHOPATH_RENDER')".format(area, p)) register_engine_with_panels( "properties_render", [ "RENDER_PT_color_management", "RENDER_PT_color_management_curves", ] ) register_engine_with_panels( "properties_output", [ "RENDER_PT_encoding", "RENDER_PT_encoding_audio", "RENDER_PT_encoding_video", "RENDER_PT_format", "RENDER_PT_frame_range", "RENDER_PT_output", "RENDER_PT_output_views", "RENDER_PT_post_processing", "RENDER_PT_stamp", "RENDER_PT_stamp_burn", "RENDER_PT_stamp_note", # "RENDER_PT_stereoscopy", "RENDER_PT_time_stretching", ] ) register_engine_with_panels( "properties_view_layer", [ "VIEWLAYER_PT_layer", ] ) register_engine_with_panels( "properties_data_camera", [ "DATA_PT_context_camera", "DATA_PT_custom_props_camera", "DATA_PT_camera", "DATA_PT_lens", "DATA_PT_camera_dof", "DATA_PT_camera_dof_aperture", "DATA_PT_camera_display", "DATA_PT_camera_display_composition_guides", "DATA_PT_camera_safe_areas", "DATA_PT_camera_safe_areas_center_cut", "DATA_PT_camera_background_image", ] ) register_engine_with_panels( "properties_data_mesh", [ "DATA_PT_context_mesh", "DATA_PT_custom_props_mesh", "DATA_PT_customdata", "DATA_PT_face_maps", "DATA_PT_mesh_attributes", "DATA_PT_normals", "DATA_PT_remesh", "DATA_PT_shape_keys", "DATA_PT_texture_space", "DATA_PT_uv_texture", "DATA_PT_vertex_colors", "DATA_PT_vertex_groups", ] ) register_engine_with_panels( "properties_particle", [ "PARTICLE_MT_context_menu", "PARTICLE_PT_boidbrain", "PARTICLE_PT_cache", "PARTICLE_PT_children", "PARTICLE_PT_children_clumping", "PARTICLE_PT_children_clumping_noise", "PARTICLE_PT_children_kink", "PARTICLE_PT_children_parting", "PARTICLE_PT_children_roughness", "PARTICLE_PT_context_particles", "PARTICLE_PT_custom_props", "PARTICLE_PT_draw", "PARTICLE_PT_emission", "PARTICLE_PT_emission_source", "PARTICLE_PT_field_weights", "PARTICLE_PT_force_fields", "PARTICLE_PT_force_fields_type1", "PARTICLE_PT_force_fields_type1_falloff", "PARTICLE_PT_force_fields_type2", "PARTICLE_PT_force_fields_type2_falloff", "PARTICLE_PT_hair_dynamics", "PARTICLE_PT_hair_dynamics_collision", "PARTICLE_PT_hair_dynamics_presets", "PARTICLE_PT_hair_dynamics_structure", "PARTICLE_PT_hair_dynamics_volume", "PARTICLE_PT_hair_shape", "PARTICLE_PT_physics", "PARTICLE_PT_physics_boids_battle", "PARTICLE_PT_physics_boids_misc", "PARTICLE_PT_physics_boids_movement", "PARTICLE_PT_physics_deflection", "PARTICLE_PT_physics_fluid_advanced", "PARTICLE_PT_physics_fluid_interaction", "PARTICLE_PT_physics_fluid_springs", "PARTICLE_PT_physics_fluid_springs_advanced", "PARTICLE_PT_physics_fluid_springs_viscoelastic", "PARTICLE_PT_physics_forces", "PARTICLE_PT_physics_integration", "PARTICLE_PT_physics_relations", "PARTICLE_PT_render", "PARTICLE_PT_render_collection", "PARTICLE_PT_render_collection_use_count", "PARTICLE_PT_render_extra", "PARTICLE_PT_render_object", "PARTICLE_PT_render_path", "PARTICLE_PT_render_path_timing", "PARTICLE_PT_rotation", "PARTICLE_PT_rotation_angular_velocity", "PARTICLE_PT_textures", "PARTICLE_PT_velocity", "PARTICLE_PT_vertexgroups", ] ) # Physics. # (Why these require renderer compatibility settings # is beyond me. But they do.) register_engine_with_panels( "properties_physics_cloth", [ "PHYSICS_PT_cloth", "PHYSICS_PT_cloth_cache", "PHYSICS_PT_cloth_collision", "PHYSICS_PT_cloth_damping", "PHYSICS_PT_cloth_field_weights", "PHYSICS_PT_cloth_internal_springs", "PHYSICS_PT_cloth_object_collision", "PHYSICS_PT_cloth_physical_properties", "PHYSICS_PT_cloth_pressure", "PHYSICS_PT_cloth_property_weights", "PHYSICS_PT_cloth_self_collision", "PHYSICS_PT_cloth_shape", "PHYSICS_PT_cloth_stiffness", ], ) register_engine_with_panels( "properties_physics_common", [ "PHYSICS_PT_add", ] ) register_engine_with_panels( "properties_physics_dynamicpaint", [ "PHYSICS_PT_dp_brush_source", "PHYSICS_PT_dp_brush_source_color_ramp", "PHYSICS_PT_dp_brush_velocity", "PHYSICS_PT_dp_brush_velocity_color_ramp", "PHYSICS_PT_dp_brush_velocity_smudge", "PHYSICS_PT_dp_brush_wave", "PHYSICS_PT_dp_cache", "PHYSICS_PT_dp_canvas_initial_color", "PHYSICS_PT_dp_canvas_output", "PHYSICS_PT_dp_canvas_output_paintmaps", "PHYSICS_PT_dp_canvas_output_wetmaps", "PHYSICS_PT_dp_effects", "PHYSICS_PT_dp_effects_drip", "PHYSICS_PT_dp_effects_drip_weights", "PHYSICS_PT_dp_effects_shrink", "PHYSICS_PT_dp_effects_spread", "PHYSICS_PT_dp_surface_canvas", "PHYSICS_PT_dp_surface_canvas_paint_dissolve", "PHYSICS_PT_dp_surface_canvas_paint_dry", "PHYSICS_PT_dynamic_paint", "PHYSICS_PT_dynamic_paint_settings", ] ) register_engine_with_panels( "properties_physics_field", [ "PHYSICS_PT_collision", "PHYSICS_PT_collision_particle", "PHYSICS_PT_collision_softbody", "PHYSICS_PT_field", "PHYSICS_PT_field_falloff", "PHYSICS_PT_field_falloff_angular", "PHYSICS_PT_field_falloff_radial", "PHYSICS_PT_field_settings", "PHYSICS_PT_field_settings_kink", "PHYSICS_PT_field_settings_texture_select", ] ) register_engine_with_panels( "properties_physics_fluid", [ "PHYSICS_PT_adaptive_domain", "PHYSICS_PT_borders", "PHYSICS_PT_cache", "PHYSICS_PT_collections", "PHYSICS_PT_diffusion", "PHYSICS_PT_export", "PHYSICS_PT_field_weights", "PHYSICS_PT_fire", "PHYSICS_PT_flow_initial_velocity", "PHYSICS_PT_flow_source", "PHYSICS_PT_flow_texture", "PHYSICS_PT_fluid", "PHYSICS_PT_guide", "PHYSICS_PT_liquid", "PHYSICS_PT_mesh", "PHYSICS_PT_noise", "PHYSICS_PT_particles", "PHYSICS_PT_settings", "PHYSICS_PT_smoke", "PHYSICS_PT_smoke_dissolve", "PHYSICS_PT_viscosity", ] ) register_engine_with_panels( "properties_physics_rigidbody", [ "PHYSICS_PT_rigid_body", "PHYSICS_PT_rigid_body_collisions", "PHYSICS_PT_rigid_body_collisions_collections", "PHYSICS_PT_rigid_body_collisions_sensitivity", "PHYSICS_PT_rigid_body_collisions_surface", "PHYSICS_PT_rigid_body_dynamics", "PHYSICS_PT_rigid_body_dynamics_deactivation", "PHYSICS_PT_rigid_body_settings", ] ) register_engine_with_panels( "properties_physics_rigidbody_constraint", [ "PHYSICS_PT_rigid_body_constraint", "PHYSICS_PT_rigid_body_constraint_limits", "PHYSICS_PT_rigid_body_constraint_limits_angular", "PHYSICS_PT_rigid_body_constraint_limits_linear", "PHYSICS_PT_rigid_body_constraint_motor", "PHYSICS_PT_rigid_body_constraint_motor_angular", "PHYSICS_PT_rigid_body_constraint_motor_linear", "PHYSICS_PT_rigid_body_constraint_objects", "PHYSICS_PT_rigid_body_constraint_override_iterations", "PHYSICS_PT_rigid_body_constraint_settings", "PHYSICS_PT_rigid_body_constraint_springs", "PHYSICS_PT_rigid_body_constraint_springs_angular", "PHYSICS_PT_rigid_body_constraint_springs_linear", ] ) register_engine_with_panels( "properties_physics_softbody", [ "PHYSICS_PT_softbody", "PHYSICS_PT_softbody_cache", "PHYSICS_PT_softbody_collision", "PHYSICS_PT_softbody_edge", "PHYSICS_PT_softbody_edge_aerodynamics", "PHYSICS_PT_softbody_edge_stiffness", "PHYSICS_PT_softbody_field_weights", "PHYSICS_PT_softbody_goal", "PHYSICS_PT_softbody_goal_settings", "PHYSICS_PT_softbody_goal_strengths", "PHYSICS_PT_softbody_object", "PHYSICS_PT_softbody_simulation", "PHYSICS_PT_softbody_solver", "PHYSICS_PT_softbody_solver_diagnostics", "PHYSICS_PT_softbody_solver_helpers", ] ) #-------------------------------------------------------------- class PsychopathPanel(): COMPAT_ENGINES = {'PSYCHOPATH_RENDER'} @classmethod def poll(cls, context): rd = context.scene.render return rd.engine in cls.COMPAT_ENGINES class RENDER_PT_psychopath_render_settings(PsychopathPanel, bpy.types.Panel): bl_label = "Render Settings" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "render" def draw(self, context): scene = context.scene layout = self.layout col = layout.column() col.label(text="Sampling") col.prop(scene.psychopath, "spp") col.label(text="Dicing") col.prop(scene.psychopath, "dicing_rate") col.label(text="Motion Blur") col.prop(scene.psychopath, "motion_blur_segments") col.prop(scene.psychopath, "shutter_start") col.prop(scene.psychopath, "shutter_end") col.label(text="Performance") col.prop(scene.psychopath, "bucket_size") class RENDER_PT_psychopath_export_settings(PsychopathPanel, bpy.types.Panel): bl_label = "Export Settings" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "render" def draw(self, context): scene = context.scene layout = self.layout col = layout.column() col.prop(scene.psychopath, "export_path") class WORLD_PT_psychopath_background(PsychopathPanel, bpy.types.Panel): bl_label = "Background" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "world" @classmethod def poll(cls, context): return context.world and PsychopathPanel.poll(context) def draw(self, context): layout = self.layout world = context.world layout.prop(world.psychopath, "background_color", text="Color") class DATA_PT_psychopath_lamp(PsychopathPanel, bpy.types.Panel): bl_label = "Lamp" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "data" @classmethod def poll(cls, context): engine = context.scene.render.engine return context.active_object.type == 'LIGHT' and PsychopathPanel.poll(context) def draw(self, context): ob = context.active_object layout = self.layout col = layout.column() row = col.row() row.prop(ob.data, "type", expand=True) if ob.data.type != 'HEMI' and ob.data.type != 'AREA': col.prop(ob.data, "shadow_soft_size") col.prop(ob.data.psychopath, "color_type") if ob.data.psychopath.color_type == 'Rec709': col.prop(ob.data, "color") elif ob.data.psychopath.color_type == 'Blackbody' or ob.data.psychopath.color_type == 'ColorTemperature': col.prop(ob.data.psychopath, "color_blackbody_temp") col.prop(ob.data, "energy") class DATA_PT_psychopath_area_lamp(PsychopathPanel, bpy.types.Panel): bl_label = "Area Shape" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "data" @classmethod def poll(cls, context): engine = context.scene.render.engine return context.active_object.type == 'LIGHT' \ and context.active_object.data.type == 'AREA' \ and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout lamp = context.active_object.data col = layout.column() col.row().prop(lamp, "shape", expand=True) sub = col.row(align=True) if lamp.shape == 'SQUARE' or lamp.shape == 'DISK': sub.prop(lamp, "size") elif lamp.shape == 'RECTANGLE' or lamp.shape == 'ELLIPSE': sub.prop(lamp, "size", text="Size X") sub.prop(lamp, "size_y", text="Size Y") class DATA_PT_psychopath_mesh(PsychopathPanel, bpy.types.Panel): bl_label = "Psychopath Mesh Properties" bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' bl_context = "data" @classmethod def poll(cls, context): engine = context.scene.render.engine return context.mesh and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout mesh = context.mesh layout.row().prop(mesh.psychopath, "is_subdivision_surface") class MATERIAL_PT_psychopath_context_material(PsychopathPanel, bpy.types.Panel): bl_label = "" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "material" bl_options = {'HIDE_HEADER'} @classmethod def poll(cls, context): return (context.material or context.object) and PsychopathPanel.poll(context) def draw(self, context): layout = self.layout mat = context.material ob = context.object slot = context.material_slot space = context.space_data if ob: row = layout.row() row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1) col = row.column(align=True) col.operator("object.material_slot_add", icon='ADD', text="") col.operator("object.material_slot_remove", icon='REMOVE', text="") col.menu("MATERIAL_MT_context_menu", icon='DOWNARROW_HLT', text="") if ob.mode == 'EDIT': row = layout.row(align=True) row.operator("object.material_slot_assign", text="Assign") row.operator("object.material_slot_select", text="Select") row.operator("object.material_slot_deselect", text="Deselect") split = layout.split(factor=0.65) if ob: split.template_ID(ob, "active_material", new="material.new") row = split.row() if slot: row.prop(slot, "link", text="") else: row.label() elif mat: split.template_ID(space, "pin_id") split.separator() class MATERIAL_PT_psychopath_surface(PsychopathPanel, bpy.types.Panel): bl_label = "Surface" bl_space_type = "PROPERTIES" bl_region_type = "WINDOW" bl_context = "material" @classmethod def poll(cls, context): return context.material and PsychopathPanel.poll(context) def draw(self, context): layout = self.layout col = layout.column() mat = context.material col.prop(mat.psychopath, "surface_shader_type") col.prop(mat.psychopath, "color_type") if mat.psychopath.color_type == 'Rec709': col.prop(mat.psychopath, "color") elif mat.psychopath.color_type == 'Blackbody' or mat.psychopath.color_type == 'ColorTemperature': col.prop(mat.psychopath, "color_blackbody_temp") if mat.psychopath.surface_shader_type == 'GTR': layout.prop(mat.psychopath, "roughness") layout.prop(mat.psychopath, "tail_shape") layout.prop(mat.psychopath, "fresnel") if mat.psychopath.surface_shader_type == 'GGX': layout.prop(mat.psychopath, "roughness") layout.prop(mat.psychopath, "fresnel") def register(): bpy.utils.register_class(RENDER_PT_psychopath_render_settings) bpy.utils.register_class(RENDER_PT_psychopath_export_settings) bpy.utils.register_class(WORLD_PT_psychopath_background) bpy.utils.register_class(DATA_PT_psychopath_mesh) bpy.utils.register_class(DATA_PT_psychopath_lamp) bpy.utils.register_class(DATA_PT_psychopath_area_lamp) bpy.utils.register_class(MATERIAL_PT_psychopath_context_material) bpy.utils.register_class(MATERIAL_PT_psychopath_surface) def unregister(): bpy.utils.unregister_class(RENDER_PT_psychopath_render_settings) bpy.utils.unregister_class(RENDER_PT_psychopath_export_settings) bpy.utils.unregister_class(WORLD_PT_psychopath_background) bpy.utils.unregister_class(DATA_PT_psychopath_mesh) bpy.utils.unregister_class(DATA_PT_psychopath_lamp) bpy.utils.unregister_class(DATA_PT_psychopath_area_lamp) bpy.utils.unregister_class(MATERIAL_PT_psychopath_context_material) bpy.utils.unregister_class(MATERIAL_PT_psychopath_surface)