[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2125] trunk/py/scripts/addons/ object_grease_scatter.py: initial commit of grease scatter script, still needs updating.
Campbell Barton
ideasman42 at gmail.com
Sun Jul 17 15:03:06 CEST 2011
Revision: 2125
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2125
Author: campbellbarton
Date: 2011-07-17 13:03:05 +0000 (Sun, 17 Jul 2011)
Log Message:
-----------
initial commit of grease scatter script, still needs updating.
Added Paths:
-----------
trunk/py/scripts/addons/object_grease_scatter.py
Added: trunk/py/scripts/addons/object_grease_scatter.py
===================================================================
--- trunk/py/scripts/addons/object_grease_scatter.py (rev 0)
+++ trunk/py/scripts/addons/object_grease_scatter.py 2011-07-17 13:03:05 UTC (rev 2125)
@@ -0,0 +1,426 @@
+# ##### 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 compliant>
+
+# Script copyright (C) Campbell Barton
+
+bl_info = {
+ "name": "Export Camera Animation",
+ "author": "Campbell Barton",
+ "version": (0, 1),
+ "blender": (2, 5, 8),
+ "api": 36079,
+ "location": "File > Export > Cameras & Markers (.py)",
+ "description": "Export Cameras & Markers (.py)",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
+ "Scripts/Object/Grease_Scatter",
+ "tracker_url": "https://projects.blender.org/tracker/index.php?"\
+ "func=detail&aid=TODO",
+ "support": 'OFFICIAL',
+ "category": "Object"}
+
+from mathutils import Vector, RotationMatrix, Quaternion
+from math import radians
+from random import uniform, shuffle
+import bpy
+
+def _main(self, DENSITY=1.0, SCALE=0.6, RAND_LOC=0.8, RAND_ALIGN=0.75):
+ from math import radians
+
+ C = bpy.context
+ o = C.object
+ # print(o.ray_cast(Vector(), Vector(0,0,0.2)))
+
+ OFS = 0.2
+ SEEK = 2.0 # distance for ray to seek
+ BAD_NORMAL = Vector((0,0,-1))
+ WALL_LIMIT = radians(45.0)
+
+ mats = [
+ RotationMatrix(radians(-45), 3, 'X'),
+ RotationMatrix(radians( 45), 3, 'X'),
+ RotationMatrix(radians(-45), 3, 'Y'),
+ RotationMatrix(radians( 45), 3, 'Y'),
+ RotationMatrix(radians(-45), 3, 'Z'),
+ RotationMatrix(radians( 45), 3, 'Z')]
+
+
+ Z_UP = Vector((0,0,1.0))
+ dirs = [
+ Vector((0,0,OFS)),
+ Vector((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:
+ self.report({'WARNING'}, "Group '%s' not found, must match object name" % o.name)
+ return
+
+ def faces_from_hits(hit_list):
+ def from_pydata(self, verts, edges, faces):
+ """
+ Make a mesh from a list of verts/edges/faces
+ Until we have a nicer way to make geometry, use this.
+ """
+ self.add_geometry(len(verts), len(edges), len(faces))
+
+ verts_flat = [f for v in verts for f in v]
+ self.verts.foreach_set("co", verts_flat)
+ del verts_flat
+
+ edges_flat = [i for e in edges for i in e]
+ self.edges.foreach_set("verts", edges_flat)
+ del edges_flat
+
+ def treat_face(f):
+ if len(f) == 3:
+ return f[0], f[1], f[2], 0
+ elif f[3] == 0:
+ return f[3], f[0], f[1], f[2]
+ return f
+
+ faces_flat = [v for f in faces for v in treat_face(f)]
+ self.faces.foreach_set("verts_raw", faces_flat)
+ del faces_flat
+
+
+
+
+ def debug_edge(v1,v2):
+ mesh = bpy.data.meshes.new("Retopo")
+ mesh.from_pydata([v1,v2], [(0,1)], [])
+
+ scene = bpy.context.scene
+ mesh.update()
+ obj_new = bpy.data.objects.new("Torus", mesh)
+ scene.objects.link(obj_new)
+
+ ray = o.ray_cast
+ #ray = C.scene.ray_cast
+
+ DEBUG = False
+ def fix_point(p):
+ for d in dirs:
+ # print(p)
+ hit, no, ind = ray(p, p + d)
+ if ind != -1:
+ 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):
+ l = None
+ for l in gp.layers:
+ if l.active: # XXX - should be layers.active
+ break
+ if l:
+ frame = l.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 = RotationMatrix(radians(22.5), 3, n)
+ m_alt_2 = RotationMatrix(radians(-22.5), 3, n)
+ for _m in mats:
+ for m in (_m, m_alt_1 * _m, m_alt_2 * _m):
+ hit, nor, ind = ray(pofs, pofs + (m * n_seek))
+ if ind != -1:
+ dist = (pofs - hit).length
+ if dist < best_dist:
+ best_dist = dist
+ 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:
+ for p,n,n_other in s: # point, normal, n_other the closest hit normal
+ if n is BAD_NORMAL:
+ continue
+ if n_other:
+ # cast vectors twice as long as the distance needed just incase.
+ 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
+
+ hit, hit_no, ind = ray(vantage, vantage + ntmp)
+ # print(hit, hit_no)
+ if ind != -1:
+ 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("Retopo")
+ mesh.from_pydata(hits, [], [])
+
+ scene = bpy.context.scene
+ mesh.update()
+ obj_new = bpy.data.objects.new("Torus", mesh)
+ scene.objects.link(obj_new)
+ obj_new.layers[:] = o.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_subset = triples[0:tot_div]
+ triples[0:tot_div] = []
+
+ vv = [tuple(v) for f in triple_subset for v in f]
+
+ mesh = bpy.data.meshes.new("Retopo")
+ mesh.from_pydata(vv, [], [(i*3, i*3+1, i*3+2) for i in range(len(triple_subset))])
+
+ scene = bpy.context.scene
+ mesh.update()
+ obj_new = bpy.data.objects.new("Torus", mesh)
+ scene.objects.link(obj_new)
+ obj_new.layers[:] = o.layers
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list