Skip to content
Snippets Groups Projects
Commit fe8cbeae authored by Campbell Barton's avatar Campbell Barton
Browse files

update the script to remove UI hack and use dialog

parent 37242333
Branches
Tags
No related merge requests found
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# ##### END GPL LICENSE BLOCK ##### # ##### END GPL LICENSE BLOCK #####
# <pep8 compliant> # <pep8-80 compliant>
# Script copyright (C) Campbell Barton # Script copyright (C) Campbell Barton
...@@ -42,41 +42,35 @@ from random import uniform, shuffle ...@@ -42,41 +42,35 @@ from random import uniform, shuffle
import bpy import bpy
def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): def _main(self,
from math import radians obj,
group,
DENSITY=1.0,
SCALE=0.6,
RAND_LOC=0.8,
RAND_ALIGN=0.75,
):
C = bpy.context from math import radians, pi
o = C.object
# print(o.ray_cast(Vector(), Vector(0,0,0.2)))
OFS = 0.2 # OFS = 0.2
SEEK = 2.0 # distance for ray to seek SEEK = 2.0 # distance for ray to seek
BAD_NORMAL = Vector((0.0, 0.0, -1.0)) BAD_NORMAL = Vector((0.0, 0.0, -1.0))
WALL_LIMIT = radians(45.0) WALL_LIMIT = radians(45.0)
mats = [Matrix.Rotation(radians(-45), 3, 'X'), mats = (Matrix.Rotation(radians(-45), 3, 'X'),
Matrix.Rotation(radians(+45), 3, 'X'), Matrix.Rotation(radians(+45), 3, 'X'),
Matrix.Rotation(radians(-45), 3, 'Y'), Matrix.Rotation(radians(-45), 3, 'Y'),
Matrix.Rotation(radians(+45), 3, 'Y'), Matrix.Rotation(radians(+45), 3, 'Y'),
Matrix.Rotation(radians(-45), 3, 'Z'), Matrix.Rotation(radians(-45), 3, 'Z'),
Matrix.Rotation(radians(+45), 3, 'Z'), Matrix.Rotation(radians(+45), 3, 'Z'),
] )
Z_UP = Vector((0.0, 0.0, 1.0)) Z_UP = Vector((0.0, 0.0, 1.0))
dirs = [Vector((0.0, 0.0, OFS)), Y_UP = Vector((0.0, 1.0, 0.0))
Vector((0.0, 0.0, -OFS)),
]
'''
Vector(0,OFS,0),
Vector(0,-OFS,0),
Vector(OFS,0,0),
Vector(-OFS,0,0)
'''
group = bpy.data.groups.get(o.name)
if not group: if not group:
self.report({'WARNING'}, "Group '%s' not found, must match object name" % o.name) self.report({'WARNING'}, "Group '%s' not found" % obj.name)
return return
def faces_from_hits(hit_list): def faces_from_hits(hit_list):
...@@ -115,14 +109,13 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): ...@@ -115,14 +109,13 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
obj_new = bpy.data.objects.new("Torus", mesh) obj_new = bpy.data.objects.new("Torus", mesh)
scene.objects.link(obj_new) scene.objects.link(obj_new)
ray = o.ray_cast ray = obj.ray_cast
closest_point = o.closest_point_on_mesh closest_point_on_mesh = obj.closest_point_on_mesh
#ray = C.scene.ray_cast
DEBUG = False DEBUG = False
def fix_point(p): def fix_point(p):
hit, no, ind = closest_point(p) hit, no, ind = closest_point_on_mesh(p)
if ind != -1: if ind != -1:
if DEBUG: if DEBUG:
return [p, no, None] return [p, no, None]
...@@ -196,7 +189,8 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): ...@@ -196,7 +189,8 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
pt[2] = best_nor pt[2] = best_nor
#scene.cursor_location[:] = best_hitnyway #scene.cursor_location[:] = best_hitnyway
# bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1) # bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP',
# iterations=1)
# debug_edge(p, best_hit) # debug_edge(p, best_hit)
# p[:] = best_hit # p[:] = best_hit
...@@ -206,11 +200,13 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): ...@@ -206,11 +200,13 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
nors = [] nors = []
oris = [] oris = []
for s in splines: for s in splines:
for p, n, n_other in s: # point, normal, n_other the closest hit normal # point, normal, n_other the closest hit normal
for p, n, n_other in s:
if n is BAD_NORMAL: if n is BAD_NORMAL:
continue continue
if n_other: if n_other:
# cast vectors twice as long as the distance needed just incase. # cast vectors twice as long as the distance
# needed just incase.
n_down = (n * -SEEK) n_down = (n * -SEEK)
l = n_down.length l = n_down.length
n_other.length = l n_other.length = l
...@@ -249,14 +245,14 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): ...@@ -249,14 +245,14 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
#oris.append(n_other) #oris.append(n_other)
if 0: if 0:
mesh = bpy.data.meshes.new("Retopo") mesh = bpy.data.meshes.new("ScatterDupliFace")
mesh.from_pydata(hits, [], []) mesh.from_pydata(hits, [], [])
scene = bpy.context.scene scene = bpy.context.scene
mesh.update() mesh.update()
obj_new = bpy.data.objects.new("Torus", mesh) obj_new = bpy.data.objects.new("ScatterPar", mesh)
scene.objects.link(obj_new) scene.objects.link(obj_new)
obj_new.layers[:] = o.layers obj_new.layers[:] = obj.layers
# Now setup dupli-faces # Now setup dupli-faces
obj_new.dupli_type = 'VERTS' obj_new.dupli_type = 'VERTS'
...@@ -274,28 +270,33 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): ...@@ -274,28 +270,33 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
tot_div = int(len(triples) / tot) tot_div = int(len(triples) / tot)
for inst_ob in obs: for inst_ob in obs:
triple_subset = triples[0:tot_div] triple_sub = triples[0:tot_div]
triples[0:tot_div] = [] triples[0:tot_div] = []
vv = [tuple(v) for f in triple_subset for v in f] vv = [tuple(v) for f in triple_sub for v in f]
mesh = bpy.data.meshes.new("Retopo") mesh = bpy.data.meshes.new("ScatterDupliFace")
mesh.from_pydata(vv, [], [(i * 3, i * 3 + 1, i * 3 + 2) for i in range(len(triple_subset))]) mesh.from_pydata(vv, [], [(i * 3, i * 3 + 1, i * 3 + 2)
for i in range(len(triple_sub))])
scene = bpy.context.scene scene = bpy.context.scene
mesh.update() mesh.update()
obj_new = bpy.data.objects.new("Torus", mesh) obj_new = bpy.data.objects.new("ScatterPar", mesh)
scene.objects.link(obj_new) scene.objects.link(obj_new)
obj_new.layers[:] = o.layers obj_new.layers[:] = obj.layers
# Now setup dupli-faces # Now setup dupli-faces
obj_new.dupli_type = 'FACES' obj_new.dupli_type = 'FACES'
obj_new.use_dupli_faces_scale = True obj_new.use_dupli_faces_scale = True
obj_new.dupli_faces_scale = 100.0 obj_new.dupli_faces_scale = 100.0
inst_ob.location = obj_new.location inst_ob.location = 0.0, 0.0, 0.0
inst_ob.parent = obj_new inst_ob.parent = obj_new
# important to set last
obj_new.matrix_world = obj.matrix_world
# BGE settings for testiing # BGE settings for testiing
''' '''
inst_ob.game.physics_type = 'RIGID_BODY' inst_ob.game.physics_type = 'RIGID_BODY'
...@@ -319,100 +320,107 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75): ...@@ -319,100 +320,107 @@ def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
quat = no.to_track_quat('X', 'Z') quat = no.to_track_quat('X', 'Z')
# make 2 angles and blend # make 2 angles and blend
angle = radians(uniform(-180, 180.0)) angle = uniform(-pi, pi)
angle_aligned = -(ori.angle(quat * Vector((0.0, 1.0, 0.0)), radians(180.0))) angle_aligned = -(ori.angle(quat * Y_UP, pi))
quat = Quaternion(no, (angle * (1.0 - RAND_ALIGN)) + (angle_aligned * RAND_ALIGN)).cross(quat) quat = Quaternion(no,
(angle * (1.0 - RAND_ALIGN)) +
(angle_aligned * RAND_ALIGN)
).cross(quat)
f = uniform(0.1, 1.2) * SCALE f = uniform(0.1, 1.2) * SCALE
coords.append([co + (quat * (tri[0] * f)), co + (quat * (tri[1] * f)), co + (quat * (tri[2] * f))]) coords.append([co + (quat * (tri[0] * f)),
# face_ind.append([i*3, i*3+1, i*3+2]) co + (quat * (tri[1] * f)),
co + (quat * (tri[2] * f)),
])
apply_faces(coords) apply_faces(coords)
main() main()
from bpy.props import FloatProperty from bpy.props import FloatProperty, StringProperty
class Scatter(bpy.types.Operator): class Scatter(bpy.types.Operator):
'''''' ''''''
bl_idname = "object.scatter" bl_idname = "object.scatter"
bl_label = "Scatter" bl_label = "Grease Pencil Scatter"
bl_options = {'REGISTER'}
density = FloatProperty(name="Density", density = FloatProperty(
name="Density",
description="Multiplier for the density of items", description="Multiplier for the density of items",
default=1.0, min=0.01, max=10.0) default=1.0, min=0.01, max=10.0,
)
scale = FloatProperty(name="Scale", scale = FloatProperty(
name="Scale",
description="Size multiplier for duplifaces", description="Size multiplier for duplifaces",
default=1.0, min=0.01, max=10.0) default=1.0, min=0.01, max=10.0,
)
rand_align = FloatProperty(name="Random Align", rand_align = FloatProperty(
name="Random Align",
description="Randomize alignmet with the walls", description="Randomize alignmet with the walls",
default=0.75, min=0.0, max=1.0) default=0.75, min=0.0, max=1.0,
)
rand_loc = FloatProperty(name="Random Loc", rand_loc = FloatProperty(
name="Random Loc",
description="Randomize Placement", description="Randomize Placement",
default=0.75, min=0.0, max=1.0) default=0.75, min=0.0, max=1.0,
)
_parent = None # XXX, should not be a string - TODO, add a way for scritps to select ID's
group = StringProperty(
name="Group",
description=("Group name to use for object placement, "
"defaults to object name when that matches a group"))
def execute(self, context): def execute(self, context):
#self.properties.density = self.__class__._parent.properties.density # XXX bad way to copy args. obj = bpy.context.object
#self.properties.scale = self.__class__._parent.properties.scale # XXX bad way to copy args. group = bpy.data.groups.get(self.group)
for attr in self.__class__.__dict__["order"]: if not group:
if not attr.startswith("_"): self.report({'ERROR'}, "Group %r not found", self.group)
try: return {'CANCELLED'}
setattr(self.properties, attr, getattr(self.__class__._parent.properties, attr))
except:
pass
_main(self, _main(self,
DENSITY=self.properties.density, obj,
SCALE=self.properties.scale, group,
RAND_LOC=self.properties.rand_loc, DENSITY=self.density,
RAND_ALIGN=self.properties.rand_align, SCALE=self.scale,
RAND_LOC=self.rand_loc,
RAND_ALIGN=self.rand_align,
) )
return {'FINISHED'} return {'FINISHED'}
def invoke(self, context, event): def check(self, context):
wm = context.window_manager if self.group not in bpy.data.groups:
wm.invoke_popup(self, width=180) self.group = ""
return {'RUNNING_MODAL'} return True
return False
def draw(self, context): def invoke(self, context, event):
self.__class__._parent = self
layout = self.layout
for attr in self.__class__.__dict__["order"]: # useful to initialize, take a guess
if not attr.startswith("_"): if not self.group and context.object.name in bpy.data.groups:
try: self.group = context.object.name
layout.prop(self.properties, attr)
except:
pass
layout.operator_context = 'EXEC_DEFAULT' wm = context.window_manager
layout.operator(self.bl_idname) wm.invoke_props_dialog(self, width=180)
return {'RUNNING_MODAL'}
# Add to the menu def menu_func(self, context):
menu_func = (lambda self, context: self.layout.operator(Scatter.bl_idname, self.layout.operator(Scatter.bl_idname, icon='AUTO')
text="Scatter", icon='AUTO'))
def register(): def register():
bpy.utils.register_class(Scatter) bpy.utils.register_class(Scatter)
bpy.types.VIEW3D_PT_tools_objectmode.append(menu_func) bpy.types.INFO_MT_mesh_add.append(menu_func)
def unregister(): def unregister():
bpy.utils.unregister_class(Scatter) bpy.utils.unregister_class(Scatter)
bpy.types.VIEW3D_PT_tools_objectmode.remove(menu_func) bpy.types.INFO_MT_mesh_add.remove(menu_func)
#if __name__ == "__main__": #if __name__ == "__main__":
# _main() # _main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment