diff options
author | Jacques Lucke <mail@jlucke.com> | 2018-10-30 18:39:43 +0300 |
---|---|---|
committer | Jacques Lucke <mail@jlucke.com> | 2018-10-30 18:39:43 +0300 |
commit | b8a0f8c8fe65337a718e215db9ebd53c39a7a173 (patch) | |
tree | c30f816926332ac761c59ff60f216b8bef908977 /object_grease_scatter.py | |
parent | 54d50aec6f135236e6a5346b61be56e3f550da55 (diff) |
Remove "Object Grease Scatter" addon in Blender 2.8
There is a new "Object Scatter" addon as a replacement.
Diffstat (limited to 'object_grease_scatter.py')
-rw-r--r-- | object_grease_scatter.py | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/object_grease_scatter.py b/object_grease_scatter.py deleted file mode 100644 index df1c7cce..00000000 --- a/object_grease_scatter.py +++ /dev/null @@ -1,401 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# <pep8-80 compliant> - -# Script copyright (C) Campbell Barton - -bl_info = { - "name": "Grease Scatter Objects", - "author": "Campbell Barton", - "version": (0, 1), - "blender": (2, 58, 0), - "location": "3D View, Add Mesh", - "description": "Scatter a group of objects onto the active mesh using " - "the grease pencil lines", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/Object/Grease_Scatter", - "support": 'OFFICIAL', - "category": "Object", -} - -from mathutils import Vector, Matrix, Quaternion -from random import uniform, shuffle -import bpy - - -def _main(self, - obj, - group, - DENSITY=1.0, - SCALE=0.6, - RAND_LOC=0.8, - RAND_ALIGN=0.75, - ): - - from math import radians, pi - - # OFS = 0.2 - SEEK = 2.0 # distance for ray to seek - BAD_NORMAL = Vector((0.0, 0.0, -1.0)) - WALL_LIMIT = radians(45.0) - - mats = (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, 'Z'), - Matrix.Rotation(radians(+45), 3, 'Z'), - ) - - Z_UP = Vector((0.0, 0.0, 1.0)) - Y_UP = Vector((0.0, 1.0, 0.0)) - - if not group: - self.report({'WARNING'}, "Group '%s' not found" % obj.name) - return - - def debug_edge(v1, v2): - mesh = bpy.data.meshes.new("Retopo") - mesh.from_pydata([v1, v2], [(0.0, 1.0)], []) - - scene = bpy.context.scene - mesh.update() - obj_new = bpy.data.objects.new("Torus", mesh) - scene.objects.link(obj_new) - - ray = obj.ray_cast - closest_point_on_mesh = obj.closest_point_on_mesh - - obj_mat = obj.matrix_world.copy() - obj_mat_inv = obj_mat.inverted() - # obj_quat = obj_mat.to_quaternion() - # obj_quat_inv = obj_mat_inv.to_quaternion() - - DEBUG = False - - def fix_point(p): - ok, hit, no, ind = closest_point_on_mesh(obj_mat_inv * p) - if ok: - if DEBUG: - return [p, no, None] - else: - # print("good", hit, no) - return [hit, no, None] - - # worry! - print("bad!", p, BAD_NORMAL) - - return [p, BAD_NORMAL, None] - - def get_points(stroke): - return [fix_point(point.co) for point in stroke.points] - - def get_splines(gp): - if gp.layers.active: - frame = gp.layers.active.active_frame - return [get_points(stroke) for stroke in frame.strokes] - else: - return [] - - def main(): - scene = bpy.context.scene - obj = bpy.context.object - - gp = None - - if obj: - gp = obj.grease_pencil - - if not gp: - gp = scene.grease_pencil - - if not gp: - self.report({'WARNING'}, "No grease pencil layer found") - return - - splines = get_splines(gp) - - for s in splines: - for pt in s: - p = pt[0] - n = pt[1] - # print(p, n) - if n is BAD_NORMAL: - continue - - # # dont self intersect - best_nor = None - #best_hit = None - best_dist = 10000000.0 - pofs = p + n * 0.01 - - n_seek = n * SEEK - m_alt_1 = Matrix.Rotation(radians(22.5), 3, n) - m_alt_2 = Matrix.Rotation(radians(-22.5), 3, n) - for _m in mats: - for m in (_m, m_alt_1 * _m, m_alt_2 * _m): - pdir = m * n_seek - ok, hit, nor, ind = ray(pofs, pdir, best_dist) - if ok: - best_dist = (pofs - hit).length - best_nor = nor - # best_hit = hit - - if best_nor: - pt[1].length = best_dist - best_nor.negate() - pt[2] = best_nor - - #scene.cursor_location[:] = best_hitnyway - # bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', - # iterations=1) - # debug_edge(p, best_hit) - # p[:] = best_hit - - # Now we need to do scattering. - # first corners - hits = [] - nors = [] - oris = [] - for s in splines: - # point, normal, n_other the closest hit normal - for p, n, n_other in s: - if n is BAD_NORMAL: - continue - if n_other: - # cast vectors twice as long as the distance - # needed just in case. - n_down = (n * -SEEK) - l = n_down.length - n_other.length = l - - vantage = p + n - if DEBUG: - p[:] = vantage - - # We should cast rays between n_down and n_other - #for f in (0.0, 0.2, 0.4, 0.6, 0.8, 1.0): - TOT = int(10 * DENSITY) - #for i in list(range(TOT)): - for i in list(range(TOT))[int(TOT / 1.5):]: # second half - f = i / (TOT - 1) - - # focus on the center - ''' - f -= 0.5 - f = f*f - f += 0.5 - ''' - - ntmp = f * n_down + (1.0 - f) * n_other - # randomize - ntmp.x += uniform(-l, l) * RAND_LOC - ntmp.y += uniform(-l, l) * RAND_LOC - ntmp.z += uniform(-l, l) * RAND_LOC - - ok, hit, hit_no, ind = ray(vantage, ntmp, ntmp.length) - # print(hit, hit_no) - if ok: - if hit_no.angle(Z_UP) < WALL_LIMIT: - hits.append(hit) - nors.append(hit_no) - oris.append(n_other.cross(hit_no)) - #oris.append(n_other) - - if 0: - mesh = bpy.data.meshes.new("ScatterDupliFace") - mesh.from_pydata(hits, [], []) - - scene = bpy.context.scene - mesh.update() - obj_new = bpy.data.objects.new("ScatterPar", mesh) - scene.objects.link(obj_new) - obj_new.layers[:] = obj.layers - - # Now setup dupli-faces - obj_new.dupli_type = 'VERTS' - ob_child = bpy.data.objects["trash"] - ob_child.location = obj_new.location - ob_child.parent = obj_new - else: - - def apply_faces(triples): - # first randomize the faces - shuffle(triples) - - obs = group.objects[:] - tot = len(obs) - tot_div = int(len(triples) / tot) - - for inst_ob in obs: - triple_sub = triples[0:tot_div] - triples[0:tot_div] = [] - - vv = [tuple(v) for f in triple_sub for v in f] - - mesh = bpy.data.meshes.new("ScatterDupliFace") - mesh.from_pydata(vv, [], [(i * 3, i * 3 + 1, i * 3 + 2) - for i in range(len(triple_sub))]) - - scene = bpy.context.scene - mesh.update() - obj_new = bpy.data.objects.new("ScatterPar", mesh) - - scene.objects.link(obj_new) - obj_new.layers[:] = obj.layers - - # Now setup dupli-faces - obj_new.dupli_type = 'FACES' - obj_new.use_dupli_faces_scale = True - obj_new.dupli_faces_scale = 100.0 - - inst_ob.location = 0.0, 0.0, 0.0 - inst_ob.parent = obj_new - - # align the object with worldspace - obj_new.matrix_world = obj_mat - - # BGE settings for testing - ''' - inst_ob.game.physics_type = 'RIGID_BODY' - inst_ob.game.use_collision_bounds = True - inst_ob.game.collision_bounds = 'TRIANGLE_MESH' - inst_ob.game.collision_margin = 0.1 - obj_new.select = True - ''' - - # build faces from vert/normals - tri = (Vector((0.0, 0.0, 0.01)), - Vector((0.0, 0.0, 0.0)), - Vector((0.0, 0.01, 0.01))) - - coords = [] - # face_ind = [] - for i in range(len(hits)): - co = hits[i] - no = nors[i] - ori = oris[i] - quat = no.to_track_quat('X', 'Z') - - # make 2 angles and blend - angle = uniform(-pi, pi) - angle_aligned = -(ori.angle(quat * Y_UP, pi)) - - quat = Quaternion(no, - (angle * (1.0 - RAND_ALIGN)) + - (angle_aligned * RAND_ALIGN) - ).cross(quat) - - f = uniform(0.1, 1.2) * SCALE - - coords.append([co + (quat * (tri[0] * f)), - co + (quat * (tri[1] * f)), - co + (quat * (tri[2] * f)), - ]) - - apply_faces(coords) - - main() - - -from bpy.props import FloatProperty, StringProperty - - -class Scatter(bpy.types.Operator): - """""" - bl_idname = "object.scatter" - bl_label = "Grease Pencil Scatter" - - density = FloatProperty( - name="Density", - description="Multiplier for the density of items", - default=1.0, min=0.01, max=10.0, - ) - scale = FloatProperty( - name="Scale", - description="Size multiplier for duplifaces", - default=1.0, min=0.01, max=10.0, - ) - rand_align = FloatProperty( - name="Random Align", - description="Randomize alignment with the walls", - default=0.75, min=0.0, max=1.0, - ) - rand_loc = FloatProperty( - name="Random Loc", - description="Randomize placement", - default=0.75, min=0.0, max=1.0, - ) - # 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): - obj = bpy.context.object - group = bpy.data.groups.get(self.group) - - if not group: - self.report({'ERROR'}, "Group %r not found" % self.group) - return {'CANCELLED'} - - _main(self, - obj, - group, - DENSITY=self.density, - SCALE=self.scale, - RAND_LOC=self.rand_loc, - RAND_ALIGN=self.rand_align, - ) - return {'FINISHED'} - - def check(self, context): - if self.group not in bpy.data.groups: - self.group = "" - return True - return False - - def invoke(self, context, event): - - # useful to initialize, take a guess - if not self.group and context.object.name in bpy.data.groups: - self.group = context.object.name - - wm = context.window_manager - wm.invoke_props_dialog(self, width=180) - return {'RUNNING_MODAL'} - - -def menu_func(self, context): - self.layout.operator(Scatter.bl_idname, icon='AUTO') - - -def register(): - bpy.utils.register_class(Scatter) - bpy.types.VIEW3D_MT_mesh_add.append(menu_func) - - -def unregister(): - bpy.utils.unregister_class(Scatter) - bpy.types.VIEW3D_MT_mesh_add.remove(menu_func) - -#if __name__ == "__main__": -# _main() |