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