AnimAll: update translation
[blender-addons.git] / mesh_tools / random_vertices.py
blobc61cbbfcb50cea52822778a4c92b0c932ed11638
1 # SPDX-FileCopyrightText: 2019-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 bl_info = {
6 "name": "Random Vertices",
7 "author": "Oscurart, Greg",
8 "version": (1, 3),
9 "blender": (2, 63, 0),
10 "location": "Object > Transform > Random Vertices",
11 "description": "Randomize selected components of active object",
12 "warning": "",
13 "doc_url": "",
14 "category": "Mesh",
18 import bpy
19 from bpy.types import Operator
20 import random
21 import bmesh
22 from bpy.props import (
23 BoolProperty,
24 FloatProperty,
25 IntVectorProperty,
29 def add_object(self, context, valmin, valmax, factor, vgfilter):
30 # select an option with weight map or not
31 mode = bpy.context.active_object.mode
32 # generate variables
33 objact = bpy.context.active_object
34 listver = []
35 warn_message = False
37 # switch to edit mode
38 bpy.ops.object.mode_set(mode='OBJECT')
39 bpy.ops.object.mode_set(mode='EDIT')
41 # bmesh object
42 odata = bmesh.from_edit_mesh(objact.data)
43 odata.select_flush(False)
45 # if the vertex is selected add to the list
46 for vertice in odata.verts[:]:
47 if vertice.select:
48 listver.append(vertice.index)
50 # If the minimum value is greater than the maximum,
51 # it adds a value to the maximum
52 if valmin[0] >= valmax[0]:
53 valmax[0] = valmin[0] + 1
55 if valmin[1] >= valmax[1]:
56 valmax[1] = valmin[1] + 1
58 if valmin[2] >= valmax[2]:
59 valmax[2] = valmin[2] + 1
61 odata.verts.ensure_lookup_table()
63 random_factor = factor
64 for vertice in listver:
65 odata.verts.ensure_lookup_table()
66 if odata.verts[vertice].select:
67 if vgfilter is True:
68 has_group = getattr(objact.data.vertices[vertice], "groups", None)
69 vertex_group = has_group[0] if has_group else None
70 vertexweight = getattr(vertex_group, "weight", None)
71 if vertexweight:
72 random_factor = factor * vertexweight
73 else:
74 random_factor = factor
75 warn_message = True
77 odata.verts[vertice].co = (
78 (((random.randrange(valmin[0], valmax[0], 1)) * random_factor) / 1000) +
79 odata.verts[vertice].co[0],
80 (((random.randrange(valmin[1], valmax[1], 1)) * random_factor) / 1000) +
81 odata.verts[vertice].co[1],
82 (((random.randrange(valmin[2], valmax[2], 1)) * random_factor) / 1000) +
83 odata.verts[vertice].co[2]
86 if warn_message:
87 self.report({'WARNING'},
88 "Some of the Selected Vertices don't have a Group with Vertex Weight assigned")
89 bpy.ops.object.mode_set(mode=mode)
92 class MESH_OT_random_vertices(Operator):
93 bl_idname = "mesh.random_vertices"
94 bl_label = "Random Vertices"
95 bl_description = ("Randomize the location of vertices by a specified\n"
96 "Multiplier Factor and random values in the defined range\n"
97 "or a multiplication of them and the Vertex Weights")
98 bl_options = {'REGISTER', 'UNDO'}
100 vgfilter: BoolProperty(
101 name="Vertex Group",
102 description="Use Vertex Weight defined in the Active Group",
103 default=False
105 factor: FloatProperty(
106 name="Factor",
107 description="Base Multiplier of the randomization effect",
108 default=1
110 valmin: IntVectorProperty(
111 name="Min XYZ",
112 description="Define the minimum range of randomization values",
113 default=(0, 0, 0)
115 valmax: IntVectorProperty(
116 name="Max XYZ",
117 description="Define the maximum range of randomization values",
118 default=(1, 1, 1)
121 @classmethod
122 def poll(cls, context):
123 return (context.object and context.object.type == "MESH" and
124 context.mode == "EDIT_MESH")
126 def execute(self, context):
127 add_object(self, context, self.valmin, self.valmax, self.factor, self.vgfilter)
129 return {'FINISHED'}
132 # Registration
134 def register():
135 bpy.utils.register_class(MESH_OT_random_vertices)
138 def unregister():
139 bpy.utils.unregister_class(MESH_OT_random_vertices)
142 if __name__ == '__main__':
143 register()