[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3742] branches/protopipe/jointproto.py : Proto descritpor

Aurel W aurel.w at gmail.com
Sat Sep 15 23:07:17 CEST 2012


Revision: 3742
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3742
Author:   aurel
Date:     2012-09-15 21:07:16 +0000 (Sat, 15 Sep 2012)
Log Message:
-----------
Proto descritpor
Kabsch alignment
not tested!

Modified Paths:
--------------
    branches/protopipe/jointproto.py

Modified: branches/protopipe/jointproto.py
===================================================================
--- branches/protopipe/jointproto.py	2012-09-15 16:55:20 UTC (rev 3741)
+++ branches/protopipe/jointproto.py	2012-09-15 21:07:16 UTC (rev 3742)
@@ -20,6 +20,10 @@
 import bmesh
 from mathutils import *
 
+import math
+import numpy
+import itertools
+
 class JointProto:
 
     """
@@ -41,9 +45,11 @@
     def __init__(self):
         # list of normalized vectors
         self.jointVectors = []
+        self.jointVectorMatrix = []
         # the corresponding lengths of the joint
         self.jointLengthsIn = []
         self.jointLengthsOut = []
+        self.diameter = -1
         self.name = "Unnamed Joint Prototype"
         pass
 
@@ -52,6 +58,17 @@
         self.name = name
 
 
+    def setDiameter(self, diameter)
+        self.diameter = diameter
+
+
+    def buildJointVectorMatrix(self, jointVectors):
+        m = []
+        for v in jointVectors:
+            m.append(v.to_tuple())
+        return m
+
+
     def buildFromMeshProto(self, mesh):
         self.jointVectors = []
         self.jointLengthsIn = []
@@ -90,11 +107,64 @@
                     self.jointLengthsOut.append(n_edge.calc_length())
                     break
 
+        self.jointVectorMatrix = self.buildJointVectorMatrix(self.jointVectors)
 
+
+    def quickDescriptorCheck(self, descriptor):
+        if len(descriptor.jointVectors) != len(self.jointVectors):
+            return False
+        if descriptor.diameter != self.diameter:
+            return False
+
+
     def registerDescriptor(self, descriptor):
-        pass
+        """
+        Register the descriptor with the prototype
 
+        - Evaluate quickly on some gross parameter.
+        - Enumate through all possible pairings.
+        - Use Kabsch Algorithm to fit a pairing and register with 
+          right transformation.
+        """
+        if not self.quickDescriptorCheck(descriptor):
+            return (False, None)
 
+        # the prototype matrix
+        mp = self.jointVectorMatrix
+        # the descriptor matrix
+        descriptor_mat = self.buildJointVectorMatrix(descriptor.jointVectors)
+
+        # try all possible pairings until a fit is found
+        for md in itertools.permutation(descriptor_mat):
+            ### calculate the optimal superposition for the pairing ###
+            correlation_mat = numpy.dot ( numpy.transpose(mp), md)
+            v, s, w_tr = numpy.linalg.svd(correlation_mat)
+            is_reflection = (numpy.linalg.det(v) * numpy.linalg.det(w_tr)) < 0.0
+            if is_reflection:
+                v[:,-1] = -v[:,-1]
+            rot_mat = numpy.matrix(numpy.dot(v, w_tr))
+
+            ### check the fit of the current alignment ###
+            # rotate descritpor points
+            r_vecs = map (lambda v : numpy.dot(rot_mat, numpy.transpose(v)), md)
+            # compute deviation angles
+            deviation_angles = map (lambda v0, v1 :
+                    math.acos(numpy.dot(v0, v1)),
+                    r_vecs, mp)
+
+            for angle in deviation_angles:
+                # A threshhold of how the model is alowed to deviate from
+                # the descritor, continue with next permutation if error
+                # is too high.
+                if angle > 0.01:
+                    continue # with permutation
+
+            # everything is fine and aligned
+            return (True, rot_mat)
+
+        return (False, None)
+
+
     def findCenter(self, bm):
         """Returns the index of the point closest to the origin."""
         center = Vector((0,0,0))
@@ -109,3 +179,34 @@
 
 
 
+
+class ProtoDescriptor:
+
+    def __init__():
+        self.jointVectors = []
+        self.diameter = -1
+
+
+    def buildFromVert(self, bm, vertIndex):
+        """
+        Builds a JointDescripor at the vertex of a mesh.
+
+        bm -- A BMesh.
+        vertIndex -- The index of the vertex to build the descriptor. 
+        """
+
+        vc = bm.verts[vertIndex]
+        for edge in vc.edges:
+            if edge.verts[0] == vc:
+                vec = edge.verts[1].co - vc.co
+            else:
+                vec = edge.verts[0].co - vc.co
+
+            jointVectors.append(vec.normalized)
+
+
+    def setDiameter(self, diameter)
+        """ only one global diameter for now """
+        self.diameter = diameter
+
+



More information about the Bf-extensions-cvs mailing list