AnimAll: rename the "Animate" tab back to "Animation"
[blender-addons.git] / object_scatter / ui.py
blob92dab96cb3ec4588b343f0afb6c7a798210ed89a
1 # SPDX-FileCopyrightText: 2018-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 import bpy
6 import math
8 from collections import namedtuple
10 from bpy.props import (
11 BoolProperty,
12 IntProperty,
13 FloatProperty,
14 PointerProperty
18 ScatterSettings = namedtuple("ScatterSettings",
19 ["seed", "density", "radius", "scale", "random_scale",
20 "rotation", "normal_offset", "use_normal_rotation"])
22 class ObjectScatterProperties(bpy.types.PropertyGroup):
23 seed: IntProperty(
24 name="Seed",
25 default=0,
26 description="Change it to get a different scatter pattern",
29 density: FloatProperty(
30 name="Density",
31 default=10,
32 min=0,
33 soft_max=50,
34 description="The amount of objects per unit on the line",
37 radius: FloatProperty(
38 name="Radius",
39 default=1,
40 min=0,
41 soft_max=5,
42 subtype='DISTANCE',
43 unit='LENGTH',
44 description="Maximum distance of the objects to the line",
47 scale: FloatProperty(
48 name="Scale",
49 default=0.3,
50 min=0.00001,
51 soft_max=1,
52 description="Size of the generated objects",
55 random_scale_percentage: FloatProperty(
56 name="Random Scale Percentage",
57 default=80,
58 min=0,
59 max=100,
60 subtype='PERCENTAGE',
61 precision=0,
62 description="Increase to get a larger range of sizes",
65 rotation: FloatProperty(
66 name="Rotation",
67 default=0.5,
68 min=0,
69 max=math.pi * 2,
70 soft_max=math.pi / 2,
71 subtype='ANGLE',
72 unit='ROTATION',
73 description="Maximum rotation of the generated objects",
76 normal_offset: FloatProperty(
77 name="Normal Offset",
78 default=0,
79 soft_min=-1.0,
80 soft_max=1.0,
81 description="Distance from the surface",
84 use_normal_rotation: BoolProperty(
85 name="Use Normal Rotation",
86 default=True,
87 description="Rotate the instances according to the surface normals",
90 def to_settings(self):
91 return ScatterSettings(
92 seed=self.seed,
93 density=self.density,
94 radius=self.radius,
95 scale=self.scale,
96 random_scale=self.random_scale_percentage / 100,
97 rotation=self.rotation,
98 normal_offset=self.normal_offset,
99 use_normal_rotation=self.use_normal_rotation,
103 class ObjectScatterPanel(bpy.types.Panel):
104 bl_idname = "OBJECT_PT_object_scatter"
105 bl_label = "Object Scatter"
106 bl_space_type = 'VIEW_3D'
107 bl_region_type = 'UI'
108 bl_category = "Tool"
110 def draw(self, context):
111 layout = self.layout
112 layout.use_property_split = True
113 scatter = context.scene.scatter_properties
115 layout.prop(scatter, "density", slider=True)
116 layout.prop(scatter, "radius", slider=True)
118 col = layout.column(align=True)
119 col.prop(scatter, "scale", slider=True)
120 col.prop(scatter, "random_scale_percentage", text="Randomness", slider=True)
122 layout.prop(scatter, "use_normal_rotation")
123 layout.prop(scatter, "rotation", slider=True)
124 layout.prop(scatter, "normal_offset", text="Offset", slider=True)
125 layout.prop(scatter, "seed")
127 def draw_menu(self, context):
128 layout = self.layout
129 layout.operator("object.scatter")
131 classes = (
132 ObjectScatterProperties,
133 ObjectScatterPanel,
136 def register():
137 for cls in classes:
138 bpy.utils.register_class(cls)
139 bpy.types.Scene.scatter_properties = PointerProperty(type=ObjectScatterProperties)
140 bpy.types.VIEW3D_MT_object.append(draw_menu)
142 def unregister():
143 for cls in classes:
144 bpy.utils.unregister_class(cls)
145 del bpy.types.Scene.scatter_properties
146 bpy.types.VIEW3D_MT_object.remove(draw_menu)