[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