def get_rot_angles(ex, ey, ez):
"""Get the x- and y-rotation from the ez unit vector"""
rx = atan2(ez[1], ez[2])
rx_matrix = mathutils.Euler((rx, 0.0, 0.0), "XYZ")
# Rotate the ez vector by the previously found angle
ez.rotate(rx_matrix)
# Negative value because of right handed rotation
ry = - atan2(ez[0], ez[2])
# Rotate the ex vector by the previously found angles
rxy_matrix = mathutils.Euler((rx, ry, 0.0), "XYZ")
ex.rotate(rxy_matrix)
# Negative value because of right handed rotation
rz = - atan2(ex[1], ex[0])
return [rx, ry, rz]
python类Euler()的实例源码
camera-calibration-pvr.py 文件源码
项目:camera-calibration-pvr
作者: mrossini-ethz
项目源码
文件源码
阅读 39
收藏 0
点赞 0
评论 0
def transform_edit_bone(bl_armature, bone_name, center_point, end_point, orientation):
b_bone = bl_armature.data.edit_bones[bone_name]
center_point = [
b_bone.bdst_center_point[0] + coords_to_blender(center_point)[0],
b_bone.bdst_center_point[1] + coords_to_blender(center_point)[1],
b_bone.bdst_center_point[2] + coords_to_blender(center_point)[2]
]
end_point = [
b_bone.bdst_end_point[0] + coords_to_blender(end_point)[0],
b_bone.bdst_end_point[1] + coords_to_blender(end_point)[1],
b_bone.bdst_end_point[2] + coords_to_blender(end_point)[2]
]
orientation = [
b_bone.bdst_orientation[0] + rotation_to_blender(orientation)[0],
b_bone.bdst_orientation[1] + rotation_to_blender(orientation)[1],
b_bone.bdst_orientation[2] + rotation_to_blender(orientation)[2]
]
if center_point == end_point:
end_point = (end_point[0], end_point[1], end_point[2] + 0.3)
len = (mathutils.Vector(center_point) - mathutils.Vector(end_point)).length
b_bone.head = (0, 0, 0)
if b_bone.bdst_sign in ["+X", "-X"]:
sign = 1 if b_bone.bdst_sign == "+X" else -1
b_bone.tail = (sign * len, 0, 0)
elif b_bone.bdst_sign in ["+Y", "-Y"]:
sign = 1 if b_bone.bdst_sign == "+Y" else -1
b_bone.tail = (0, sign * len, 0)
else:
sign = 1 if b_bone.bdst_sign == "+Z" else -1
b_bone.tail = (0, 0, sign * len)
b_bone.roll = 0
rot = mathutils.Euler(((orientation[0]), (-orientation[1]), (orientation[2])), "XZY").to_matrix().to_4x4()
b_bone.transform(rot)
b_bone.translate(mathutils.Vector(center_point))
def console_math_data():
from mathutils import Matrix, Vector, Quaternion, Euler
data_matrix = {}
data_quat = {}
data_euler = {}
data_vector = {}
data_vector_array = {}
for key, var in console_namespace().items():
if key[0] == "_":
continue
var_type = type(var)
if var_type is Matrix:
if len(var.col) != 4 or len(var.row) != 4:
if len(var.col) == len(var.row):
var = var.to_4x4()
else: # todo, support 4x3 matrix
continue
data_matrix[key] = var
elif var_type is Vector:
if len(var) < 3:
var = var.to_3d()
data_vector[key] = var
elif var_type is Quaternion:
data_quat[key] = var
elif var_type is Euler:
data_euler[key] = var
elif var_type in {list, tuple}:
if var:
ok = True
for item in var:
if type(item) is not Vector:
ok = False
break
if ok:
data_vector_array[key] = var
return data_matrix, data_quat, data_euler, data_vector, data_vector_array
EulerXYZToQuaternionNode.py 文件源码
项目:InSituImmersiveAuthoring
作者: sat-metalab
项目源码
文件源码
阅读 17
收藏 0
点赞 0
评论 0
def init(self, context):
super().init(context)
self.inputs.new('NodeSocketVectorEuler', "Euler XYZ")
self.outputs.new('NodeSocketQuaternion', "Quaternion")
EulerXYZToQuaternionNode.py 文件源码
项目:InSituImmersiveAuthoring
作者: sat-metalab
项目源码
文件源码
阅读 20
收藏 0
点赞 0
评论 0
def run(self):
self.outputs["Quaternion"].default_value = Euler(self.getInputValue("Euler XYZ")).to_quaternion()
QuaternionToEulerXYZNode.py 文件源码
项目:InSituImmersiveAuthoring
作者: sat-metalab
项目源码
文件源码
阅读 18
收藏 0
点赞 0
评论 0
def init(self, context):
super().init(context)
self.inputs.new('NodeSocketQuaternion', "Quaternion")
self.outputs.new('NodeSocketVectorEuler', "Euler XYZ")
QuaternionToEulerXYZNode.py 文件源码
项目:InSituImmersiveAuthoring
作者: sat-metalab
项目源码
文件源码
阅读 17
收藏 0
点赞 0
评论 0
def run(self):
self.outputs["Euler XYZ"].default_value = self.getInputValue("Quaternion").to_euler('XYZ')
def update_scene(scene):
"""Update the scene before rendering."""
LOGGER.info("Hello!")
cube = scene.objects["Cube"]
rotation_vector = (uniform(0, 360),
uniform(0, 360),
uniform(0, 360))
rotation_vector_radians = (radians(scalar) for scalar in rotation_vector)
rotation_euler_angles = Euler(rotation_vector_radians, 'XYZ')
cube.rotation_euler.rotate(rotation_euler_angles)
cube.scale.x = cube.scale.y = cube.scale.z = uniform(1, 3)
# Equivalent to:
# cube.scale = Vector(3 * [uniform(1, 3)])
cube.location.x = uniform(-2, 2)
cube.location.y = uniform(-2, 2)
cube.location.z = uniform(-2, 2)
# Equivalent to
# cube.location = Vector((uniform(-2, 2),
# uniform(-2, 2),
# uniform(-2, 2)))
cube.active_material.diffuse_color.h = uniform(0, 1)
cube.active_material.diffuse_color.s = uniform(.8, 1)
cube.active_material.diffuse_color.v = uniform(.8, 1)
for vertex in cube.data.vertices:
vertex.co = Vector((vertex.co[0] + uniform(0, 0.1),
vertex.co[1] + uniform(0, 0.1),
vertex.co[2] + uniform(0, 0.1)))
cube.data.materials[0].diffuse_shader = "TOON"
def set_random_clitoris_rotation():
"""Sets a random rotation on every axis."""
rotation_vector = (uniform(-45, 45),
uniform(0, 360),
uniform(-45, 45))
rotation_vector_radians = (radians(scalar) for scalar in rotation_vector)
rotation_euler_angles = mathutils.Euler(rotation_vector_radians, 'XYZ')
TRACKBALL_OBJ.rotation_euler.rotate(rotation_euler_angles)
DEBUG_INFO["rotation_vector"] = rotation_vector
def matrix_calibrate_r(y, d, mat, parent, bone):
"""transforms "absolute" rotation coordinates into"relative" ones, using the default pose rotation matrix"""
# note: using GC coordinate organization: therefor rotations are in XYZ order
EPSILON = 1/100
# ret_y = (parent*y.to_matrix().to_4x4()*mat).to_euler('XYZ') # computing rotation value
ret_y = (y.to_matrix().to_4x4()*mat).to_euler('XYZ') # computing rotation value
# computes rotation tangents by definition of derivative
# (and now, the incredibly complex equivalent of "dy = EPSILON*d + y":
dy = Euler((0,0,0), "XYZ")
dy.x = EPSILON * d.x + y.x
dy.y = EPSILON * d.y + y.y
dy.z = EPSILON * d.z + y.z
ret_dy = (parent*dy.to_matrix().to_4x4()*mat).to_euler('XYZ')
ret_d = Euler((0,0,0), 'XYZ')
ret_d.x = (ret_dy.x - ret_y.x) / EPSILON
ret_d.y = (ret_dy.y - ret_y.y) / EPSILON
ret_d.z = (ret_dy.z - ret_y.z) / EPSILON
y,d = ret_y, ret_d
if hasattr(bone, 'parent_rot_matrix'): # sililar to calibrate_t, need to transform the original vector
parent_rot_matrix = bone.parent_rot_matrix
else:
if type(bone.parent.fget()) == Pseudobone:
parent_rot_matrix = bone.parent.fget().jnt_frame.incr_matrix.to_quaternion().to_matrix().to_4x4()
else:
parent_rot_matrix = Matrix.Identity(4)
bone.parent_rot_matrix = parent_rot_matrix
y = Euler((parent_rot_matrix * Vector(y)), 'XYZ')
dy = Vector((0, 0, 0))
dy.x = EPSILON * d.x + y.x
dy.y = EPSILON * d.y + y.y
dy.z = EPSILON * d.z + y.z
dy = parent_rot_matrix * dy
d = Euler((0, 0, 0), 'XYZ')
d.x = (dy.x - y.x) / EPSILON
d.y = (dy.y - y.y) / EPSILON
d.z = (dy.z - y.z) / EPSILON
return y, d
def __init__(self, startpoint, endpoint, z_up):
ori = endpoint - startpoint
self.endpoint = endpoint
self._name = None
self.length = math.sqrt(ori.x**2 + ori.y**2 + ori.z**2)
self.orientation = vect_normalize(ori)
self.scale = mathutils.Vector((1, 1, 1))
self.jnt_frame = None
self.rotation_euler = mathutils.Euler((0, 0, 0), 'XYZ')
self.position = startpoint
self.scale_kf = {} # keyframes (values)
self.scale_tkf = {} # keyframes (tangents)
self.rotation_kf = {}
self.rotation_tkf = {}
self.position_kf = {}
self.position_tkf = {}
# self.transform = mathutils.Matrix.Identity(4) # what to do with that? it will be ultimately useless.
self._parent = None
self.children = []
# property busyness --------------------------------
def _getname():
return self._name
def _setname(val):
global instances
if self._name is not None:
del instances[self._name]
if val is None and val in instances.keys():
raise ValueError('name taken')
self._name = val
instances[val] = self
def _delname():
self.name = None
self.name = property(_getname, _setname, _delname)
def _getparent():
return self._parent
def _setparent(val):
if (self.parent.fget() is not None) and (self in self.parent.fget().children):
self.parent.fget().children.remove(self)
self._parent = val
if val is None or isinstance(val, mathutils.Vector):
return
val.children.append(self)
self.parent = property(_getparent, _setparent)
def _setinchildren(holder, val):
list.append(holder.children, val)
val._parent = holder
self.children_append = (lambda self2, x: _setinchildren(self, x))
# def update_r_t(self):
# pass # will work this out later
# def recalculate_transform(self):
# pass # procrastinating here too.
def UrhoGatherInstances(obj):
# Compute transforms and append instance to the list of models to process
def UrhoDupliTransforms(dupli, root, parent = None):
if dupli.matrix_local.to_euler() != Euler((0.0, 0.0, 0.0)):
log.warning('You should apply rotation to object {:s}'.format(dupli.name))
if dupli.matrix_local.to_scale() != Vector((1.0, 1.0, 1.0)):
log.warning('You should apply scale to object {:s}'.format(dupli.name))
instance = UrhoInstance()
instance.name = dupli.name
instance.matrix = root.matrix_world
instance.objectName = obj.name
if parent:
instance.matrix = instance.matrix * parent.matrix_world
# Parent-child relationship inside a group object
if dupli.children:
instance.objectName += dupli.name # Make parent name unic for parent-child relationship
if dupli.parent and dupli.parent.type != 'ARMATURE':
instance.parentName = obj.name + dupli.parent.name # See parent naming above
instance.matrix = dupli.matrix_local
instances.append(instance)
if obj.hide:
return
if obj.type == 'EMPTY' and obj.dupli_group: # Look for instances
for dupli in obj.dupli_group.objects: # Find members for this group
if dupli.hide or dupli.type == 'ARMATURE': continue
if dupli.type == 'EMPTY' and dupli.dupli_group: # Bunch of instances found
for subDupli in dupli.dupli_group.objects:
UrhoDupliTransforms(subDupli, obj, dupli)
else:
UrhoDupliTransforms(dupli, obj)
elif obj.type == 'MESH': # Look for mesh objects
instance = UrhoInstance()
instance.name = obj.data.name # Use mesh name instead of object name
instance.matrix = obj.matrix_world
instance.objectName = obj.name
if obj.parent and obj.parent.type == 'MESH':
instance.parentName = obj.parent.name
instance.matrix = obj.matrix_local
instances.append(instance)
#------------------------
# Export scene prefab
#------------------------
def createLeaves(tree, probability=0.5, size=0.5, randomsize=0.1, randomrot=0.1, maxconnections=2, bunchiness=1.0, connectoffset=-0.1):
p = bpy.context.scene.cursor_location
verts = []
faces = []
c1 = Vector((connectoffset, -size / 2, 0))
c2 = Vector((size+connectoffset, -size / 2, 0))
c3 = Vector((size+connectoffset, size / 2, 0))
c4 = Vector((connectoffset, size / 2, 0))
t = gauss(1.0 / probability, 0.1)
bpswithleaves = 0
for bp in tree.branchpoints:
if bp.connections < maxconnections:
dv = tree.branchpoints[bp.parent].v - bp.v if bp.parent else Vector((0, 0, 0))
dvp = Vector((0, 0, 0))
bpswithleaves += 1
nleavesonbp = 0
while t < bpswithleaves:
nleavesonbp += 1
rx = (random() - 0.5) * randomrot * 6.283 # TODO vertical tilt in direction of tropism
ry = (random() - 0.5) * randomrot * 6.283
rot = Euler((rx, ry, random() * 6.283), 'ZXY')
scale = 1 + (random() - 0.5) * randomsize
v = c1.copy()
v.rotate(rot)
verts.append(v * scale + bp.v + dvp)
v = c2.copy()
v.rotate(rot)
verts.append(v * scale + bp.v + dvp)
v = c3.copy()
v.rotate(rot)
verts.append(v * scale + bp.v + dvp)
v = c4.copy()
v.rotate(rot)
verts.append(v * scale + bp.v + dvp)
n = len(verts)
faces.append((n - 1, n - 4, n - 3, n - 2))
t += gauss(1.0 / probability, 0.1) # this is not the best choice of distribution because we might get negative values especially if sigma is large
dvp = nleavesonbp * (dv / (probability ** bunchiness)) # TODO add some randomness to the offset
mesh = bpy.data.meshes.new('Leaves')
mesh.from_pydata(verts, [], faces)
mesh.update(calc_edges=True)
mesh.uv_textures.new()
return mesh
def execute(self, context):
from .model import SelectModel
from .rigid_bodies import SelectGeometry, AssignGeometry
from .segments import SelectSegment
C = bpy.context
D = bpy.data
model = C.active_object
bone_name = C.active_bone.name
axis = C.active_bone.RobotEditor.axis
pose_bone = C.active_object.pose.bones[bone_name]
parent_bone = pose_bone.parent
bone_to_parent = pose_bone.matrix.inverted() * parent_bone.matrix
bone_world = model.matrix_world * pose_bone.matrix
segment_length = bone_to_parent.translation.length
distance_to_children = [(child.matrix.inverted() * pose_bone.matrix).translation.length for child in
pose_bone.children]
self.logger.debug("%s, %s", segment_length, distance_to_children)
# if there is no translation to parent, the parent (or its parent) draws the joint
if bone_to_parent.translation.length > 0.001:
max_length = max(distance_to_children+[segment_length])
# If there is only one children, and its a distance 0, we have a ball joint
if len(pose_bone.children) == 1 and distance_to_children[0] < 0.001:
bpy.ops.mesh.primitive_uv_sphere_add(size=segment_length / 15.0)
C.active_object.matrix_world = bone_world
# if there IS a child, at distance >0 (or more than one child), draw a hinge joint
elif len(pose_bone.children):
bpy.ops.mesh.primitive_cylinder_add(radius=max_length / 15, depth=max_length / 5)
if axis == 'X':
m = Euler((0, 0, pi / 4)).to_matrix().to_4x4()
elif axis == 'Y':
m = Euler((0, 0, pi / 4)).to_matrix().to_4x4()
else:
m = Matrix()
C.active_object.matrix_world = bone_world * m
else:
bpy.ops.mesh.primitive_cone_add(radius1=segment_length/10,radius2=segment_length/10)
C.active_object.name = bone_name + '_axis'
new_name = C.active_object.name
SelectModel.run(model_name=model.name)
SelectSegment.run(bone_name)
SelectGeometry.run(new_name)
AssignGeometry.run()
return {'FINISHED'}
def build(self, buildRequest):
t = time.time()
guide = bpy.data.objects[self.settings["guideMesh"]]
data = guide.data
wrld = guide.matrix_world
if self.totalArea is None:
self.totalArea = sum(p.area for p in data.polygons)
positions = []
for n in range(self.settings["noToPlace"]):
remaining = random.random() * self.totalArea
index = 0
while remaining > 0:
remaining -= data.polygons[index].area
if remaining <= 0:
a = data.vertices[data.polygons[index].vertices[0]].co
b = data.vertices[data.polygons[index].vertices[1]].co
c = data.vertices[data.polygons[index].vertices[2]].co
r1 = math.sqrt(random.random())
r2 = random.random()
pos = (1 - r1) * a + (r1 * (1 - r2)) * b + (r1 * r2) * c
if self.settings["overwritePosition"]:
pos = wrld * pos
else:
pos.rotate(mathutils.Euler(buildRequest.rot))
pos *= buildRequest.scale
pos = buildRequest.pos + pos
positions.append(pos)
index += 1
if self.settings["relax"]:
sce = bpy.context.scene
gnd = sce.objects[self.settings["guideMesh"]]
if self.bvhtree is None:
self.bvhtree = BVHTree.FromObject(gnd, sce)
radius = self.settings["relaxRadius"]
for i in range(self.settings["relaxIterations"]):
kd = KDTree(len(positions))
for n, p in enumerate(positions):
kd.insert(p, n)
kd.balance()
for n, p in enumerate(positions):
adjust = Vector()
localPoints = kd.find_range(p, radius * 2)
for (co, ind, dist) in localPoints:
if ind != n:
v = p - co
if v.length > 0:
adjust += v * \
((2 * radius - v.length) / v.length)
if len(localPoints) > 0:
adjPos = positions[n] + adjust / len(localPoints)
positions[n] = self.bvhtree.find_nearest(adjPos)[0]
cm_timings.placement["TemplateMESHPOSITIONING"] += time.time() - t
cm_timings.placementNum["TemplateMESHPOSITIONING"] += 1
for newPos in positions:
newBuildRequest = buildRequest.copy()
newBuildRequest.pos = newPos
self.inputs["Template"].build(newBuildRequest)
def __init__(self, ob ):
if ob.location.x != 0 or ob.location.y != 0 or ob.location.z != 0:
Report.warnings.append('ERROR: Mesh (%s): is offset from Armature - zero transform is required' %ob.name)
if ob.scale.x != 1 or ob.scale.y != 1 or ob.scale.z != 1:
Report.warnings.append('ERROR: Mesh (%s): has been scaled - scale(1,1,1) is required' %ob.name)
self.object = ob
self.bones = []
mats = {}
self.arm = arm = findArmature( ob )
arm.hide = False
self._restore_layers = list(arm.layers)
#arm.layers = [True]*20 # can not have anything hidden - REQUIRED?
for pbone in arm.pose.bones:
mybone = Bone( arm.data.bones[pbone.name], pbone, self )
self.bones.append( mybone )
if arm.name not in Report.armatures:
Report.armatures.append( arm.name )
## bad idea - allowing rotation of armature, means vertices must also be rotated,
## also a bug with applying the rotation, the Z rotation is lost
#x,y,z = arm.matrix_local.copy().inverted().to_euler()
#e = mathutils.Euler( (x,z,y) )
#self.object_space_transformation = e.to_matrix().to_4x4()
x,y,z = arm.matrix_local.to_euler()
if x != 0 or y != 0 or z != 0:
Report.warnings.append('ERROR: Armature: %s is rotated - (rotation is ignored)' %arm.name)
## setup bones for Ogre format ##
for b in self.bones:
b.rebuild_tree()
## walk bones, convert them ##
self.roots = []
ep = 0.0001
for b in self.bones:
if not b.parent:
b.compute_rest()
loc,rot,scl = b.ogre_rest_matrix.decompose()
#if loc.x or loc.y or loc.z:
# Report.warnings.append('ERROR: root bone has non-zero transform (location offset)')
#if rot.w > ep or rot.x > ep or rot.y > ep or rot.z < 1.0-ep:
# Report.warnings.append('ERROR: root bone has non-zero transform (rotation offset)')
self.roots.append( b )
def insert_bone (si_bone, armdat):
"""Create bone and insert into armature.
Uses:
node.id as as bone name (these are used in morph formulas)
node_instance.id as custom property bdst_instance_id (these are used in poses / scene.animations)
"""
bname = si_bone.node.id
b_info = bone_info(bone=si_bone, bname=bname)
b_bone = armdat.edit_bones.new(name=bname)
b_bone.bdst_instance_id = si_bone.id
orient = si_bone.orientation
b_bone.use_deform = True
b_bone.use_inherit_scale = si_bone.inherits_scale
center_point = si_bone.center_point
end_point = si_bone.end_point
if center_point == end_point:
end_point = (end_point[0], end_point[1], end_point[2] + 0.3)
len = (mathutils.Vector(center_point) - mathutils.Vector(end_point)).length
b_bone.head = (0,0,0)
rot_order = si_bone.rotation_order
if si_bone.rotation_order[0] == "X":
sign = 1 if center_point[0] < end_point[0] else -1
b_bone.bdst_sign = "+X" if sign == 1 else "-X"
b_info.rotation_order = swap_rot(rot_order, {"X": "Y", "Y": "X", "Z": "Z"})
b_bone.tail = (sign * len, 0, 0)
elif si_bone.rotation_order[0] == "Y":
sign = 1 if center_point[1] < end_point[1] else -1
b_bone.bdst_sign = "+Y" if sign == 1 else "-Y"
b_info.rotation_order = swap_rot(rot_order, {"X": "X", "Y": "Y", "Z": "Z"})
b_bone.tail = (0, sign * len, 0)
else:
sign = 1 if center_point[2] < end_point[2] else -1
b_bone.bdst_sign = "+Z" if sign == 1 else "-Z"
b_info.rotation_order = swap_rot(rot_order, {"X": "X", "Y": "Z", "Z": "Y"})
b_bone.tail = (0, 0, sign * len)
b_bone.roll = 0
rot = mathutils.Euler(((orient[0]), (-orient[1]), (orient[2])), "XZY").to_matrix().to_4x4()
b_bone.transform(rot)
b_bone.translate(mathutils.Vector(center_point))
b_bone.bdst_center_point = center_point
b_bone.bdst_end_point = end_point
b_bone.bdst_orientation = orient
b_info.roots.append(bname)
b_info.leaf = bname
return [b_info]
def __init__(self, ob ):
if ob.location.x != 0 or ob.location.y != 0 or ob.location.z != 0:
Report.warnings.append('ERROR: Mesh (%s): is offset from Armature - zero transform is required' %ob.name)
if ob.scale.x != 1 or ob.scale.y != 1 or ob.scale.z != 1:
Report.warnings.append('ERROR: Mesh (%s): has been scaled - scale(1,1,1) is required' %ob.name)
self.object = ob
self.bones = []
mats = {}
self.arm = arm = findArmature( ob )
arm.hide = False
self._restore_layers = list(arm.layers)
#arm.layers = [True]*20 # can not have anything hidden - REQUIRED?
for pbone in arm.pose.bones:
mybone = Bone( arm.data.bones[pbone.name], pbone, self )
self.bones.append( mybone )
if arm.name not in Report.armatures:
Report.armatures.append( arm.name )
## bad idea - allowing rotation of armature, means vertices must also be rotated,
## also a bug with applying the rotation, the Z rotation is lost
#x,y,z = arm.matrix_local.copy().inverted().to_euler()
#e = mathutils.Euler( (x,z,y) )
#self.object_space_transformation = e.to_matrix().to_4x4()
x,y,z = arm.matrix_local.to_euler()
if x != 0 or y != 0 or z != 0:
Report.warnings.append('ERROR: Armature: %s is rotated - (rotation is ignored)' %arm.name)
## setup bones for Ogre format ##
for b in self.bones:
b.rebuild_tree()
## walk bones, convert them ##
self.roots = []
ep = 0.0001
for b in self.bones:
if not b.parent:
b.compute_rest()
loc,rot,scl = b.ogre_rest_matrix.decompose()
#if loc.x or loc.y or loc.z:
# Report.warnings.append('ERROR: root bone has non-zero transform (location offset)')
#if rot.w > ep or rot.x > ep or rot.y > ep or rot.z < 1.0-ep:
# Report.warnings.append('ERROR: root bone has non-zero transform (rotation offset)')
self.roots.append( b )
def execute(self, context):
node = context.node
selected_object = context.object
# get attribute value and type
data_path = "bpy.data."+node.data_enum + "['"+node.data_item+"']"
data_path = eval(data_path)
try:
attribute = eval("data_path"+"."+node.attribute_property)
except:
attribute = None
if attribute is not None:
if isinstance(attribute, str):
node.outputs.new('NodeSocketString', node.attribute_property)
elif isinstance(attribute, bool):
node.outputs.new('NodeSocketBool', node.attribute_property)
elif isinstance(attribute, int):
node.outputs.new('NodeSocketInt', node.attribute_property)
elif isinstance(attribute, float):
node.outputs.new('NodeSocketFloat', node.attribute_property)
elif isinstance(attribute, mathutils.Color):
node.outputs.new('NodeSocketColor', node.attribute_property)
elif isinstance(attribute, mathutils.Vector):
node.outputs.new('NodeSocketVector', node.attribute_property)
elif isinstance(attribute, mathutils.Euler):
node.outputs.new('NodeSocketVector', node.attribute_property)
elif isinstance(attribute, mathutils.Quaternion):
node.outputs.new('NodeSocketVector', node.attribute_property)
elif len(attribute) == 4: # RGBA
node.outputs.new('NodeSocketColor', node.attribute_property)
return{'FINISHED'}
def execute(self, context):
node = context.node
selected_object = context.object
# get attribute value and type
data_path = "bpy.data."+node.data_enum + "['"+node.data_item+"']"
data_path = eval(data_path)
try:
attribute = eval("data_path"+"."+node.attribute_property)
except:
attribute = None
if attribute is not None:
if isinstance(attribute, str):
node.inputs.new('NodeSocketString', node.attribute_property)
elif isinstance(attribute, bool):
node.inputs.new('NodeSocketBool', node.attribute_property)
elif isinstance(attribute, int):
node.inputs.new('NodeSocketInt', node.attribute_property)
elif isinstance(attribute, float):
node.inputs.new('NodeSocketFloat', node.attribute_property)
elif isinstance(attribute, mathutils.Color):
node.inputs.new('NodeSocketColor', node.attribute_property)
elif isinstance(attribute, mathutils.Vector):
node.inputs.new('NodeSocketVector', node.attribute_property)
elif isinstance(attribute, mathutils.Euler):
node.inputs.new('NodeSocketVector', node.attribute_property)
elif isinstance(attribute, mathutils.Quaternion):
node.inputs.new('NodeSocketVector', node.attribute_property)
elif len(attribute) == 4: # RGBA
node.inputs.new('NodeSocketColor', node.attribute_property)
return{'FINISHED'}