1 # SPDX-FileCopyrightText: 2019-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 "name": "Random Vertices",
7 "author": "Oscurart, Greg",
10 "location": "Object > Transform > Random Vertices",
11 "description": "Randomize selected components of active object",
19 from bpy
.types
import Operator
22 from bpy
.props
import (
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
33 objact
= bpy
.context
.active_object
38 bpy
.ops
.object.mode_set(mode
='OBJECT')
39 bpy
.ops
.object.mode_set(mode
='EDIT')
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
[:]:
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
:
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)
72 random_factor
= factor
* vertexweight
74 random_factor
= factor
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]
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(
102 description
="Use Vertex Weight defined in the Active Group",
105 factor
: FloatProperty(
107 description
="Base Multiplier of the randomization effect",
110 valmin
: IntVectorProperty(
112 description
="Define the minimum range of randomization values",
115 valmax
: IntVectorProperty(
117 description
="Define the maximum range of randomization values",
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
)
135 bpy
.utils
.register_class(MESH_OT_random_vertices
)
139 bpy
.utils
.unregister_class(MESH_OT_random_vertices
)
142 if __name__
== '__main__':