Basic vertex group lookup for samples.
authorLukas Tönne <lukas.toenne@gmail.com>
Tue, 9 Dec 2014 23:29:29 +0000 (00:29 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Tue, 9 Dec 2014 23:29:29 +0000 (00:29 +0100)
object_physics_meadow/blob.py
object_physics_meadow/duplimesh.py
object_physics_meadow/meadow.py

index ddb9975..738538d 100644 (file)
@@ -203,27 +203,59 @@ def make_blobs(context, gridob, groundob, samples, display_radius):
 
 from object_physics_meadow.patch import patch_objects, patch_group_assign
 
+def find_vertex_groups(groundob, patches):
+    names = set(ob.meadow.density_vgroup_name for ob in patches)
+    return [vg for vg in groundob.vertex_groups if vg.name in names]
+
 # select one patch object for each sample based on vertex groups
-def assign_sample_patches(vgroups, blob):
-    vgroup_samples = { name : [] for name in vgroups }
+def assign_sample_patches(groundob, vgroups, blob):
+    faces = groundob.data.tessfaces
+    vertices = groundob.data.vertices
+    indexmap = [-1 for i in range(max(vg.index for vg in groundob.vertex_groups)+1)] if groundob.vertex_groups else []
+    for i, vg in enumerate(vgroups):
+        indexmap[vg.index] = i
     
+    vgroup_samples = { vg.name : [] for vg in vgroups }
+    vgroup_samples[""] = [] # samples for unassigned patches
     for loc, nor, face_index in blob.samples:
+        face = faces[face_index]
+        # XXX this throws an exception if testing for vertex outside the group
+        # but there seems to be no nice way to test beforehand ...
+        #weights = [ [vg.weight(i) for i in face.vertices] for vg in vgroups ]
+        weights = [0.0 for vg in vgroups]
+        for i in face.vertices:
+            v = vertices[i]
+            for vg in v.groups:
+                index = indexmap[vg.group]
+                if index >= 0:
+                    weights[index] = vg.weight
+        
         # XXX testing
-        vgroup_samples[vgroups[-1]].append((loc, nor))
+        if weights:
+            select, (vg, w) = max(enumerate(zip(vgroups, weights)), key=lambda x: x[1][1])
+            if w > 0.0:
+                vgroup_samples[vg.name].append((loc, nor))
+            else:
+                vgroup_samples[""].append((loc, nor))
+        else:
+            vgroup_samples[""].append((loc, nor))
     
     return vgroup_samples
 
-def setup_blob_duplis(context, display_radius):
+def setup_blob_duplis(context, groundob, display_radius):
     global blobs
     
+    assert(blobs)
+    
+    groundob.data.calc_tessface()
     patches = [ob for ob in patch_objects(context) if blobs[ob.meadow.blob_index] is not None]
+    vgroups = find_vertex_groups(groundob, patches)
     
-    vgroups = [""] + list(set(ob.meadow.density_vgroup_name for ob in patches))
     for blob_index, blob in enumerate(blobs):
         if blob is None:
             continue
         
-        vgroup_samples = assign_sample_patches(vgroups, blob)
+        vgroup_samples = assign_sample_patches(groundob, vgroups, blob)
         
         for ob in patches:
             if ob.meadow.blob_index != blob_index:
index 49a665a..499e1c7 100644 (file)
 import bpy
 from mathutils import *
 
-def get_vgroup_index(ob, name):
-    for v in ob.vertex_groups:
-        if v.name == name:
-            return v.index
-    return -1
-
-def get_vgroup_weight(vertex, index):
-    for elem in vertex.groups:
-        if elem.group == index:
-            return elem.weight
-    return 0.0
-
-def interp_vgroup(ob, face_index, co, vgroup):
-    vgroup_index = get_vgroup_index(ob, vgroup)
-    if vgroup_index < 0:
-        return 0.0
-    
-    mesh = ob.data
-    face = mesh.tessfaces[face_index]
-    verts = [mesh.vertices[i] for i in face.vertices]
-    weights = [get_vgroup_weight(v, vgroup_index) for v in verts]
-    return weights[0] # XXX TODO
-
 def project_on_ground(groundob, co):
     groundmat4 = groundob.matrix_world
     groundmat3 = groundmat4.to_3x3()
index b5753f3..39f7b60 100644 (file)
@@ -72,4 +72,4 @@ def make_patches(context, gridob, groundob):
     scene = context.scene
     template_objects = [ob for ob in scene.objects if ob.meadow.type == 'TEMPLATE']
     patch.make_patches(context, gridob, template_objects)
-    blob.setup_blob_duplis(context, 0.333 * gridob.meadow.patch_radius)
+    blob.setup_blob_duplis(context, groundob, 0.333 * gridob.meadow.patch_radius)