py api
- mathutils.Color.hsv attribute. eg. material.diffuse_color.hsv = 0.2, 0.8, 0.4 - Vector/Euler/Quaternion/Color now only take a single seq arg. - internal function for parsing arrays. (cleanup messy internal list/vector/tuple/seq parsing) - didnt update rigify yet.
This commit is contained in:
@@ -54,50 +54,11 @@ import time
|
|||||||
import math # math.pi
|
import math # math.pi
|
||||||
import shutil # for file copying
|
import shutil # for file copying
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# import Blender
|
|
||||||
import bpy
|
import bpy
|
||||||
import mathutils
|
from mathutils import Vector, Euler, Matrix, RotationMatrix
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def copy_file(source, dest):
|
def copy_file(source, dest):
|
||||||
|
# XXX - remove, can use shutil
|
||||||
file = open(source, 'rb')
|
file = open(source, 'rb')
|
||||||
data = file.read()
|
data = file.read()
|
||||||
file.close()
|
file.close()
|
||||||
@@ -135,7 +96,7 @@ def copy_images(dest_dir, textures):
|
|||||||
# I guess FBX uses degrees instead of radians (Arystan).
|
# I guess FBX uses degrees instead of radians (Arystan).
|
||||||
# Call this function just before writing to FBX.
|
# Call this function just before writing to FBX.
|
||||||
def eulerRadToDeg(eul):
|
def eulerRadToDeg(eul):
|
||||||
ret = mathutils.Euler()
|
ret = Euler()
|
||||||
|
|
||||||
ret.x = 180 / math.pi * eul[0]
|
ret.x = 180 / math.pi * eul[0]
|
||||||
ret.y = 180 / math.pi * eul[1]
|
ret.y = 180 / math.pi * eul[1]
|
||||||
@@ -143,10 +104,10 @@ def eulerRadToDeg(eul):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
mtx4_identity = mathutils.Matrix()
|
mtx4_identity = Matrix()
|
||||||
|
|
||||||
# testing
|
# testing
|
||||||
mtx_x90 = mathutils.RotationMatrix( math.pi/2, 3, 'X') # used
|
mtx_x90 = RotationMatrix( math.pi/2, 3, 'X') # used
|
||||||
#mtx_x90n = RotationMatrix(-90, 3, 'x')
|
#mtx_x90n = RotationMatrix(-90, 3, 'x')
|
||||||
#mtx_y90 = RotationMatrix( 90, 3, 'y')
|
#mtx_y90 = RotationMatrix( 90, 3, 'y')
|
||||||
#mtx_y90n = RotationMatrix(-90, 3, 'y')
|
#mtx_y90n = RotationMatrix(-90, 3, 'y')
|
||||||
@@ -154,11 +115,11 @@ mtx_x90 = mathutils.RotationMatrix( math.pi/2, 3, 'X') # used
|
|||||||
#mtx_z90n = RotationMatrix(-90, 3, 'z')
|
#mtx_z90n = RotationMatrix(-90, 3, 'z')
|
||||||
|
|
||||||
#mtx4_x90 = RotationMatrix( 90, 4, 'x')
|
#mtx4_x90 = RotationMatrix( 90, 4, 'x')
|
||||||
mtx4_x90n = mathutils.RotationMatrix(-math.pi/2, 4, 'X') # used
|
mtx4_x90n = RotationMatrix(-math.pi/2, 4, 'X') # used
|
||||||
#mtx4_y90 = RotationMatrix( 90, 4, 'y')
|
#mtx4_y90 = RotationMatrix( 90, 4, 'y')
|
||||||
mtx4_y90n = mathutils.RotationMatrix(-math.pi/2, 4, 'Y') # used
|
mtx4_y90n = RotationMatrix(-math.pi/2, 4, 'Y') # used
|
||||||
mtx4_z90 = mathutils.RotationMatrix( math.pi/2, 4, 'Z') # used
|
mtx4_z90 = RotationMatrix( math.pi/2, 4, 'Z') # used
|
||||||
mtx4_z90n = mathutils.RotationMatrix(-math.pi/2, 4, 'Z') # used
|
mtx4_z90n = RotationMatrix(-math.pi/2, 4, 'Z') # used
|
||||||
|
|
||||||
# def strip_path(p):
|
# def strip_path(p):
|
||||||
# return p.split('\\')[-1].split('/')[-1]
|
# return p.split('\\')[-1].split('/')[-1]
|
||||||
@@ -333,7 +294,7 @@ def write(filename, batch_objects = None, \
|
|||||||
EXP_CAMERA = True,
|
EXP_CAMERA = True,
|
||||||
EXP_EMPTY = True,
|
EXP_EMPTY = True,
|
||||||
EXP_IMAGE_COPY = False,
|
EXP_IMAGE_COPY = False,
|
||||||
GLOBAL_MATRIX = mathutils.Matrix(),
|
GLOBAL_MATRIX = Matrix(),
|
||||||
ANIM_ENABLE = True,
|
ANIM_ENABLE = True,
|
||||||
ANIM_OPTIMIZE = True,
|
ANIM_OPTIMIZE = True,
|
||||||
ANIM_OPTIMIZE_PRECISSION = 6,
|
ANIM_OPTIMIZE_PRECISSION = 6,
|
||||||
@@ -600,8 +561,8 @@ def write(filename, batch_objects = None, \
|
|||||||
matrix_rot = matrix_rot * mtx_x90
|
matrix_rot = matrix_rot * mtx_x90
|
||||||
elif type =='CAMERA':
|
elif type =='CAMERA':
|
||||||
# elif ob and type =='Camera':
|
# elif ob and type =='Camera':
|
||||||
y = matrix_rot * mathutils.Vector(0,1,0)
|
y = matrix_rot * Vector((0.0, 1.0, 0.0))
|
||||||
matrix_rot = mathutils.RotationMatrix(math.pi/2, 3, y) * matrix_rot
|
matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
|
||||||
|
|
||||||
return matrix_rot
|
return matrix_rot
|
||||||
|
|
||||||
@@ -702,8 +663,8 @@ def write(filename, batch_objects = None, \
|
|||||||
matrix_rot = matrix_rot * mtx_x90
|
matrix_rot = matrix_rot * mtx_x90
|
||||||
rot = tuple(matrix_rot.to_euler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
elif ob and ob.type =='Camera':
|
elif ob and ob.type =='Camera':
|
||||||
y = matrix_rot * mathutils.Vector(0,1,0)
|
y = matrix_rot * Vector((0.0, 1.0, 0.0))
|
||||||
matrix_rot = mathutils.RotationMatrix(math.pi/2, 3, y) * matrix_rot
|
matrix_rot = RotationMatrix(math.pi/2, 3, y) * matrix_rot
|
||||||
rot = tuple(matrix_rot.to_euler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
else:
|
else:
|
||||||
rot = tuple(matrix_rot.to_euler())
|
rot = tuple(matrix_rot.to_euler())
|
||||||
@@ -1088,8 +1049,8 @@ def write(filename, batch_objects = None, \
|
|||||||
file.write('\n\t\tTypeFlags: "Camera"')
|
file.write('\n\t\tTypeFlags: "Camera"')
|
||||||
file.write('\n\t\tGeometryVersion: 124')
|
file.write('\n\t\tGeometryVersion: 124')
|
||||||
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
|
file.write('\n\t\tPosition: %.6f,%.6f,%.6f' % loc)
|
||||||
file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(matrix_rot * mathutils.Vector(0,1,0)) )
|
file.write('\n\t\tUp: %.6f,%.6f,%.6f' % tuple(matrix_rot * Vector((0.0, 1.0, 0.0))))
|
||||||
file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(matrix_rot * mathutils.Vector(0,0,-1)) )
|
file.write('\n\t\tLookAt: %.6f,%.6f,%.6f' % tuple(matrix_rot * Vector((0.0, 0.0, -1.0))))
|
||||||
|
|
||||||
#file.write('\n\t\tUp: 0,0,0' )
|
#file.write('\n\t\tUp: 0,0,0' )
|
||||||
#file.write('\n\t\tLookAt: 0,0,0' )
|
#file.write('\n\t\tLookAt: 0,0,0' )
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def eulerRotate(x, y, z, rot_order):
|
|||||||
|
|
||||||
# Should work but doesnt!
|
# Should work but doesnt!
|
||||||
'''
|
'''
|
||||||
eul = Euler(x,y,z)
|
eul = Euler((x, y, z))
|
||||||
eul.order = "XYZ"[rot_order[0]] + "XYZ"[rot_order[1]] + "XYZ"[rot_order[2]]
|
eul.order = "XYZ"[rot_order[0]] + "XYZ"[rot_order[1]] + "XYZ"[rot_order[2]]
|
||||||
return tuple(eul.to_matrix().to_euler())
|
return tuple(eul.to_matrix().to_euler())
|
||||||
'''
|
'''
|
||||||
@@ -136,7 +136,7 @@ def read_bvh(context, file_path, ROT_MODE='XYZ', GLOBAL_SCALE=1.0):
|
|||||||
#print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
|
#print '%snode: %s, parent: %s' % (len(bvh_nodes_serial) * ' ', name, bvh_nodes_serial[-1])
|
||||||
|
|
||||||
lineIdx += 2 # Incriment to the next line (Offset)
|
lineIdx += 2 # Incriment to the next line (Offset)
|
||||||
rest_head_local = Vector(float(file_lines[lineIdx][1]), float(file_lines[lineIdx][2]), float(file_lines[lineIdx][3])) * GLOBAL_SCALE
|
rest_head_local = Vector((float(file_lines[lineIdx][1]), float(file_lines[lineIdx][2]), float(file_lines[lineIdx][3]))) * GLOBAL_SCALE
|
||||||
lineIdx += 1 # Incriment to the next line (Channels)
|
lineIdx += 1 # Incriment to the next line (Channels)
|
||||||
|
|
||||||
# newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
|
# newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
|
||||||
@@ -188,7 +188,7 @@ def read_bvh(context, file_path, ROT_MODE='XYZ', GLOBAL_SCALE=1.0):
|
|||||||
# Account for an end node
|
# Account for an end node
|
||||||
if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it.
|
if file_lines[lineIdx][0].lower() == 'end' and file_lines[lineIdx][1].lower() == 'site': # There is somtimes a name after 'End Site' but we will ignore it.
|
||||||
lineIdx += 2 # Incriment to the next line (Offset)
|
lineIdx += 2 # Incriment to the next line (Offset)
|
||||||
rest_tail = Vector(float(file_lines[lineIdx][1]), float(file_lines[lineIdx][2]), float(file_lines[lineIdx][3])) * GLOBAL_SCALE
|
rest_tail = Vector((float(file_lines[lineIdx][1]), float(file_lines[lineIdx][2]), float(file_lines[lineIdx][3]))) * GLOBAL_SCALE
|
||||||
|
|
||||||
bvh_nodes_serial[-1].rest_tail_world = bvh_nodes_serial[-1].rest_head_world + rest_tail
|
bvh_nodes_serial[-1].rest_tail_world = bvh_nodes_serial[-1].rest_head_world + rest_tail
|
||||||
bvh_nodes_serial[-1].rest_tail_local = bvh_nodes_serial[-1].rest_head_local + rest_tail
|
bvh_nodes_serial[-1].rest_tail_local = bvh_nodes_serial[-1].rest_head_local + rest_tail
|
||||||
@@ -267,8 +267,8 @@ def read_bvh(context, file_path, ROT_MODE='XYZ', GLOBAL_SCALE=1.0):
|
|||||||
# raise 'error, bvh node has no end and no children. bad file'
|
# raise 'error, bvh node has no end and no children. bad file'
|
||||||
|
|
||||||
# Removed temp for now
|
# Removed temp for now
|
||||||
rest_tail_world = Vector(0.0, 0.0, 0.0)
|
rest_tail_world = Vector((0.0, 0.0, 0.0))
|
||||||
rest_tail_local = Vector(0.0, 0.0, 0.0)
|
rest_tail_local = Vector((0.0, 0.0, 0.0))
|
||||||
for bvh_node_child in bvh_node.children:
|
for bvh_node_child in bvh_node.children:
|
||||||
rest_tail_world += bvh_node_child.rest_head_world
|
rest_tail_world += bvh_node_child.rest_head_world
|
||||||
rest_tail_local += bvh_node_child.rest_head_local
|
rest_tail_local += bvh_node_child.rest_head_local
|
||||||
@@ -328,7 +328,7 @@ def bvh_node_dict2objects(context, bvh_nodes, IMPORT_START_FRAME=1, IMPORT_LOOP=
|
|||||||
lx, ly, lz, rx, ry, rz = bvh_node.anim_data[frame_current]
|
lx, ly, lz, rx, ry, rz = bvh_node.anim_data[frame_current]
|
||||||
|
|
||||||
rest_head_local = bvh_node.rest_head_local
|
rest_head_local = bvh_node.rest_head_local
|
||||||
bvh_node.temp.loc = rest_head_local + Vector(lx, ly, lz)
|
bvh_node.temp.loc = rest_head_local + Vector((lx, ly, lz))
|
||||||
|
|
||||||
bvh_node.temp.rot = rx, ry, rz
|
bvh_node.temp.rot = rx, ry, rz
|
||||||
|
|
||||||
@@ -531,7 +531,7 @@ def bvh_node_dict2armature(context, bvh_nodes, ROT_MODE='XYZ', IMPORT_START_FRAM
|
|||||||
prev_euler[i] = euler
|
prev_euler[i] = euler
|
||||||
|
|
||||||
if bvh_node.has_loc:
|
if bvh_node.has_loc:
|
||||||
pose_bone.location = (bone_rest_matrix_inv * TranslationMatrix(Vector(lx, ly, lz) - bvh_node.rest_head_local)).translation_part()
|
pose_bone.location = (bone_rest_matrix_inv * TranslationMatrix(Vector((lx, ly, lz)) - bvh_node.rest_head_local)).translation_part()
|
||||||
|
|
||||||
if bvh_node.has_loc:
|
if bvh_node.has_loc:
|
||||||
pose_bone.keyframe_insert("location")
|
pose_bone.keyframe_insert("location")
|
||||||
|
|||||||
@@ -95,19 +95,19 @@ class _GenericBone:
|
|||||||
def x_axis(self):
|
def x_axis(self):
|
||||||
""" Vector pointing down the x-axis of the bone.
|
""" Vector pointing down the x-axis of the bone.
|
||||||
"""
|
"""
|
||||||
return self.matrix.rotation_part() * Vector(1.0, 0.0, 0.0)
|
return self.matrix.rotation_part() * Vector((1.0, 0.0, 0.0))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def y_axis(self):
|
def y_axis(self):
|
||||||
""" Vector pointing down the x-axis of the bone.
|
""" Vector pointing down the x-axis of the bone.
|
||||||
"""
|
"""
|
||||||
return self.matrix.rotation_part() * Vector(0.0, 1.0, 0.0)
|
return self.matrix.rotation_part() * Vector((0.0, 1.0, 0.0))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z_axis(self):
|
def z_axis(self):
|
||||||
""" Vector pointing down the x-axis of the bone.
|
""" Vector pointing down the x-axis of the bone.
|
||||||
"""
|
"""
|
||||||
return self.matrix.rotation_part() * Vector(0.0, 0.0, 1.0)
|
return self.matrix.rotation_part() * Vector((0.0, 0.0, 1.0))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def basename(self):
|
def basename(self):
|
||||||
@@ -237,7 +237,7 @@ class EditBone(StructRNA, _GenericBone):
|
|||||||
Expects a 4x4 or 3x3 matrix.
|
Expects a 4x4 or 3x3 matrix.
|
||||||
"""
|
"""
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
z_vec = self.matrix.rotation_part() * Vector(0.0, 0.0, 1.0)
|
z_vec = self.matrix.rotation_part() * Vector((0.0, 0.0, 1.0))
|
||||||
self.tail = matrix * self.tail
|
self.tail = matrix * self.tail
|
||||||
self.head = matrix * self.head
|
self.head = matrix * self.head
|
||||||
scalar = matrix.median_scale
|
scalar = matrix.median_scale
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
|
|||||||
for minor_index in range(minor_seg):
|
for minor_index in range(minor_seg):
|
||||||
angle = 2 * pi * minor_index / minor_seg
|
angle = 2 * pi * minor_index / minor_seg
|
||||||
|
|
||||||
vec = Vector(major_rad + (cos(angle) * minor_rad), 0.0,
|
vec = Vector((major_rad + (cos(angle) * minor_rad), 0.0,
|
||||||
(sin(angle) * minor_rad)) * quat
|
(sin(angle) * minor_rad))) * quat
|
||||||
|
|
||||||
verts.extend([vec.x, vec.y, vec.z])
|
verts.extend([vec.x, vec.y, vec.z])
|
||||||
|
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ class MakeDupliFace(bpy.types.Operator):
|
|||||||
|
|
||||||
SCALE_FAC = 0.01
|
SCALE_FAC = 0.01
|
||||||
offset = 0.5 * SCALE_FAC
|
offset = 0.5 * SCALE_FAC
|
||||||
base_tri = Vector(-offset, -offset, 0.0), Vector(offset, -offset, 0.0), Vector(offset, offset, 0.0), Vector(-offset, offset, 0.0)
|
base_tri = Vector((-offset, -offset, 0.0)), Vector((offset, -offset, 0.0)), Vector((offset, offset, 0.0)), Vector((-offset, offset, 0.0))
|
||||||
|
|
||||||
def matrix_to_quat(matrix):
|
def matrix_to_quat(matrix):
|
||||||
# scale = matrix.median_scale
|
# scale = matrix.median_scale
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ def pointInEdges(pt, edges):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def pointInIsland(pt, island):
|
def pointInIsland(pt, island):
|
||||||
vec1 = Vector(); vec2 = Vector(); vec3 = Vector()
|
vec1, vec2, vec3 = Vector(), Vector(), Vector()
|
||||||
for f in island:
|
for f in island:
|
||||||
vec1.x, vec1.y = f.uv[0]
|
vec1.x, vec1.y = f.uv[0]
|
||||||
vec2.x, vec2.y = f.uv[1]
|
vec2.x, vec2.y = f.uv[1]
|
||||||
@@ -389,7 +389,7 @@ def mergeUvIslands(islandList):
|
|||||||
w, h = maxx-minx, maxy-miny
|
w, h = maxx-minx, maxy-miny
|
||||||
|
|
||||||
totFaceArea = 0
|
totFaceArea = 0
|
||||||
offset= Vector(minx, miny)
|
offset= Vector((minx, miny))
|
||||||
for f in islandList[islandIdx]:
|
for f in islandList[islandIdx]:
|
||||||
for uv in f.uv:
|
for uv in f.uv:
|
||||||
uv -= offset
|
uv -= offset
|
||||||
@@ -513,7 +513,7 @@ def mergeUvIslands(islandList):
|
|||||||
|
|
||||||
##testcount+=1
|
##testcount+=1
|
||||||
#print 'Testing intersect'
|
#print 'Testing intersect'
|
||||||
Intersect = islandIntersectUvIsland(sourceIsland, targetIsland, Vector(boxLeft, boxBottom))
|
Intersect = islandIntersectUvIsland(sourceIsland, targetIsland, Vector((boxLeft, boxBottom)))
|
||||||
#print 'Done', Intersect
|
#print 'Done', Intersect
|
||||||
if Intersect == 1: # Line intersect, dont bother with this any more
|
if Intersect == 1: # Line intersect, dont bother with this any more
|
||||||
pass
|
pass
|
||||||
@@ -539,7 +539,7 @@ def mergeUvIslands(islandList):
|
|||||||
|
|
||||||
# Move faces into new island and offset
|
# Move faces into new island and offset
|
||||||
targetIsland[0].extend(sourceIsland[0])
|
targetIsland[0].extend(sourceIsland[0])
|
||||||
offset= Vector(boxLeft, boxBottom)
|
offset= Vector((boxLeft, boxBottom))
|
||||||
|
|
||||||
for f in sourceIsland[0]:
|
for f in sourceIsland[0]:
|
||||||
for uv in f.uv:
|
for uv in f.uv:
|
||||||
@@ -564,7 +564,7 @@ def mergeUvIslands(islandList):
|
|||||||
|
|
||||||
|
|
||||||
targetIsland[7].extend(sourceIsland[7])
|
targetIsland[7].extend(sourceIsland[7])
|
||||||
offset= Vector(boxLeft, boxBottom, 0)
|
offset= Vector((boxLeft, boxBottom, 0.0))
|
||||||
for p in sourceIsland[7]:
|
for p in sourceIsland[7]:
|
||||||
p+= offset
|
p+= offset
|
||||||
|
|
||||||
@@ -780,9 +780,9 @@ def packIslands(islandList):
|
|||||||
def VectoMat(vec):
|
def VectoMat(vec):
|
||||||
a3 = vec.__copy__().normalize()
|
a3 = vec.__copy__().normalize()
|
||||||
|
|
||||||
up = Vector(0,0,1)
|
up = Vector((0.0, 0.0, 1.0))
|
||||||
if abs(a3.dot(up)) == 1.0:
|
if abs(a3.dot(up)) == 1.0:
|
||||||
up = Vector(0,1,0)
|
up = Vector((0.0, 1.0, 0.0))
|
||||||
|
|
||||||
a1 = a3.cross(up).normalize()
|
a1 = a3.cross(up).normalize()
|
||||||
a2 = a3.cross(a1)
|
a2 = a3.cross(a1)
|
||||||
@@ -963,7 +963,7 @@ def main(context, island_margin, projection_limit):
|
|||||||
newProjectMeshFaces.append(tempMeshFaces.pop(fIdx))
|
newProjectMeshFaces.append(tempMeshFaces.pop(fIdx))
|
||||||
|
|
||||||
# Add the average of all these faces normals as a projectionVec
|
# Add the average of all these faces normals as a projectionVec
|
||||||
averageVec = Vector(0,0,0)
|
averageVec = Vector(0.0, 0.0, 0.0)
|
||||||
if USER_AREA_WEIGHT:
|
if USER_AREA_WEIGHT:
|
||||||
for fprop in newProjectMeshFaces:
|
for fprop in newProjectMeshFaces:
|
||||||
averageVec += (fprop.no * fprop.area)
|
averageVec += (fprop.no * fprop.area)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
|||||||
|
|
||||||
# get the direction of the vectors between the vertex and it's connected vertices
|
# get the direction of the vectors between the vertex and it's connected vertices
|
||||||
for c in con[i]:
|
for c in con[i]:
|
||||||
vec += Vector(me.verts[c].co - co).normalize()
|
vec += (me.verts[c].co - co).normalize()
|
||||||
|
|
||||||
# normalize the vector by dividing by the number of connected verts
|
# normalize the vector by dividing by the number of connected verts
|
||||||
tot_con = len(con[i])
|
tot_con = len(con[i])
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
/* Note: Changes to Mathutils since 2.4x
|
/* Note: Changes to Mathutils since 2.4x
|
||||||
* use radians rather then degrees
|
* use radians rather then degrees
|
||||||
|
* - Mathutils.Vector/Euler/Quaternion(), now only take single sequence arguments.
|
||||||
* - Mathutils.MidpointVecs --> vector.lerp(other, fac)
|
* - Mathutils.MidpointVecs --> vector.lerp(other, fac)
|
||||||
* - Mathutils.AngleBetweenVecs --> vector.angle(other)
|
* - Mathutils.AngleBetweenVecs --> vector.angle(other)
|
||||||
* - Mathutils.ProjectVecs --> vector.project(other)
|
* - Mathutils.ProjectVecs --> vector.project(other)
|
||||||
@@ -55,6 +56,42 @@
|
|||||||
static char M_Mathutils_doc[] =
|
static char M_Mathutils_doc[] =
|
||||||
"This module provides access to matrices, eulers, quaternions and vectors.";
|
"This module provides access to matrices, eulers, quaternions and vectors.";
|
||||||
|
|
||||||
|
/* helper functionm returns length of the 'value', -1 on error */
|
||||||
|
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
|
||||||
|
{
|
||||||
|
PyObject *value_fast= NULL;
|
||||||
|
|
||||||
|
int i, size;
|
||||||
|
|
||||||
|
/* non list/tuple cases */
|
||||||
|
if(!(value_fast=PySequence_Fast(value, error_prefix))) {
|
||||||
|
/* PySequence_Fast sets the error */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size= PySequence_Fast_GET_SIZE(value_fast);
|
||||||
|
|
||||||
|
if(size > array_max || size < array_min) {
|
||||||
|
if (array_max == array_min) PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected %d", error_prefix, size, array_max);
|
||||||
|
else PyErr_Format(PyExc_ValueError, "%.200s: sequence size is %d, expected [%d - %d]", error_prefix, size, array_min, array_max);
|
||||||
|
Py_DECREF(value_fast);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i= size;
|
||||||
|
do {
|
||||||
|
i--;
|
||||||
|
if(((array[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i))) == -1.0) && PyErr_Occurred()) {
|
||||||
|
PyErr_Format(PyExc_ValueError, "%.200s: sequence index %d is not a float", error_prefix, i);
|
||||||
|
Py_DECREF(value_fast);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while(i);
|
||||||
|
|
||||||
|
Py_XDECREF(value_fast);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------METHODS----------------------------
|
//-----------------------------METHODS----------------------------
|
||||||
//-----------------quat_rotation (internal)-----------
|
//-----------------quat_rotation (internal)-----------
|
||||||
//This function multiplies a vector/point * quat or vice versa
|
//This function multiplies a vector/point * quat or vice versa
|
||||||
|
|||||||
@@ -115,4 +115,7 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
|
|||||||
#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1))
|
#define BaseMath_ReadIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_ReadIndexCallback((BaseMathObject *)_self, _index):1))
|
||||||
#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1))
|
#define BaseMath_WriteIndexCallback(_self, _index) (((_self)->cb_user ? _BaseMathObject_WriteIndexCallback((BaseMathObject *)_self, _index):1))
|
||||||
|
|
||||||
|
/* utility func */
|
||||||
|
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
|
||||||
|
|
||||||
#endif /* EXPP_Mathutils_H */
|
#endif /* EXPP_Mathutils_H */
|
||||||
|
|||||||
@@ -31,50 +31,20 @@
|
|||||||
//makes a new color for you to play with
|
//makes a new color for you to play with
|
||||||
static PyObject *Color_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
|
static PyObject *Color_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
|
||||||
{
|
{
|
||||||
PyObject *listObject = NULL;
|
float col[3]= {0.0f, 0.0f, 0.0f};
|
||||||
int size, i;
|
|
||||||
float col[3];
|
|
||||||
PyObject *e;
|
|
||||||
|
|
||||||
|
switch(PyTuple_GET_SIZE(args)) {
|
||||||
size = PyTuple_GET_SIZE(args);
|
case 0:
|
||||||
if (size == 1) {
|
break;
|
||||||
listObject = PyTuple_GET_ITEM(args, 0);
|
case 1:
|
||||||
if (PySequence_Check(listObject)) {
|
if((mathutils_array_parse(col, 3, 3, PyTuple_GET_ITEM(args, 0), "mathutils.Color()")) == -1)
|
||||||
size = PySequence_Length(listObject);
|
|
||||||
} else { // Single argument was not a sequence
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Color(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
break;
|
||||||
} else if (size == 0) {
|
default:
|
||||||
//returns a new empty 3d color
|
PyErr_SetString(PyExc_TypeError, "mathutils.Color(): more then a single arg given");
|
||||||
return newColorObject(NULL, Py_NEW, NULL);
|
|
||||||
} else {
|
|
||||||
listObject = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != 3) { // Invalid color size
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Color(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
return newColorObject(col, Py_NEW, type);
|
||||||
for (i=0; i<size; i++) {
|
|
||||||
e = PySequence_GetItem(listObject, i);
|
|
||||||
if (e == NULL) { // Failed to read sequence
|
|
||||||
Py_DECREF(listObject);
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "mathutils.Color(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
col[i]= (float)PyFloat_AsDouble(e);
|
|
||||||
Py_DECREF(e);
|
|
||||||
|
|
||||||
if(col[i]==-1 && PyErr_Occurred()) { // parsed item is not a number
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Color(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newColorObject(col, Py_NEW, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------METHODS----------------------------
|
//-----------------------------METHODS----------------------------
|
||||||
@@ -131,7 +101,7 @@ static PyObject *Color_repr(ColorObject * self)
|
|||||||
|
|
||||||
tuple= Color_ToTupleExt(self, -1);
|
tuple= Color_ToTupleExt(self, -1);
|
||||||
|
|
||||||
ret= PyUnicode_FromFormat("Color%R", tuple);
|
ret= PyUnicode_FromFormat("Color(%R)", tuple);
|
||||||
|
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -363,6 +333,43 @@ static int Color_setChannelHSV(ColorObject * self, PyObject * value, void * type
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* color channel (HSV), color.h/s/v */
|
||||||
|
static PyObject *Color_getHSV(ColorObject * self, void *type)
|
||||||
|
{
|
||||||
|
float hsv[3];
|
||||||
|
PyObject *ret;
|
||||||
|
|
||||||
|
if(!BaseMath_ReadCallback(self))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rgb_to_hsv(self->col[0], self->col[1], self->col[2], &(hsv[0]), &(hsv[1]), &(hsv[2]));
|
||||||
|
|
||||||
|
ret= PyTuple_New(3);
|
||||||
|
PyTuple_SET_ITEM(ret, 0, PyFloat_FromDouble(hsv[0]));
|
||||||
|
PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(hsv[1]));
|
||||||
|
PyTuple_SET_ITEM(ret, 2, PyFloat_FromDouble(hsv[2]));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Color_setHSV(ColorObject * self, PyObject * value, void * type)
|
||||||
|
{
|
||||||
|
float hsv[3];
|
||||||
|
|
||||||
|
if(mathutils_array_parse(hsv, 3, 3, value, "mathutils.Color.hsv = value") == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
CLAMP(hsv[0], 0.0f, 1.0f);
|
||||||
|
CLAMP(hsv[1], 0.0f, 1.0f);
|
||||||
|
CLAMP(hsv[2], 0.0f, 1.0f);
|
||||||
|
|
||||||
|
hsv_to_rgb(hsv[0], hsv[1], hsv[2], &(self->col[0]), &(self->col[1]), &(self->col[2]));
|
||||||
|
|
||||||
|
if(!BaseMath_WriteCallback(self))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Python attributes get/set structure: */
|
/* Python attributes get/set structure: */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -375,6 +382,8 @@ static PyGetSetDef Color_getseters[] = {
|
|||||||
{"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Saturation component in [0, 1]. **type** float", (void *)1},
|
{"s", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Saturation component in [0, 1]. **type** float", (void *)1},
|
||||||
{"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Value component in [0, 1]. **type** float", (void *)2},
|
{"v", (getter)Color_getChannelHSV, (setter)Color_setChannelHSV, "HSV Value component in [0, 1]. **type** float", (void *)2},
|
||||||
|
|
||||||
|
{"hsv", (getter)Color_getHSV, (setter)Color_setHSV, "HSV Values in [0, 1]. **type** float triplet", (void *)0},
|
||||||
|
|
||||||
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
|
{"is_wrapped", (getter)BaseMathObject_getWrapped, (setter)NULL, BaseMathObject_Wrapped_doc, NULL},
|
||||||
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
|
{"_owner", (getter)BaseMathObject_getOwner, (setter)NULL, BaseMathObject_Owner_doc, NULL},
|
||||||
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
|
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
|
||||||
|
|||||||
@@ -39,48 +39,26 @@
|
|||||||
//makes a new euler for you to play with
|
//makes a new euler for you to play with
|
||||||
static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
|
static PyObject *Euler_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
|
||||||
{
|
{
|
||||||
PyObject *listObject = NULL;
|
PyObject *seq= NULL;
|
||||||
int size, i;
|
char *order_str= NULL;
|
||||||
float eul[3];
|
|
||||||
PyObject *e;
|
|
||||||
short order= 0; // TODO, add order option
|
|
||||||
|
|
||||||
size = PyTuple_GET_SIZE(args);
|
float eul[3]= {0.0f, 0.0f, 0.0f};
|
||||||
if (size == 1) {
|
short order= 0;
|
||||||
listObject = PyTuple_GET_ITEM(args, 0);
|
|
||||||
if (PySequence_Check(listObject)) {
|
|
||||||
size = PySequence_Length(listObject);
|
|
||||||
} else { // Single argument was not a sequence
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Euler(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else if (size == 0) {
|
|
||||||
//returns a new empty 3d euler
|
|
||||||
return newEulerObject(NULL, order, Py_NEW, NULL);
|
|
||||||
} else {
|
|
||||||
listObject = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != 3) { // Invalid euler size
|
if(!PyArg_ParseTuple(args, "|Os:mathutils.Euler", &seq, &order_str))
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Euler(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<size; i++) {
|
switch(PyTuple_GET_SIZE(args)) {
|
||||||
e = PySequence_GetItem(listObject, i);
|
case 0:
|
||||||
if (e == NULL) { // Failed to read sequence
|
break;
|
||||||
Py_DECREF(listObject);
|
case 2:
|
||||||
PyErr_SetString(PyExc_RuntimeError, "mathutils.Euler(): 3d numeric sequence expected\n");
|
if((order=euler_order_from_string(order_str, "mathutils.Euler()")) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
/* intentionally pass through */
|
||||||
|
case 1:
|
||||||
eul[i]= (float)PyFloat_AsDouble(e);
|
if (mathutils_array_parse(eul, 3, 3, seq, "mathutils.Euler()") == -1)
|
||||||
Py_DECREF(e);
|
|
||||||
|
|
||||||
if(eul[i]==-1 && PyErr_Occurred()) { // parsed item is not a number
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Euler(): 3d numeric sequence expected\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
return newEulerObject(eul, order, Py_NEW, NULL);
|
return newEulerObject(eul, order, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
@@ -353,7 +331,7 @@ static PyObject *Euler_repr(EulerObject * self)
|
|||||||
|
|
||||||
tuple= Euler_ToTupleExt(self, -1);
|
tuple= Euler_ToTupleExt(self, -1);
|
||||||
|
|
||||||
ret= PyUnicode_FromFormat("Euler%R", tuple);
|
ret= PyUnicode_FromFormat("Euler(%R)", tuple);
|
||||||
|
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ static PyObject *Quaternion_repr(QuaternionObject * self)
|
|||||||
|
|
||||||
tuple= Quaternion_ToTupleExt(self, -1);
|
tuple= Quaternion_ToTupleExt(self, -1);
|
||||||
|
|
||||||
ret= PyUnicode_FromFormat("Quaternion%R", tuple);
|
ret= PyUnicode_FromFormat("Quaternion(%R)", tuple);
|
||||||
|
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -743,94 +743,27 @@ static PyObject *Quaternion_getAxisVec( QuaternionObject * self, void *type )
|
|||||||
//----------------------------------mathutils.Quaternion() --------------
|
//----------------------------------mathutils.Quaternion() --------------
|
||||||
static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
PyObject *listObject = NULL, *n, *q;
|
PyObject *seq= NULL;
|
||||||
int size, i;
|
|
||||||
float quat[4];
|
|
||||||
double angle = 0.0f;
|
double angle = 0.0f;
|
||||||
|
float quat[4]= {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
size = PyTuple_GET_SIZE(args);
|
if(!PyArg_ParseTuple(args, "|Of:mathutils.Quaternion", &seq, &angle))
|
||||||
if (size == 1 || size == 2) { //seq?
|
return NULL;
|
||||||
listObject = PyTuple_GET_ITEM(args, 0);
|
|
||||||
if (PySequence_Check(listObject)) {
|
|
||||||
size = PySequence_Length(listObject);
|
|
||||||
if ((size == 4 && PySequence_Length(args) !=1) ||
|
|
||||||
(size == 3 && PySequence_Length(args) !=2) || (size >4 || size < 3)) {
|
|
||||||
// invalid args/size
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(size == 3){ //get angle in axis/angle
|
|
||||||
n = PySequence_GetItem(args, 1);
|
|
||||||
if(n == NULL) { // parsed item not a number or getItem fail
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
angle = PyFloat_AsDouble(n);
|
switch(PyTuple_GET_SIZE(args)) {
|
||||||
Py_DECREF(n);
|
case 0:
|
||||||
|
break;
|
||||||
if (angle==-1 && PyErr_Occurred()) {
|
case 1:
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
if (mathutils_array_parse(quat, 4, 4, seq, "mathutils.Quaternion()") == -1)
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
listObject = PyTuple_GET_ITEM(args, 1);
|
|
||||||
if (size>1 && PySequence_Check(listObject)) {
|
|
||||||
size = PySequence_Length(listObject);
|
|
||||||
if (size != 3) {
|
|
||||||
// invalid args/size
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
angle = PyFloat_AsDouble(PyTuple_GET_ITEM(args, 0));
|
|
||||||
|
|
||||||
if (angle==-1 && PyErr_Occurred()) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else { // argument was not a sequence
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (size == 0) { //returns a new empty quat
|
|
||||||
return newQuaternionObject(NULL, Py_NEW, NULL);
|
|
||||||
} else {
|
|
||||||
listObject = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size == 3) { // invalid quat size
|
|
||||||
if(PySequence_Length(args) != 2){
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
break;
|
||||||
}else{
|
case 2:
|
||||||
if(size != 4){
|
if (mathutils_array_parse(quat, 3, 3, seq, "mathutils.Quaternion()") == -1)
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<size; i++) { //parse
|
|
||||||
q = PySequence_GetItem(listObject, i);
|
|
||||||
if (q == NULL) { // Failed to read sequence
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
quat[i] = PyFloat_AsDouble(q);
|
|
||||||
Py_DECREF(q);
|
|
||||||
|
|
||||||
if (quat[i]==-1 && PyErr_Occurred()) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Quaternion(): 4d numeric sequence expected or 3d vector and number\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(size == 3) //calculate the quat based on axis/angle
|
|
||||||
axis_angle_to_quat(quat, quat, angle);
|
axis_angle_to_quat(quat, quat, angle);
|
||||||
|
break;
|
||||||
|
/* PyArg_ParseTuple assures no more then 2 */
|
||||||
|
}
|
||||||
return newQuaternionObject(quat, Py_NEW, NULL);
|
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,48 +47,20 @@ static PyObject *Vector_ToTupleExt(VectorObject *self, int ndigits);
|
|||||||
// accepted. Mixed float and int values accepted. Ints are parsed to float
|
// accepted. Mixed float and int values accepted. Ints are parsed to float
|
||||||
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
PyObject *listObject = NULL;
|
float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
int size, i;
|
int size= 3; /* default to a 3D vector */
|
||||||
float vec[4], f;
|
|
||||||
PyObject *v;
|
|
||||||
|
|
||||||
size = PyTuple_GET_SIZE(args); /* we know its a tuple because its an arg */
|
switch(PyTuple_GET_SIZE(args)) {
|
||||||
if (size == 1) {
|
case 0:
|
||||||
listObject = PyTuple_GET_ITEM(args, 0);
|
break;
|
||||||
if (PySequence_Check(listObject)) {
|
case 1:
|
||||||
size = PySequence_Length(listObject);
|
if((size=mathutils_array_parse(vec, 2, 4, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1)
|
||||||
} else { // Single argument was not a sequence
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
break;
|
||||||
} else if (size == 0) {
|
default:
|
||||||
//returns a new empty 3d vector
|
PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): more then a single arg given");
|
||||||
return newVectorObject(NULL, 3, Py_NEW, type);
|
|
||||||
} else {
|
|
||||||
listObject = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size<2 || size>4) { // Invalid vector size
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<size; i++) {
|
|
||||||
v=PySequence_GetItem(listObject, i);
|
|
||||||
if (v==NULL) { // Failed to read sequence
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((f=PyFloat_AsDouble(v)) == -1 && PyErr_Occurred()) { // parsed item not a number
|
|
||||||
Py_DECREF(v);
|
|
||||||
PyErr_SetString(PyExc_TypeError, "mathutils.Vector(): 2-4 floats or ints expected (optionally in a sequence)\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec[i]= f;
|
|
||||||
Py_DECREF(v);
|
|
||||||
}
|
|
||||||
return newVectorObject(vec, size, Py_NEW, type);
|
return newVectorObject(vec, size, Py_NEW, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +698,7 @@ static PyObject *Vector_repr(VectorObject *self)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
tuple= Vector_ToTupleExt(self, -1);
|
tuple= Vector_ToTupleExt(self, -1);
|
||||||
ret= PyUnicode_FromFormat("Vector%R", tuple);
|
ret= PyUnicode_FromFormat("Vector(%R)", tuple);
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1488,8 +1460,8 @@ static int Vector_setLength(VectorObject *self, PyObject * value )
|
|||||||
in Vector_createSwizzleGetSeter. */
|
in Vector_createSwizzleGetSeter. */
|
||||||
static PyObject *Vector_getSwizzle(VectorObject *self, void *closure)
|
static PyObject *Vector_getSwizzle(VectorObject *self, void *closure)
|
||||||
{
|
{
|
||||||
size_t axisA;
|
size_t axis_to;
|
||||||
size_t axisB;
|
size_t axis_from;
|
||||||
float vec[MAX_DIMENSIONS];
|
float vec[MAX_DIMENSIONS];
|
||||||
unsigned int swizzleClosure;
|
unsigned int swizzleClosure;
|
||||||
|
|
||||||
@@ -1497,22 +1469,22 @@ static PyObject *Vector_getSwizzle(VectorObject *self, void *closure)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Unpack the axes from the closure into an array. */
|
/* Unpack the axes from the closure into an array. */
|
||||||
axisA = 0;
|
axis_to = 0;
|
||||||
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
||||||
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
||||||
{
|
{
|
||||||
axisB = swizzleClosure & SWIZZLE_AXIS;
|
axis_from = swizzleClosure & SWIZZLE_AXIS;
|
||||||
if(axisB >= self->size) {
|
if(axis_from >= self->size) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.");
|
PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec[axisA] = self->vec[axisB];
|
vec[axis_to] = self->vec[axis_from];
|
||||||
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
||||||
axisA++;
|
axis_to++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return newVectorObject(vec, axisA, Py_NEW, Py_TYPE(self));
|
return newVectorObject(vec, axis_to, Py_NEW, Py_TYPE(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the items of this vector using a swizzle.
|
/* Set the items of this vector using a swizzle.
|
||||||
@@ -1527,16 +1499,16 @@ static PyObject *Vector_getSwizzle(VectorObject *self, void *closure)
|
|||||||
unchanged. */
|
unchanged. */
|
||||||
static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure)
|
static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure)
|
||||||
{
|
{
|
||||||
VectorObject *vecVal = NULL;
|
size_t size_from;
|
||||||
PyObject *item;
|
|
||||||
size_t listLen;
|
|
||||||
float scalarVal;
|
float scalarVal;
|
||||||
|
|
||||||
size_t axisB;
|
size_t axis_from;
|
||||||
size_t axisA;
|
size_t axis_to;
|
||||||
|
|
||||||
unsigned int swizzleClosure;
|
unsigned int swizzleClosure;
|
||||||
|
|
||||||
float vecTemp[MAX_DIMENSIONS];
|
float tvec[MAX_DIMENSIONS];
|
||||||
|
float vec_assign[MAX_DIMENSIONS];
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(self))
|
if(!BaseMath_ReadCallback(self))
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1544,95 +1516,49 @@ static int Vector_setSwizzle(VectorObject *self, PyObject * value, void *closure
|
|||||||
/* Check that the closure can be used with this vector: even 2D vectors have
|
/* Check that the closure can be used with this vector: even 2D vectors have
|
||||||
swizzles defined for axes z and w, but they would be invalid. */
|
swizzles defined for axes z and w, but they would be invalid. */
|
||||||
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
||||||
|
axis_from= 0;
|
||||||
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
||||||
{
|
{
|
||||||
axisA = swizzleClosure & SWIZZLE_AXIS;
|
axis_to = swizzleClosure & SWIZZLE_AXIS;
|
||||||
if (axisA >= self->size)
|
if (axis_to >= self->size)
|
||||||
{
|
{
|
||||||
PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n");
|
PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
||||||
|
axis_from++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VectorObject_Check(value))
|
if (((scalarVal=PyFloat_AsDouble(value)) == -1 && PyErr_Occurred())==0) {
|
||||||
{
|
int i;
|
||||||
/* Copy vector contents onto swizzled axes. */
|
for(i=0; i < MAX_DIMENSIONS; i++)
|
||||||
vecVal = (VectorObject*) value;
|
vec_assign[i]= scalarVal;
|
||||||
axisB = 0;
|
|
||||||
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
|
||||||
while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < vecVal->size)
|
|
||||||
{
|
|
||||||
axisA = swizzleClosure & SWIZZLE_AXIS;
|
|
||||||
|
|
||||||
if(axisB >= vecVal->size) {
|
size_from= axis_from;
|
||||||
PyErr_SetString(PyExc_AttributeError, "Error: vector does not have specified axis.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vecTemp[axisA] = vecVal->vec[axisB];
|
|
||||||
|
|
||||||
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
|
||||||
axisB++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(axisB != vecVal->size) {
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "Error: vector size does not match swizzle.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(self->vec, vecTemp, axisB * sizeof(float));
|
|
||||||
/* continue with BaseMathObject_WriteCallback at the end */
|
|
||||||
}
|
}
|
||||||
else if (PyList_Check(value))
|
else if((size_from=mathutils_array_parse(vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) {
|
||||||
{
|
|
||||||
/* Copy list contents onto swizzled axes. */
|
|
||||||
listLen = PyList_GET_SIZE(value);
|
|
||||||
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
|
||||||
axisB = 0;
|
|
||||||
while (swizzleClosure & SWIZZLE_VALID_AXIS && axisB < listLen)
|
|
||||||
{
|
|
||||||
item = PyList_GET_ITEM(value, axisB);
|
|
||||||
|
|
||||||
if((scalarVal=PyFloat_AsDouble(item))==-1.0 && PyErr_Occurred()) {
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "Error: list item could not be used as a float.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
axisA= swizzleClosure & SWIZZLE_AXIS;
|
|
||||||
vecTemp[axisA] = scalarVal;
|
|
||||||
|
|
||||||
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
|
||||||
axisB++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(axisB != listLen) {
|
|
||||||
PyErr_SetString(PyExc_AttributeError, "Error: list size does not match swizzle.\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(self->vec, vecTemp, axisB * sizeof(float));
|
|
||||||
/* continue with BaseMathObject_WriteCallback at the end */
|
|
||||||
}
|
|
||||||
else if (((scalarVal=PyFloat_AsDouble(value)) == -1 && PyErr_Occurred())==0)
|
|
||||||
{
|
|
||||||
/* Assign the same value to each axis. */
|
|
||||||
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
|
||||||
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
|
||||||
{
|
|
||||||
axisA = swizzleClosure & SWIZZLE_AXIS;
|
|
||||||
self->vec[axisA] = scalarVal;
|
|
||||||
|
|
||||||
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
|
||||||
}
|
|
||||||
/* continue with BaseMathObject_WriteCallback at the end */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PyErr_SetString( PyExc_TypeError, "Expected a Vector, list or scalar value." );
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(axis_from != size_from) {
|
||||||
|
PyErr_SetString(PyExc_AttributeError, "Error: vector size does not match swizzle.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy vector contents onto swizzled axes. */
|
||||||
|
axis_from = 0;
|
||||||
|
swizzleClosure = GET_INT_FROM_POINTER(closure);
|
||||||
|
while (swizzleClosure & SWIZZLE_VALID_AXIS)
|
||||||
|
{
|
||||||
|
axis_to = swizzleClosure & SWIZZLE_AXIS;
|
||||||
|
tvec[axis_to] = vec_assign[axis_from];
|
||||||
|
swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS;
|
||||||
|
axis_from++;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(self->vec, tvec, axis_from * sizeof(float));
|
||||||
|
/* continue with BaseMathObject_WriteCallback at the end */
|
||||||
|
|
||||||
if(!BaseMath_WriteCallback(self))
|
if(!BaseMath_WriteCallback(self))
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user