4 "name": "Add Random Box Structure",
7 "location": "View3D > Add > Make Box Structure",
8 "description": "Fill selected box shaped meshes with randomly sized cubes",
11 "tracker_url": "dannyboypython.blogspot.com",
16 from bpy
.types
import Operator
17 from bpy
.props
import (
25 class makestructure(Operator
):
26 bl_idname
= "object.make_structure"
27 bl_label
= "Add Random Box Structure"
28 bl_description
= ("Create a randomized structure made of boxes\n"
29 "with various control parameters\n"
30 "Needs an existing Active Mesh Object")
31 bl_options
= {'REGISTER', 'UNDO'}
34 name
="Delete Base Mesh(es)",
38 name
="Stay Within Bounds",
39 description
="Keeps cubes from exceeding base mesh bounds",
43 name
="Uniform Cube Quantity",
51 mn
= FloatVectorProperty(
53 default
=(0.1, 0.1, 0.1),
56 mx
= FloatVectorProperty(
58 default
=(2.0, 2.0, 2.0),
61 lo
= FloatVectorProperty(
63 default
=(0.0, 0.0, 0.0),
72 def poll(cls
, context
):
73 obj
= context
.active_object
74 return obj
is not None and obj
.type == "MESH" and obj
.mode
== "OBJECT"
76 def draw(self
, context
):
80 box
.label(text
="Options:")
86 box
.label(text
="Parameters:")
93 def execute(self
, context
):
97 bpy
.ops
.group
.create(name
='Cubagrouper')
98 bpy
.ops
.group
.objects_remove()
100 for ob
in bpy
.context
.selected_objects
:
104 bpy
.ops
.object.select_pattern(pattern
=obj
.name
) # Select base mesh
105 bpy
.context
.scene
.objects
.active
= obj
106 if obj
.data
.uv_layers
[:] != []:
110 bpy
.ops
.object.group_link(group
='Cubagrouper')
112 rot
= obj
.rotation_euler
114 area
= dim
.x
* dim
.y
* dim
.z
118 for cube
in range(round((area
/ 75) * self
.qn
)):
119 random
.seed(rsdchange
)
120 pmn
= self
.mn
# Proxy values
123 if dim
.x
< pmx
.x
: # Keeping things from exceeding proper size
129 if 0.0 > pmn
.x
: # Keeping things from going under zero
135 sx
= (random
.random() * (pmx
.x
- pmn
.x
)) + pmn
.x
# Just changed self.mx and .mn to pmx.
136 sy
= (random
.random() * (pmx
.y
- pmn
.y
)) + pmn
.y
137 sz
= (random
.random() * (pmx
.z
- pmn
.z
)) + pmn
.z
138 if self
.wh
is True: # This keeps the cubes within the base mesh
139 ex
= (random
.random() * (dim
.x
- sx
)) - ((dim
.x
- sx
) / 2) + obj
.location
.x
140 wy
= (random
.random() * (dim
.y
- sy
)) - ((dim
.y
- sy
) / 2) + obj
.location
.y
141 ze
= (random
.random() * (dim
.z
- sz
)) - ((dim
.z
- sz
) / 2) + obj
.location
.z
142 elif self
.wh
is False:
143 ex
= (random
.random() * dim
.x
) - (dim
.x
/ 2) + obj
.location
.x
144 wy
= (random
.random() * dim
.y
) - (dim
.y
/ 2) + obj
.location
.y
145 ze
= (random
.random() * dim
.z
) - (dim
.z
/ 2) + obj
.location
.z
146 bpy
.ops
.mesh
.primitive_cube_add(
147 radius
=0.5, location
=(ex
+ self
.lo
.x
, wy
+ self
.lo
.y
, ze
+ self
.lo
.z
)
149 bpy
.ops
.object.mode_set(mode
='EDIT')
150 bpy
.ops
.mesh
.select_all(action
='SELECT')
151 bpy
.ops
.transform
.resize(
152 value
=(sx
, sy
, sz
), constraint_axis
=(True, True, True),
153 constraint_orientation
='GLOBAL', mirror
=False, proportional
='DISABLED',
154 proportional_edit_falloff
='SMOOTH', proportional_size
=1, release_confirm
=True
156 bpy
.ops
.object.mode_set(mode
='OBJECT')
157 select
= bpy
.context
.object # This is used to keep something selected for poll()
158 bpy
.ops
.object.group_link(group
='Cubagrouper')
160 bpy
.ops
.object.select_grouped(type='GROUP')
161 bpy
.ops
.transform
.rotate(
162 value
=rot
[0], axis
=(1, 0, 0), constraint_axis
=(False, False, False),
163 constraint_orientation
='GLOBAL', mirror
=False, proportional
='DISABLED',
164 proportional_edit_falloff
='SMOOTH', proportional_size
=1, release_confirm
=True
166 bpy
.ops
.transform
.rotate(
167 value
=rot
[1], axis
=(0, 1, 0), constraint_axis
=(False, False, False),
168 constraint_orientation
='GLOBAL', mirror
=False, proportional
='DISABLED',
169 proportional_edit_falloff
='SMOOTH', proportional_size
=1, release_confirm
=True
171 bpy
.ops
.transform
.rotate(
172 value
=rot
[2], axis
=(0, 0, 1), constraint_axis
=(False, False, False),
173 constraint_orientation
='GLOBAL', mirror
=False, proportional
='DISABLED',
174 proportional_edit_falloff
='SMOOTH', proportional_size
=1, release_confirm
=True
176 bpy
.context
.scene
.objects
.active
= obj
# Again needed to avoid poll() taking me down
177 bpy
.ops
.object.make_links_data(type='MODIFIERS')
178 bpy
.ops
.object.make_links_data(type='MATERIAL')
181 bpy
.ops
.object.join_uvs()
183 bpy
.ops
.group
.objects_remove()
184 bpy
.context
.scene
.objects
.active
= select
187 bpy
.context
.scene
.objects
.unlink(obj
)
193 bpy
.utils
.register_class(makestructure
)
197 bpy
.utils
.unregister_class(makestructure
)
200 if __name__
== "__main__":