[Bf-extensions-cvs] [3b9f6ae] master: Smoother weighting for blob assignment.

Lukas Tönne noreply at git.blender.org
Wed Nov 26 14:55:06 CET 2014


Commit: 3b9f6ae905afb8e18c16553f6b0477375dbcffc0
Author: Lukas Tönne
Date:   Wed Nov 26 14:52:55 2014 +0100
Branches: master
https://developer.blender.org/rBAC3b9f6ae905afb8e18c16553f6b0477375dbcffc0

Smoother weighting for blob assignment.

This somewhat randomizes the blob that a sample is being assigned to
for duplification, in order to avoid sharp boundaries where all duplis
switch to the nearest blob at once. The new method dithers the
blob boundaries based on distance weighting.

===================================================================

M	object_physics_meadow/blob.py
M	object_physics_meadow/hierarchical_dart_throw.py
M	object_physics_meadow/util.py

===================================================================

diff --git a/object_physics_meadow/blob.py b/object_physics_meadow/blob.py
index 717f262..9b1ed37 100644
--- a/object_physics_meadow/blob.py
+++ b/object_physics_meadow/blob.py
@@ -23,6 +23,8 @@ from bpy_extras import object_utils
 from math import *
 from mathutils import *
 from mathutils.kdtree import KDTree
+from itertools import accumulate
+import random
 
 from object_physics_meadow import settings as _settings
 from object_physics_meadow import duplimesh
@@ -85,9 +87,23 @@ def assign_blob(blobtree, loc, nor):
     num_nearest = 4 # number of blobs to consider
     
     nearest = blobtree.find_n(loc, num_nearest)
-    if nearest:
+    
+    totn = len(nearest)
+    if totn == 0:
+        return -1
+    if totn == 1:
         return nearest[0][1]
+    totdist = fsum(dist for co, index, dist in nearest)
+    if totdist == 0.0:
+        return -1
+    
+    norm = 1.0 / (float(totn-1) * totdist)
+    accum = list(accumulate(((totdist - dist) * norm) ** 8 for co, index, dist in nearest))
     
+    u = random.uniform(0.0, accum[-1])
+    for a, (co, index, dist) in zip(accum, nearest):
+        if u < a:
+            return index
     return -1
 
 def make_blob_object(context, index, loc, samples):
@@ -115,7 +131,8 @@ def make_blobs(context, gridob, groundob, samples):
     
     blobtree = KDTree(len(gridob.data.vertices))
     for i, v in enumerate(gridob.data.vertices):
-        blobtree.insert(v.co, i)
+        # note: only using 2D coordinates, otherwise weights get distorted by z offset
+        blobtree.insert((v.co[0], v.co[1], 0.0), i)
     blobtree.balance()
     
     blob_list = []
@@ -124,7 +141,8 @@ def make_blobs(context, gridob, groundob, samples):
         blob_list.append((loc, []))
     
     for loc, nor in samples:
-        index = assign_blob(blobtree, loc, nor)
+        # note: use only 2D coordinates for weighting, z component should be 0
+        index = assign_blob(blobtree, (loc[0], loc[1], 0.0), nor)
         if index >= 0:
             blob_list[index][1].append((loc, nor))
     
diff --git a/object_physics_meadow/hierarchical_dart_throw.py b/object_physics_meadow/hierarchical_dart_throw.py
index 2594133..ff0bdb8 100644
--- a/object_physics_meadow/hierarchical_dart_throw.py
+++ b/object_physics_meadow/hierarchical_dart_throw.py
@@ -22,15 +22,12 @@ import random, time
 import bpy
 from math import *
 
-from object_physics_meadow.util import Profiling
+from object_physics_meadow.util import *
 
 # Implements Poisson Disk sampling according to
 # "Poisson Disk Point Sets by Hierarchical Dart Throwing"
 # (White, Cline, Egbert)
 
-def ifloor(x):
-    return int(x) if x >= 0.0 else int(x) - 1
-
 prof_find_cell = Profiling("find_cell")
 prof_test_coverage = Profiling("test_coverage")
 prof_test_disk = Profiling("test_disk")
diff --git a/object_physics_meadow/util.py b/object_physics_meadow/util.py
index 0c2cfcf..b2e8998 100644
--- a/object_physics_meadow/util.py
+++ b/object_physics_meadow/util.py
@@ -20,6 +20,9 @@
 
 import bpy, time
 
+def ifloor(x):
+    return int(x) if x >= 0.0 else int(x) - 1
+
 class ObjectSelection():
     def __enter__(self):
         scene = bpy.context.scene



More information about the Bf-extensions-cvs mailing list