[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3774] branches/protopipe: Added pipeproto
Aurel W
aurel.w at gmail.com
Thu Sep 20 01:57:52 CEST 2012
Revision: 3774
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3774
Author: aurel
Date: 2012-09-19 23:57:52 +0000 (Wed, 19 Sep 2012)
Log Message:
-----------
Added pipeproto
Refactored jointproto to match pipeproto
Modified Paths:
--------------
branches/protopipe/TODO
branches/protopipe/__init__.py
branches/protopipe/jointproto.py
branches/protopipe/modelbuilder.py
branches/protopipe/ppapp.py
branches/protopipe/utils.py
Added Paths:
-----------
branches/protopipe/pipeproto.py
Modified: branches/protopipe/TODO
===================================================================
--- branches/protopipe/TODO 2012-09-19 23:55:30 UTC (rev 3773)
+++ branches/protopipe/TODO 2012-09-19 23:57:52 UTC (rev 3774)
@@ -3,3 +3,18 @@
* Apply model transformations
* Make deviation tollerance controlable
* Apply mesh modifiers
+
+
+=== LongTerm ===
+Solver:
+ - Buildplan
+ - Consider non rigid parts
+
+Bendables:
+ - Automatic bezier vurves
+ - Stress test
+
+Physics:
+ - Approximate the center of mass by assuming a set of bounding
+ boxes with a mass. Iterative solution: reduce two bounding boxes
+ to one.
Modified: branches/protopipe/__init__.py
===================================================================
--- branches/protopipe/__init__.py 2012-09-19 23:55:30 UTC (rev 3773)
+++ branches/protopipe/__init__.py 2012-09-19 23:57:52 UTC (rev 3774)
@@ -49,7 +49,7 @@
def postLoad(arg):
""" Handler which gets called post blend load. """
print("ProtoPipe post load handler.")
- ppapp.loadLibs()
+ ppapp.initFactories()
def register():
Modified: branches/protopipe/jointproto.py
===================================================================
--- branches/protopipe/jointproto.py 2012-09-19 23:55:30 UTC (rev 3773)
+++ branches/protopipe/jointproto.py 2012-09-19 23:57:52 UTC (rev 3774)
@@ -26,7 +26,9 @@
import numpy
import itertools
+from protopipe.utils import *
+
class JointProto:
"""
@@ -163,11 +165,7 @@
deviation_error = False
for (v0, v1) in zip(r_vecs, mp):
dot = numpy.dot(v0,v1)
- if dot > 1.0:
- dot = 1.0
- elif dot < -1.0:
- dot = -1.0
- angle = math.acos(dot)
+ angle = math.acos(clamp11(dot))
if angle > 0.01:
print("deviation angle too high")
@@ -177,8 +175,13 @@
if deviation_error:
continue # with permutation
+ # calculate the mapping from the permutation
+ mapping = map (lambda v : md.index(v), descriptor_mat)
+
+ jr = JointRegistration(self, descriptor, rot_mat, mapping)
+
# everything is fine and aligned
- return (True, rot_mat)
+ return (True, jr)
return (False, None)
@@ -198,7 +201,31 @@
+class JointRegistration:
+ """
+ Describes a successful fit in respect to a given descriptor.
+
+ rot_mat - The rotation of the joint.
+ mapping - The mapping between jproto and the descriptor axes.
+ jproto - JointPrototype which fits.
+ descriptor - Descriptor used for this registration.
+ modelInstance - A mesh object for the joint.
+ """
+
+ def __init__(self, jproto, descriptor, rot_mat, mapping, modelInstance=None):
+ self.rot_mat = rot_mat
+ self.mapping = mapping
+ self.jproto = jproto
+ self.descriptor = descriptor
+ self.modelInstance = modelInstance
+
+
+
+
class JointDescriptor:
+ """
+ A Descritpor of the joint to be found/generated.
+ """
def __init__(self):
self.jointVectors = []
@@ -228,7 +255,10 @@
self.diameter = diameter
+
+
class JointProtoProvider:
+ """ Adapter Base for the Factory """
def __init__(self):
pass
@@ -240,6 +270,10 @@
class ProtoLibrary(JointProtoProvider):
+ """
+ Adapter for the factory.
+ Loads several JointProtos from a library scene.
+ """
def __init__(self):
super().__init__()
@@ -286,16 +320,24 @@
def search(self, descriptor):
super().search(descriptor)
+
for jproto in self.protos:
- (isreg, rot_mat) = jproto.registerDescriptor(descriptor)
+ (isreg, jr) = jproto.registerDescriptor(descriptor)
+
if isreg:
- return (True, rot_mat, jproto)
+ ### instanciate the model object here ###
+ model = jr.jproto.model
+ nobj = bpy.data.objects[model.name].copy()
+ jr.modelInstance = nobj
+ bpy.context.scene.objects.link(nobj)
- return (False, None, None)
+ return (True, jr)
+ return (False, None)
+
class JointFactory:
def __init__(self):
@@ -304,10 +346,10 @@
def getProto(self, desc):
for provider in self.providers:
- (isreg, rot_mat, jproto) = provider.search(desc)
+ (isreg, jr) = provider.search(desc)
if isreg:
- return (True, rot_mat, jproto)
- return (False, None, None)
+ return (True, jr)
+ return (False, None)
def addJointProtoProvider(self, provider):
Modified: branches/protopipe/modelbuilder.py
===================================================================
--- branches/protopipe/modelbuilder.py 2012-09-19 23:55:30 UTC (rev 3773)
+++ branches/protopipe/modelbuilder.py 2012-09-19 23:57:52 UTC (rev 3774)
@@ -23,6 +23,7 @@
from protopipe.jointproto import JointProto
from protopipe.jointproto import JointDescriptor
from protopipe.jointproto import ProtoLibrary
+from protopipe.jointproto import JointRegistration
from protopipe import ppapp
@@ -44,31 +45,41 @@
for vert in bm.verts:
desc = JointDescriptor()
desc.buildFromVert(bm, vert.index)
- (reg, rot_mat, jproto) = ppapp.jointFactory.getProto(desc)
+ (reg, jr) = ppapp.jointFactory.getProto(desc)
if reg:
print("inserting model for joint")
- self.insertJoint(vert.co, rot_mat, jproto)
+ self.insertJoint(vert.co, jr)
- def insertJoint(self, co, rot_mat, jproto):
- #nobj = jproto.model.copy()
- #FIXME voodoo workaround
- print("model: ", jproto.model)
- nobj = bpy.data.objects[jproto.model.name].copy()
+ def insertJoint(self, co, jr):
+ model = jr.modelInstance
# put on a layer
- nobj.layers[self.buildLayer] = True
+ #FIXME can't assign layers
+ model.layers[self.buildLayer] = True
# translate
- nobj.location = co
+ model.location = co
# rotate (convert to blender matrix)
- bmat = mathutils.Matrix(rot_mat.tolist())
+ bmat = mathutils.Matrix(jr.rot_mat.tolist())
bmat.invert()
- nobj.rotation_euler = bmat.to_euler()
+ model.rotation_euler = bmat.to_euler()
# set the name
- nobj.name = self.nextJointName()
- #FIXME segfaults here
- bpy.context.scene.objects.link(nobj)
+ model.name = self.nextJointName()
+ def insertPipe(self, co, rot_mat, pproto):
+ # - Translate by the in-length or have the model created accordingly
+ # - Get the edge vector
+ # - Specify a axis where the pipe is oriented as a Vector
+ # - Compute the cross product between those two vectors
+ # - Compute the angle between both vectors
+ # - Define a quaternion with axis/angle
+ # - Rotate by the quaternion
+ # - Bake that Cake!
+ #nobj = None
+ pass # over that joint
+
+
+
def nextJointNameGen(self):
i = 0
while True:
Added: branches/protopipe/pipeproto.py
===================================================================
--- branches/protopipe/pipeproto.py (rev 0)
+++ branches/protopipe/pipeproto.py 2012-09-19 23:57:52 UTC (rev 3774)
@@ -0,0 +1,120 @@
+#
+# Copyright 2012, Aurel Wildfellner.
+#
+# 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.
+#
+
+import math
+
+import bpy
+from mathutils import *
+
+from protopipe.utils import *
+
+
+class PipeProto:
+
+ def __init__(self, length=0.0, diameter=0.0, insideDiameter=0.0, model=None, name=""):
+ self.length = length
+ self.diameter = diameter
+ self.insideDiameter = insideDiameter
+ self.model = model
+ self.name = name
+
+
+ def registerDescriptor(self, descriptor):
+ self.length = descriptor.length
+ self.diameter = descriptor.diameter
+
+ # generate the acording mesh object
+ bpy.ops.mesh.primitive_cylinder_add(radius=diameter)
+ model = bpy.context.active_object
+ model.scale[2] = (self.length/2.0)
+ self.model = model
+
+ pReg = PipeRegistration(self, descriptor)
+
+ return (True, pReg)
+
+
+
+
+class PipeDescriptor:
+
+ def __init__(self, length, diameter):
+ self.length = length
+ self.diameter = diameter
+
+
+
+
+class PipeRegistration:
+ """
+ Describes a match between a pipe descriptor
+ and the generated/found prototype.
+
+ No transformation to a mesh-edge is specified.
+ """
+
+ def __init__(self, pProto, descritpor, modelInstance=None):
+ self.descriptor = descriptor
+ self.pipeProto = pipeProto
+ self.modeInstance = modelInstance
+
+
+
+
+class PipeProtoProvider:
+
+ def __init__(self):
+ pass
+
+ def search(self, descritpor):
+ pass
+
+
+
+
+class PipeGenerator(PipeProtoProvider):
+
+ def __init__(self):
+ super().__init__()
+
+ def search(self, descriptor):
+ pProto = PipeProto()
+ (isreg, pReg) = pProto.register(descriptor)
+ # the prototype is single, so use model as instance
+ pReg.modelInstance = pReg.PipeProto.model
+ if isreg:
+ return (True, pReg)
+
+
+
+class PipeFactory:
+
+ def __init__(self):
+ self.providers = []
+
+
+ def getProto(self, descriptor):
+ for provider in self.providers:
+ (isreg, pReg) = provider.search(descriptor)
+ if reg:
+ return (True, pReg)
+
+
+ def addPipeProvider(self, provider):
+ self.providers.append(provider)
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list